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

neoGFX

103 views
Skip to first unread message

Mr Flibble

unread,
May 30, 2017, 12:36:04 PM5/30/17
to
Hi!

Handling a button clicked event in my C++ GUI library "neoGFX" is
simplicity at its finest:

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

This is achieved without the egregious use of macros to auto generate code.

http://neogfx.org

/Flibble

Rick C. Hodgin

unread,
May 30, 2017, 5:07:19 PM5/30/17
to
On Tuesday, May 30, 2017 at 12:36:04 PM UTC-4, Mr Flibble wrote:
> Handling a button clicked event in my C++ GUI library "neoGFX" is:
> button1.clicked([](){ /* do stuff */}); // simplicity

What about parameters passed to the clicked() event? I might want
to know if it was left-clicked, right-clicked, middle-clicked, or
left-and-right clicked, left-and-middle-clicked, double-clicked,
double-right-clicked, etc. And what about the condition of the
modification keys like shift, alt, ctrl? Do you have thread-
level callbacks which support real-time sampling of those values?
What if the code on my clicked() event has to access a remote
Internet connection and it takes 5 seconds to establish a
connection, will the values of shift, ctrl, alt still be held
for me to examine if I poll them at some later point in my
algorithm after many seconds have gone by?

And what about code grouping? Am I now having to sift through
my GUI init() code to find all of the algorithms which handle
the various events? I don't have them arranged in a header or
class structure which can use traditional IDE tools to goto
body / definition? Now I'm going to a single init() event and
manually searching page after page for code, or using only a
ctrl+f Find feature of my editor?

It might be simple, but unless it provides some real utility in
function and the development environment, then such simplicity
is akin to useless.

Thank you,
Rick C. Hodgin

Mr Flibble

unread,
May 30, 2017, 5:35:43 PM5/30/17
to
On 30/05/2017 22:07, Rick C. Hodgin wrote:
> On Tuesday, May 30, 2017 at 12:36:04 PM UTC-4, Mr Flibble wrote:
>> Handling a button clicked event in my C++ GUI library "neoGFX" is:
>> button1.clicked([](){ /* do stuff */}); // simplicity
>
> What about parameters passed to the clicked() event? I might want
> to know if it was left-clicked, right-clicked, middle-clicked, or
> left-and-right clicked, left-and-middle-clicked, double-clicked,
> double-right-clicked, etc. And what about the condition of the
> modification keys like shift, alt, ctrl? Do you have thread-
> level callbacks which support real-time sampling of those values?

Such information is available allowing such events to be easily created.
Left clicking a button is a common use-case whilst right clicking a
button is a rare use-case. I provide ready baked events for common
use-cases whilst allowing the flexibility to create events for rare
use-cases.

> What if the code on my clicked() event has to access a remote
> Internet connection and it takes 5 seconds to establish a
> connection, will the values of shift, ctrl, alt still be held
> for me to examine if I poll them at some later point in my
> algorithm after many seconds have gone by?

Then you are doing it wrong. A library doesn't have to support doing it
wrong use cases.

>
> And what about code grouping? Am I now having to sift through
> my GUI init() code to find all of the algorithms which handle
> the various events? I don't have them arranged in a header or
> class structure which can use traditional IDE tools to goto
> body / definition? Now I'm going to a single init() event and
> manually searching page after page for code, or using only a
> ctrl+f Find feature of my editor?

You appear to have a beef with C++ lambdas which is foolish as they are
a great improvement to the language. You are not forced to use a lambda
as you can use use anything convertible to a std::function object.

> It might be simple, but unless it provides some real utility in
> function and the development environment, then such simplicity
> is akin to useless.

It is both simple and provides utility.

/Flibble

Daniel

unread,
May 30, 2017, 9:57:02 PM5/30/17
to
On Tuesday, May 30, 2017 at 5:35:43 PM UTC-4, Mr Flibble wrote:
> On 30/05/2017 22:07, Rick C. Hodgin wrote:
> > On Tuesday, May 30, 2017 at 12:36:04 PM UTC-4, Mr Flibble wrote:
> >> Handling a button clicked event in my C++ GUI library "neoGFX" is:
> >> button1.clicked([](){ /* do stuff */}); // simplicity
> >
> > What about parameters passed to the clicked() event? I might want
> > to know if it was left-clicked, right-clicked, middle-clicked, or
> > left-and-right clicked, left-and-middle-clicked, double-clicked,
> > double-right-clicked, etc. And what about the condition of the
> > modification keys like shift, alt, ctrl? Do you have thread-
> > level callbacks which support real-time sampling of those values?
>
> Such information is available allowing such events to be easily created.
> Left clicking a button is a common use-case whilst right clicking a
> button is a rare use-case. I provide ready baked events for common
> use-cases whilst allowing the flexibility to create events for rare
> use-cases.
>
There is considerable a priori experience with event handlers. Typically
event handlers take an event source and an event object as parameters. A
clicked event object holds the state of the shift, alt and ctrl keys, the x
and y coordinates of the mouse pointer, which mouse button was clicked, etc.
My suggestion would be to follow that practice.

Does neoGFX support attaching multiple handlers for the same event on the
same widget?

Best regards,
Daniel

Mr Flibble

unread,
May 30, 2017, 10:44:31 PM5/30/17
to
As I said in my reply this information is available.

>
> Does neoGFX support attaching multiple handlers for the same event on the
> same widget?

Yes. Note this is not a mouse button clicked event I am talking about but a
button widget "clicked" event which is also triggered by pressing space bar
if widget has focus.

/Flibble


Rick C. Hodgin

unread,
May 30, 2017, 11:26:38 PM5/30/17
to
On Tuesday, May 30, 2017 at 5:35:43 PM UTC-4, Mr Flibble wrote:
> On 30/05/2017 22:07, Rick C. Hodgin wrote:
> > On Tuesday, May 30, 2017 at 12:36:04 PM UTC-4, Mr Flibble wrote:
> >> Handling a button clicked event in my C++ GUI library "neoGFX" is:
> >> button1.clicked([](){ /* do stuff */}); // simplicity
> >
> > What about parameters passed to the clicked() event? I might want
> > to know if it was left-clicked, right-clicked, middle-clicked, or
> > left-and-right clicked, left-and-middle-clicked, double-clicked,
> > double-right-clicked, etc. And what about the condition of the
> > modification keys like shift, alt, ctrl? Do you have thread-
> > level callbacks which support real-time sampling of those values?
>
> Such information is available allowing such events to be easily created.

I would think it would be the norm. One API with the extraneous info
being ignored if not used, rather than two or more APIs, one for the
"simple stuff" and one for the "regular stuff."

I'm not being picky or purposefully mean to you, Leigh. I honestly
do not see the advantage.

> Left clicking a button is a common use-case whilst right clicking a
> button is a rare use-case. I provide ready baked events for common
> use-cases whilst allowing the flexibility to create events for rare
> use-cases.

That's not true. It is in many use cases, but in those use cases
where right-clicking is common / standard, it's not at all true.

You're creating a true graphical UI. You have to expect people
will be coding for right-clicks on most everything, so as to
access settings about things they're clicking on, rather than a
type of normal navigation or selection.

> > What if the code on my clicked() event has to access a remote
> > Internet connection and it takes 5 seconds to establish a
> > connection, will the values of shift, ctrl, alt still be held
> > for me to examine if I poll them at some later point in my
> > algorithm after many seconds have gone by?
>
> Then you are doing it wrong. A library doesn't have to support doing it
> wrong use cases.

Well, I don't generally code like that. Sometimes you have to
because you receive OS callbacks without that information, but I
mention it here because I didn't see any parameters being passed
to your simplicity version above, hence the need for such functions
in such a case.

I think if you want simplicity, you should just receive a struct
or class that has defined callback functions, and then use those
if they're not NULL. Something simple:

struct SEvents {
bool (*onLeftClick)(SObject* state);
bool (*onRightClick)(SObject* state);
// ... and other such stuff
};

I think neoGrx could prepare a snapshot data object, or pass several
parameters, and have everything setup for the instance handoff, which
may then be propagated through for a while before control returns
from the dispatcher. In fact, you could even setup a dispatcher
which launches each event in its own thread as a nice service that
would prevent the user from having to write that code.

> > And what about code grouping? Am I now having to sift through
> > my GUI init() code to find all of the algorithms which handle
> > the various events? I don't have them arranged in a header or
> > class structure which can use traditional IDE tools to goto
> > body / definition? Now I'm going to a single init() event and
> > manually searching page after page for code, or using only a
> > ctrl+f Find feature of my editor?
>
> You appear to have a beef with C++ lambdas which is foolish as they are
> a great improvement to the language. You are not forced to use a lambda
> as you can use use anything convertible to a std::function object.

I do have a beef with lambdas. I've created an alternative which
better documents what's taking place by giving it a name, and allowing
it to be moved away from the syntax of the instruction in use.

I call it an adhoc, which is arbitrary code created at any point, and
it is not normally entered through normal flow, but only when explicitly
called by name or by address:

Search for "adhoc" on this message:
https://groups.google.com/d/msg/caliveprogramminglanguage/pSV7rzGcIeE/Ix3pBmhsBgAJ

Its syntax is basically like a type of local function, but by
creating it as a adhoc, it is documented in code for its explicit
use case:

int main(int argc, char* argv[])
{
// Create a function to reference which is related to this
// code immediately nearby.
adhoc int my_adhoc(int a, int b) {
return(a + b + 9);
}

cout << "5,6 equals " << my_adhoc(5, 6);
return 0;
}

CAlive also allows alternate syntax to create the same thing,
which can appear to be more similar to lambdas, and can be
encoded where lambdas are.

> > It might be simple, but unless it provides some real utility in
> > function and the development environment, then such simplicity
> > is akin to useless.
>
> It is both simple and provides utility.

As Einstein once said: "Things should be as simple as possible,
but no simpler." I think you've tried to make things simple, but
you're missed out on the fact that more is required for normal
events processing than your simple model, meaning the model is
now doubly complex because you have simple things and normal
things. I think it will be more confusing to users.

Juha Nieminen

unread,
May 31, 2017, 2:13:51 AM5/31/17
to
Rick C. Hodgin <rick.c...@gmail.com> wrote:
> I think if you want simplicity, you should just receive a struct
> or class that has defined callback functions, and then use those
> if they're not NULL. Something simple:
>
> struct SEvents {
> bool (*onLeftClick)(SObject* state);
> bool (*onRightClick)(SObject* state);
> // ... and other such stuff
> };

That's the C kludge that tries to emulate interfaces, ie. a base class
with virtual functions.

Rick C. Hodgin

unread,
May 31, 2017, 6:11:47 AM5/31/17
to
Juha Nieminen wrote:
> That's the C kludge that tries to emulate interfaces, ie. a base
> class with virtual functions.

It can be coded however you like. That was just an example. But I
would argue such an implementation is simple and easy to understand.

Daniel

unread,
May 31, 2017, 7:23:48 AM5/31/17
to
On Tuesday, May 30, 2017 at 10:44:31 PM UTC-4, Mr Flibble wrote:
> Daniel wrote:
> >>
> > There is considerable a priori experience with event handlers. Typically
> > event handlers take an event source and an event object as parameters. A
> > clicked event object holds the state of the shift, alt and ctrl keys, the x
> > and y coordinates of the mouse pointer, which mouse button was clicked, etc.
> > My suggestion would be to follow that practice.
>
> As I said in my reply this information is available.
>
Could you show an example that illustrates how a handler could save the
x and y screen coordinates when the right mouse button is pressed in
combination with the shift key being pressed?

Thanks,
Daniel

David Brown

unread,
May 31, 2017, 8:05:50 AM5/31/17
to
On 31/05/17 05:26, Rick C. Hodgin wrote:
> On Tuesday, May 30, 2017 at 5:35:43 PM UTC-4, Mr Flibble wrote:
>> On 30/05/2017 22:07, Rick C. Hodgin wrote:
>>> On Tuesday, May 30, 2017 at 12:36:04 PM UTC-4, Mr Flibble wrote:
>>>> Handling a button clicked event in my C++ GUI library "neoGFX" is:
>>>> button1.clicked([](){ /* do stuff */}); // simplicity
>>>
>>> What about parameters passed to the clicked() event? I might want
>>> to know if it was left-clicked, right-clicked, middle-clicked, or
>>> left-and-right clicked, left-and-middle-clicked, double-clicked,
>>> double-right-clicked, etc. And what about the condition of the
>>> modification keys like shift, alt, ctrl? Do you have thread-
>>> level callbacks which support real-time sampling of those values?
>>
>> Such information is available allowing such events to be easily created.
>
> I would think it would be the norm. One API with the extraneous info
> being ignored if not used, rather than two or more APIs, one for the
> "simple stuff" and one for the "regular stuff."

My understanding is that the "clicked" event is a button or widget
clicked event, not a /mouse/ click event. I don't know anything about
neoGFX, but it is quite common for widget libraries to have a simple
"clicked" event that is triggered by a left mouse click, or a keyboard
press when the widget has the focus. That would different from a more
detailed "mouse" event that would say which mouse button is used,
modifier keys, exact position, etc. And there may be other related
events suchas "right_clicked".

It would be nice to see an example of the neoGFX syntax for how the
details are captured for events that have information such as more
general mouse click events.

>
> I'm not being picky or purposefully mean to you, Leigh. I honestly
> do not see the advantage.
>
>> Left clicking a button is a common use-case whilst right clicking a
>> button is a rare use-case. I provide ready baked events for common
>> use-cases whilst allowing the flexibility to create events for rare
>> use-cases.
>
> That's not true. It is in many use cases, but in those use cases
> where right-clicking is common / standard, it's not at all true.
>
> You're creating a true graphical UI. You have to expect people
> will be coding for right-clicks on most everything, so as to
> access settings about things they're clicking on, rather than a
> type of normal navigation or selection.
>
>>> What if the code on my clicked() event has to access a remote
>>> Internet connection and it takes 5 seconds to establish a
>>> connection, will the values of shift, ctrl, alt still be held
>>> for me to examine if I poll them at some later point in my
>>> algorithm after many seconds have gone by?
>>
>> Then you are doing it wrong. A library doesn't have to support doing it
>> wrong use cases.
>
> Well, I don't generally code like that. Sometimes you have to
> because you receive OS callbacks without that information, but I
> mention it here because I didn't see any parameters being passed
> to your simplicity version above, hence the need for such functions
> in such a case.

Even if there is no information sent in parameters (we need to wait for
Leigh to give more details here for events that have parameters), the
way you would deal with a long-running event function is to first
capture the important information, then to pass it on to an asynchronous
function (perhaps in another thread) that handles the waiting and other
time-consuming work. You don't put a 5 second delay in your event handler.
You can do /exactly/ the same thing with lambdas, bar minor syntactic
details:

#include <iostream>
using std::cout;

int main(void) {

auto my_adhoc = [](int a, int b) -> int {
return a + b + 9;
};

cout << "5, 6 equals " << my_adhoc(5, 6) << "\n";
}

Lambdas can be defined in all sorts of places, and named if you want to.

Does that cover your "beef" against lambdas?

(And as Leigh says, there is no requirement to use lambdas for events -
you can use normal functions, functor objects, or anything else that is
callable.)

>
>>> It might be simple, but unless it provides some real utility in
>>> function and the development environment, then such simplicity
>>> is akin to useless.
>>
>> It is both simple and provides utility.
>
> As Einstein once said: "Things should be as simple as possible,
> but no simpler." I think you've tried to make things simple, but
> you're missed out on the fact that more is required for normal
> events processing than your simple model, meaning the model is
> now doubly complex because you have simple things and normal
> things. I think it will be more confusing to users.
>

I think it is just a case of Leigh picking an example event that is so
simple that it has no need of parameters.



Rick C. Hodgin

unread,
May 31, 2017, 9:05:33 AM5/31/17
to
On Wednesday, May 31, 2017 at 8:05:50 AM UTC-4, David Brown wrote:
> [snip]

I appreciate your desire to help me to be a better person, David.
I also continue to pray for you as well.

David Brown

unread,
May 31, 2017, 9:10:46 AM5/31/17
to
On 31/05/17 15:05, Rick C. Hodgin wrote:
> On Wednesday, May 31, 2017 at 8:05:50 AM UTC-4, David Brown wrote:
>> [snip]
>
> I appreciate your desire to help me to be a better person, David.
> I also continue to pray for you as well.
>

I am not trying to make you a better person - I am trying to discuss C++
and a C++ library in a C++ thread on a C++ forum.

You have previously decided not to discuss off-topic issues with me.
Fair enough - I have not always been polite or patient with you. And I
am happy not to engage in discussions that are usually extremely
frustrating for me, and make no visible progress.

But surely we can talk about C++ (and other technical topics in other
groups)? I am not trying to help you be a "better person" - I am trying
to tell you a little more about lambdas that you might not have known,
and learn more about why you don't like them.


Rick C. Hodgin

unread,
May 31, 2017, 9:19:26 AM5/31/17
to
On Wednesday, May 31, 2017 at 9:10:46 AM UTC-4, David Brown wrote:
> [snip]

I appreciate your desire to help me to be a better person, David,
by giving me guidance in these areas where you feel I am lacking.

I also desire to help you to be a better person, so I continue to
pray for you as well.

Alf P. Steinbach

unread,
May 31, 2017, 9:21:42 AM5/31/17
to
The time has come to put you in my kill-file, Rick.

Or, what passes for a kill-file in Thunderbird, but same effect.

Plonk.


Sorry 'bout that,

- Alf

Rick C. Hodgin

unread,
May 31, 2017, 9:37:19 AM5/31/17
to
On Wednesday, May 31, 2017 at 9:21:42 AM UTC-4, Alf P. Steinbach wrote:
> The time has come to put you in my kill-file, Rick.
> Sorry 'bout that,

I would like to ask you to consider something, Alf, or to the
other people reading this, when you add someone advocating a life
lived in service to Jesus Christ (and separate yourself from the
lived follow-through of that life's profession in reality, such
as by an outward example of simply praying for people), consider
that by separating yourself from that God-seeking person you are
separating yourself from a person focused on serving the Lord in
real ways rightly here upon this Earth.

Consider also that in so doing, you are also separating yourself
from the Lord because He sends men and women like me out into the
world to help encourage and guide people away from where they are
and toward where they should be.

So in essence, when you "kill-file" me, you are really doing much,
much more. You are effectively cutting yourself off from a voice
of the Lord in your life, which means you're embracing another's
guidance, the one bent on killing your eternal soul in Hell as you
choose a path away from God, and toward that other calling.

Consider what this means to you beyond the confines of this world.

Mr Flibble

unread,
May 31, 2017, 1:43:37 PM5/31/17
to
On 31/05/2017 04:26, Rick C. Hodgin wrote:
> On Tuesday, May 30, 2017 at 5:35:43 PM UTC-4, Mr Flibble wrote:
>> On 30/05/2017 22:07, Rick C. Hodgin wrote:
>>> On Tuesday, May 30, 2017 at 12:36:04 PM UTC-4, Mr Flibble wrote:
>>>> Handling a button clicked event in my C++ GUI library "neoGFX" is:
>>>> button1.clicked([](){ /* do stuff */}); // simplicity
>>>
>>> What about parameters passed to the clicked() event? I might want
>>> to know if it was left-clicked, right-clicked, middle-clicked, or
>>> left-and-right clicked, left-and-middle-clicked, double-clicked,
>>> double-right-clicked, etc. And what about the condition of the
>>> modification keys like shift, alt, ctrl? Do you have thread-
>>> level callbacks which support real-time sampling of those values?
>>
>> Such information is available allowing such events to be easily created.
>
> I would think it would be the norm. One API with the extraneous info
> being ignored if not used, rather than two or more APIs, one for the
> "simple stuff" and one for the "regular stuff."
>
> I'm not being picky or purposefully mean to you, Leigh. I honestly
> do not see the advantage

Grow up.

>
>> Left clicking a button is a common use-case whilst right clicking a
>> button is a rare use-case. I provide ready baked events for common
>> use-cases whilst allowing the flexibility to create events for rare
>> use-cases.
>
> That's not true. It is in many use cases, but in those use cases
> where right-clicking is common / standard, it's not at all true.

It is true. This is an event sent from a button widget: you don't
normally right click on button widgets.

/Leigh

Rick C. Hodgin

unread,
May 31, 2017, 1:59:59 PM5/31/17
to
On Wednesday, May 31, 2017 at 1:43:37 PM UTC-4, Mr Flibble wrote:
> On 31/05/2017 04:26, Rick C. Hodgin wrote:
> > I'm not being picky or purposefully mean to you, Leigh. I honestly
> > do not see the advantage
> Grow up.

It's a proper statement ... even for a grow-up. I included it at
all because I thought you might feel I was trying to be picky for
some petty reasons because of our post-relationship on issues of
Jesus Christ. That's not the case. I did not see the advantage
of having that feature when most of the time I would think you
would want additional information for the click event.

> >> Left clicking a button is a common use-case whilst right clicking a
> >> button is a rare use-case. I provide ready baked events for common
> >> use-cases whilst allowing the flexibility to create events for rare
> >> use-cases.
> >
> > That's not true. It is in many use cases, but in those use cases
> > where right-clicking is common / standard, it's not at all true.
>
> It is true. This is an event sent from a button widget: you don't
> normally right click on button widgets.

I don't know what you're referring to, but I have defined a full
event stack on my objects, which are largely based upon a tool that
I use daily which has similar events:

It's "SBaseEventsMap" on line 1623, and then 1656:
http://tinyurl.com/accessors-h

Each callback receives a passed object which has property members
with the items required for whatever the event is:

union {
uptr _defaultHandler;
bool (*defaultHandler) (SObject* obj, u32 tnIndex);
};

They are referenced in code by an id which finds them by name.
It is slower than doing it a direct way, but it allows full and
custom expansion of add-on properties, events, methods, and other
objects at runtime.

Mr Flibble

unread,
May 31, 2017, 2:14:35 PM5/31/17
to
The idea is that a widget of a specific type will translate a generic
mouse clicked event (which comes from the native window/surface and
contains all the meta information asked about here) and translates it
into an event that fits in with the widget's abstraction. It is not
useful (in general), for example, for a push button widget to emit right
mouse click events or to know the x,y position of a left click event on
the push button widget.

If you want to emit event meta information from a custom widget type
then simply override thus:

class my_xy_widget : public neogfx::widget
{
public:
event<const point&> xy;
event<const point&> xy_context;
public:
void mouse_button_pressed(mouse_button aButton, const point& aPosition,
key_modifiers_e aKeyModifiers) override
{
if (aButton == mouse_button::Left)
xy.trigger(aPosition);
else if (aButton == mouse_button::Right)
xy_context.trigger(aPosition);
}
}

I only include events in the API that make sense for the specific widget
abstractions.

It is also possible to be notified of all events coming from
window/surface (with access to all meta information) and there is
provision for filtering those events.

>>>> It might be simple, but unless it provides some real utility in
>>>> function and the development environment, then such simplicity
>>>> is akin to useless.
>>>
>>> It is both simple and provides utility.
>>
>> As Einstein once said: "Things should be as simple as possible,
>> but no simpler." I think you've tried to make things simple, but
>> you're missed out on the fact that more is required for normal
>> events processing than your simple model, meaning the model is
>> now doubly complex because you have simple things and normal
>> things. I think it will be more confusing to users.
>>
>
> I think it is just a case of Leigh picking an example event that is so
> simple that it has no need of parameters.

Correct. :)

/Flibble

Mr Flibble

unread,
May 31, 2017, 2:18:19 PM5/31/17
to
The problem isn't that neoGFX supports lambdas the problem is that you
don't like lambdas which is your problem not mine or that of anyone who
wants to use lambdas with neoGFX.

You obviously are having a problem embracing modern C++ techniques
because you like to cling on to the old fashioned paradigms.

/Flibble


Rick C. Hodgin

unread,
May 31, 2017, 2:55:41 PM5/31/17
to
On Wednesday, May 31, 2017 at 2:18:19 PM UTC-4, Mr Flibble wrote:
> The problem isn't that neoGFX supports lambdas the problem is that you
> don't like lambdas which is your problem not mine or that of anyone who
> wants to use lambdas with neoGFX.

I don't like lambdas. I do like lambs, however. They're useful.

> You obviously are having a problem embracing modern C++ techniques
> because you like to cling on to the old fashioned paradigms.

It's not a problem so much as a choice. But, to be fair, I have
embraced many C++ programming techniques, and I'm adding them to
CAlive. I've also come up with several more of my own which I
think C and C++ will eventually adopt.

Scott Lurndal

unread,
May 31, 2017, 2:57:36 PM5/31/17
to
"Rick C. Hodgin" <rick.c...@gmail.com> writes:

>
>I don't like lambdas. I do like lambs, however. They're useful.

:%s/useful/tasty/g

Rick C. Hodgin

unread,
May 31, 2017, 3:05:34 PM5/31/17
to
:-)

Daniel

unread,
May 31, 2017, 4:16:42 PM5/31/17
to
On Wednesday, May 31, 2017 at 2:14:35 PM UTC-4, Mr Flibble wrote:
>
> The idea is that a widget of a specific type will translate a generic
> mouse clicked event (which comes from the native window/surface and
> contains all the meta information asked about here) and translates it
> into an event that fits in with the widget's abstraction. It is not
> useful (in general), for example, for a push button widget to emit right
> mouse click events or to know the x,y position of a left click event on
> the push button widget.

The x,y position of a left or right click event are properties of an
event, not a widget. All other GUI frameworks that I know of (including
pyqt, wxpython, .NET) associate an event object type with each enumerated
event, and pass an instance of that type to the handler.

For example, in wxpython, a handler would be bound to an event on the
widget,

widget.Bind(wx.EVT_MOVE, OnMove)

def OnMove(self, e):
x, y = e.GetPosition()
print "current window position x = ",x," y= ",y







Mr Flibble

unread,
May 31, 2017, 5:25:43 PM5/31/17
to
On 31/05/2017 21:16, Daniel wrote:
> On Wednesday, May 31, 2017 at 2:14:35 PM UTC-4, Mr Flibble wrote:
>>
>> The idea is that a widget of a specific type will translate a generic
>> mouse clicked event (which comes from the native window/surface and
>> contains all the meta information asked about here) and translates it
>> into an event that fits in with the widget's abstraction. It is not
>> useful (in general), for example, for a push button widget to emit right
>> mouse click events or to know the x,y position of a left click event on
>> the push button widget.
>
> The x,y position of a left or right click event are properties of an
> event, not a widget. All other GUI frameworks that I know of (including
> pyqt, wxpython, .NET) associate an event object type with each enumerated
> event, and pass an instance of that type to the handler.

Correct the x,y position is a property of an event and this is the case
in neoGFX; it is up to the widget in question how this event is
translated into a widget specific event.

>
> For example, in wxpython, a handler would be bound to an event on the
> widget,
>
> widget.Bind(wx.EVT_MOVE, OnMove)
>
> def OnMove(self, e):
> x, y = e.GetPosition()
> print "current window position x = ",x," y= ",y

That is not how neoGFX works however it is possible to get access to the
base event if required.

/Flibble

Mr Flibble

unread,
May 31, 2017, 8:52:34 PM5/31/17
to
On 31/05/2017 18:59, Rick C. Hodgin wrote:
> On Wednesday, May 31, 2017 at 1:43:37 PM UTC-4, Mr Flibble wrote:
>> On 31/05/2017 04:26, Rick C. Hodgin wrote:
>>> I'm not being picky or purposefully mean to you, Leigh. I honestly
>>> do not see the advantage
>> Grow up.
>
> It's a proper statement ... even for a grow-up. I included it at
> all because I thought you might feel I was trying to be picky for
> some petty reasons because of our post-relationship on issues of
> Jesus Christ. That's not the case. I did not see the advantage
> of having that feature when most of the time I would think you
> would want additional information for the click event.

Stop polluting this newsgroup with your proselytising (which includes
meta-proselytising).

It is rare to want additional information about a simple button click
event other than the fact that the event has happened. You are
confusing mouse button click events with button widget "clicked" events.

[snip]
>
> I don't know what you're referring to, but I have defined a full
> event stack on my objects, which are largely based upon a tool that
> I use daily which has similar events:
>
> It's "SBaseEventsMap" on line 1623, and then 1656:
> http://tinyurl.com/accessors-h
>
> Each callback receives a passed object which has property members
> with the items required for whatever the event is:
>
> union {
> uptr _defaultHandler;
> bool (*defaultHandler) (SObject* obj, u32 tnIndex);
> };
>
> They are referenced in code by an id which finds them by name.
> It is slower than doing it a direct way, but it allows full and
> custom expansion of add-on properties, events, methods, and other
> objects at runtime.

Your code looks like horrible old fashioned C code (which I am not
interested in) rather than modern new C++ code (which I am interested
in). Unions? Seriously?

/Flibble

Rick C. Hodgin

unread,
May 31, 2017, 9:14:31 PM5/31/17
to
On Wednesday, May 31, 2017 at 8:52:34 PM UTC-4, Mr Flibble wrote:
> Unions? Seriously?

Unions. Seriously.

Behold ... The Mighty Union Brigade!
https://groups.google.com/d/msg/comp.lang.c/qt1b1yZesws/-LJbJ90jnYYJ

Mr Flibble

unread,
May 31, 2017, 9:22:02 PM5/31/17
to
On 01/06/2017 02:14, Rick C. Hodgin wrote:
> On Wednesday, May 31, 2017 at 8:52:34 PM UTC-4, Mr Flibble wrote:
>> Unions? Seriously?
>
> Unions. Seriously.
>
> Behold ... The Mighty Union Brigade!
> https://groups.google.com/d/msg/comp.lang.c/qt1b1yZesws/-LJbJ90jnYYJ

No fucking way am I going to read all that crap.

The need to use unions in modern C++ is rare as using them outside of
library code is nearly always a mistake (as is the case here).

/Flibble

Rick C. Hodgin

unread,
May 31, 2017, 9:30:42 PM5/31/17
to
On Wednesday, May 31, 2017 at 9:22:02 PM UTC-4, Mr Flibble wrote:
> On 01/06/2017 02:14, Rick C. Hodgin wrote:
> > On Wednesday, May 31, 2017 at 8:52:34 PM UTC-4, Mr Flibble wrote:
> >> Unions? Seriously?
> >
> > Unions. Seriously.
> >
> > Behold ... The Mighty Union Brigade!
> > https://groups.google.com/d/msg/comp.lang.c/qt1b1yZesws/-LJbJ90jnYYJ
>
> No .. way am I going to read all that crap.

It's a song. You have to hear the tune in your mind. It's kind of
like a marching song, like the opening part of the "I'm A Lumberjack
And I'm Okay" song by Monty Python.

> The need to use unions in modern C++ is rare as using them outside of
> library code is nearly always a mistake (as is the case here).

I use them to simplify syntax, so I can store store in an unsigned
integer, or void* the value of some more complex form. I've actually
defined the ability in my CAlive language to automatically reference
every named variable by its underscore form (such as _fred for fred)
so that it is in that case referenced as an unsigned integer of the
equivalent size.

It is a way to make code more clean without having complex casting,
or even having to have the auto keyword.

Mr Flibble

unread,
May 31, 2017, 9:38:22 PM5/31/17
to
No it isn't because your proprietary language is not C++ and we are only
concerned with C++ here.

/Flibble

Rick C. Hodgin

unread,
May 31, 2017, 9:46:44 PM5/31/17
to
I think C++ is way too complex. I think C is lacking. I think what's
needed is a happy medium for 99% of code. Enter CAlive.

It's not proprietary. It's fully open. CAlive is being built in a
framework (like GCC) called RDC. RDC actually exposes nearly all of
the abilities necessary to make a C-like language, and it is, therefore,
going to also be used to create other languages:

http://www.libsf.org:8990/projects/LIB/repos/libsf/browse/books/rdc
https://groups.google.com/forum/#!forum/rapid_development_compiler

CAlive has its own definitions as well (these are actually a combination
of RDC specs, as well as CAlive specs, but will be mapped slightly
differently for each implementation, as RDC looks at things from a data
size point of view, and CAlive looks at things from a language point of
view):

http://www.libsf.org:8990/projects/LIB/repos/libsf/browse/exodus/tools/rdc/rdc_specs.txt
https://groups.google.com/forum/#!forum/caliveprogramminglanguage

And these are all works in progress. I am only one person who cannot
seem to garner any help from any source or location no matter how hard
I try. I keep coding, keep asking, keep reaching out, but it's like
that big white cross on the door sends everybody packin'.

It really is amazing just how powerful that cross is, Leigh! It really
strikes fear in people's souls.

Mr Flibble

unread,
May 31, 2017, 9:52:19 PM5/31/17
to
On 01/06/2017 02:46, Rick C. Hodgin wrote:

[proselytising snipped]

Fuck. Off.

/Flibble

Chris M. Thomasson

unread,
May 31, 2017, 10:10:01 PM5/31/17
to
On 5/31/2017 5:52 PM, Mr Flibble wrote:
> On 31/05/2017 18:59, Rick C. Hodgin wrote:
>> On Wednesday, May 31, 2017 at 1:43:37 PM UTC-4, Mr Flibble wrote:
>>> On 31/05/2017 04:26, Rick C. Hodgin wrote:
>>>> I'm not being picky or purposefully mean to you, Leigh. I honestly
>>>> do not see the advantage
>>> Grow up.
>>
>> It's a proper statement ... even for a grow-up. I included it at
>> all because I thought you might feel I was trying to be picky for
>> some petty reasons because of our post-relationship on issues of
>> Jesus Christ. That's not the case. I did not see the advantage
>> of having that feature when most of the time I would think you
>> would want additional information for the click event.
>
> Stop polluting this newsgroup with your proselytising (which includes
> meta-proselytising).
>
> It is rare to want additional information about a simple button click
> event other than the fact that the event has happened. You are
> confusing mouse button click events with button widget "clicked" events.

Fwiw, a while back I did a custom animated button that wanted to know
where the user clicked as an origin point for an animation. If you right
clicked it in "edit mode", a list of different button animations would
pop up and hover. I guess the name "custom animated button" is rare by
default in a sense.

;^)

[...]

David Brown

unread,
Jun 1, 2017, 3:28:14 AM6/1/17
to
I am right in thinking that you would use this sort of inheritance to
make an "xy_button" from a neogfx::button? And then you would use the
event as:

xy_button1.xy([](const point& pos){
// Do left-click stuff with pos.x and pos.y
}
xy_button1.xy_context([](const point& pos){
// Do right-click stuff with pos.x and pos.y
}

That is a different way of handling things that most gui toolkits I am
familiar with. It is not necessarily a bad thing - it lets your normal
widgets remain simple. This is in stark contrast to toolkits such as
Delphi/C++ Builder, where widgets acquire a dozen new events and
properties for every new version of the tool, and usually all you ever
want is a "clicked" event. I'd imagine that using an IDE's
auto-complete on an instance of one of your widgets is going to be a lot
more efficient than doing so on a wxWidgets object.

However, this also means that you can't easily make use of additional
events on existing widgets. If you have a button in your design, and
you later decide that you want to catch right-hand mouse clicks for it,
you have to create your own specialised button class, and then change
your design to use that type of button in the right places. This seems
a significant complication and effort.

I have not looked at the design or implementation of neoGFX, so I may be
asking a silly question here. But would it be possible to arrange your
widgets so that they have an interface with something like:


public:
eventGroup events;
event<> & clicked;
event<const point&> & rightClicked;

The "events" member would be a struct listing all the different events
possible for such widgets. ("eventGroup" would probably be a template
here, for different sorts of widgets.) The normal event members would
now be references pointing to the "real" event in the events collection.

Then the user can attach handlers to normal events in the same simple
fashion as they do now:

button1.clicked([]...)

and people using less common events can use

button1.events.middleClicked([]...)

Normal events would be references, so that everything will be consistent
if the user writes:

button1.events.clicked([]...)


David Brown

unread,
Jun 1, 2017, 3:36:17 AM6/1/17
to
It certainly happens that you want right-click events on buttons. For
most widgets, you are usually only interested in one or two events - but
/sometimes/ you want an extra event. It is good that a gui toolkit is
optimised to make it as simple as possible to deal with the common case
(many toolkits are not) - but it is also important that it is not /too/
hard to deal with the rare cases.

I had an application where the interface had a range of buttons,
sliders, gauges, etc., for controlling and monitoring a range of
hardware inputs and outputs. Right-clicking on these widgets gave easy
access to configuring the choice of input or output for the widget in
question. It made the system quite simple to configure or modify in use.


Rick C. Hodgin

unread,
Jun 1, 2017, 7:41:17 AM6/1/17
to
On Wednesday, May 31, 2017 at 9:52:19 PM UTC-4, Mr Flibble wrote:
> On 01/06/2017 02:46, Rick C. Hodgin wrote:
> [proselytising snipped]

If you want to understand me, there's a video I recorded back in
2012 about this project I'm on and why I devote to it. It's a
different reason than you might think.

the philophy part begins about 37 minutes in:

http://www.visual-freepro.org/videos/2012_12_08__01_vvmmc__and_vfrps_relationship_to_christianity.ogv

It describes how things in our world are reversed, and what the
true way is intended to be where people are our focus, not money
or other things, and why. I hope you'll listen to it.

Rick C. Hodgin

unread,
Jun 1, 2017, 8:41:49 AM6/1/17
to
On Thursday, June 1, 2017 at 7:41:17 AM UTC-4, Rick C. Hodgin wrote:
> On Wednesday, May 31, 2017 at 9:52:19 PM UTC-4, Mr Flibble wrote:
> > On 01/06/2017 02:46, Rick C. Hodgin wrote:
> > [proselytising snipped]
>
> If you want to understand me, there's a video I recorded back in
> 2012 about this project I'm on and why I devote to it. It's a
> different reason than you might think.
>
> the philophy part begins about 37 minutes in:

The philosophy part begins about 37 minutes in:

> http://www.visual-freepro.org/videos/2012_12_08__01_vvmmc__and_vfrps_relationship_to_christianity.ogv
>
> It describes how things in our world are reversed, and what the
> true way is intended to be where people are our focus, not money
> or other things, and why. I hope you'll listen to it.

If anyone knows how to completely turn off auto-correct on a Kindle
Fire, please let me know. I have turned off all parts, but at times
it randomly changes the last word that was typed in.

Ben Bacarisse

unread,
Jun 1, 2017, 9:11:13 AM6/1/17
to
"Rick C. Hodgin" <rick.c...@gmail.com> writes:

> On Wednesday, May 31, 2017 at 9:22:02 PM UTC-4, Mr Flibble wrote:
<snip>
>> The need to use unions in modern C++ is rare as using them outside of
>> library code is nearly always a mistake (as is the case here).
>
> I use them to simplify syntax, so I can store store in an unsigned
> integer, or void* the value of some more complex form.
<snip>
> It is a way to make code more clean without having complex casting,

Students of C++ (and C) should be aware that Rick deliberately blurs the
distinction between re-interpreting the representation of an object and
converting the value stored in an object.

A union is not an alternative to a cast, even when the result is the
same in some cases on some implementations. (This is just short
"warning" note -- the whole thing was hashed out more than once in
comp.lang.c a while ago.)

<snip>
--
Ben.

Rick C. Hodgin

unread,
Jun 1, 2017, 9:22:06 AM6/1/17
to
On Thursday, June 1, 2017 at 9:11:13 AM UTC-4, Ben Bacarisse wrote:
> A union is not an alternative to a cast, even when the result is the
> same in some cases on some implementations.

CAlive looks at data as data, and the data type manipulations are
merely for protocol and convention, making sure things are coded
properly. But if the developer is aware that it is correct, then
an assignment through a union should always be valid. And, in
CAlive it will be. :-)

> (This is just short
> "warning" note -- the whole thing was hashed out more than once in
> comp.lang.c a while ago.)

Yes. And if you look back on those threads in comp.lang.c, you'll
also find a follow-up post at each point written by Ben outlining
his same correction here.

And, for the record, I recognize that C and C++ do not allow this
type of casting through a union as a valid language feature, but
on x86 and in the compilers I use it works ... so I use it. And,
from what I understand of the underlying data mechanisms at work,
it should always work on any similar CPU (with same-sized pointers
for all types, and a "linear" address architecture).

Ben Bacarisse

unread,
Jun 1, 2017, 10:20:46 AM6/1/17
to
"Rick C. Hodgin" <rick.c...@gmail.com> writes:

> On Thursday, June 1, 2017 at 9:11:13 AM UTC-4, Ben Bacarisse wrote:
>> A union is not an alternative to a cast, even when the result is the
>> same in some cases on some implementations.
>
> CAlive looks at data as data,

In what sense does it do anything?

<snip>
> And, for the record, I recognize that C and C++ do not allow this
> type of casting through a union as a valid language feature, but
> on x86 and in the compilers I use it works ... so I use it. And,
> from what I understand of the underlying data mechanisms at work,
> it should always work on any similar CPU (with same-sized pointers
> for all types, and a "linear" address architecture).

If anyone wants to know why this is, at best, confused, they should just
re-read the old threads. Rick seems determined to repeat the same old
stuff, but I don't have the energy to go over it all again.

--
Ben.

Rick C. Hodgin

unread,
Jun 1, 2017, 10:41:10 AM6/1/17
to
On Thursday, June 1, 2017 at 10:20:46 AM UTC-4, Ben Bacarisse wrote:
> "Rick C. Hodgin" <rick.c...@gmail.com> writes:
> > CAlive looks at data as data,
>
> In what sense does it do anything?

I have designed algorithms for its core, but it can only parse
source code into tokens right now, and perform expansion passes
on #defines. I don't have the RDC logic developed sufficiently
yet to actually compile anything. But, that is what's next in
the process, and I have it mapped out offline in concept, just
not in code save a few templates I've written for the various
flow control types I allow.

> <snip>
> > And, for the record, I recognize that C and C++ do not allow this
> > type of casting through a union as a valid language feature, but
> > on x86 and in the compilers I use it works ... so I use it. And,
> > from what I understand of the underlying data mechanisms at work,
> > it should always work on any similar CPU (with same-sized pointers
> > for all types, and a "linear" address architecture).
>
> If anyone wants to know why this is, at best, confused, they should just
> re-read the old threads. Rick seems determined to repeat the same old
> stuff, but I don't have the energy to go over it all again.

The only reason I stick with something, Ben, is because it holds up
to scrutiny and is not supplanted by new information which alters my
fundamental understanding.

It really is a root philosophical viewpoint I hold here, Ben, and
not just a misunderstanding relative to C/C++'s use of a union. The
underlying data exchange is merely a re-interpretation of bits. And
in the case of a data address on a conventional architecture, that
value will be the same whether it's expressed as a function pointer,
a void pointer, or an unsigned integer of equivalent size. CAlive
takes that reality and uses it, because it has value. It allows
those things which really are re-interpretable data without casting
to be used fundamentally in their alternate form.

Ben Bacarisse

unread,
Jun 1, 2017, 11:18:56 AM6/1/17
to
"Rick C. Hodgin" <rick.c...@gmail.com> writes:
<snip>
> It really is a root philosophical viewpoint I hold here,

I know it is. Provided it remains your own philosophical viewpoint it
will be largely harmless.

<snip>
--
Ben.

Rick C. Hodgin

unread,
Jun 1, 2017, 11:32:40 AM6/1/17
to
You don't have to be hateful or mean, Ben. If you feel your position
is on such solid ground that it is truly superior or more foundational
than mine, then it should stand on its own merits.

Perhaps there is something I'm not understanding here. I'm willing
to listen. But consider also that you, in your far greater knowledge
of C, C++, and programming languages in general, may also be lacking
in some understanding, or may possibly be possessing a bias which is
keeping you from seeing the reality I'm pointing to.

I don't come from an "institutional" background. I didn't learn
about these things at a university in conventional instruction.

Everything I've learned about hardware and software design has
come from my own research and understanding, and in thinking things
through on my own. I don't have a led-by-a-prior-instruction
initial thinking, so when I come up with something it is through an
examination of the facts, on the evidence of those facts itself.
And I have been wrong on many things, only later to realize why
some things exist the way they do. I actually had the thought
walking through my office at work yesterday that for the first time
I can actually see why many of the things in C++ exist as they do.
And I can't pin fault or blame on anyone for those things I do
understand, because I see them now through a revised-over-time
lens and perspective.

But ... in the area of unions ... I am still back to where I
initially found myself when I encountered them back in the 80s
because at that point my knowledge of computer programming
stemmed primarily from 8086 assembly language, and later 80386
assembly language. I looked at low-level data as data, and
not higher constructs.

So, when a cast would not yield a conversion, but merely asserts to
the compiler that the type is being knowingly converted from type
A to type B, but no underlying data change takes place (such as
a round operation in casting a floating point to an int), then I
see no issue with such a reinterpretation of literal bits through
a union to be any sort of issue, because that's what actually is
happening in the cast. No real data is changed, which is what
actually happens when the same types are accessed through a union.

-----
I honestly can't understand what you find at odds with that
reality, except that it's not "legal" through the C/C++ standards.

What is your concern over this use of unions?

Mr Flibble

unread,
Jun 1, 2017, 1:41:16 PM6/1/17
to
The widget base interface class contains the following events:

class i_widget : ...
{
public:
event<> visibility_changed;
event<graphics_context&> painting;
event<neogfx::mouse_event&> mouse_event;
event<neogfx::keyboard_event&> keyboard_event;
...

so you can have:

button1.mouse_event([](neogfx::mouse_event& e)
{
/* do stuff with 'e' */
});

So you are not forced to use inheritance if you want full event
information but the idea is still to create new events appropriate for
new widget abstractions.

>
> I have not looked at the design or implementation of neoGFX, so I may be
> asking a silly question here. But would it be possible to arrange your
> widgets so that they have an interface with something like:
>
>
> public:
> eventGroup events;
> event<> & clicked;
> event<const point&> & rightClicked;
>
> The "events" member would be a struct listing all the different events
> possible for such widgets. ("eventGroup" would probably be a template
> here, for different sorts of widgets.) The normal event members would
> now be references pointing to the "real" event in the events collection.
>
> Then the user can attach handlers to normal events in the same simple
> fashion as they do now:
>
> button1.clicked([]...)
>
> and people using less common events can use
>
> button1.events.middleClicked([]...)
>
> Normal events would be references, so that everything will be consistent
> if the user writes:
>
> button1.events.clicked([]...)

Sorry not sure about this idea or what it achieves.

/Flibble

David Brown

unread,
Jun 2, 2017, 7:37:42 AM6/2/17
to
On 01/06/17 19:40, Mr Flibble wrote:
> On 01/06/2017 08:27, David Brown wrote:
<snip>
>
> The widget base interface class contains the following events:
>
> class i_widget : ...
> {
> public:
> event<> visibility_changed;
> event<graphics_context&> painting;
> event<neogfx::mouse_event&> mouse_event;
> event<neogfx::keyboard_event&> keyboard_event;
> ...
>
> so you can have:
>
> button1.mouse_event([](neogfx::mouse_event& e)
> {
> /* do stuff with 'e' */
> });
>
> So you are not forced to use inheritance if you want full event
> information but the idea is still to create new events appropriate for
> new widget abstractions.
>

That sounds fair enough. Your widgets have all the standard events,
like most toolkits, and you need to make your own classes if you want to
add additional event types.

>>
>> I have not looked at the design or implementation of neoGFX, so I may be
>> asking a silly question here. But would it be possible to arrange your
>> widgets so that they have an interface with something like:
>>
>>
>> public:
>> eventGroup events;
>> event<> & clicked;
>> event<const point&> & rightClicked;
>>
>> The "events" member would be a struct listing all the different events
>> possible for such widgets. ("eventGroup" would probably be a template
>> here, for different sorts of widgets.) The normal event members would
>> now be references pointing to the "real" event in the events collection.
>>
>> Then the user can attach handlers to normal events in the same simple
>> fashion as they do now:
>>
>> button1.clicked([]...)
>>
>> and people using less common events can use
>>
>> button1.events.middleClicked([]...)
>>
>> Normal events would be references, so that everything will be consistent
>> if the user writes:
>>
>> button1.events.clicked([]...)
>
> Sorry not sure about this idea or what it achieves.
>

The idea is to have the commonly used features conveniently available,
while less common features are "packed away" one level deeper. Think of
it like the options screen of an application, where there is a button
labelled "advanced" that hides the complicated stuff most people don't need.


0 new messages