ACFactory Day 5: Welcome to Paper World

This is the fifth part of a series documenting the development of ‘ACFactory’ (ACFabrik in German), an application that generates printable character sheets for the Pen & Paper role playing game Arcane Codex (English page).You might also want to read ACFactory Day 4: Command & Control.ACFactory prototype showing two almost entirely empty pages.Pixels in WPF are device-independent and set at 96 pixels per inch. This means, that one WPF-pixel corresponds to one device-pixel if and only if the resolution of the device is 96 dpi. Despite sounding complicated, this is a good thing, because WPF pixels have fixed dimensions. One pixel equals 1/96th of an inch, or 3.77952755905512 pixels are equal to one millimetre. (I’m sorry, but who ever invented inches should be slapped). Naturally, it would not be practical to author the talent sheet in WPF-pixels, constantly having to convert back and forth using a calculator or a table (or both: Excel).ACFactory Zoom controlIt would be nice to let someone else worry about my coordinate system of choice, someone like WPF. Unlike GDI+, WPF does not provide explicit coordinate system transformations, probably for a good reason. What you can do, are layout transforms. The scale transform looks particularly promising. Initialised with my magic number, I could author my sheets in millimetres and WPF converts them into pixels. There is one problem there: ScaleTransform not only transforms the coordinate system, but everything inside the affected control, including font sizes. While in 99 out 100 cases, this is the expected behaviour, in my exact scenario it’s not. Cambria 12pt should render like Cambria 12pt would render on paper. However, these normal-looking 12 points are scaled to giant 45.3354… points by the ScaleTransform.Maybe the StackOverflow.com community knows an answer. Until then, I created the hopefully temporary markup extension PaperFontSize, that automatically reverses the effects of such a ScaleTransform.Having everything set up, I can finally start implementing the talent sheet.

ACFactory Day 4: Command&Control

This is the fourth part of a series documenting the development of ‘ACFactory’ (ACFabrik in German), an application that generates printable character sheets for the Pen & Paper role playing game Arcane Codex (English page).

You might also want to read Day 3: Authoring XAML.

Today, I was mostly lost in the vast unknown jungle that WPF is, even after having read “Windows Presentation Foundation: Unleashed by Adam Nathan” (I really recommend it!).

Control

First there was the difference between UserControl and custom control. (No, I am not very familiar with any other UI framework). Whereas UserControls are little more than include on steroids (you get a code behind file), if you *really* want to create something new or abstract over a composition of controls, then creating custom controls is your only option.

But custom controls are just C# (or VB.NET) code files. There is no XAML involved. How can that be the preferred way to author new controls? Remember that WPF controls are supposed to be look-less, platonic ideas of what they represent.
I wanted to create a zoom view control. What are the abstract properties of such a zoom view control?

  1. It has content
  2. It can magnify its content

Number 1 tells us to derive from ContentControl, the type that defines the Content property. Number 2 is a bit trickier. I decided that my control has a ZoomFactor property (type double, 1.0 == 100%) to which a ScaleTransform is bound. Whether or not this works, I am not exactly sure as the control is not working yet.

But how does the control look? Well that’s not the controls concern. A look is provided by the Themes/Generic.xaml resource dictionary, the default fallback in the absence of local definitions and system specific themes. In my case there is going to be a neat little zoom control (combo box + slider) hovering in the top left corner.

Command

To establish communication between the ZoomViewer template and the ZoomViewer control, there is really only one good mechanism: Commands. Commands are yet another abstraction that makes event handling more modular. Controls like buttons, hyperlinks and menu item can be “bound” to a certain command. That command determines whether they are enabled or not and what happens when they are clicked. You could for instance bind the menu item Edit > Paste, a toolbar button and Ctr+V to the Application.Paste command and they would all automatically be activated/deactivated depending on the state of the clipboard.

Even better, the default implementation, RoutedCommands, work just like routed events and bubble up the tree of your XAML interface. You can then define different command bindings at different locations in your UI. The best of all: Via the command target property, you can tell the command routing where to look for command bindings. I could have two buttons, that both invoke the Navigation.Zoom command, but on two different ZoomViewers.

My ZoomViewer does support the Navigation.IncreaseZoom, .DecreaseZoom and .Zoom commands. This is how the default control template can communicate with the ZoomViewer, by invoking those commands.

There is however one thing, I found very irritating: neither the slider nor the combo box implement commands by default. The msdn contains a sample, that shows how to do this. It turns out to come with quite a few things to watch out for:

  • You must differentiate between routed and ordinary commands as only the former can react to command bindings and can be set to originate from different InputElements.
  • You should rather pass a reference to the invoking control than null as the command target.
  • You must be careful with the CanExecuteChanged event handler. It must be correctly unset, when the command is changed/removed.

How well this all turns out, will hoepfully see soon. Development right now is a bit sluggish as I keep switching over to msdn and/or my book for reference, since Visual Studios XAML editor is not very sophisticated, even with basic ReSharper support. This must get much better in VS10. Up until now, I have observed VS08SP1 only crash 3 times (twice due to a recursive binding *blush*) and once with an HRESULT of E_FAIL (whatever that exactly was). But at least I lost no code.

Oh, and why exactly the Microsoft Blend XAML editor does not provide any support is totally beyond me. I mean free (that means it costs nothing) tools provide better code completion than Blend: Kaxaml, the “better XamlPad”. Even though it takes some time to load, I can definitely recommend it.

ACFactory Day 3: Authoring XAML

This is the third part of a series documenting the development of ‘ACFactory’ (ACFabrik in German), an application that generates printable character sheets for the Pen & Paper role playing game Arcane Codex (English page).

You might also want to read Day 2: ExtendableEnum and XAML Serialization.

File Formats

ACFactory is going to use two file formats: *.aclib and *.achero. The former basically contains data for rules implemented in code. Library files are ordinary XAML (and therefore also XML) files with a Library root node.

Hero files (*.achero) will most likely be more important to ordinary users. They contain, well, heroes to be loaded into the application. Milestone 1 doesn’t require editing of heroes, neither does it require that the user can change the hero once the application runs. I do however plan to implement that functionality, should I find the time to revise the application. In the distant future, ACFactory might even handle multiple heroes at once via a tabbed interface.

User Interface

As I am not an artist, ACFactory will most probably not look very pretty. I do, however, plan to take advantage of at least some of WPF’s rich styling capabilities. I had a pretty cool Office 2007-like page preview control assembled, only to find out, that bitmap effects are damn slow, like in it-takes-a-second-to-highlight-a-hyperlink-slow. Why on earth they have to be rendered in software, on the UI thread, is beyond me (and I hope it doesn’t have anything to do with WPF being rushed to market). Tim Cahill blames the limitations of graphics cards in one of his blog posts.

Adding seemingly simple tweaks (e.g., clipping, bitmap effects) to our scene causes us to fall back to software, and software rending in WPF is slower than GDI+ software rendering.

First, the WPF software rendering code is derived from the GDI+ codebase. There are certain limits to what can be accomplished in hardware, and we have to work around what the hardware vendors give us. As graphics hardware evolves, those limits are likely to become better over time. If at least some portion of your scene is rendered in hardware, the cost of rendering is already going to be faster than it was in GDI+. Finally, we shipped a tool at the PDC called ‘Perforator’ to help identify where software rendering occurs.

I don’t know about you, but I have seen outer glow effects rendered at over 30 frames per second in many computer games, Fable only being one example. Maybe they just want to keep us developers with our uber-machines from terrorising poor users with too-flashy applications.

ACFactory_Day3

ACFactory Day 2: ExtendableEnum and XAML Serialization

This is the second part of a series documenting the development of ‘ACFactory’ (ACFabrik in German), an application that generates printable character sheets for the Pen & Paper role playing game Arcane Codex (English page).You might also want to read Day 1: SealedSun goes WPF.

ExtendableEnum

Talents in Arcane Codex have a number of properties that are best described as enumerations. Unfortunately plain old enumerations are very flat. Translating them (when displayed in a user interface) requires you to wrap each and every appearance in the system. This is why I need a richer enumeration type.Enter ExtendableEnum, an abstract base class that handles comparison and parsing of enumeration values. An existing enumeration could even be extended by a plug-in, should my application ever implement a plug-in system.I was, however, confronted with a very annoying problem: type initialisation is lazy. The CLR employs certain “heuristics” to find out when to initialise a type. By default, a type is marked with “beforeFieldInit”, which means that the type is usable before its static fields have been initialised. Of course, static fields are always initialised “just-in-time” when they are accessed. The attribute is not applied when the class contains a static constructor (or class constructor or type initializer). In that case, the type is initialised when one of its members is first accessed.While this is a pretty good strategy for the “normal” use of types, it might be a problem in XAML-based applications since the ExtendableEnum-parser is used before any of the enumeration values is referenced in code, which in turn means that the corresponding enumeration types had no chance to register their enumeration values with the corresponding registry.One Solution I have found is the System.Runtime.CompilerServices.RuntimeHelpers.RunClassConstructor method which, well, runs type initializers. I can only hope that the method (which points right into the heart of the CLR) is smart enough not to initialise a type twice. My approach is not perfect as extensions of enumerations are not necessarily included. For a future plug-in system, some sort of InitializeOnLoad attribute could save the plug-in writers day. But my hack works 100% for all non-extended enumerations and that’s enough for milestone 1.

XAML Serialization

Step 1: Make your objects “expressable” in XAML

The “read”-aspect of XAML serialization is much more important as it is an absolute requirement for milestone 1. The tricky thing with XAML is, that you cannot express circular references for plain CLR objects (no DependencyObject). My object model, however, requires two way relationships in some places. For instance: Talents need access to the attributes of “their” hero in order to compute effective talent levels. Now since there has to be a default constructor, the hero reference will be initialised with null, resulting in an invalid state. There is no way to ensure that your object is initialised correctly, as you don’t know when WPF/XAML is “done” with its manipulations.The only option is to propagate the hero reference down the hero graph once the hero is created, which means that even collections have references to the hero they belong to.

Step 2: Make your objects serialize correctly

Contrary to what people might tell you, XAML Serialization does not come for free. There are severe limitations and not that many customisation options. Here is how I wished I could store my heroes:

<Hero ShortName="Kyle" FullName="Kyle MacDuncan"><Hero.Attributes><Attribute Level="8">Strength</Attribute>...</Hero.Attributes><Hero.Talents><Talent Level="5">Sword</Talent>...</Hero.Talents></Hero>

Automatically converting the hero-less Attribute and Talent to their bound equivalents, HeroAttribute and HeroTalent respectively. Interpreting this is one thing. A bit of Voodoo magic and a couple of virgins (read: TypeConverters and the like) would make this work. But as I said, there is no way to tell the XAML serializer to first convert certain values to more serializable equivalents.So eventually I gave up and implemented  XAML serialization using a pretty nasty hack: All the properties that need processing prior to assignment are loaded off into a xData class (HeroData, TalentData, and so on). This essentially means that I have to implement each non-trivial property at least twice and that extension via plug-ins has become at least twice as difficult. My serialised hero looks like this:

<Hero x:Key="codeHero"xmlns="clr-namespace:ACFabrik.Model"xmlns:wpf="http://schemas.microsoft.com/winfx/2006/xaml/presentation"ShortName="Kyle" FullName="Kyle Mac Duncan"ExperienceTotal="14" ExperienceUsed="12"FameTotal="15" FameUsed="10" Encumberment="0" ><HeroData LocalLibrary="{wpf:StaticResource defaultLibrary}"><HeroData.Attributes><HeroAttribute Level="8" Attribute="Strength" /><HeroAttribute Level="7" Attribute="Constitution" />...</HeroData.Attributes><HeroData.Talents><HeroTalent Level="7">Alchemy</HeroTalent><HeroTalent Level="8">Attention</HeroTalent>...</HeroData.Talents></HeroData></Hero>

The HeroData node defines a new attribute: “LocalLibrary”. It is used to map the talent names (and possibly others) to their definition in an external library. This way multiple heroes can share the same talents. LocalLibrary is only required when heroes are loaded as part of XAML resources, i.e. when you don’t have control over the XamlReader.Load method.The result is a bit more verbose and not that beautiful.Well, at least it will yield good compression ratios (the “<Hero”-prefix…).

Next Steps

On the data side, the next question to answer is how the file formats look exactly. While I now have the basic capability to serialize my objects to streams, I need to come up with concrete formats for heroes and libraries.Also, I need to start thinking about the general UI concept. Printing in WPF works via Visuals, so I literally get previewing for free. I therefore include a very basic UI (preview + print button) in the requirements for milestone 1.

ACFactory Day 1: SealedSun goes WPF

This is the first part of a series documenting the development of ‘ACFactory’ (ACFabrik in German), an application that generates printable character sheets for the Pen & Paper role playing game Arcane Codex (English page).Before I explain why I chose to implement ACFactory in WPF, let me quickly sketch the application’s functionality planned for the first iteration:

  • Read a hero definition from a human-writeable text file
  • Print a sheet that lists all the talents known by a hero

Note that having a graphical UI is explicitly not a requirement for the first iteration. It is not the first character sheet generator I’m writing. The Heldenfabrik (Hero factory, not released) project for instance uses the Prexonite scripting engine to define a DSL used to specify heroes and the same GDI+ based rendering framework (read: bunch-a-classes) as the DSA calendar generator (DSA Kalendergenerator) to generate an almost-A4-sized png. Needless to say, that it was very painful to hard code all the spacings and layout characteristics. I needed something that supported me in designing fixed-page layouts. One solution would have been to write a custom rendering engine that would be tailored to the special needs of fitting content of variable size onto a fixed page. I even went so far as to prototype a possible architecture in F#, only find out that

  1. It is really hard to express complex object models in F# due to the lack of forward declarations.
  2. It is a lot of work to implement automated layout.

So what are the alternatives? What publicly available layout engines exist out there? One obvious answer is XHTML+CSS. XHTML documents are relatively easy to generate (System.Xml.Linq aka LINQ to XML or XLINQ), well understood and can be printed by modern browsers. The problem: XHTML documents are inherently digital and thus optimised for variable sizes. Also the final look depends on the layout engine (read: browser) used to display the document. I don’t even want to talk about the horror that printing from a browser is.Living in a .NET 3.5 environment I could no longer ignore our little newcomer to the graphical user interface world: Windows Presentation Foundation (WPF). We all suspected, that this user interface framework has more to offer than a ridiculously unpronounceable name and fancy 3D graphics. It comes with layout features web designers can only dream about (one word: Grid). So what’s the catch apart from acknowledging that WPF might be cool?A friggin’ steep learning curve. You can learn C# without a book if you’ve already worked with the .NET framework (via, say, VB.NET). You can learn CSS, XML, XPath, XSLT without a book given good online tutorials. But WPF is so complex, that it would take you months to harvest even basic knowledge of WPF from blogs and tutorials all over the net.Windows Presentation Foundation Unleashed (WPF) (Paperback)Since I want to finish the project within 7 days, this was not an option (also, I’m a very impatient person). I needed a book. There were two books recommended all over the internet (Applications = Code + Markup by Charles Petzold) and Windows Presentation Foundation Unleashed by Adam Nathan. Based on the customer reviews I decided to buy the latter (the fact that this one was printed in colour made the decision much easier :-) ).So here I am, roughly in the middle of the book on page 355 at the beginning of chapter 11 about 2D graphics. One thing I noticed was the alarming number of pitfalls or things-to-remember when coding WPF interfaces. Although the majority of the framework builds on predictable and consistent patterns, there are odd edges here and there such as having to use {Binding RelativeSource={RelativeSource …}} for relative sources as opposed to the uniform {Binding Source={RelativeSource …}. Overall I have the feeling that there will be a lot of reinventing-the-wheel involved as WPF is not as complete as it could (should?) be. Sortable ListView out of the box, anyone?But wait! Didn’t I forget something? Right: Like XHTML, WPF is tailored towards flexible layouts in containers of variable size. Doesn’t this rule WPF out as the layout engine of choice? Nope: WPF was designed to be resolution independent, operating on “virtual” pixels the size of 1/96th of an inch (or device pixels at DPI=96). I can therefore calculate the size of an A4 page at 96 DPI, which is roughly 793.701 pixels times 1122.52 pixels or 3.77953 pixels per millimetre (Beautiful number isn’t it? :-( ).

Next Steps

Before I start designing the character sheet, I want to have my Business Objects (the hero + his/her talents) to be up and running. I need a format that is human-writeable and can be loaded by my application. I’m currently looking into the object serialization aspect of XAML, which I already successfully used to define a serializable library of talents available to heroes.XAML (aka System.Windows.Markup) knows how to serialize objects that

  • Have a public default constructor (no arguments)
  • Expose their representation in writeable properties

It’s not that adhering to those rules is especially difficult but it is extremely tedious as immutable objects are essentially ruled out. I like to build my objects (classes) like fortresses, using the type system, readonly modifiers and immutablity to reduce the number of ways an object can enter an invalid state. Designing a business model that serializes to XAML therefor means opening all doors to malicious (and/or stupid) users (developers that use my code). I practically live in the library-writer-world and having to write class that expose their representation the way WPF likes it, makes me twitch.But seeing how elegant XAML maps XML elements to the familiar .NET objects really makes up for the mental pain I am about to go through. You’ll hear from me.Continue reading on ACFactory Day 2: ExtendableEnum and XAML Serialization

Operator overloading for Prexonite, more or less

Prexonite October 2008

While Prexonite Script does not formally provide any means of object-oriented programming (not just consuming objects but actually defining new ones) there are mechanisms in Prexonite (the runtime) that try to make up for this.

What Prexonite includes so far

  • The Structure data type
    • groups values and functions together
    • provides "natural" access via dot-notation

    function create_complex(_re, _im)
    {   
        _re ??= 0.0;
        _im ??= 0.0;
        var z = new Structure;
       
        z.\("re") = _re;
        z.\("im") = _im;
       
        z.\\("norm") = (this) =>
            sqrt(this.re^2 + this.im^2);
        z.\\("add") = (this,other) =>
            create_complex(this.re + other.re,this.im + other.im);
        z.\\("ToString") = (this) =>
            this.re + " " + this.im + "i";
       
        return z;
    }

  • The ExtendableObject base class
    • Makes it possible for Prexonite code to "extend" .NET objects, should the developer want to allow this.
  • The struct function (in psr/struct.pxs )
    • automates construction of Structure objects via reflection

    build does require("psr\\struct.pxs");

    function create_complex(_re, _im)
    {   
        _re ??= 0.0;
        _im ??= 0.0;
       
        function re(this, new_re)
        {
            if(new_re is not Null)
                _re = new_re;
            return _re;   
        }
       
        function im(this, new_im)
        {
            if(new_im is not Null)
                _im = new_im;
            return _im;   
        }
       
        function norm = sqrt(_re^2 + _im^2);
       
        function add(this, other) =
            create_complex(re + other.re,im + other.im);
       
        function ToString =
            re + " " + im + "i";
       
        return struct;
    }

New in this release1

  • auto-property, proxy-property, property support via psr/prop.pxs
    build does require("psr\\struct.pxs","psr\\prop.pxs");

    function create_car(a_color)
    {     
        _re ??= 0.0;
        _im ??= 0.0;
       
        function re = struct_prop(_re);
       
        function im = struct_prop(_im);
       
        function norm = sqrt(re^2 + im^2);
       
        function add(this, other) =
            create_complex(re + other.re,im + other.im);
       
        function ToString =
            re + " " + im + "i";
       
        return struct;
    }

  • operator overloading via (+), (==) etc.
    //...
    function (+) this other =
        create_complex(re + other.re,im + other.im);

    function (-.) =
        create_complex(-re, -im);
       
    function (-) this other = this + (-other);
       
    //...

1psr/prop.pxs is in the repository since August.Let's discuss those two extensions one by one…

Properties

First of all, there still is no language support for structures and properties. As of right now, they are implemented via compile time transformations. These two transformations can be enabled via importing the Prexonite Standard Repository scripts psr/struct.pxs and psr/prop.pxs. While the former has been around for some time now, the latter has only recently been implemented in managed code.psr/prop.pxs defines the special function prop which is expanded into get and set code depending on the way it is used. The easiest mode of operation implements a property with an anonymous backing field (defined in the surrounding scope, i.e. as a global variable in a top-level function or a shared variable in the outer function) The second mode mimics a simple get-set proxy where the expression passed as an argument is used as the backing field. This works for arbitrary expressions as long as they can be the target of an assignment (i.e. they are get-set expressions). The third mode finally is a replication of C# properties taking separate lambda expressions for its get and set implementations.struct_prop works the same way but ignores the additional this parameter for structure methods.

Operator overloading

When resolving operator calls, generic objects (as well as structures) now also try to call special instance methods after failing to find a corresponding static operator overload. This makes the implementation of operator overloads for structures and ExtendableObjects (An abstract class that makes an object extendable in the same way a structure can be extended) possible. In order to avoid strange operator names, I have introduced operator ids, special literals (on the lexical level) that represent operator names. There is nothing special about these literals, they can be used everywhere an id can be used. You could for instance define a local variable with the name (+).

First week with the ThinkPad X61T WWAN

X61 Tablet

X61 Tablet

I have recently bought a Lenovo X61. Not the normal one though, the TabletPC version. What I wanted was a small, reliable but still very capable laptop, which is why I didn't just walk into the next electronics discounter and bought the smallest machine in stock. After reading several blogs about living paperless (StudentTabletPC.com and PaperlessUndergrad.co.uk), I decided to have a closer look at the available tablet versions of common laptops. I read a lot of good reviews about the TabletPCs from HP and the X61T from Lenovo. In the end, I went for the ThinkPad because I was already familiar with that product line from school.The reason I bought the wireless WAN version, however, has nothing to do with my plans of using the machine at the university, as they have a pretty sophisticated wireless LAN there, but lies in the fact that I have no access to the internet on any machine in the military service at the moment, even though I'm working in an office every day. Wireless internet is what keeps me from becoming insane in here (well that's probably a bit exaggerated, but you know what I mean).I knew what to expect when I unpacked the X61 as I've not only read, but also watched a lot of reviews before. I was positively surprised by the fact that the battery was already charged (something that is a requirement for a long lifespan, as I learned later) and the machine almost ready to use. A lot of people online suggest throwing away the default installation of Windows Vista and "recover" immediately, disabling every unwanted piece of software from Lenovo. I decided to give the whole ThinkVantage package a go and leave it as it is. After a week of use, I can say that I have definitely seen worse (I'm looking at you, Acer).Some parts are comparatively good, like the connection manager, while others, like the [Fn]+[F2] (Lock) "shortcut" which requires me to click on a button on the screen to lock the machine (don't tell Lenovo that the Windows Vista start menu comes with a locking button at the bottom right).Speaking of the [Fn] key, it is one thing I don't like about the keyboard (which apart from that is very good, considering the limited space). The problem: I'm used to finding the [Ctrl] key by pressing the left most key in the last row. For some reason, the guys behind the X61 and maybe a dozen other models have decided that exactly that position is suited for their [Fn] key. As a developer I use keyboard shortcuts wherever possible. Not having the [Ctrl] key right beneath the [Shift] key is a major annoyance to me. But I guess with time I will accustom myself to this "feature" just like I did with the inverted volume controls of my iriver Clix 2.On a side note: I am currently using the "Offline Files" feature of Windows to always have my documents with me. How well that works in a home environment, I cannot say yet. What bugged me when setting up the cached files is the complete lack of a status report. There is no way to tell how long the synchronization will take. Also, I had to give up a couple of soft links in my documents directory. While tools like robocopy can be configured to treat links like the actual files behind them, the Sync Center user interface does not seem to provide such an option.The pen input works very well (that is once you have the necessary plug-ins for Firefox installed: Grab and Drag (allows for scrolling like in Adobe Reader) and Gesso (adds TIP support to textboxes). What I like most, is the ability to "erase" strokes with the back of the pen. Just like my pencil. The handwriting recognition is amazingly powerful, especially when used in context (i.e., in a phrase). Unfortunately I have not had the chance to test note taking in a real situation (like a meeting or a class) so I cannot tell, whether a TabletPC is an actual alternative to pen and paper.What I definitely love about my X61T, is its mobile antenna. I can connect to the internet wherever I am (in more or less "civilized" areas at least). Swisscom has a very generous offer for students: 5 gigabytes a month for CHF 40.- (about USD 42). With EDGE and HSPA, mobile internet getting closer and closer to the DSL experience the prices will fall over the next four years.I hope that the X61T will live up the promises it made in this first week of use and I wonder whether or not I will adopt a paperless lifestyle, now that I have all means to do so.

SealedSun.GamePanel June08

[ Download SealedSun.Gamepanel June08]SealedSun.GamePanel is a high level wrapper around the managed LcdInterface by http://www.cabhair-cainte.com/ismiselemeas/ that features a Winforms-like controls system as well as simplified event routing for the four soft buttons of the G15.The library is not very mature and only the most commonly used features are implemented. Everyone with basic knowledge of System.Drawing should be able to implement custom functionality via user controls.

Quick Start

1. Create a new LcdScreen

The LcdScreen represents an entry in GamePanel manager and can be selected by the user via the application switch button on the Keyboard.

using(var screen = new LcdScreen())// ...}

2. Open the LcdScreen

To notify the GamePanel manager of the new screen, call the Open method.

screen.Open("My LCD");

3. Create a new LcdPage

An LCD page is like an empty canvas. It is the container for all your UI elements.

var page = new LcdPage(screen);

4. Add controls to the LcdPage

There are currently only two built-in general purpose controls: LcdLabel and LcdImage. In order for your controls to show up, you need to add them to the page object. You can also nest controls by adding them to other controls. Always keep in mind, that the positioning is relative to the parent control and that controls cannot exceed the bounds of their container.

var lTitle = new LcdLabel();lTitle.Text = "My LCD";lTitle.Location = new Point(10,10);page.Controls.Add(lTitle);

5. Configure soft buttons

The page object provides access to the four soft buttons via its Button0,1,2,3 members. Those special controls provide 'button pressed' events and are always located immediately above the respective buttons. Their Text and Image properties can be used to label them. If you need better control over the labelling, you can add child controls to the soft buttons like to any other control.

page.Button0.Pressed += (sender,e) =&gt; {Console.WriteLine("0 Pressed!");};

6. Select active page

In order for a page to be displayed on a screen, it must be assigned to its CurrentPage property. Only pages that are currently active will fire events.

screen.CurrentPage = page;

7. Enter message loop

Like a windows forms application, an LCD application too has a message loop. Similar to Application.Run, screen.Run will use the current thread to process messages from the GamePanel manager.

From here on...

If you want to get the users attention, you can change the pages screen priority to Alert for a short amount of time. A convenient way to do so is the TemporaryAlert method. This of course only works, if the user allows high priority screens.

page.TemporaryAlert(500);

If you want to quit the message loop, either close the screen or call Screen.ExitMessageLoop.

License and Disclaimer

Except for the components mentioned in the ExternalResources.txt, I hereby release everything the zip archive under the terms of the Creative Commons Attribution-Share Alike 2.5 Switzerland license.The software was written over the course of a few days and did therefor not undergo much testing. It is most likely that you will encounter bugs and unexpected behaviour. You use the library at your own risk.Creative Commons LicenseSealedSun.GamePanel by Christian Klauser is licensed under a Creative Commons Attribution-Share Alike 2.5 Switzerland License.

Upcoming: Event-based G15 LCD library

I'm sure all of you have heard of Logitech's G15 gaming keyboard, yes the one with the built-in LCD. I've recently bought the first version (see picture) and obviously want to write applications that target the small 160x43 pixel screen. Logitech provides a native (C++) SDK with their drivers and someone was kind enough to descend into the creepy world of pointers and manual memory management for all .NET developers out there.This managed wrapper, however, is an extremely low-level interface: In order to draw something onto the screen, you have to pass an array of bytes (more precisely: a pointer to its first element) that holds the bitmap to display. This is obviously not very practical and completely alienating for people who, up until now, lived in the comfortable world of Windows.Forms.Logitech G15 (first version)Not being able to find a more abstract library for the G15 LCD, I decided to write my own GUI library. The first task was to make rendering via System.Drawing possible. After having to find out that the only monochrome pixel format is indexed and can therefor not be targeted by a Graphics object, I resorted to using a 24BppRGB  bitmap for rendering instead. I then manually iterate over the pixels in that buffer, determining the brightness of the pixel and applying a threshold in order to get a monochrome copy into a byte array.On top of that I am currently building a Widget/Control oriented display layer complete with event routing for the four soft buttons, Z-ordering and clipping for nested controls. Below you see the trivial implementation of the LcdLabel control:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Drawing;

namespace Logitech.GamePanel
{
  public class LcdLabel : LcdControl
  {

    public LcdLabel()
    {
      StringFormat = new StringFormat()
      Size = new Size(LcdScreen.Width, DefaultFont.Height);
    }

    private string _text;

    public string Text
    {
      get
      {
        return _text;
      }
      set
      {
        if (value == null)
          value = "";
        _text = value;
        Update();
      }
    }

    public StringFormat StringFormat { get; set; }

    protected override void OnPaintBackground(PaintEventArgs e)
    {
      using (var back = new SolidBrush(BackgroundColor))
        e.Graphics.FillRectangle(back, ClientBounds);
    }

    protected override void OnPaint(PaintEventArgs e)
    {
      //Paints background
      base.OnPaint(e);

      using (var fore = new SolidBrush(ForegroundColor))
        e.Graphics.DrawString(_text, Font, fore,
            ClientBounds, StringFormat);
    }
  }
}

G15 Counter in the LCD emulatorOne thing I am proud of, is my implementation of delayed and repeated button press events if a button is being hold down. The buttons use the same repeat delay as the Keyboard (configurable via the device driver/windows).Repeated Pressed events are particularly useful for the sample application below, a little application that provides a counter that can be incremented, decremented and reset via soft buttons.
using System;
using System.Drawing;
using System.Threading;
using Logitech.GamePanel;

namespace LcdSandbox
{
  class CounterPage : LcdPage
  {
    const string counterFormat = "Count: {0:N0}";

    LcdLabel lTitle;
    LcdLabel lCounter;

    public int Count { get; set; }

    public CounterPage(LcdScreen scr)
      : base(scr)
    {
      #region Page initialization

      //Although the page itself does not draw any text,
      // the font is inherited by child controls
      Font = new Font("Calibri", 12, GraphicsUnit.Pixel);

      //lTitle - A label that display a title
      lTitle = new LcdLabel()
      {
        Location = new Point(0, 2),
        Text = "I'll count for you!"
      };
      Controls.Add(lTitle);

      //lCounter - A label that displays the current count
      lCounter = new LcdLabel()
      {
        Location = new Point(0, 20),
        StringFormat = new StringFormat()
        {
          Alignment = StringAlignment.Center,
          LineAlignment = StringAlignment.Center
        }
      };
      Controls.Add(lCounter);

      //Define soft button descriptions
      LcdControl BDesc;

      //Button 0 - Increment
      BDesc = new LcdImage(Icons.UpArrow);
      Button0.Controls.Add(BDesc);
      Button0.Pressed += (obj, e) =>
      {
        Count++;
        updateCounter();
      };

      //Button 1 - Decrement
      BDesc = new LcdImage(Icons.DownArrow);
      Button1.Controls.Add(BDesc);
      Button1.Pressed += (obj, e) =>
      {
        Count--;
        updateCounter();
      };

      //Button 2 - Reset
      BDesc = new LcdImage(Icons.First);
      Button2.Controls.Add(BDesc);
      Button2.Pressed += (obj, e) =>
      {
        Count = 0;
        updateCounter();
      };

      //Button 3 - Exit
      var exitSignal = new AutoResetEvent(false);
      BDesc = new LcdImage(Icons.Delete);
      Button3.Controls.Add(BDesc);
      Button3.Pressed += (obj, e) =>
      {
        Screen.ExitMessageLoop();
      };

      #endregion

      Priority = ScreenPriority.Normal;
      updateCounter();
    }   

    private void updateCounter()
    {
      lCounter.Text = String.Format(counterFormat, Count);
      Update();
    }

  }

  class Program
  {
    static void Main(string[] args)
    {
      using (var screen = new LcdScreen())
      {
        //You must not forget to open the screen
        // before asigning any pages.
        screen.Open("My LCD Sandbox");

        //Create a new instance of our counter page       
        var page = new CounterPage(screen);

        //Tell the screen to display our counter page
        screen.CurrentPage = page;

        //Temporarily set the priority to Alert
        page.TemporaryAlert(500);       

        Console.WriteLine("Application running.");
        Console.WriteLine("See LCD for instructions");

        //The Run method is similar to Application.Run
        // from System.Windows.Forms. Until screen.Close
        // or screen.ExitMessageLoop is called, this
        // thread will handle events.
        screen.Run();
      }
    }
  }
}

The library is in what others call 'Alpha' stage. I do plan to release it here once I'm done documenting the most commonly used methods or if someone is particularly interested and wants to start coding right now.

Using LINQ for the Euler Project

Project Euler is a series of challenging mathematical/computer programming problems that will require more than just mathematical insights to solve. Although mathematics will help you arrive at elegant and efficient methods, the use of a computer and programming skills will be required to solve most problems.The motivation for starting Project Euler, and its continuation, is to provide a platform for the inquiring mind to delve into unfamiliar areas and learn new concepts in a fun and recreational context.

If you need to kill time and like mathematics and programming, Project Euler is a great source of nearly 200 tricky problems to solve. Having found a solution is especially rewarding as there is a strict policy of not providing any help apart from the problem description. If you can't solve a problem, then you can't solve it.As of right now I have solved 26 out of 196 Problems, which according to the website makes me a 13% genius. My tool of choice is of course C# 3.0 and I must say that LINQ to Objects has allowed me to write solutions that resemble those shiny Haskell and Mathematica code snippets you find in the answer forums.Even though I am probably not supposed to publicly post problem solutions, there is this one particular program that beautifully outlines how LINQ can be employed to compute the result:

Consider all integer combinations of ab for 2 ≤ a ≤ 5 and 2 ≤ b ≤ 5:22=4, 23=8, 24=16, 25=3232=9, 33=27, 34=81, 35=24342=16, 43=64, 44=256, 45=102452=25, 53=125, 54=625, 55=3125If they are then placed in numerical order, with any repeats removed, we get the following sequence of 15 distinct terms:4, 8, 9, 16, 25, 27, 32, 64, 81, 125, 243, 256, 625, 1024, 3125How many distinct terms are in the sequence generated by ab for 2 ≤ a ≤ 100 and 2 ≤ b ≤ 100?

public static IEnumerable Digits(this int n){while (n&gt; 0){yield return n%10;n /= 10;}}var s = (from i in 2.To(999999)where i == i.Digits().Select(d => (int) Math.Pow(d, 5)).Sum()select i).Sum();

The only part where this solution could be improved is the choice of the range to search in as one could reason about the maximum number of digits (Hint: 6*95).In the problem forums there is often a competition around writing the shortest program possible and obviously "minimalistic" (in terms of syntax) languages like J and Ruby have an advantage there. But with today's IDE support actually writing the LINQ-expression above didn't take any longer.