InfoQ

News

Ruby Shoes for lightweight GUIs, graphics and animation

Posted by Werner Schuster on Sep 19, 2007 12:05 AM

Community
Ruby
Topics
Rich Client / Desktop ,
Dynamic Languages
Tags
Metaprogramming ,
GUI
The experimentation in the Ruby GUI space continues. There are many old style bindings to GUI toolkits such as Qt or GTK, or embedded DSLs or APIs based on JRuby such as these three new ways of building GUIs with Swing. These libraries use different approaches for building and arranging GUI components.

Ruby Shoes is a GUI toolkit with a slightly different focus. Ruby Shoes is a creation of Why The Lucky Stiff, author of Why's (Poignant) Guide to Ruby and prolific programmer of libraries such as HPricot (HTML Parser), the web framework Camping and many others. Why's toolkit Ruby Shoes, is a GUI toolkit built on GTK technologies Cairo (drawing) and Pango (for text). The number of GUI controls it supports is limited by design, and the ones that do exist use OS GUI specific components. Currently MacOS X, Windows and GTK versions are available.

 Ruby Shoes is actually written in C and uses Ruby native extensions to allow interaction with Ruby code. The Ruby Shoes Readme names toolkits such as HyperCard or languages such as Processing or NodeBox as influences. The latter languages are specialized for tasks such as visualization. The influence of the languages for visualization can be seen by looking at some of the samples included with the Ruby Shoes. Here a code snippet for a simple animation showing a counter:
l = text "0"
animate(24) do |i|
 l.replace "#{i}"
end
The animate call handles animation in a very succinct way. The numeric parameter is the frame rate for the animation, and the given block is executed update the animation at the given rate.

Ruby Shoes supports the creation of graphics with primitives such as lines or ovals and paths, and operations for transformation, scaling or rotation. Here another example that also shows how to track motions of the mouse cursor:
Shoes.app do
 radius = 20.0
 vert = width - 30.0
 hor = width - 30.0
 o = oval(hor, vert, 10.0)
 animate(10) do |anim|
 nofill
  clear do
  oval(hor - radius, vert-radius, radius*2.0)
 satellites = vert /10
 satellites.to_i.times {|x|
h = hor + Math::sin(((6.28/satellites) * x )) * 40.0
 v = vert - Math::cos(((6.28/satellites) * x ))* 40.0
 fill rgb(1.0/satellites, 1.0/satellites, 0.8)
oval(h, v, 5.0)
}
  skew vert/10*Math::cos(anim)
 end
end
motion do |x,y|
 hor, vert = x, y
end
end
The animation and graphics capabilities lower the barrier for graphical applications such as visualization or creation of teaching materials. This shouldn't be surprising, as Ruby Shoes originated with the Hackety project, aimed at making programming easy for programming beginners.

Another aspect, as can be seen from the sample, is the use of Web concepts. Ruby Shoes brings URLs and links to the GUI and makes actions simple to implement. Setting up links to the GUI is easy, as is handling them in the code. The following sample is a very simple Class/Object browser: it lists all classes loaded as paginated link list. Clicking on a link shows the instances of the classes:
1 module Util 
2 def self.find_objects(name, from=0, to=10)
3 objects = []
4 c = 0
5 # get the class object from its name string
6 name_const = eval(name)
7 ObjectSpace::each_object( name_const ){|x |
8 if c >= from
9 objects << x
10 end
11 break if c >= to
12 c += 1
13 }
14 objects.sort{|first, second| first.to_s <=> second.to_s }
15 end
16 end
17 class ClassList < Shoes
18 url '/', :index
19 url '/objects/(\d+)', :object
20 url '/next', :next_page
21 url '/prev', :prev_page
22 def index
23 @@from = 0
24 object(0)
25 end
26 def next_page
27 @@from += 10
28 object(@@from)
29 end
30 def prev_page
31 @@from -= 10
32 object(@@from)
33 end
34 def object(num)
35 @@from ||= 0
36 num = num.to_i
37 stack :width => 500 do
38 flow :width => 200, :margin => 10, :margin_left => 200, :margin_top => 20 do
39 obj = Util::find_objects(@@objects[num].to_s)
40 text "#{obj.size}:" + obj.join(',')
41 end
42 flow :width => 380, :margin_left => 10 do
43 @@links = text ""
44 links = ""
45 if @@from >= 10
46 links += "<a href='/prev'>prev</a>\n"
47 end
48 @@objects[@@from, @@from+10].each_with_index{|el, idx|
49 links += "<span> <a href='/objects/#{@@from + idx}'>#{el}</a></span>"
50 }
51 links += "<a href='/next'> next</a>"
52 @@links.replace links
53 end
54 end
55 end
56 end
57 @@objects = Util::find_objects("Class", 0, 200)
58 Shoes.app :width => 640, :height => 700, :title => "Classes"
This code shows some concepts that Ruby Shoes uses.
  • URL routing for assigning handler functions to URL patterns
    Lines 18 through 21 show how URLs are routed to handler functions. It's easy to see that the home i.e. the root of the application is routed to the index method. In the same way, everything under the objects/ directory is routed to the object method, with everything after the slash passed to the handler method as argument. This is an easy way of associating events with handler functions, unlike the Publish/Subscribe model that is otherwise used for GUI interaction
  • Layout methods flow and stack
In conclusion: Ruby Shoes is definitely worth a look, if only because it uses different concepts than other plain GUI toolkits. It is a bit early in it's development process and, as Why The Lucky Stiff says, some concepts of the toolkit are prone to change. Also, the documentation is quite sparse at the moment, which turns programming into a guessing game at times.

Despite that, Ruby Shoes' animation and graphical abilities make it very handy for quickly prototyping applications with graphical elements. For some more Ruby Shoes information, RubyInside list provides a list of Ruby Shoes resources, such as tutorials to get started with simple GUI components or getting started with the 2D capabilities.

No comments

Watch Thread Reply

Educational Content

Bindings, Platforms, and Innovation

This presentation focuses on the Internet and separating myth from fact, history from the future, and the mundane from the imaginative. Bob Frankston presents a vision of what could and should be.

Orchestrating Long Running Activities with JBoss / JBPM

This article explores the use of JBoss and jBPM to implement design solutions that effectively address the issue of orchestrating long running activities.

Neo4j - The Benefits of Graph Databases

This presentation covers the use of graph databases as an optimal solution for data that is difficult to fit in static tables, rapidly evolving data or data that has a lot of optional attributes.

Realistic about Risk: Software development with Real Options

This session introduces Real Options and shows how it can help in running your project. Real Options is a decision-making process that can be used to manage risk.

Communication Flexibility Using Bindings

This article discusses the use of bindings on services and references (including the instance of non-configured bindings) as the means to implement SCA communications in a Web and SOA environment.

Writing DSLs in Groovy

After a short introduction to DSLs, Scott Davis plays with the keyboard showing how to approach the creation of a DSL by typing working snippets of Groovy code that get executed.

Scaling Agile with C/ALM (Collaborative Application Lifecycle Management)

IBM Rational and InfoQ present, Scaling Agile with C/ALM, an eBook showing organizations how to become “finely tuned software delivery machines” by enabling team integration and scaling.

Concurrent Programming with Microsoft F#

Amanda Laucher presents a real life enterprise application written in F#. She shows actual code snippets, explaining design decisions and suggesting how to use some of the F# constructs.