Charlie Robbins A collection of technical thoughts http://www.charlierobbins.com//rss.xml/ en-us 40 XamQuery: Reconciling the "theory" and "reality" of WPF vs. Silverlight <div class="hentry" id="article-xamquery-reconciling-the-theory-and-reality-of-wpf-vs-silverlight"> <div class="entry-content"> <p><b><em>Disclaimer: This technology does not actually exist yet, I am looking for feedback about this idea and anyone interested in working on it.</em></b></p> <p>I’m sure a lot of you have seen this image. It highlights some of the pain of working with Silverlight coming from a WPF background. </p> <p><img src="/assets/25/image.axd.png" height="450px" style="margin-left:150px" alt='silverlight-wpf-subset' /></p> <p>It occurred to me over the weekend that this is really a statement about <b><em>the consistency of the implementation of XAML DOM APIs.</em></b> With that in mind the next logical conclusion was that there is a very important parallel in the Javascript world, i.e. <b><em>the consistency of the implementation of the Javascript and HTML DOM APIs.</em></b> Thankfully since about 2005, much of this pain has been encapsulated into <a href="http://jquery.org">jQuery.</a></p> <p>So what about XAML? What can we do about it? This is where <b>XamQuery</b> would come in. Here’s a highlight of the core features I see and where I have needed them:</p> <ul> <li><p>A XAML DOM selector engine similar to Sizzle. Given that XAML doesn’t have complex selector syntax like CSS this would essentially be a highly optimized tree walker for the VisualTree that would wrap the disjoint APIs in WPF / Silverlight for getting visual parents and children.</p></li> <li><p>A set of fluent APIs for creating XAML DOM objects (Panels, Controls, etc) that would wrap some annoying inconsistencies when travelling between Silverlight and WPF as well as making it easier to do things in code that are <b>painfully verbose in pure XAML</b> (I think states of the VSM is a great example of this).</p></li> <li><p>A simple plug-in system for System.Interactivity Attached Behaviors to attach into. This would mirror the jQuery plugin system where each selector statement actually returns the jQuery object which you can then call plugins on.</p></li> </ul> <p>Feel free to contact me directly about this idea. I&#8217;m looking to get some like minded developers together to work on this. I think that this could be the thing that takes WPF and Silverlight development to the next level. </p> </div> <br/> <ul class="meta"> <li>Posted by <span class="fn">Charlie Robbins</span></li> </ul> </div> Mon, 22 Feb 2010 16:07:00 GMT http://www.charlierobbins.com//articles/2010/02/22/xamquery-reconciling-the-theory-and-reality-of-wpf-vs-silverlight/ http://www.charlierobbins.com//articles/2010/02/22/xamquery-reconciling-the-theory-and-reality-of-wpf-vs-silverlight/ Parsing JSON into dynamic objects using MGrammar and C# 4.0 <div class="hentry" id="article-parsing-json-into-dynamic-objects-using-mgrammar-and-c-4-0"> <div class="entry-content"> <p>I gave a talk last week at the <a href="http://njmsdev.org">New Jersey .NET User Meetup Group</a> on designing textual DSLs using MGrammar. You can download the slides here: <a href="/assets/19/Writing_Textual_DSLs.pptx">Textual DSLs with MGrammar</a>. The code portion of the project was focused around developing a JSON parser into dynamic objects in C# 4.0. JSON has become an increasingly popular data format over the last several years for it&#8217;s flexibility and simplicity. The entire JSON specification can be summarized in just five words: objects, arrays, values, numbers, and strings. Each of these diagrams has a clear representation in MGrammar shown below:</p> <h2>Objects</h2> <p><img src="/assets/20/object.gif" alt='json-object' /></p> <pre> <code> syntax Object = ObjectStart first:KeyValuePair rest:ObjectPart* ObjectEnd => Object { Pairs { first, valuesof(rest) } }; syntax ObjectPart = Comma pair:KeyValuePair => pair; syntax KeyValuePair = key:String Colin value:Value => Pair { Key { key }, Value { value } }; </code> </pre> <h2>Arrays</h2> <p><img src="/assets/21/array.gif" alt='json-array' /></p> <pre> <code> syntax Array = ArrayStart first:Value rest:ArrayPart* ArrayEnd => Array [ first, valuesof(rest) ]; syntax ArrayPart = Comma value:Value => value; </code> </pre> <h2>Values</h2> <p><img src="/assets/24/value.gif" alt='json-value' /></p> <pre> <code> syntax Value = string:String => string | number:Number => Number { number } | object:Object => object | array:Array => array | primitive:Primitive => Primitive { primitive }; </code> </pre> <h2>Numbers</h2> <p><img src="/assets/22/number.gif" alt='json-number' /></p> <pre> <code> token Number = Minus? Digit+ ('.' Digit+)? Exponent?; token Exponent = ("e" | "E") Sign? Digit+; token Digit = "0" .. "9"; token Sign = Plus | Minus; token Minus = "-"; token Plus = "+"; </code> </pre> <h2>Strings</h2> <p><img src="/assets/23/string.gif" alt='json-string' /></p> <pre> <code> syntax String = '"' text:(text:StringText | empty) '"' => String { valuesof(text) } ; token StringText = !('\u0022')+; </code> </pre> <h2>Inside the Parser</h2> <p>Much of the actual parsing is done using simple LINQ expressions. First through, you have to install Visual Studio 2010 and the <a href="http://www.microsoft.com/downloads/details.aspx?familyid=29E4EAD0-FD81-42BA-862B-F3589378466A&amp;displaylang=en">SQL Modeling November 2009 CTP (formerly &#8220;Oslo&#8221;)</a> and created a new &#8220;Oslo Library.&#8221; This is important because it sets up all the M and MGrammar dependencies for you. </p> <p>After you&#8217;ve created your Oslo Library, you must add your *.mg file and set the build action to &#8220;MCompile.&#8221; This will use the <a href="http://msdn.microsoft.com/en-us/library/dd129517%28VS.85%29.aspx">M tools</a> to compile the *.mg file into a *.mx image. After that&#8217;s completed we can create our parser at runtime:</p> <pre> <code class="csharp"> MImage grammar = new MImage(@"jsonm.mx"); grammarParser = grammar.ParserFactories["jsonm.jsonm"].Create(); grammarParser.GraphBuilder = new NodeGraphBuilder(); </code> </pre> <p>Now that we have our parser we can use that to parse the raw text into MGraph:</p> <pre> <code> var inputText = new StringTextStream(sourceText); var errorReporter = new ParserErrorReporter(); Node rootNode = (Node)grammarParser.Parse(inputText, errorReporter); JsonmObject obj = ParseObject(rootNode); return obj; </code> </pre> <p>The rest of the process uses a series of LINQ expressions using some extension methods (included with the project). Here&#8217;s an example of how objects are parsed:</p> <p>private static JsonmObject ParseObject(Node objectNode) { JsonmObject jsonmObject = new JsonmObject();</p> <pre><code>List&lt;Tuple&lt;string, object&gt;&gt; keyValuePairs = objectNode .Edges.FindNodeWithBrand("Pairs") .Edges.FindNodesWithBrand("Pair") .Select(node =&gt; ParseKeyValuePair(node)) .ToList(); foreach (Tuple&lt;string, object&gt; pair in keyValuePairs) { jsonmObject.TrySetMember( new DynamicDictionaryMemberBinder(pair.Item1, false), pair.Item2); } return jsonmObject; </code></pre> } </code> </pre> <p>You can see in the above example that in addition to parsing the MGraph, it sets members on our <a href="http://blog.lab49.com/archives/3893">dynamic dictionary</a>. This is how we can parse some sample JSON like this:</p> <pre> <code> { "Object" : { "String" : "StringValue", "Number" : -1.4e1, "null" : null, "true" : true, "false" : false }, "Array" : [ "StringValue", 42, false, true, null ], "String" : "StringValue", "Empty" : "", "Number" : -1.4e1, "null" : null, "true" : true, "false" : false } </code> </pre> <p>Into a dynamic object using our parser like so:</p> <pre> <code> dynamic result = JsonmParser.Parse(new Uri(Environment.CurrentDirectory + @"\sample.json")); Console.Out.WriteLine(result.Object,String); // ==> "StringValue" </code> </pre> <p>As always this code is on <a href="http://github.com/indexzero/jsonm">GitHub</a>. I look forward to see more parsers in MGrammar in the future, send any MGrammar hacks my way in email or comments!</p> </div> <br/> <ul class="meta"> <li>Posted by <span class="fn">Charlie Robbins</span></li> </ul> </div> Thu, 11 Feb 2010 20:11:00 GMT http://www.charlierobbins.com//articles/2010/02/11/parsing-json-into-dynamic-objects-using-mgrammar-and-c-4-0/ http://www.charlierobbins.com//articles/2010/02/11/parsing-json-into-dynamic-objects-using-mgrammar-and-c-4-0/ Capturing Raw Images from the Microsoft Surface <div class="hentry" id="article-capturing-raw-images-from-the-microsoft-surface"> <div class="entry-content"> <h2>Surface Multi-touch</h2> <p>As I mentioned in <a href="http://www.charlierobbins.com/articles/2009/12/25/adding-contactmultitap-to-the-microsoft-surface/">a previous post</a> the Microsoft Surface implements multi-touch using infrared computer vision as opposed to a capacitive approach. This is interesting for a couple of reasons. First it allows the Surface to recognize a <strong>very</strong> large number of touches. Second, it allows ambitious developers to tap directly into this infrared image data to perform more complex operations (like shape recognition). Getting at this information however is not entirely straight forward though. To simply things I created an attached behavior.</p> <h2>Attached Behaviors</h2> <p>Attached behaviors are something that I&#8217;ve <a href="http://www.charlierobbins.com/articles/2009/12/25/adding-contactmultitap-to-the-microsoft-surface/">blogged about</a> <a href="http://www.charlierobbins.com/articles/2009/07/13/robust-reusable-drag-drop-behavior-in-silverlight-3/">before.</a> They are a very convenient way to add user interface behavior to controls without having to implement a proper subclass. This behavior also implements a custom <a href="http://www.charlierobbins.com/articles/2009/07/13/robust-reusable-drag-drop-behavior-in-silverlight-3/">attached event</a>, which allows you to easily handle and process images captured from the Surface.</p> <h2>Using the Behavior</h2> <p>Using the behavior is simple; you just have to include the library in your solution, add the xmlns and set a couple of <a href="http://msdn.microsoft.com/en-us/library/ms749011.aspx">attached properties</a> and an event handler:</p> <pre> <code class="xaml"> &lt;s:SurfaceWindow behaviors:SurfaceWindowRawImageCapture.IsEnabled="True" behaviors:SurfaceWindowRawImageCapture.RawImageCaptured="YourEventHandler"&gt; (...) &lt;/s:SurfaceWindow&gt; </code> </pre> <h2>Optional Parameters</h2> <p>This behavior is designed to be flexible. There are several parameters that allow you to take advantage of this flexibility.</p> <p><strong>UseExplicitCapture=(true | false)</strong></p> <p>Setting this property to true will disable the attached event from being raised. It is false by default. Use it if you want to capture images programmatically which is explained below.</p> <p><strong>SaveTo=&#8221;C:\path\to\captured\images</strong></p> <p>Often it may be necessary to save the images that you capture to a specific location. If you set this property all images captured by the behavior will be saved to the specified directory.</p> <h2>Capturing Images Programmatically</h2> <p>The one drawback to the way that the Surface SDK allows developers to capture raw images is that the ContactDown event must be handled on the instance of the SurfaceWindow itself. What that means is that your attached event handler has to also be on the SurfaceWindow itself. The solution to this limitation is to call the behavior programmatically from your own code:</p> <pre> <code class="csharp"> SurfaceWindowRawImageCapture.CaptureRawImageAsync( Application.Current.MainWindow as SurfaceWindow, new Rect(100, 100, 100, 100), result => { // Code to execute when the result has been captured }); </code> </pre> <p>The Rect that is passed to the method defines an area to crop the entire Surface image. This is useful if you are only interested in a small sub-area of the total Surface. The callback that is passed to the method will be executed after the image has been captured. </p> <p>Let me know if you run into any issues with the behavior by emailing me: charlie [you know] robbins [obviously] gmail [you know] com. As always, all of this code is available under the MIT license on <a href="http://github.com/indexzero/wpf-samples">GitHub</a>.</p> </div> <br/> <ul class="meta"> <li>Posted by <span class="fn">Charlie Robbins</span></li> </ul> </div> Fri, 22 Jan 2010 05:25:00 GMT http://www.charlierobbins.com//articles/2010/01/22/capturing-raw-images-from-the-microsoft-surface/ http://www.charlierobbins.com//articles/2010/01/22/capturing-raw-images-from-the-microsoft-surface/ Fudging the non-client area of Custom Chrome Windows using WPF and Win32 <div class="hentry" id="article-fudging-the-non-client-area-of-custom-chrome-windows-using-wpf-and-win32"> <div class="entry-content"> <p>Now that I&#8217;m back from <a href="http://static.howstuffworks.com/gif/staycation-1.jpg">staycation</a> I&#8217;ve been looking around at some miscellany that needs to be done at the Lab. One of those items used my open-source (MIT ftw)<a href="http://github.com/indexzero/wpf-window-chrome">Custom Chrome Window library</a>. In the process of using it I came across a little bug that&#8217;s discussed on the WPF Window Chrome site <a href="http://code.msdn.microsoft.com/chrome/Thread/View.aspx?ThreadId=1673">here.</a> </p> <p>Basically, even though the &#8220;Caption bar&#8221; (aka &#8220;Title bar,&#8221; aka &#8220;Window bar,&#8221; aka &#8220;Non-client Window area&#8221;) was hidden, the Window.Top and Window.Left calculations take it into account. After a <a href="http://goldmanalpha.wordpress.com/">colleague of mine</a> did some serious Google-foo on Win32 we found this solution which has been added to the library on <a href="http://github.com/indexzero/wpf-window-chrome">GitHub.</a> The solution is outlined below, starting with including some Win32 API calls:</p> <pre> <code class="csharp"> public static class SafeNativeMethods { [DllImport("user32.dll")] public static extern int GetWindowLong(IntPtr hwnd, int index); [DllImport("user32.dll")] public static extern int SetWindowLong(IntPtr hwnd, int index, int newStyle); [DllImport("user32.dll")] public static extern bool SetWindowPos(IntPtr hwnd, IntPtr hwndInsertAfter, int x, int y, int width, int height, uint flags); [DllImport("user32.dll")] public static extern IntPtr SendMessage(IntPtr hwnd, uint msg, IntPtr wParam, IntPtr lParam); internal const int WS_CHILD = 0x40000000; internal const int WS_VISIBLE = 0x10000000; internal const int LBS_NOTIFY = 0x00000001; internal const int HOST_ID = 0x00000002; internal const int LISTBOX_ID = 0x00000001; internal const int WS_VSCROLL = 0x00200000; internal const int WS_BORDER = 0x00800000; public const int GWL_EXSTYLE = -20; public const int GWL_STYLE = -16; public const int WS_EX_DLGMODALFRAME = 0x0001; public const int SWP_NOSIZE = 0x0001; public const int SWP_NOMOVE = 0x0002; public const int SWP_NOZORDER = 0x0004; public const int SWP_FRAMECHANGED = 0x0020; public const uint WM_SETICON = 0x0080; public const int WS_DLGFRAME = 0x00400000; public const int WS_SYSMENU = 0x80000; public const int WS_MINIMIZEBOX = 0x20000; public const int WS_MAXIMIZEBOX = 0x10000; } </code> </pre> <p>After which we need to call into these methods in the CustomChromeWindow class:</p> <pre> <code class="csharp"> protected override void OnSourceInitialized(EventArgs e) { base.OnSourceInitialized(e); // Get this window's handle IntPtr hwnd = new WindowInteropHelper(this).Handle; // Change the extended window style to not show a window icon int extendedStyle = SafeNativeMethods.GetWindowLong(hwnd, SafeNativeMethods.GWL_EXSTYLE); int style = SafeNativeMethods.GetWindowLong(hwnd, SafeNativeMethods.GWL_STYLE); SafeNativeMethods.SetWindowLong( hwnd, SafeNativeMethods.GWL_STYLE, style & ~SafeNativeMethods.WS_SYSMENU & ~SafeNativeMethods.WS_MINIMIZEBOX & ~SafeNativeMethods.WS_MAXIMIZEBOX & SafeNativeMethods.WS_DLGFRAME); // Update the window's non-client area to reflect the changes SafeNativeMethods.SetWindowPos( hwnd, IntPtr.Zero, 0, 0, 0, 0, SafeNativeMethods.SWP_NOMOVE | SafeNativeMethods.SWP_NOSIZE | SafeNativeMethods.SWP_NOZORDER | SafeNativeMethods.SWP_FRAMECHANGED); } </code> </pre> <p>Hopefully you&#8217;ll never have to wallow in the pain of custom window chrome, but if you do take a look at the library on <a href="http://github.com/indexzero/wpf-window-chrome">GitHub.</a></p> </div> <br/> <ul class="meta"> <li>Posted by <span class="fn">Charlie Robbins</span></li> </ul> </div> Fri, 15 Jan 2010 23:12:00 GMT http://www.charlierobbins.com//articles/2010/01/15/fudging-the-non-client-area-of-custom-chrome-windows-using-wpf-and-win32/ http://www.charlierobbins.com//articles/2010/01/15/fudging-the-non-client-area-of-custom-chrome-windows-using-wpf-and-win32/ Pseudo-Inherited Attributes in MGrammar (@November 2009 CTP) <div class="hentry" id="article-pseudo-inherited-attributes-in-mgrammar-november-2009-ctp"> <div class="entry-content"> <p>The M language and in particular MGrammar have caught my attention recently after completing Programming Languages and Translators this past semester at Columba. I didn’t take compilers as a part of my undergraduate studies at McGill and after completing Professor Aho’s course I am really intrigued by the possibilities offered by DSLs and DSVs. </p> <p>After getting setup with .NET 4, the SQL Modelling November 2009 CTP, and Intellipad my first inclination was to see how I could implement some classic ideas in language theory with MGrammar. One such idea is “inherited attributes.” An inherited attribute is a value that is captured or calculated at a parent node in an abstract syntax tree and then passed down to child nodes for any calculations or translations that they may need to perform. A classic example of this would be the “with” keyword that is available in Javascript: </p> <pre> <code class="javascript"> with (myObj) { x += 3; y += 3; } </code> </pre> <p>This would be equivalent to:</p> <pre> <code class="javascript"> myObj.x += 3; myObj.y += 3; </code> </pre> </div> <br/> <ul class="meta"> <li>Posted by <span class="fn">Charlie Robbins</span></li> </ul> </div> Sat, 26 Dec 2009 00:11:00 GMT http://www.charlierobbins.com//articles/2009/12/26/pseudo-inherited-attributes-in-mgrammar-november-2009-ctp/ http://www.charlierobbins.com//articles/2009/12/26/pseudo-inherited-attributes-in-mgrammar-november-2009-ctp/ Adding ContactMultiTap to the Microsoft Surface <div class="hentry" id="article-adding-contactmultitap-to-the-microsoft-surface"> <div class="entry-content"> <p>The Surface SDK comes in two flavors; WPF and XNA. All of the input events on the WPF Surface SDK are implemented as <a href="http://msdn.microsoft.com/en-us/library/bb613550.aspx">Attached Events</a>, which are essentially just a clever use of standard Routed Events in WPF. I won&#8217;t delve into the all details here about what Attached Events are, but they were a primary focus for an implementation of ContactMultiTap on the Surface.</p> <p>For those of you not familiar with the Surface, it&#8217;s convenient to think of it as a gigantic iPhone (although it&#8217;s been around in secret long before the iPhone) that can also recognize object tags (like 2D barcodes). This is because instead of using a capacitive multi-touch approach like the iPhone it implements a multi-camera computer vision system and interprets inputs from that. In this post, I discuss my implementation as well as the benefits of time-based multi-tap input on this <a href="http://www.youtube.com/watch?v=CZrr7AZ9nCY">&#8220;big a** table.&#8221;</a></p> </div> <br/> <ul class="meta"> <li>Posted by <span class="fn">Charlie Robbins</span></li> </ul> </div> Fri, 25 Dec 2009 06:32:00 GMT http://www.charlierobbins.com//articles/2009/12/25/adding-contactmultitap-to-the-microsoft-surface/ http://www.charlierobbins.com//articles/2009/12/25/adding-contactmultitap-to-the-microsoft-surface/ Microsoft unshackles the Surface SDK <div class="hentry" id="article-microsoft-unshackles-the-surface-sdk"> <div class="entry-content"> <p>Recently, I have been more involved with development on the <a href="http://www.microsoft.com/surface/">Microsoft Surface</a> as part of my work with the <a href="http://graphics.cs.columbia.edu/top.html">Computer Graphics and User Interfaces Lab.</a> We also have a couple of Surfaces here at <a href="http://www.lab49.com">Lab49</a>. The Surface is a very interesting device to me because of it&#8217;s potential not necessarily as a consumer device but in marketplace and enterprise scenarios. Furthermore, it&#8217;s SDK is implemented in WPF using very clever tricks like attached events. </p> <p>One thing that frustrated me about the Surface though, was how closed off its development community had been. If Microsoft really wants this thing to take off (a topic that has been the subject of heated debate), then why not just let anyone who wants to download the tools and SDK to test it out? Well it seems that Microsoft has come to their senses and put all the Surface materials (technical resources, documentation, and downloads) up for public consumption. If you&#8217;re a UI enthusiast or just a WPF developer I highly suggest checking it out:</p> <p><a href="http://www.microsoft.com/downloads/details.aspx?displaylang=en&amp;FamilyID=3db8987b-47c8-46ca-aafb-9c3b36f43bcc">Download Surface SDK 1.0 (SP1)</a><br/> <a href="http://msdn.microsoft.com/en-us/library/ee804845.aspx">Surface Documentation on MSDN</a><br/> <a href="http://social.msdn.microsoft.com/Forums/en-US/category/surface">New Surface Forums</a><br/></p> <p>Happy Coding!</p> </div> <br/> <ul class="meta"> <li>Posted by <span class="fn">Charlie Robbins</span></li> </ul> </div> Wed, 18 Nov 2009 19:09:00 GMT http://www.charlierobbins.com//articles/2009/11/18/microsoft-unshackles-the-surface-sdk/ http://www.charlierobbins.com//articles/2009/11/18/microsoft-unshackles-the-surface-sdk/ Interesting Findings between .NET 4 Beta1 and Beta2 <div class="hentry" id="article-interesting-findings-between-net-4-beta1-and-beta2"> <div class="entry-content"> Patrick Smacchia has an interesting post on <a href="http://codebetter.com/blogs/patricksmacchia/archive/2009/10/21/interesting-findings-in-the-diff-between-net-fx-v4-beta1-and-beta2.aspx">interesting findings in the diff between .NET 4.0 Beta1 and Beta2.</a> I've been a little behind the times on updates, but this article brought me up to speed with some API changes quickly. Some interesting changes to System.Windows.Input to reflect the native Multi-Touch support for Window7. I wonder how the Surface SDK will change with the transition from Vista to Win7. </div> <br/> <ul class="meta"> <li>Posted by <span class="fn">Charlie Robbins</span></li> </ul> </div> Thu, 22 Oct 2009 15:21:00 GMT http://www.charlierobbins.com//articles/2009/10/22/interesting-findings-between-net-4-beta1-and-beta2/ http://www.charlierobbins.com//articles/2009/10/22/interesting-findings-between-net-4-beta1-and-beta2/