Ruby/Fltk Design Note

[Ruby/Fltk]

Overview


Implementation Policy


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