# Can your GUI framework do this?

**URL:** <https://www.ruby-forum.com/t/can-your-gui-framework-do-this/139843>\
**Category:** Ruby\
**Created:** [June 8, 2008, 1:33am UTC](https://www.ruby-forum.com/t/can-your-gui-framework-do-this/139843 "2008-06-08T01:33:14Z")\
**Posts on this page:** 5\
**Page:** 1

<div class="post-metadata">

**Author:** ![Martin\_DeMello](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/m/f17d59/32.png) [@Martin\_DeMello](https://www.ruby-forum.com/u/Martin_DeMello)\
**Post date:** [June 8, 2008, 1:33am UTC](https://www.ruby-forum.com/t/can-your-gui-framework-do-this/139843/1 "2008-06-08T01:33:14Z")

</div>

One of the most interesting facets of a desktop GUI system is how easy  
it makes it to go off the beaten track, particularly how well you can  
add “first class” components to the system. (Using ‘first class’ here  
to mean ‘on an equal footing with the widgets supplied by the  
toolkit’). Also, as a ruby programmer, I’d naturally rather not drop  
down into C (or Java) to do this. I’m trying to collect examples of  
the following four tasks (which I will then assemble and put up on the  
web as another datapoint in the eternal GUI debate :)):

1. A component consisting of a series of existing components hooked  
together to act as a single widget
2. A component built ‘from scratch’ atop a canvas, that is, handling  
its own drawing and event management
3. A component combining a canvas and existing widgets
4. A container that takes a collection of widgets and lays them out  
according to some userdefined algorithm

Examples (more welcomed):

1. An icon widget, that combines a picture and a textfield  
underneath, with config options to turn either off or size the image,  
make the text editable, etc
2. A speedometer-type dial with a configurable range and tick interval
3. A box that holds a component and paints a customised border around it
4. A pure-ruby implementation of a wrapbox  
([http://zem.novylen.net/ruby/wrapboxdemo.png](http://zem.novylen.net/ruby/wrapboxdemo.png))

martin

---

<div class="post-metadata">

**Author:** ![Martin\_DeMello](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/m/f17d59/32.png) [@Martin\_DeMello](https://www.ruby-forum.com/u/Martin_DeMello)\
**Post date:** [June 8, 2008, 7:55am UTC](https://www.ruby-forum.com/t/can-your-gui-framework-do-this/139843/2 "2008-06-08T07:55:53Z")

</div>

(These examples require a Shoes that’s no older than a week or two.)

On Sun, Jun 08, 2008 at 08:29:55AM +0900, Martin DeMello wrote:

> 1. A component consisting of a series of existing components hooked  
> together to act as a single widget

In Shoes, you inherit from the Widget class and you can paint  
your own custom widgets or combine pre-existing ones.

Like, for instance, Shoes doesn’t come with a file input field like  
HTML does. But you can combine an `edit_line` and a `button`.

class Browse \< Widget  
def initialize  
@name = edit\_line  
@find =  
button(“Browse…”).click do  
@name.text = ask\_open\_file  
end  
end  
def filename  
@name.text  
end  
end

Shoes.app do  
browse  
end

When you inherit from Widget, you get a free lowercased method added  
to Shoes for inserting that widget into any “stack” or “flow” (like  
HTML divs, basically.)

And since the widget itself is a “flow”, you can move the whole widget  
as a single component. So you can call `move(x, y)` or `show` or  
`hide` on the object returned by the `browse` method.

> 1. A component built ‘from scratch’ atop a canvas, that is, handling  
> its own drawing and event management

Too easy, Shoes has painting nailed. I’ve worked hard to get things  
on par with Processing. See the `samples` directory for a clock  
widget and a calculator and a dictionary and you’ll find a lot more  
out on the web.

> 1. A component combining a canvas and existing widgets

So a combo of #1 and #2? Well, okay, so taking the `Browse` example  
from earlier, we could add a background and a border. This just  
illustrates that all widgets are drawn on a canvas anyway.

class Browse \< Widget  
def initialize  
flow do  
background “#09F”  
border “#FFF”  
@name = edit\_line  
@find =  
button(“Browse…”).click do  
@name.text = ask\_open\_file  
end  
end  
end  
end

> 1. A container that takes a collection of widgets and lays them out  
> according to some userdefined algorithm

I’ll have to think about this one. Shoes already has a ‘wrapbox’  
called a `flow`, but I can see why you’d want to lay things out  
yourself.

Okay, let’s see. So let’s try a `cascade` layout that positions  
everything diagonally from the element previous to it.

class Cascade \< Widget  
def initialize &blk  
instance\_eval &blk  
end  
def draw(a,b)  
x, y = 0, 0  
contents.each do |e|  
if x != e.left && y != e.top  
e.move x, y  
end  
x += e.height  
y += e.width  
end  
super(a,b)  
end  
end

Shoes.app do  
cascade do  
button “1”  
button “2”  
button “3”  
end  
end

The `initialize` part works because every widget is just a canvas  
anyway.  
And the `draw` method is called every time there’s a repaint.

That’s a bit clunky. But proves that it can be done.

> Examples (more welcomed):
> 
> 1. An icon widget, that combines a picture and a textfield  
> underneath, with config options to turn either off or size the image,  
> make the text editable, etc
> 2. A speedometer-type dial with a configurable range and tick interval
> 3. A box that holds a component and paints a customised border around it
> 4. A pure-ruby implementation of a wrapbox  
> ([http://zem.novylen.net/ruby/wrapboxdemo.png](http://zem.novylen.net/ruby/wrapboxdemo.png))

I’ll work on some really nice answers to these. This is a fantastic  
exercise.

\_why

---

<div class="post-metadata">

**Author:** ![Martin\_DeMello](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/m/f17d59/32.png) [@Martin\_DeMello](https://www.ruby-forum.com/u/Martin_DeMello)\
**Post date:** [June 8, 2008, 12:18pm UTC](https://www.ruby-forum.com/t/can-your-gui-framework-do-this/139843/3 "2008-06-08T12:18:28Z")

</div>

On Sat, Jun 7, 2008 at 10:50 PM, \_why [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid) wrote:

> I’ll work on some really nice answers to these. This is a fantastic exercise.

Looking forward to them. The code looks very slick - “check out shoes”  
just moved all the way up my todo list 🙂

martin

---

<div class="post-metadata">

**Author:** ![Martin\_DeMello](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/m/f17d59/32.png) [@Martin\_DeMello](https://www.ruby-forum.com/u/Martin_DeMello)\
**Post date:** [June 8, 2008, 7:08pm UTC](https://www.ruby-forum.com/t/can-your-gui-framework-do-this/139843/4 "2008-06-08T19:08:18Z")

</div>

Martin DeMello wrote:

> together to act as a single widget  
> make the text editable, etc  
> 2. A speedometer-type dial with a configurable range and tick interval  
> 3. A box that holds a component and paints a customised border around it  
> 4. A pure-ruby implementation of a wrapbox  
> ([http://zem.novylen.net/ruby/wrapboxdemo.png](http://zem.novylen.net/ruby/wrapboxdemo.png))

Swing can certainly do all this, and with layout tools like Netbeans  
Matisse you can do almost all of it drag-and-drop (though obviously  
implementing your own component atop a canvase requires code).

I could try to dig up some examples of doing this in Ruby, but I would  
wager the Monkeybars guys have some already. In general, it’s pretty  
easy.

- Charlie

---

<div class="post-metadata">

**Author:** ![Martin\_DeMello](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/m/f17d59/32.png) [@Martin\_DeMello](https://www.ruby-forum.com/u/Martin_DeMello)\
**Post date:** [June 26, 2008, 5:31pm UTC](https://www.ruby-forum.com/t/can-your-gui-framework-do-this/139843/5 "2008-06-26T17:31:38Z")

</div>

From: “Martin DeMello” [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid)  
Subject: Can your GUI framework do this?  
Date: Sun, 8 Jun 2008 08:29:55 +0900  
Message-ID:  
[removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid)

> Examples (more welcomed):

On Ruby/Tk,

> 1. An icon widget, that combines a picture and a textfield  
> underneath, with config options to turn either off or size the image,  
> make the text editable, etc

Use a TkLabel widget.

> 1. A speedometer-type dial with a configurable range and tick interval

Use (install) Tcl/Tk’s VU extension.  
Ruby/Tk has a wrapper library for the extension.

> 1. A box that holds a component and paints a customised border around it

Probably, a TkFrame widget is enough to do this.

> 1. A pure-ruby implementation of a wrapbox

Use a TkText widget and TkTextWindow objects.
