When Shoes – a “tiny graphics toolkit for Ruby” – first came out a month or two ago, I was excited, but didn’t really have much to do with it. Then it hit me – I love my Binary Clock on my iGoogle home page – why not build one?
The first thing to learn about Shoes is that you can stack things and then save them basically as an array. Since a binary clock has 6 columns, I created a variable for each column which contained the squares. This looked like:
@hours2 = stack {
fill @fill
4.times do |i|
rect :left => @left, :top => (@top - (i*@offset)), :width => @width
end
}
Which says to create a stack with the fill color of our fill, and draw four rectangles, bottom up.
Next, I had to figure out which images to turn on. The code to flip the seconds looked like:
sec = now.sec.to_s.split(//)
sec1 = []
sec1 = get_image_pos_to_turn_on(sec[0]) if sec.length > 1
sec2 = get_image_pos_to_turn_on(sec[sec.length-1])
turn_on_images(@seconds1, sec1)
turn_on_images(@seconds2, sec2)
Which isn’t all that pretty, but works. For example, the get_image_pos_to_turn_on method is just this:
def get_image_pos_to_turn_on(num)
images = []
images = [0] if num == "1"
images = [1] if num == "2"
images = [0,1] if num == "3"
images = [2] if num == "4"
images = [0,2] if num == "5"
images = [1,2] if num == "6"
images = [0,1,2] if num == "7"
images = [3] if num == "8"
images = [0,3] if num == "9"
return images
end
And, well, that’s it. Which is the beauty of the Shoes app. It makes simple things simple. Here’s a screen shot of it in action:
You can download the full source code from here: binary_clock.rb. You’ll also need to download Shoes from the above link, and run the app by doing shoes binary_clock.rb
.
And, this being my first Shoes app, I’m more than happy to take comments and suggestions for better ways to do it. Considering I did this whole thing in about 30 minutes with having barely looked at Shoes before, I’m pretty happy.
Cool app. Shoes is indeed cool, and as it matures it’s definitely something that many people may use.
By the way, for the get_image_pos_to_turn_on method, why don’t you use a case block?
Or even better—since num is just an integer string, just use a single array:
IMAGE_POSITIONS = [
[],
[0],
[1],
[0, 1],
[2],
[0, 2],
[1, 2],
[0, 1, 2],
[3],
[0, 3]
]
end
def get_image_pos_to_turn_on num
IMAGE_POSITIONS[num.to_i] or []
end
…Actually, since the array follows a pattern, you probably could just generate it, if it’s worth it.
Great idea! That’s what I get for doing it late at night and without a pair – I missed both the simplest thing, and an interesting pattern.
Fantastic! I love simple code. :)