public
Description: IronRuby sugar for WPF, Silverlight and Windows Forms.
Homepage:
Clone URL: git://github.com/thbar/magic.git
Click here to lend your support to: magic and make a donation at www.pledgie.com !
commit  d1e7238d3592b6fecff8301e316f3eeb81eaa7ba
tree    49175570122071c9a6c9f018de50620b2408ead7
parent  faf98c3161221e309290e7a6e311adb27fddf825
magic /
name age message
file LICENSE Loading commit data...
file README.textile
file Rakefile
file VERSION.yml
directory lib/
file magic.gemspec
directory spec/
README.textile

Magic is an IronRuby gem making it easier to develop Windows Forms, WPF and Silverlight UI with IronRuby.

USAGE

Here are quick starters:

Windows Forms

form = Magic.build do
@menu = main_menu do
menu_item(“&File”) do
menu_item(“&New”)
menu_item(“&Quit”).click { Application.Exit }
menu_item(“&Other Quit”, :click => lambda { Application.Exit })
end
end
form(:text => “Title”, :menu => @menu) do
flow_layout_panel(:dock => :fill) do
button(:text => “Click me!”).click do
MessageBox.Show(“Hello from button!”)
end
end
end
end

Application.Run(form)

WPF

window = Magic.build do
window(:width => 600, :height => 480, :title => ‘Hello world!’) do
stack_panel(:margin => thickness(30)) do
button(:content => ‘Click me!’, :font_size => 22).click do
MessageBox.show(“Ok!”)
end
end
end
end

app = Application.new
app.run(window)

Silverlight

You’ll need to run “rake compress” to create magic-compressed.rb, which gathers all the magic files into one. Once you have magic-compressed.rb, you can use it like that:

require “silverlight”
require “magic-compressed”

class App < SilverlightApplication

def initialize
application.root_visual = Magic.build do
stack_panel do
10.times { |i| text_block(:text => i.to_s, :width => 30,:height => 30) }
end
end
end
end

$app = App.new

It makes it easy to create XAML-free applications, or to reduce the amount of XAML to be created.

UNDER THE COVER

A few points (see spec/magic_spec.rb for details):

  • classes to be built are inferred from method calls (converted from snake_case to CamelCase)
    • menu_item creates an instance of MenuItem
    • button becomes Button
    • flow_layout_panel becomes FlowLayoutPanel
  • if a method call matches an existing method of the parent, the method is called
  • the instanciated control is passed as an optional param to the block
  • method calls automatically add the object to its parent children collection (if the object is a Control, a MenuItem or a UIElement – this will become configurable)
  • if the parent responds to :content (eg: WPF Window), then parent.content will use the (unique) child
  • if a Hash is passed, corresponding properties are set after instanciation (:text => “This is the text”)
  • if the property is an enum, snake_case symbol value is allowed (:dock => :fill is the same as :dock => DockStyle.Fill)
  • handlers are registered if a lambda is passed (:click => lambda)
  • handlers can also be registered by calling the block directly (button.lambda do … end)
  • instance variables can be reused (form.menu = @menu)
  • non-control (like BackgroundWorker for long-running operations) instances can be created (worker = background_worker)
  • the last evaluted expression is returned.

TESTING

Magic comes with its set of specs (based on MSpec). You’ll currently have to tweak Rakefile (see spec task) to match your environment.

Then you can run (either on Windows or Mac OS):

rake spec

to see all the (m)specs running.

Note that I currently use a few nasty mocks (see mocks.rb) that I’ll need to clean-up.

PLANNED FEATURES AND STUFF

Wildo:

  • support flag enums as an array of symbol
  • support delegate definition inside the block (vs. as param)
  • ensure event handlers can be registered from inside the block (vs. as param)
  • create a website (useful resources: here and here)

Maydo:

  • allow to always assume Magic.build { } is called (method_missing patch on self)
  • convert :margin => 30 to :margin => thickness(30) – needs reflection

IDEAS

  • use to generate graphs with QuickGraph
  • use outside IronRuby (the coupling to IronRuby is quite isolated)

COPYRIGHT

Copyright © 2008 Thibaut Barrère. See LICENSE for details.