This weekend I’ve been working on one of my many self-edification projects, and against my better judgment I was implementing it with .NET 3.0/Windows Presentation Foundation, mainly because of the markup-like UI model which fit nicely with a few of my project’s idioms.
Anyway, I wanted to get a quick hit this weekend to keep momentum going, so I thought I’d put together the rich text interface of the project first. This should be stupid-easy, since WPF contains a
RichTextBox class that does everything you could ask for with rich text, and the underlying content model is itself a XAML document, a
FlowDocument. Too easy.
RichTextBox doesn’t ship with the standard rich text toolbar, for doing things like bold, italics, etc. No problem; WPF has a toolbar element too. I wired up a bunch of buttons, each using the standard icon for its corresponding function, and set the buttons to invoke WPF commands like
EditingCommands.ToggleBold, which the rich text box knows how to handle. “Wow”, I thought to myself, “this WPF thing isn’t half bad!”.
Then I noticed something. When commands are disabled (for example, the ‘Cut’ command is disabled when there’s nothing to cut), the toolbar button doesn’t respond to mouseovers or clicks just like a disabled button wouldn’t, but the icon on the button isn’t grayed out like one would expect. Then I tried something simpler; I created a
Button with an
Image in it, and explicitly set the
IsEnabled property to
false. Sure enough, the image was still not grayed out.
Then I used Microsoft Expression Blend (a tool about which I could write a whole stream of angry rants) to show me the built-in XAML template for the
Button control. Imagine my surprise when I discovered the only logic in the template that deals with rendering the disabled button is setting the foreground color to gray. That’s _it_. No wonder, then, that my images weren’t rendering differently; the foreground color has no effect on images.
You can see for yourself. Type this XAML code into XamlPad and see what happens:
<Page xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"> <StackPanel HorizontalAlignment="Left"> <Button> <TextBlock>This button is enabled <Image Source="http://apocryph.org/themes/apocryph/logo.png" Width="32" /> </TextBlock> </Button> <Button IsEnabled="false"> <TextBlock>This button is disabled <Image Source="http://apocryph.org/themes/apocryph/logo.png" Width="32" /> </TextBlock> </Button> </StackPanel> </Page>
You’ll see two buttons, one with grayed-out text, but both with the same fucking image.
So let’s ponder this a moment. Back in 1995, I got my first copy of Visual C++ for free from a guy named Mike Strock (this was back when companies sold compilers for an outrageous sum, and thus I couldn’t afford them). One of the kickass features that blew me away was the MFC document/view model, where toolbar buttons mapped to commands, and would automatically disable themselves if the commands were disabled. Somehow, MFC automatically grayed out the toolbar button icons as well. It was incredible. “Surely”, I thought, “programming can’t get any easier than this”.
Apparently, I was right, coz here we are, 12 long years later, and we’ve taken a huge fucking step backwards. Now, don’t get me wrong. Using WPF I can easily make a button which contains a spinning 3D cube playing videos on each face that turns green when the mouse goes over it, all without any C# code. Unfortunately, no one would ever want to do that, while it’s easy to imagine a situation wherein you’d want toolbar icons to gray themselves (like, I dunno, every Windows application ever made).
This gives me a great startup idea. I’ll found a company in some tort-free jurisdiction like Costa Rica, called “FuckIt, Inc”. We’d offer an exclusive “Fuck This Shit(tm)” package, wherein programmers who can no longer bear the absurdity and kludge which is modern software engineering would be cryogenically frozen in a bunker on a secret island off the coast, to be revived 100 years hence or when the software industry gets its head out of its ass, whichever comes first. One of the test cases used to determine if the industry has its head out of its ass yet would be this one:
Using the latest development tools from the vendor of the most popular desktop operating system on the planet, is it easier to create toolbar buttons with icons that automatically disable themselves when the action they correspond to is disable, or to create a huge button containing a spinning 3D cube with video playing on each face? If the answer is the latter, as it is today, then the programmers stay frozen.
UPDATE: I’ve got a couple of solutions, here. Neither of them are optimal, but then, neither is life itself.