|
|
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");};
}
---
[ Direct Link to Message ] | |
|
| |