Saturday, January 17, 2009

Exploring the Shoes class hierarchy

I've spent a lot of time this week attempting to get to know the Shoes ruby GUI kit better. Shoes is an open source project, and one that is pretty early in its evolution.

This has a couple of implications:

  1. Its very raw. It doesn't take too much tinkering to find something thats broken.

  2. It is incomplete. Shoes has a few fundamental abstractions that make basic layout straightforward, and generally makes simple things simple. However, if you try to do something that _why hasn't tried to do yet, it probably won't work.

  3. You can open it up, learn how it works, and fix things!

I've spent most of my train/commute time (3 hours a day) this week digging into the source, fixing minor bugs, and trying to understand how it all works. While Shoes is a ruby toolkit, most of it is written in C. From what I've been able to determine, there are essentially three layers.

The uppermost layer is the set of Ruby classes and their methods, most defined in C and then exposed to Ruby. These live in lib/shoes.rb, the various files in lib/shoes, shoes/ruby.[ch], and shoes/canvas.[ch].

Below that there is a set of abstract windowing code. This defines the way that Shoes layouts occur, how the different objects relate to each other within the visible canvas, etc. This is located primarily in shoes/app.[ch] and shoes/world.[ch]. Also living in this middle layer are things like image handling, http handling, and special effects.

Finally, the bottom layer is the interface to the native graphics libraries... a gtk interface, a windows interface, and an interface to Cocoa for OS X. These are located in shoes/native.h and the shoes/native directory. These are typically called into from the middle layer, and issue event-related callbacks back up into the middle layer.

As I learn more about Shoes, I hope to understand and write about all of these pieces, but for now I'm focusing most on learning about the interface Shoes exposes to ruby. This allows me to better make sense of what works and what doesn't, and gain an intuition for how things should work in Shoes programs. Since a lot of the code is written in C, I've spent some time figuring out just the Ruby class hierarchy.

Here's the basic hierarchy... I haven't included anything about what methods are defined on what classes here, but I've put my notes at if you want to look at them. I'll probably update them as I do more learning.

class Window; end
class Mouse; end
class Canvas; end
class Shoes < Canvas
# Canvas-like things
class App < ::Shoes; end
class Flow < ::Shoes; end
class Stack < ::Shoes; end
class Mask < ::Shoes; end
class Widget < ::Shoes; end

# Standalones with no children
class Shape; end
class Effect; end
class Video; end

# Patterns
class Pattern; end
class Background < Pattern; end
class Border < Pattern; end

# TextBlocks
class TextBlock; end
class Para < TextBlock; end
class Banner < TextBlock; end
class Title < TextBlock; end
class Subtitle < TextBlock; end
class Tagline < TextBlock; end
class Caption < TextBlock; end
class Inscription< TextBlock; end

# Text
class Text; end
class Code < Text; end
class Del < Text; end
class Em < Text; end
class Ins < Text; end
class Span < Text; end
class Strong < Text; end
class Sup < Text; end
class Sub < Text; end
class Link < Text; end
class LinkHover < Text; end

# Natives
class Native; end
class Button < Native; end
class EditLine < Native; end
class EditBox < Native; end
class ListBox < Native; end
class Progress < Native; end
class Check < Native; end
class Radio < Native; end

# Timing related stuff
class TimerBase; end
class Animation < TimerBase; end
class Every < TimerBase; end
class Timer < TimerBase; end

class Color; end

class Download
class Response; end

# Errors
class InvalidModeError < StandardError; end
class NotImplementedError < StandardError; end
class VideoError < StandardError; end

So at least now I know that if I've figured out something that works pretty well flows, it should work for stacks or the entire app as well. Similarly if I'm comfortable working with para, its likely similar techniques will work for banners, titles, subtitles, captions etc.

Its a work in progress; let me know if I got anything wrong, or if you want to know more about the methods available for each class.


  1. Nice work - one thing that would be helpful is a complete listing of methods as these can change from release to release

  2. Thank you! this should give me a good headstart on my shoes internals learning venture. :)