Reading the forums I've found interesting ideas about extending the 
functionality of callbacks in FLTK.

Here is my two cents on this issue:

---- Fl_Widget.H
class Fl_AnyClass {};

/** Default member callback type definition for all fltk widgets (by far the 
most used) */
typedef void (Fl_AnyClass::*Fl_MCallback)(Fl_Widget*, void*);
/** Default member callback type pointer definition for all fltk widgets */
typedef Fl_MCallback* Fl_MCallback_p; // needed for BORLAND
/** Zero parameter member callback type definition passing only the widget */
typedef void (Fl_AnyClass::*Fl_MCallback0)();
/** One parameter member callback type definition passing only the widget */
typedef void (Fl_AnyClass::*Fl_MCallback1)(Fl_Widget*);
/** Member callback type definition passing the widget and a long data value */
typedef void (Fl_AnyClass::*Fl_MCallback2)(Fl_Widget*, long);

#define MCALLBACK(wdg, mf) wdg->mcallback((Fl_AnyClass*)this, (Fl_MCallback)&mf)

..

class FL_EXPORT Fl_Widget {
  friend class Fl_Group;

  Fl_Group* parent_;
  union { //new
      Fl_Callback* callback_;
      Fl_MCallback mcallback_; //new
  };
  void* user_data_;
  Fl_AnyClass *any_class_mcb_; //new
  int x_,y_,w_,h_;

..

  /** class that holds a method for callbacks*/
  Fl_AnyClass *any_class_mcb() {return any_class_mcb_;};

  /** Gets the current class method callback function for the widget.
      Each widget has a single class method callback.
      \return current mcallback
   */
  Fl_MCallback mcallback() const {return mcallback_;}

  /** Sets the current class method callback function for the widget.
      Each widget has a single class method callback.
      \param[in] cb new class method callback
      \param[in] p user data
   */
  void mcallback(Fl_AnyClass *klass, Fl_MCallback cb, void* p) {
      any_class_mcb_ = klass;
      mcallback_=cb;
      user_data_=p;
  }

  /** Sets the current class method callback function for the widget.
      Each widget has a single callback.
      \param[in] cb new method callback
   */
  void mcallback(Fl_AnyClass *klass, Fl_MCallback cb) {
      any_class_mcb_ = klass;
      mcallback_=cb;
  }

  /** Sets the current callback method function for the widget.
      Each widget has a single method callback.
      \param[in] cb new callback
   */
  void mcallback(Fl_AnyClass *klass, Fl_MCallback0 cb) {
        any_class_mcb_ = klass;
        mcallback_=(Fl_MCallback)cb;
  }

  /** Sets the current callback method function for the widget.
      Each widget has a single method callback.
      \param[in] cb new callback
   */
  void mcallback(Fl_AnyClass *klass, Fl_MCallback1 cb) {
      any_class_mcb_ = klass;
      mcallback_=(Fl_MCallback)cb;
  }

  /** Sets the current callback method function for the widget.
      Each widget has a single method callback.
      \param[in] cb new callback
      \param[in] p user data
   */
  void mcallback(Fl_AnyClass *klass, Fl_MCallback2 cb, long p=0) {
      any_class_mcb_ = klass;
      mcallback_=(Fl_MCallback)cb;
      user_data_=(void*)p;
  }
------

Fl_Widget.cxx
------

Fl_Widget::Fl_Widget(int X, int Y, int W, int H, const char* L) {
..
  any_class_mcb_ = 0;
..
}

...

void
Fl_Widget::do_callback(Fl_Widget* o,void* arg) {
  Fl_Widget_Tracker wp(this);
  if(any_class_mcb_) (*any_class_mcb_.*mcallback_)(o,arg); //new
  else callback_(o,arg); //new
  if (wp.deleted()) return;
  if (callback_ != default_callback)
    clear_changed();
}

------

Usage:
-----
class MyWindow : public Fl_Window {
  MyWindow(int x, int y, int w, int h, const char *L=0):Fl_Window(x,y,wh,L){
     btnDoIt = new Fl_Button(0,0, 40, 25, "Do It ?");
     MCALLBACK(btnDoIt, MyWindow::doIt);
  }
  Fl_Button *btnDoIt;
  void doIt(){ printf("Done !\n");};
}
---
_______________________________________________
fltk-dev mailing list
[email protected]
http://lists.easysw.com/mailman/listinfo/fltk-dev

Reply via email to