Monday, May 19, 2008
Have you ever been shamboozled by the WinForms designer in Visual Studio?  If you haven't, its likely only because you've never used it.  Over the last several years I've had many wars with the WinForms designer, and unfortunately I've lost every single time. 

Not long ago as I was exploring a couple interesting open source ruby projects, I came across one that had me longing for something as simple in the .NET world.  The project was shoes, done by none other then why the lucky stiff.  For those unfamiliar with shoes, it's website describes it as:
Shoes is a very informal graphics and windowing toolkit. It's for making regular old apps that run on Windows, Mac OS X and Linux. It's a blend of my favorite things from the Web, some Ruby style, and a sprinkling of cross-platform widgets.
To give you an idea of how simple shoes makes creating the simplest of GUI's checkout the following code:
Shoes.app {
button("Press Me") { alert("You pressed me") }
}
To give you a little more background, shoes uses a ruby "dsl" for describing the layout of desktop GUI, and under the covers is implemented in C.  Although I wasn't sure how far I could get, I decided to "implement" shoes using IronRuby for my philly code camp presentation.  My goal was to keep the same ruby syntax for declaring the layout and controls that make up the screen,  however, instead of using the backend implementation of shoes I wanted to write my own implementation in IronRuby by leveraging the interop capabilities between IronRuby and Windows Forms.  After hacking on it for a few hours a couple nights last week, as well as doing a little more this past weekend I've been able to get enough of shoes replicated in IronRuby to create some reasonable apps.  Let's start with a simple "Hello Iron Shoes" example. 
require "shoes"
Shoes.app :width => 450, :height => 400, :title => "Hello!" do
banner "Hello Iron Shoes"
end

We start with a require statement that includes the shoes.rb file that implements the shoes "dsl".  Every shoes app starts with a call to Shoes.app that takes a hash of options.  In this example we specify the width and height of the form as well as a title.  We then pass a block that contains a simple banner "Hello Iron Shoes" statement.  Within shoes, all layout and nesting is done via Ruby blocks.  So everything within the do...end block of Shoes.app is added as content to the form.  When we run the above using IronRuby we get the following result.

What's you might find particularly interesting is that since Mono just recently completed their implementation of Windows Forms, and since IronRuby is open source we get the same cross platform support from our IronRuby implementation as we get with the real shoes.  We can also add a bit of user interaction by using an edit_line and button like so:

require "shoes"
Shoes.app :width => 200, :height => 200, :title => "Hello!" do
@input = edit_line
button("Say Hello") { alert("Hello #{@input.text}")}
end


Finally to see some of the other controls that are supported checkout this very beautifully designed form:

The code for this beauty is as follows:
require "shoes"
Shoes.app :width => 800, :height => 600, :title => "IronShoes everything sample" do
flow :width => 800, :height => 600 do
stack :width => 300, :height => 600 do
link "CLICK ME" do; alert "HEY"; end
link "GOOGLE", :click => "http://google.com"
image "shoes-logo.png", :click => "http://code.whytheluckystiff.net/shoes/"
@e = edit_line
banner "Hello Iron Shoes"
para "This is shoes...", strong("and another"), em("and a final one")
button "Foo" do
alert("Hello Foo")
end
button "Bar" do
alert("Hello Bar")
end
button "Get Textbox Value" do
alert(@e.text)
end
edit_box :width => 200, :height => 100
end
    stack :width => 400, :height => 600 do
  banner "Banner"
title "Title"
subtitle "Subtitle"
tagline "Tagline"
caption "Caption"
para "This is some more text"
image "rails.png"
para "Jimmy kissed", strong("Margaret"),
"and I've saved a picture somewhere on",
link("Flickr", :click => "http://flickr.com")
end
end
end

To checkout the code for my IronRuby implementation of shoes you can download the zip file containing my demos from my Code Camp presentation.

Overall, the experience of creating a basic implementation of shoes with IronRuby was very enjoyable.  While I did run into some problems, for the most part things went very smoothly.  I created a basic calculator, a very ugly friendfeed client (since twitter was down), as well as the other basic examples shown here. 

There is still a lot of API's available within shoes I'm not handling, as well as many things I'm not handling as well as I could so I'll likely continue to hack around on it a bit.  WPF and Silverlight support would be nice (and very doable) as well!

Search
Archive
Links
Categories
Admin Login
Sign In
Blogroll
Themes
Pick a theme: