   GUI Programming question (handling events)
  Hello.I am programming my own GUI system and I was hoping for an advice about how to handle events when they are clicked.The way my GUI is structured is with a base class cGUIWindow which all other types of windows inherit from.Every window has a list of children that it updates when it (the parent) itself is being updated.I can detect mouse clicks, mouse held, mouse release everything without a problem.My main trouble is deciding on how to handle what the GUI should do, for example, if it is to call a function, and how to handle it if the function is within another class?I was thinking of two possibilities:1. Have a message system kinda like the windows message system which will send the ID of the GUI which was clicked. Then use a switch message to run a function.2. Use a function pointer.I am leaning towards option number 2 but I have several questions on how to handle this type of method:For example, how do I set the function pointer if I am loading the GUI from a file? (I don't want to inherit a class every time I want a different function for a simple button after all)And the other question is, how do I handle function pointers if the function called is within another class or even another window (how would the system find it?)Thanks for anyone willing to help :)   
  I'm an advocate of using a system similar to the C# delegate and event system. If you search Google for "fast delegate" you should get a code project page for system that works similarly to C# delegates. I believe the boost library has function and bind interfaces for similar behaviour. In my experience messaging systems get too complicated as the complexity and size of the GUI grows. At my last studio we were gradually transitioning from messages to event/delegates and Winforms has done the same from Win32.I can't give any suggestions for scripting however.   ;  i'm using option two and it works quite well. I havn't started on loading from file yet but i could think of making the user provide the function to call together with the path which file should be loaded.not sure what you mean by inheriting other classes, but the callback function should be able to handle all events. Something like:void( *callbackFunction )( int guiId, int widgetId, int state, void* argList )guiId will be the id of the gui the widget that made the event happen is located in.widgetId will be the id of the widgetstate will be the event, Button::PRESSED CheckBox::TAGGED or smth.argList is needed to get the callback to happen for a certain object.you can make the callback happen to a static class function but then you'll still need to get to the object, for that you use the argList. While setting the callback function say that you want 'this' provided back to you in the argList. Then when the callback gets called (the static function) you can cast this to whatever class you're using and call annother function but now for the object.Example:class Woot{public:    Woot();    void GuiCallback( int guiId, int widgetId, int state );//Might be private tho?private:    static void StaticGuiCallback( int guiId, int widgetId, int state, void* argList );};Woot::Woot(){    Gui = new Gui( Woot::StaticGuiCallback, this );}Woot::StaticGuiCallback( int guiId, int widgetId, int state, void* argList ){    dynamic_cast<Woot*>( argList )->GuiCallback( guiId, widgetId, state );}Woot::GuiCallback( int guiId, int widgetId, int state ){    if( guiId == myGui && widgetId == myButton && state == Button::PRESSED )   //Yay button got pressed.}Well that's just an example to give you an idea ofcourse.Not sure what you mean by how to handle function pointers when it's in annother class or window(you mean widget by window?).   ;Quote:Original post by DaveI'm an advocate of using a system similar to the C# delegate and event system. If you search Google for "fast delegate" you should get a code project page for system that works similarly to C# delegates. I believe the boost library has function and bind interfaces for similar behaviour. In my experience messaging systems get too complicated as the complexity and size of the GUI grows. At my last studio we were gradually transitioning from messages to event/delegates and Winforms has done the same from Win32.I can't give any suggestions for scripting however.Hi Dave!From what I understand delegate is pretty much a pointer to anything with any number of values?How do I handle saving/loading of my windows then? By that I mean, how do they know which function pointer they need to set?   ;  At my last studio the game was one of the most GUI heavy games around and we just hard coded everything. There was no GUI scripting, so the events and delegates where all set up when the widgets were constructed.   ;Quote:Original post by DaveAt my last studio the game was one of the most GUI heavy games around and we just hard coded everything. There was no GUI scripting, so the events and delegates where all set up when the widgets were constructed.I thought about the problem a lot. I don't think it's possible (in a sensible way) to avoid hard coding at some point.You have a bunch of totally unrelated variables that need to be altered by the GUI, how could you address them in a general way? For example one widget toggles V-sync, another sets the view-distance, a third changes anisotropic filter size. I can't think of any ways to avoid stuff like (quickly made up C code):AnisotropicFilterSize = ...;VSyncEnabled = ...;ViewFarPlaneDistance = ...;......//long list of associationsAnd vice-versa.So I'm curios how it's done by real programmers.   ;  We scripted the front end on my last game, but we only scripted the appearance, specifying fonts, textures and colours as well as positions of widgets. But the functionality of an in-game screen was all written in an InGameScreen class which derrived from a Screen class. At the end of the day if you keep your core components completely seperate from your game specific components, there isn't really much need to script functionality.   ;  Hey Again :)Dave - I think your approach is good for me, I can use it until I have a scripting system and then I will be able to switch to use a script OR a delegate if I hardcode it so it can fit quite nicely for now and even for later.So I will just check which of the two is available. That will handle both hardcoding for now and the loading functions from files later when I have scripts working.Thanks!szecs - I think this where scripts comes in. For example, a way my scripting works is have a class called cScript and another class cInstructioncScript has a cInstruction. cInstruction has its virtual Run() and a pointer to another cInstruction if needed (as well as some other stuff, but this is what you need to know to get the idea)A file might haveScript <name here>Instruction SetResolution  intX intYInstruction SetMipFilter ...The script compiler reads them, creates a new cScript and links to the instructions. So you need to hardcode the Instructions so you can do whatever you want but later you can call it all from a text file/script file and it will chain the functions just like you want.Later a button will have the cScript and just .Run() it and then all the Instructions will run.   ;Quote:Original post by Shaneeszecs - I think this where scripts comes in. For example, a way my scripting works is have a class called cScript and another class cInstructioncScript has a cInstruction. cInstruction has its virtual Run() and a pointer to another cInstruction if needed (as well as some other stuff, but this is what you need to know to get the idea)A file might haveScript <name here>Instruction SetResolution  intX intYInstruction SetMipFilter ...The script compiler reads them, creates a new cScript and links to the instructions. So you need to hardcode the Instructions so you can do whatever you want but later you can call it all from a text file/script file and it will chain the functions just like you want.Later a button will have the cScript and just .Run() it and then all the Instructions will run.That's exactly what I'm saying: You have to hardcode at some point, if you have script system, then in that. Of course, you only have to do it at one specific part, and if your design is good, it's just a list of associations, that you can easily (or not) expand.( Unrelated: Do I use too many punctuations? )   ;Quote:Original post by szecsThat's exactly what I'm saying: You have to hardcode at some point, if you have script system, then in that. Of course, you only have to do it at one specific part, and if your design is good, it's just a list of associations, that you can easily (or not) expand.( Unrelated: Do I use too many punctuations? )Related to Unrelated: yeah I think you do, but I'm sometimes guilty of it as well. I'd reword it as follows:Quote:That's exactly what I'm saying: you have to hard-code at some point if you have a scripting system. Of course, you only have to do it for one specific part if your design is good. It's just a list of associations that you can easily expand (or not).Unrelated to Unrelated, but related to the OP ^_^: I too wrote / write a GUI system. I don't like using a switch statement (centralization of event code, or decentralization of widget initialisation code and it's event handling code, it's a non-OOP way of handling events), neither to using callbacks directly. I used callbacks in a more complete way, in that you can bind multiple functions to one event, but also allow delegates (a delegate is like a function pointer, but then for a class member function. It holds both a pointer to the class' instance and to a member function of that class).This system is also known as the signal and slot system. It too gets you decentralized code, since the function declaration cannot be near the same spot as the GUI widget initialisation code. In C++ I haven't found a truly nice event handling system. In &#106avascript it is possible though, since you CAN declare instant-functions (that is, where you need to pass a function (callback), the function doesn't yet have to exist, you can write the function in-place). Something also D more or less has, where you can define functions in functions.   