Wednesday, December 25, 2013

The "widget" problem

Newsgroup: comp.lang.c++

Subject: The "widget" problem

From: Tom <tflynn@...>

Date: Tue, 24 Dec 2013 12:27:00 GMT



I don't know if that's the right name for this but it's refers to the

situation that might arise in a GUI framework where classes are used to

represents widgets like buttons and text boxes. Member functions of the

widget like button::press() are called on input. A user defined widget

may contain other widgets as members (for instance a file browsing

dialog has buttons, lists, textboxes, etc..), and may wish to do some

processing of a button press after the original widget has done its

work. Every GUI framework must at some point decide how this

capability is made available to the end user of the library.



The mostly widely used OO GUI framework for C++ is Qt enables this with

their "signals and slots" mechanism. This involves introducting new

syntax into the code and preprocessing the source with the moc (meta

object compiler) system. This doesn't prevent people from being

productive with Qt of course, but it raises the question (which I'm sure

has been addressed before) of how to do this with pure C++ in a

typesafe manner while preserving the ability to seperately compile

widgets. Also we want the process of setting up callbacks to be as

simple as e.g. passing function pointers.



Part of the issue is that one cannot make use of a pointer to a member

function without an instance of the class itself. Yet we don't want

any previously defined widgets to know anything about our new widget

or have to be recompiled,



Let me know what you think of this solution. Here "button"

and "mywidget" are two widgets in the system, mywidget contains a

button and the wants to receive the press events of the button.



class cb_base{

public:

virtual void call () = 0;

};



template<class T>

struct cb_c {



template<void (T::*fn)()>

class cb_t : public cb_base{

public:

T * t;



cb_t(T * _t):t(_t){}



virtual void call(){

((*t).*(fn))();

}

};



};



class button{

public:

cb_base * callback;



button(cb_base * _callback=NULL):callback(_callback){}



void press(){

printf("In press\n");

if(callback) callback->call();

}

};





class mywidget{

public:

typedef cb_c<mywidget> cb_type;



button * b;



mywidget(){

b = new button(new handler_cb(this));

}



void my_handler(){

printf("In my handler\n");

}



typedef cb_type::cb_t<&mywidget::my_handler> handler_cb;

};



/* An example of calling the press event, which would be done by the

windowing system */

int main(){ mywidget m; m.b->press(); return 0; }





-Thomas Flynn









via Usenet Forums - Usenet Search,Free Usenet - comp.lang.c++ http://www.pocketbinaries.com/usenet-forums/showthread.php?158342-The-widget-problem&goto=newpost

View all the progranning help forums at:

http://www.pocketbinaries.com/usenet-forums/forumdisplay.php?128-Coding-forums

No comments:

Post a Comment