Ruby/Fltk Design Note
[Ruby/Fltk]
Overview
Implementation Policy
- Each Fl_Xxxx class has a C++ subclass called `RBFLSubXxxx' for
handling the handle() and draw().
- handle() and draw() calls the `handle' and `draw' methods in
the Ruby layer using rb_funcall().
- Ruby's `handle' and `draw' methods are defined in the calss
of Fltk::FLWidget as the empty method, since the exception
is raised if we don't implement those.
- The C++ class hierarchy is directly refrected in the Ruby class
hierarchy.
Details
Creating and Deleting the Widget
All Fltk's widget objects are wrapped by the structure `RBFLData'.
typedef struct rb_fltk_widget_data {
Fl_Widget *widget;
VALUE callback;
} RBFLData;
if you'd like to create the `Fltk::Xxxx' object, you can use
rb_flwidget_new() like this:
Fl_Xxxx w = new Fl_Xxxx(...);
VALUE obj = rb_flwidget_new(rb_cXxxx, w);
where `rb_cXxxx' represents the class `Fltk::Xxxx'.
and you can destroy the widget like this:
rb_flwidget_destroy(obj);
we also use rb_flwidget_check() to check if the target widget
is destroied or not. if the target object has been destroied,
an exception is raised by the function.
rb_flwidget_check(obj);
Callbacks
`RBFLData' has the member `callback' to store the Proc object.
we can set the callback using FLWidget#callback.
widget = Fltk::FLWindow.new(....)
widget.callback{|win,e|
....
}
when running this code, rb_flwidget_callback() is called.
In this function, the given block is converted into the
Proc object by rb_f_lambda().
the object is stored in the RBFLData, and it set the internal
callback function rb_flwidget_callback_func() using
Fl_Widget::callback().
rb_flwidget_callback_func() calls the Proc object.
Event Handling and Drawing
`RBFLSubXxxx' is a C++ class which inherits from the `Fl_Xxxx' and
it must have methods handle() and draw() to call the Ruby's
methods `handle' and `draw' respectively.
about how to obtain the Ruby object, we can use rb_fltk_objmap_aref()
like this:
obj = rb_fltk_objmap_aref(this);
`this' is a C++ keyword which represent self object.
Class Hierarcy
The C++ class hierarcy must be something like this:
Fl_Widget ---> RBFLSubWidget
|
V
Fl_Group ---> RBFLSubGroup
|
V
Fl_Window ---> RBFLSubWIndow
and the Ruby class hierarcy is something like this:
FLWidget ---> FLSubWidget
|
V
FLGroup ---> FLSubGroup
|
V
FLWindow ---> FLSubWindow