GUI's and the Rouge, Part II 
Author Message
 GUI's and the Rouge, Part II

in part one of this message i mention the problem of non-POLS and
ugliness when it came to hand coding a GUI interface. follow this link.
it is example code of the Rouge's utopia:

http://www.*-*-*.com/

i can honestly say this code is probably better than any i have ever
seen, but i'm sorry, it's still just dosen't look like my idea of gui
utopia. it is still a traditional approach, albiet very innovative in
its use of ruby's OO and iterators, it nonetheless follows the same
overall design characteristics of other tools: defining each and every
widget, designating *content* and style, their coorelation, and binding
procedures before passing off execution control (app.controller.start)
to the gui engine. but, i hear you thinking, "what other way is there?
that's just how it's done!" well, i emphisized content above because its
the key to a better approach. we can get a taste of this by looking
amrita:

http://www.*-*-*.com/

the beauty of amrita lies in the fact that the data which is to appear
in the end result contributes to its design. thus, in part, the layout
does not have to be specified because the data itself designates it. the
end result is cleaner leaner code. in effect amrita has done what OO
design is intended to do, it has given precedence to the data model.

although amrita is a unidirection html/xhtml templating system, her
principles just as easily carry over to guis. arbitrarily, as
programmers, we can think of it like this: instead of widget.displays(x)
we get x.widgetized. let me provide a mock code fragment to help
clearify. we'll call our imaginary gui toolkit, RougeDuex.

  require 'rougeduex'

  class MyClass
    attr_accessor avar
    def initialize

    end
  end

  myobj = MyClass.new
  myobj.avar.extend RougeDeux::WidgetFactory(:Label)

  mywin = RougeDuex::WidgetFactory(:Window).show
  mywin.embody {
    pack myobj.avar, RougeDuex::TOP
  }

  myobj.avar = "Hello, World!"

and just like that we have a window with a label in it greeting us.

you might notice something a bit odd about this very simple example: the
window was displayed prior to the label being added. this is a key
point. by retaining execution, such that the gui is a spawned processes,
we retain the ability to modify it "on-the-fly". just think of all the
neat tricks we can do with that! no longer are we limited to just the
event model of the gui's engine. morever, notice that the class
definition is completly clean. there's no mention of RougeDuex anywhere
in it, nonetheless it is direclty linked to our gui. should avar change
for any reason, so will our label. and if avar were a text entry field
or any other input widget, instead of a label, avar would automagically
reflect that input.

you may wonder how other aspects of avar as a label get designated. well
since avar was extended to be a label it gained a few things that allow
us to do that: myobj.avar.style={:color=>'red'}, for example. no
problem!

also one might be concerned about performance with such dynamic
rendering, since anytime one changes a variable the gui requires
refreshing. well, a transaction model can help with that were it is
essential.

so there's the ideal, my friends. i am sure certain elements of the
current Rouge project could be carried over into this, and i think the
end result would be the easiest, most intuitive and fun (like ruby!) gui
to ever have the priviledge of being coded by you ;-)

in the last part of my series (don't ask me what posessed me to do this,
i don't know!) i'll go into the possabilities of implementation.

~transami

  _(")_  v man
   \v/  
   ^ ^



Thu, 06 Jan 2005 01:04:00 GMT  
 GUI's and the Rouge, Part II

Quote:
>  we can think of it like this: instead of widget.displays(x)
> we get x.widgetized.

The main problem with this is that the data shouldn't have to know
about how it's going to be presented.

When you want to display something on (say) a PDA, you might choose to
have different representations (shorter strings, no colors, etc.).

Maybe the best strategy would be to have an intervening policy object
between the data and the widgets that determines how a given piece of
data would be presented in a particular kind of UI.

--
Ned Konz
http://bike-nomad.com
GPG key ID: BEEA7EFE



Thu, 06 Jan 2005 02:27:10 GMT  
 GUI's and the Rouge, Part II
I'm sorry, Tom, but I don't see a really new direction in your comments.  It
appears that you have simply repackaged/renamed the current solutions to
writing a GUI program.  Perhaps I am just slow-witted or perhaps my opinion
is premature and I should wait on more details.   Let me specify the sources
of my confusion:
1)  GUI design is more of an art form than a technology.  I don't believe that
good design of a user interface can be automated.
2)  How is replacing a GUI specification with a template an improvement?  The
same design decisions that go into a GUI specification will have to go into
template design.
3)  It seems that you are unhappy with the concept of a mainloop and
callbacks.  Yet, the whole purpose of a GUI is not to just display data but
to monitor the user's actions and carry out his intent.  The user's
keyboard/mouse actions are an event that triggers a cascade of internal
events.  How would you handle this?

What am I missing?



Thu, 06 Jan 2005 02:58:21 GMT  
 GUI's and the Rouge, Part II

Quote:

> The main problem with this is that the data shouldn't have to know
> about how it's going to be presented.

> When you want to display something on (say) a PDA, you might choose to
> have different representations (shorter strings, no colors, etc.).

> Maybe the best strategy would be to have an intervening policy object
> between the data and the widgets that determines how a given piece of
> data would be presented in a particular kind of UI.

thanks Ned,
a good point. but thanks to ruby we can deal with this farily easily w/o
having to resort to intervening objects by seperating parts of a class
definition. just as one extends a class now one can create conditional
extenstions dependent, say, on the platform. for exmaple:

pda.rb:
class MyClass
  def initialize  
    super
    avar.extend RougeDeux::WidgetFactory(:Label)
    avar.style={:width=>10}
  end
end

pc.rb:
class MyClass
  def initialize  
    super
    avar.extend RougeDeux::WidgetFactory(:Label)
    avar.style={:width=>100}
  end
end

myapp.rb:
class MyClass
  attr_accessor avar
  def initialize

  end
end
require pda.rb if $interface='PDA'
require pc.rb if $interface='PC'

so this is one approach. in a sense it is like an intervening object,
only it's an intervening definition. (note: this does "confuscate" the
object, but it does it in a clean, well seperated manner) i'm sure there
are others ways. one thing i hadn't taken into account, that your post
made me consider is the idea of stylesheets --convenient ways to set the
properties of a large number of widgets at once. but i'm sure that would
not be too difficult to factor in.

~transami

--
~transami

  _(")_  dobee dobee do...
   \v/  
   ^ ^



Thu, 06 Jan 2005 03:24:21 GMT  
 GUI's and the Rouge, Part II

Quote:

> 1)  GUI design is more of an art form than a technology.  I don't believe that
> good design of a user interface can be automated.

quite right! it can't be. but we certainly can make the tools for its
PRODUCTION easier.

Quote:
> 2)  How is replacing a GUI specification with a template an improvement?  The
> same design decisions that go into a GUI specification will have to go into
> template design.

why do people use template systems at all? but actually i'm not saying a
template is neccessary. in fact my code example had no mention of a
template. so i'm not replacing a GUi spec with a template. yet i think
template systems are very powerful tools and Rouge or whatever should
have one.

Quote:
> 3)  It seems that you are unhappy with the concept of a mainloop and
> callbacks.  Yet, the whole purpose of a GUI is not to just display data but
> to monitor the user's actions and carry out his intent.  The user's
> keyboard/mouse actions are an event that triggers a cascade of internal
> events.  How would you handle this?

this would work much like the gui's we use today. the gui engine still
processes events, and we still provide a means for action when those
events are triggered. i am only proposing the additional ability to
continue execution of the "main line" in parrallel to this. there's
nothing wrong with triggers/events, but i believe it is limiting to be
wholly dependent on those and thus having to internalize ones code into
the gui constructs via procs. in effect, and i don't think i have fully
explored this, i am trying to successfully turn the gui to app
interfacing inside-out.

~transami

--
~transami

  _(")_  dobee dobee do...
   \v/  
   ^ ^



Thu, 06 Jan 2005 03:34:50 GMT  
 GUI's and the Rouge, Part II

Quote:

> point. by retaining execution, such that the gui is a spawned processes,
> we retain the ability to modify it "on-the-fly". just think of all the
> neat tricks we can do with that! no longer are we limited to just the
> event model of the gui's engine.

I've done something like that in the past from irb with:

Thread.new { Gtk.main }

Quote:
> you may wonder how other aspects of avar as a label get designated. well
> since avar was extended to be a label it gained a few things that allow
> us to do that: myobj.avar.style={:color=>'red'},

That last one defies your purpose because it mixes model and
presentation (a lot).

Have you thought about automatic code generation?  Rather than
having GUI code mixed in the model (implicitly or explicitly), what
about, given a model class, automatically generating a class that
in turn automatically generates the appropriate GUI?  Something like...

class MyModel
  def initialize


  end

  def avar

  end

  def avar=(value)

  end

  def another

  end

  def another=(value)

  end
end

setter_getter_pairs = [
  [:avar, :avar=],
  [:another, :another]
]

MyGui = GuiFactory.new(MyModel, setter_getter_pairs)

my_instance = MyModel.new

my_instance_gui = MyGui.new(my_instance, parent_widget)

Also consider chances like...

my_instance_gui = MyGui.new(my_instance, parent_widget, stylesheet)

I've defined avar= and another= explicitly.  Remember that when you are
calling myobj.var=something, for GUI purposes you probably don't want to
catch the assignment of whatever variable(s) get assigned within the var=()
method of myobj, but rather the symmetrical value returned by the var()
method (think of a class that stores the time in milliseconds
internally but gets it from and tells it to the rest of the world in
form of a string "Sunday 4, Mar...").

My .$02.

Massimiliano



Thu, 06 Jan 2005 03:34:49 GMT  
 GUI's and the Rouge, Part II

Quote:

> Apologize in advance...this is a LONG response...

no no that's great!

Quote:
> Well I have not looked at this in a bit.  I wrote this in an evening as
> more of a proof of concept than anything else.  Sean Russell had ideas
> that appear to follow yours more closely than mine.  BTW:  I have
> uploaded the source that enabled this to:
> http://www.infoether.com/ruby/utopia.zip

great, i'll check it out.

Quote:
> First, execution control is not necessarily passed off by starting the
> controller.  It does not have to be, but since Ruby's threading is
> non-native, most UI toolkits kind of take over. This could be addressed
> (without adding native threads to Ruby)...such as having another process
> that presents and controls the UI and communicates to the Ruby process
> via a socket...like X.

that occured to me too. are there other means to this, or is socket
communication the only way. probably the best way anyway, though.

Quote:
> Second, I have no problem with binding an object-attribute in as a
> binding to a widget.  Like:

> class MyClass
>   attr_accessor :avar
>   def initialize

>   end
> end
> myobj = MyClass.new

> myLabel(:label).text(bind_object(myobj, :avar))

> and when the method bind_object is called it aliases the original avar=
> method with one that updates the Label's 'text' attribute (and vice
> versa).

that's great. i didn't see this in utopia. i was able to manage the same
thing with my miterbox (my rouge like project). but that's a one way
street. the difficulty here is going back the other way: when the bound
variable changes the gui gets automagically updated. i found this to be,
as of yet, an insurmountable problem.

Quote:
> Or to more align with your example below:

> myobj.extend Utopia::WidgetBinder
> myobj.bind_widget(mainWindow.myLabel, :avar)

this notation really works? cool!

Quote:
> Well, in amrita, the hierarchy of the data has to match the hierarchy of
> the (HTML) UI.
..
> OK, now give me syntax for the example I presented on the the rubyide
> site.  Your idea of mixing the widget capability into the object is
> cool, but how the widgets get organized on the screen needs to be
> defined somewhere.
..
> I am not hung up on anything done so far (it was a quick hack), but we
> need to see semi-realistic examples with windows, menus, events, etc.

i apologize, my example was not a good one for as showing off the amrita
concepts as applied to guis. i will work on doing so and post it.

also keep in mind, i don't have all this fully flushed out. i have just
been spending a lot of time on the gui abstraction problem, because i
have a big bad old gui forntend to write. given its breadth i have been
trying to create an abstraction to facilitate this and make my life
easier in the long run. hence the source of these concepts. hopefully i
can work it out rather then having to hand code all of it.

in that light, just how far a long is utopia? is there any development
activty going on with it or related to the Rouge project? what's the
status there?

thanks for the in depth reponse!

~transami

  _(")_  dobee dobee do...
   \v/  
   ^ ^



Thu, 06 Jan 2005 04:06:01 GMT  
 GUI's and the Rouge, Part II

Quote:
> -----Original Message-----

> Sent: Saturday, July 20, 2002 4:01 PM
> To: ruby-talk ML
> Subject: RE: GUI's and the Rouge, Part II


> > Apologize in advance...this is a LONG response...

> no no that's great!

> > Well I have not looked at this in a bit.  I wrote this in an evening
as
> > more of a proof of concept than anything else.  Sean Russell had
ideas
> > that appear to follow yours more closely than mine.  BTW:  I have
> > uploaded the source that enabled this to:
> > http://www.infoether.com/ruby/utopia.zip

> great, i'll check it out.

> > First, execution control is not necessarily passed off by starting
the
> > controller.  It does not have to be, but since Ruby's threading is
> > non-native, most UI toolkits kind of take over. This could be
addressed
> > (without adding native threads to Ruby)...such as having another
process
> > that presents and controls the UI and communicates to the Ruby
process
> > via a socket...like X.

> that occured to me too. are there other means to this, or is socket
> communication the only way. probably the best way anyway, though.

Well, we could abstract the communications ;-)  sockets would allow it
to be remoted...which would rock.

BTW, the "change the object's attribute and you change the widget"
problem can be solved by aliasing the setter method on the attribute
with one that updates the UI and then calls the original method.

- Show quoted text -

Quote:
> <SNIP>

> i apologize, my example was not a good one for as showing off the
amrita
> concepts as applied to guis. i will work on doing so and post it.

> also keep in mind, i don't have all this fully flushed out. i have
just
> been spending a lot of time on the gui abstraction problem, because i
> have a big bad old gui forntend to write. given its breadth i have
been
> trying to create an abstraction to facilitate this and make my life
> easier in the long run. hence the source of these concepts. hopefully
i
> can work it out rather then having to hand code all of it.

> in that light, just how far a long is utopia? is there any development
> activty going on with it or related to the Rouge project? what's the
> status there?

Utopia is what you got.  It's an exploration into the GUI abstraction
problem.  Rouge stalled some months ago.  Sean Russell has been focusing
on REXML and I don't if he has advanced Rouge any.  I am interested in
this, but I stopped working on it to focus on some other things
(jabber4r, FreeBASE/FreeRIDE, JXTA/RXTA, My own company, etc).

On an aside, you may actually want to look at FreeRIDE (the Ruby IDE) We
are abstracting GUI components to allow multiple 'renderers'.  It's at
that site you were on (www.rubyide.org).  It's currently using RXRuby
and VERY alpha-stage, but may give you some ideas.

-rich



Thu, 06 Jan 2005 04:42:26 GMT  
 GUI's and the Rouge, Part II

Quote:

> Have you thought about automatic code generation?  Rather than
> having GUI code mixed in the model (implicitly or explicitly), what
> about, given a model class, automatically generating a class that
> in turn automatically generates the appropriate GUI?  Something like...

> My .$02.

and a damn good $.02 it is!

i need your help with one thing though. could you give me a simple
example of generating a class?

thanks!

~transami



Thu, 06 Jan 2005 16:54:35 GMT  
 GUI's and the Rouge, Part II

Quote:

> Maybe the best strategy would be to have an intervening policy object
> between the data and the widgets that determines how a given piece of
> data would be presented in a particular kind of UI.

hey Ned! your concept of an intervening "object" turned out to be right
on! i didn't realize it at first, but massimiliano was saying essentialy
the same thing. i worked through it all and you two were on the money.
thanks!

hope you like it...

~transami

  _(")_  v: i am not an alien
   \v/  
   ^ ^



Thu, 06 Jan 2005 16:59:00 GMT  
 GUI's and the Rouge, Part II

[snipped lots and lots of interesting stuff]

Tom, the RougeProject came from a convergence of two things: Sean Russell's
personal desire for a more elegant way do GUIs in Ruby, and the FreeRIDE
project's frustration of not being able to find a GUI toolkit that fully met
all of our requirements. What you see for the RougeProject on the FreeRIDE
wiki (http://www.rubyide.org/cgi-bin/wiki.pl?RougeProject) is result of a
month long ML discussion back in Feb/Mar amongst about a dozen Ruby
developers.

Most of us who participated in the discussion did so because we were all
intensely interested having a GUI toolkit had both the same sort of elegance
and ease-of-use that REXML brought to XML processing *and* did not have any
of the annoying deficiencies found in the currently available GUI toolkits.
This was a very tall order, both in terms of design and in the amount of
effort that would be required to implement it. But definitely worthwhile, if
it could be achieved.

More than half of the participants in these discussions were FreeRIDE
developers. We wanted to use such a GUI toolkit within FreeRIDE and had a
very personal interest in contributing ideas and helping to shape the
result. But FreeRIDE is, itself, a very large effort and we could not afford
to divert any development effort off of our own project.

So, as Rich Kilmer pointed out, the implementation effort has appeared to
have stalled (Sean, if I'm wrong about that, please correct me), not from
lack of interest, but for the lack of a strong and passionate leader who has
the available time to champion this project and rally other developers to
join in.

I'm hoping that your knowledge, energy, and enthusiasm can translate into a
sustainable project from which all of us in the Ruby community can benefit
(including FreeRIDE).

To that end, I would like to invite you to create one or more pages on the
FreeRIDE wiki to capture the results of your recent discussions and
thoughts. And if you are interested in pushing forward with this, I would
even be willing to set up and host a separate wiki just for this project.

Curt



Thu, 06 Jan 2005 19:27:54 GMT  
 GUI's and the Rouge, Part II

Quote:

> i need your help with one thing though. could you give me a simple
> example of generating a class?

I see from your posts about module_eval and define_method that you've
already discovered more than I could have told you. :-)

Massimiliano



Fri, 07 Jan 2005 19:46:43 GMT  
 GUI's and the Rouge, Part II

Quote:

> I see from your posts about module_eval and define_method that you've
> already discovered more than I could have told you. :-)

yes, thanks. i managed to hack it out. :-)

--
~transami

  _(")_  dobee dobee do...
   \v/  
   ^ ^



Fri, 07 Jan 2005 20:02:36 GMT  
 GUI's and the Rouge, Part II

Quote:


> >  we can think of it like this: instead of widget.displays(x)
> > we get x.widgetized.

This ties into a discussion I was having about coding and testing html
-- that it's better to use widgets to make html easier to test, not to
prevent you from having to write html.  i.e., instead of writing:

Form:Text.new( "name", "default name", :size => 30; :maxlength => 40 )
Form:Pass.new( "password", "", :size => 30; :maxlength => 40 )

to replace

Name: <input type=text     name=name value="default name" size=30
maxlength=40>
Pass: <input type=password name=name value=""             size=30
maxlength=40>

You have:

Login.form # => outputs the above html

which we thought of as an application specific widget containing the
two form elements.  The goal here would be to break the presentation
into "widgetize" methods that make it easier to test the html.

However, this isn't something that would the basis for a library.
These widgets need to be as general as possible to be useful, instead
of GUI widgets which are made to be as flexible as possible.  I guess
the goal is to code for reuse within your application, not for reuse
outside of your application.

Quote:
> The main problem with this is that the data shouldn't have to know
> about how it's going to be presented.

> When you want to display something on (say) a PDA, you might choose to
> have different representations (shorter strings, no colors, etc.).

I think it's rare that you would want the same application on a PDA
and a desktop.  The limitations of a PDA go beyond the size and color
depth of the framebuffer; there are also major input considerations.
In a MVC architecture I don't see much benefit to sharing the the view
or controller code between dramatically different platforms (unless
the problem is dramatically simple, such as a calculater).

~ Patrick



Sat, 08 Jan 2005 14:18:59 GMT  
 
 [ 100 post ]  Go to page: [1] [2] [3] [4] [5] [6] [7]

 Relevant Pages 

1. GUI's and the Rouge, Part III (yes, finally) 1/2

2. GUI's and the Rouge, Part 1

3. ( picoVerse-:( marketing idea part II ) )

4. Relation Tree - Part II

5. The Xbase Files Brasil - Part II - To MR Al Acker

6. Check Marks Part II...How???

7. Foxpro Driver Part II

8. Wierd Stuff Part II

9. Preprinted Forms? Part II

10. COM port reading in LabVIEW - part II

11. Simple Clipper Questions Part II

12. The Power of CPP, part II.

 

 
Powered by phpBB® Forum Software