Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Signals and slots? MOC? LOL.

53 views
Skip to first unread message

Mr Flibble

unread,
Feb 11, 2016, 7:49:45 PM2/11/16
to
How to subscribe to a button press event in my C++ GUI lib, "neogfx":


button1.pressed([]() { /* do stuff */ }); // simplicity


https://github.com/FlibbleMr/neogfx/

/Flibble

Christian Gollwitzer

unread,
Feb 12, 2016, 4:24:45 AM2/12/16
to
Am 12.02.16 um 01:49 schrieb Mr Flibble:
> How to subscribe to a button press event in my C++ GUI lib, "neogfx":
>
>
> button1.pressed([]() { /* do stuff */ }); // simplicity
>

nice, but still there are three sets of parenthesis that look gibberish.
Compare with Tcl/Tk

button .b1 -command { puts "You pressed me" }

which creates a button and associates the command with it. This is one
of the times where a preprocessor macro wouldn't be too bad.
Unfortunately CPP is a really stupid one.

In fact, a fully functional program in Tcl/Tk is three lines:

package require Tk
button .b -text "Press me" -command { tk_messageBox -message "You
pressed me!" }
pack .b

I have yet to see another GUI library/language that can beat (or come
close to) this conciseness.

> https://github.com/FlibbleMr/neogfx/
>

Another general comment. It is impressive what you have achieved so far.
I don't wnt to discourage you, but for a full fledged cross-platform
widget set which I would consider in a GUI project, there is still a
long way to go. One thing is platform integration. You seem to draw the
widget elements completely on your own using OpenGL. This works now, but
soon your widgets will look old-fashioned, because the design of
computer interfaces follows fashion. Just run anything from before Win7
and you'll immediately understand. For this reason, the established
widget sets use the native widgets under Windows and Mac OSX. Of course
this requires many compromises, because not every option is supported
everywhere and a big pile of work is required to achieve a common API
for all supported systems. There is a somewhat intermediate solution by
drawing your own widgets, but calling APIs which darw parts of teh
native elements upon request. QT works this way, for instance, and ttk
(the themable version of Tk).

On Linux (or X11) it is even worse, there is no native widget set
available. You'll have to constantly rewrite your library in order not
to fall out of fashion, though the fashion is not so strong as on the
other OSes. on OSX, in particular, if it doesn't look native (read: like
any recent app from Apple) noone will buy it.

That's just my 2 sausages.

Christian


leigh.v....@googlemail.com

unread,
Feb 12, 2016, 8:29:15 AM2/12/16
to
Once I have implemented all the basic widgets I intend to move their drawing code into a default skin. Other skins will be available and there is no reason you couldn't add a skin that used native OS widget drawing helper functions so I don't believe my GUI lib will suffer from becoming outdated looking.

/Flibble

Scott Lurndal

unread,
Feb 12, 2016, 8:48:46 AM2/12/16
to
Mr Flibble <flibbleREM...@i42.co.uk> writes:
>How to subscribe to a button press event in my C++ GUI lib, "neogfx":
>
>
> button1.pressed([]() { /* do stuff */ }); // simplicity

I'd much rather register a callback function. Lambda's
can impair readability, maintainability and modularity.

Most cases where I program a button press event, it requires
dozens of lines of code - not suitable for a lambda.

An example (using GTK2):

g_signal_connect(e_drawarea, "key-press-event",
G_CALLBACK(keypress), this);


gboolean
c_env::keypress(GtkWidget *w, GdkEventKey *event, gpointer data)
{
c_env *ep = (c_env *)data;

return ep->do_key(event);
}

/**
* Handle a key press event within the drawing area for this environment.
*
* @param event The key press event descriptor
* @returns TRUE to stop other handlers for this event, FALSE to propogate
*/
gboolean
c_env::do_key(GdkEventKey *event)
{
s_screen_pos *spp = &e_kbc;
s_page *pp = &e_pages[spp->sp_page];

if (pp->p_keyboard_mode == KM_TRANSMIT) {
/*
* Ignore the key, unless it is the RCV key.
*/
if (event->keyval == GDK_F11) {
pp->p_keyboard_mode = KM_RECEIVE;
e_xmit_handler->receive_mode();
update_statusline();
goto leave;
}
gdk_beep();
goto leave;
}
pp->p_keyboard_mode = KM_LOCAL;

if ((event->keyval == GDK_Shift_L)
|| (event->keyval == GDK_Shift_R)) {
goto leave;
}

... 300 additional lines elided.

leave:
if (e_pixmap_dirty) expose(e_drawarea, &e_exposeall);
return TRUE;
}

leigh.v....@googlemail.com

unread,
Feb 12, 2016, 8:58:20 AM2/12/16
to
You are not forced to use a lambda you can use anything convertible to a std::function which includes ordinary callback functions however I disagree with your view re lambdas: embrace modern C++.

Luca Risolia

unread,
Feb 12, 2016, 9:39:59 AM2/12/16
to
On 12/02/2016 14:48, Scott Lurndal wrote:
> An example (using GTK2):
>
> g_signal_connect(e_drawarea, "key-press-event",
> G_CALLBACK(keypress), this);

that's ugly to say the least.


Mr Flibble

unread,
Feb 12, 2016, 9:45:52 AM2/12/16
to
The problem here isn't my lambda but the fact that you have a 300 line
function. Ever heard of functional decomposition? Functions can call
other functions! Break it up mate (and embrace modern C++ and lambdas).

/Flibble

Alf P. Steinbach

unread,
Feb 12, 2016, 10:42:08 AM2/12/16
to
Yes, especially with the stringly typed event id.


Cheers,

- Alf


Alf P. Steinbach

unread,
Feb 12, 2016, 10:43:36 AM2/12/16
to
On 2/12/2016 3:45 PM, Mr Flibble wrote:
> On 12/02/2016 13:48, Scott Lurndal wrote:
>> Mr Flibble <flibbleREM...@i42.co.uk> writes:
>>
>> Most cases where I program a button press event, it requires
>> dozens of lines of code - not suitable for a lambda.
>
> The problem here isn't my lambda but the fact that you have a 300 line
> function. Ever heard of functional decomposition? Functions can call
> other functions! Break it up mate (and embrace modern C++ and lambdas).

Seconded.


Cheers,

- Alf

Scott Lurndal

unread,
Feb 12, 2016, 11:39:21 AM2/12/16
to
Eye of the beholder. Less ugly than a 300 line lambda.

Scott Lurndal

unread,
Feb 12, 2016, 11:42:25 AM2/12/16
to
It's a big switch on the keyval. Sure, could use a lookup table and
call a function, but why? It works. It's easy to maintain. And it was
written a long long time ago for X11R4 and ported later to GTK2.

Mr Flibble

unread,
Feb 12, 2016, 6:36:40 PM2/12/16
to
Did you not read my other reply? Nobody is suggesting that you replace
it with a 300 line lambda. You replace it with a lambda that calls
other functions: functional decomposition mate.

/Flibble


Mr Flibble

unread,
Feb 12, 2016, 6:38:41 PM2/12/16
to
You can still have a switch but the cases simply call other functions.
Also what is this "goto leave" nonsense?

/Flibble



0 new messages