## Recommended Posts

##### Share on other sites
Whatever... Both will likely work. It just depends on how much flexibility you need, and what the rest of your UI code uses (consistency is good).

##### Share on other sites
Personally I would go for the second approach. I prefer inheritence and virtual functions over callback functions.

##### Share on other sites
Principally is separation of representation and logic a Good Thing, IMHO. That means to not use inheritance to augment MenuItem with functionality besides those necessary for the representation. Possible solutions include the aforementioned callbacks, messages, but also listeners/observers, prototypes of commands, or mediators.

##### Share on other sites
Wow! Everybody is making GUIs!

Question (because I'm making one too): What does "listener" mean?
I have a system that loops through the items when the mouse is moved, to decide, which one the mouse is over. In case of click events (or mouse roll, whatever), the corresponding function of the mouse-on item executes (after some other stuff of course, windowing/whatever). What does this system called? (I don't follow tutorials or articles, so I don't know what I'm doing). Maybe immediate mode GUI?

##### Share on other sites
Quote:
 Original post by szecsWow! Everybody is making GUIs!Question (because I'm making one too): What does "listener" mean?I have a system that loops through the items when the mouse is moved, to decide, which one the mouse is over. In case of click events (or mouse roll, whatever), the corresponding function of the mouse-on item executes (after some other stuff of course, windowing/whatever). What does this system called? (I don't follow tutorials or articles, so I don't know what I'm doing). Maybe immediate mode GUI?

seriously, im making one too.

I am representing EVERYTHING as square buttons, and a menu is just a list of buttons with text. when a specific button gets clicked, i fire an event with it's ID, then my scripting language calls the buttons Handler function using the ID and the function does whatever it is supposed to do.

A good example implementation of this (visually anyways) is Supreme Commander 2's interface. you'll notice everything fits inside a square bounds, even the arrows and such.

Its' a first iteration but it is pretty simple to implement.

##### Share on other sites
I was thinking about having a function pointer (just like for the other functions) for the selection too, so you can have rectangle in most cases, but you can have any other method too. For example circle, or 2 rectangles etc.

##### Share on other sites
Quote:
 Original post by szecsQuestion (because I'm making one too): What does "listener" mean?

The Listerner concept means that an interface class exists that declares a handler for each possible event. One way is to declare such an interface for the various kinds of GUI element actions. E.g. a PushButton has a one-shot trigger action. A suitable Listerner interface may be (using C++ for demonstration here)
class TriggerListener   : public Listener {public:   virtual void onTrigger() =0;};

A CycleButton has N>1 stable states (the ToggleButton has N=2, typical for e.g. check-boxes). A suitable Listener interface may look like
class StateListener   : public Listener {public:   virtual void onStateChange(uint oldState, uint newState) =0;};

A Menu may provide a PushMenuItem, a ToggleMenuItem, and perhaps other types, but from the sight of Listener there is no difference to a PushButton or ToggleButton, resp., so the same interfaces can be used.

A client who is interested in being notified on events then implements the appropriate interface and registers an instance of that class with the event source (which is typically the GUI element itself). When a GUI element then determines that its action is actuated, it notifies all registered listeners about this by iterating the Listener instances and invoking the appropriate routine.

The advantage of such a concept (as is also of the several other concepts I've named) is that the GUI element is responsible for its representation, but the actual effect triggered when the element is actuated is externalized. IMHO an important feature of a well done GUI system!

Quote:
 Original post by szecsI have a system that loops through the items when the mouse is moved, to decide, which one the mouse is over. In case of click events (or mouse roll, whatever), the corresponding function of the mouse-on item executes (after some other stuff of course, windowing/whatever). What does this system called? (I don't follow tutorials or articles, so I don't know what I'm doing). Maybe immediate mode GUI?
An immediate mode GUI doesn't have items one can iterate. Instead, there is just code. I personally think that immediate mode GUI doesn't work when the GUI should be somewhat flexible. However, there are other threads that discuss this issue in depth.

Please notice that the system you've described above does not explicitely say that the "corresponding function of the mouse-on item" actually means to run the high level functionality. I could say that it just notifies the registered Listeners, and we are on the same line. As said, IMHO the representation stuff should be done by the GUI, and all you've explicitely described above fits in that thinking.

##### Share on other sites
By externalized you mean that for example the toggle doesn't toggle the assigned game variable, just itself. Then on an other function, these values are read, or discarded (ok/cancel/apply buttons). Am I right?
So that means I'm on the right track with the design.
All I have to make better is the communication between the stuff, now I have global variables (uuugh), but I guess function pointers with a pointer to an item (mostly itself, I use C, so the concept of "this" is a bit hard for me yet) as argument would suffice.
I started a thread on my current GUI BTW.

##### Share on other sites
Quote:
 Original post by szecsBy externalized you mean that for example the toggle doesn't toggle the assigned game variable, just itself. Then on an other function, these values are read, or discarded (ok/cancel/apply buttons). Am I right?
Probably yes, but I'm not sure if I understand. So I give an example.

Let's use a ToggleButton for the example. You've instanciated a ToggleButton
ToggleButton * button = new ToggleButton();

and parametrized it with an image showing an empty rectangle for state 0 and an image showing a check-mark for state 1, so it looks like a typical check-box. You implement the StateListener interface with the purpose that the rendering of a model should be supressed in case that the check-box is not checked. Basically so:
class MyStateListener : public StateListener {public:   MyStateListener( Model * forModel ) : model( forModel) {}   void onStateChange(uint oldState, uint newState) {      model->shouldBeRendered( newState==1 );   }   Model * model;};

Then you register those listener with the event source
button->registerListener( new MyStateListener( myModel ) );

and you're done.

Now if the use mouse-clicks over the ToggleButton, the input sub-system determines the button as click target and invokes it onClick routine. The routine changes the state of the button from 0 to 1 (or 1 to 0, dependend on the current state, of course) and causes a redraw, because its visual representation has changed with its state. It then notifies the registered listeners w/o ever knowing what the state toggle causes outside.

You may lament that this would create a couple of additional classes, and you'd be right. In languages allowing anonymous classes the situation is a bit better. However, the shown concpet is just the basic concept. You can extend the interface with the event sender as parameter, allowing the same Listener instance to be registered several times (as long as the action is matched) because the mediator pattern can be applied internally. E.g.
class StateListener {public:   virtual void onStateChange(Widget * sender, uint oldState, uint newState) =0;};class MyStateListener : public StateListener {public:   ...   void onStateChange(Widget * sender, uint oldState, uint newState) {      if( sender==_myWidget1 ) {         ...      }      else if( sender==_myWidget2 ) {         ...      }   }   ...};

It is also possible to derive a handler that implements several Listener interfaces at once, of course.

It is further possible to allow listeners to deny toggle. Assume an interface like this:
class StateListener {public:   virtual bool onPreStateChange(Widget * sender, uint oldState, uint newState) { return true; }   virtual bool onPostStateChange(Widget * sender, uint oldState, uint newState) =0;};
When ToggleButton::onClick is invoked, all registered Listeners are notified by using onPreStateChange. If at least 1 Listener returns false then the toggle is denied, and nothing happens. Otherwise the state is updated, the redraw is caused, and the registered Listeners are notified by using onPostStateChange.

As ever, all this stuff should show only possibilities.

##### Share on other sites
I'm so blind to C++ and classes, but thanks anyway.

## Create an account

Register a new account

• ### Forum Statistics

• Total Topics
628355
• Total Posts
2982235

• 10
• 9
• 11
• 24
• 11