Scribble!

Posted May 5, 2007

Scribble!

Update: Check out the Scribble Google Group for additional news and information.

Update 2: Also use the Scribble Launchpad Site Group to make bug reports and stuff like that.

I don’t know how many folks have seen Hackety Hack, the latest project to emerge from the (somewhat psychedelic) mind of why the lucky stiff. It’s a program designed to get kids (13 and up, ostensibly, but I don’t beleive that) interested in programming. It does this by letting them write real, useful code, but focusing on what they can do with it rather than stuff like “This is the syntax, this is how you do arithmetic, blah, blah, blah.” It provides a set of very cool libraries that do actual useful stuff1. It even has its own manifesto.

One thing Hackety lacks, though, is a similarly cool way to mess with graphics. Drawing is fun! It’s also possible to draw really cool stuff using code in a friendly manner. NodeBox, a project in Python and sadly available only for OSX (although they’re working on Linux and Windows ports) proves this. In fact, I learned about NodeBox from a post on _why’s new blog, just to bring this whole thing full-circle.

Anyhoo, I thought it would be really great if there were some way to do something like NodeBox in Ruby, and preferably from within HacketyHack. Upon thinking this, I set out to create something of just this sort. I call it “Scribble” (or sometimes “Scribble!”). I even made a logo for it (see above)!

Scribble’s essentially designed to be a friendly way to create cool graphics. It’s scriptable in what I hope is a friendly manner, and can do some reasonably snazzy things. Eventually, I hope it will be able to do many very snazzy things.

Bubbles

Scribble uses the cairo graphics library for rendering the graphcs, and the GTK+ widget toolkit for the graphical user interface. The rendering bit is separated from the GUI, so it’s entirely possible to use it without needing users to install GTK. If this makes it into Hackety, that’s how I imagine it being used.

You can download and run Scribble right now from it’s Subversiony home. This home is currently on Hampton Catlin’s server, because mine doesn’t support Subversion.

svn co svn://hamptoncatlin.com/scribble/trunk scribble

To run it, just run the bin/scribble file. It requires Ruby, of course, as well as the latest Ruby GTK+ bindings and Ruby Cairo bindings (and of course GTK and Cairo themselves). Note that this won’t work with the latest RubyGems – you actually need to compile the latest development versions of these yourself. If you’ve got all of those, it should be able to run on OSX, Linux, and Windows.

Unfortunately, I haven’t gotten around to documenting anything yet, so I’ll give a little overview here. The basic concepts are that you have a brush, with which you draw shapes or scribbles. You can set various properties of the brush, like the fill color (the color inside shapes), the stroke color (the color of scribbles or shape borders), and the stroke width (the width of scribbles or shape borders).

All the colors have red, green and blue components as well as an opacity, all of which should be set as decimals between 0 and 1. Colors can be set with a hash, or just as a list of red, green, blue, and opacity. The width is simply in pixels.

brush.fill = {:red => 0.4, :green => 0.7, :blue => 1}
brush.stroke = 0, 0.5, 1, 1
brush.width = 3

There are two basic shapes: circles and rectangles. You can draw them by saying circle and rect and telling them stuff like where to put the center of the circle and upper-left-hand corner of the rectangle, how wide to make the circle, and what size the rectangle should be.

circle :center => [300, 20], :radius => 100
rect :corner => [20, 20], :size => [10, 10]

All the points, like :center and :corner, are points relative to the upper-left-hand corner. You can read it as [distance from left, distance from top]. The :size of the rectangle is just [width, height].

But rectangles and circles are boring! Who wants to be stuck with those? You can also make your own shapes, by drawing lines from point to point. Just like connecting the dots!

shape(10, 20) do |s| # Start a shape 10 pixels from the left edge and 20 from the top
  s.line 50, 20
  s.line 30, 60
  s.close
end

We just made a triangle! But what about curves? Well, curves are a just like lines, but curved. This is done by adding points which act like magnets, pulling on the line and causing it to bend.

shape(100, 100) do |s|
  s.curve 100, 200, [200, 100], [200, 200]
  s.curve 100, 100, [0, 200], [0, 100]
end

An ellipse! Notice there are two magnet-points on each of those curves. The first one pulls on the beginning of the line; the second on the end.

Scribbles are just like shapes, except that they don’t have any color inside them. They’re just lines. You can also jump around to various different places while making a scribble; you can do this with shapes, too, but it’s not as useful.

Nex3

1 By useful, I mean useful to kids. You won’t see a Bayesian filter or a heap; you’ll see a one-liner to download a video from YouTube and facilities that let you make a blog in six lines.

Ethan said May 06, 2007:

The numbers and whatnot are somewhat non-obvious. The greatest thing about a lot of the older languages was that they were written in something approaching plain English; Ruby is many things, but simple syntactically it’s not.

Nathan said May 07, 2007:

That’s a bit of a problem with any sort of graphics… there’s really no way (at least no way I’ve been able to think up) to do without numbers. I’ve tried to mitigate this as much as possible… I just added support for named colors, so you can say

brush.fill = :blue
brush.stroke = :cyan

and that’ll work. But for things like drawing lines, I just don’t think there’s a way to deal with it ecept using coordinates.

As for Ruby’s syntax, it may not be simple, but in my experience it’s simple enough. My younger brother tried Hackety Hack, and while he did make some syntax errors in the beginning, once it broke it was pretty clear to him what he had done wrong, how to fix it, and how not to do it again. And compared to other modern languages, Ruby’s syntax is reasonably forgiving; minimal parenthesizing, plain-English keywords, indentation-insensitive (don’t get me wrong, I love indentaion sensitivity, as evidenced by Haml; but I think it’s a potential source of confusion for new programmers).

Jon Leighton said May 07, 2007:

Cool. I have played around with Processing in the past but it is a bit “heavy” using Java. NodeBox looks cool but I am a Linux guy. If I get some time I might have a fiddle and maybe chuck some patches your way :)

BTW, in thearticle you talk about a circ method, but SVN head at head (and your screenshot) uses circle

zverok said May 07, 2007:

As for “non-obvious numbers” problem. I think, some “refernces” would be really helpful. By “reference”, I meen doing coordinates system obvious for drawer. In the best case, it should be axes with numbers and very light grid.

As for olors, on-screen “color repository” (list or table with colors with their names) would be enough to avoid “numeric” colors for anybody not comfortable with them.

Nathan said May 07, 2007:

Jon: Oops, I was getting it confused with my shortening of “rectangle.” I’ve fixed the post.

zverok: Those are both excellent ideas.

Jeff said May 29, 2007:

A couple thoughts:

- Maybe you could alleviate the problem of having to use numbers by having a set of little helper windows that a user would click on, and then it would insert numbers into the text buffer. A color picker would be easy: when clicked it could spit out an RGB triplet. For coordinates you could have either global coordinates by clicking in the big window, or relative coordinates by clicking in a small coordinate helper window that could have some nice hash marks and axis lines etc.

- You could extend the idea for scribbles and shapes, and it could probably be done in a way that helps people understand the code. So, for example, it would recognize when you open a new shape or scribble definition. On this event it would pop-up a coordinate window, where each successive click would draw the current scribble while also adding an “s.curve x,y, [a,b], [c,d]” line to the buffer. This way maybe you could get even younger kids to feel comfortable with connecting code to graphics, and then slowly lure them into writing more code by having lessons on creating fractals and things like that.

Really cool project. When I get some spare time I’ll try to help out as well.

hgs said May 30, 2007:

One may partially avoid numbers that look fearsome by means of turtle graphics. See how this is solved similarly in Alice 2.0 where objects (people, things) move so many metres and turn so much of a whole turn to the right or left, up or down. www.alice.org has docs about the design of the system.

Maybe your curve model could be enhanced by jumping around, dropping named magnets, and collecting named magnets into a curve. Maybe the magnets could be moved about and bend the curve? It’s tricky to make this stuff intuitive. The Alice team did lots of user testing.

The only other way I can think to get rid of number is to name the boundaries of the space, and use modifying methods. But having really(really(near(South_edge))) is a bit tedious. too. Implementing fuzzy logic is nontrivial.

I’m looking forward to seeing how this develops.

himdel said June 05, 2007:

Not sure if this is the place for bugreports, sorry. In current svn (rev 56) showing the about dialog crashes the app.

===================================================================
--- lib/scribble/gui/about_dialog.rb    (revision 56)
+++ lib/scribble/gui/about_dialog.rb    (working copy)
@@ -4,7 +4,7 @@
   class App
     class AboutDialog < GuiComponent

-      def create
+      def initialize
         @dialog = Gtk::AboutDialog.new
         @dialog.signal_connect('response', &method(:hide))
Nathan said June 05, 2007:

Thanks, himdel. I’ve fixed that in revision 61. For future reference, we now have a Launchpad page where that sort of thing should go.

mzukowski said June 07, 2007:

I’ve got ruby-gnome2 and ruby-gtk2 installed, but when I try to run bin/scribble I get:

<code>./lib/scribble/gui/scribble_area.rb:98:in `resize_drawing_area': undefined method `create_cairo_context' for #<Gdk::Pixmap:0xb6dced24 ptr=0x8516b00>
         from ./scribble/lib/../lib/scribble/gui/scribble_area.rb:92:in `initialize_drawing_area'
....</code>

Am I doing something wrong or is the trunk in svn busted right now?

mzukowski said June 07, 2007:

P.S. I thought I was missing ruby-cairo bindings, but after installing those I’m still getting the same error.

Nathan said June 07, 2007:

I think you may not have the latest development versions. create_cairo_context is only available for very recent releases of ruby-gnome2 – if you just use the Gem, Scribble won’t work.

jafraldo said April 22, 2010:

So is there a copy of why_’s blog post on nodebox anywhere? I’d like to read it but it seems to have disappeared.

Nevermind: http://web.archive.org/web/*/http://hackety.org/2007/05/03/nodeBox.html

Make your comments snazzy with Textile!