• Announcements

    • khawk

      Download the Game Design and Indie Game Marketing Freebook   07/19/17

      GameDev.net and CRC Press have teamed up to bring a free ebook of content curated from top titles published by CRC Press. The freebook, Practices of Game Design & Indie Game Marketing, includes chapters from The Art of Game Design: A Book of Lenses, A Practical Guide to Indie Game Marketing, and An Architectural Approach to Level Design. The GameDev.net FreeBook is relevant to game designers, developers, and those interested in learning more about the challenges in game development. We know game development can be a tough discipline and business, so we picked several chapters from CRC Press titles that we thought would be of interest to you, the GameDev.net audience, in your journey to design, develop, and market your next game. The free ebook is available through CRC Press by clicking here. The Curated Books The Art of Game Design: A Book of Lenses, Second Edition, by Jesse Schell Presents 100+ sets of questions, or different lenses, for viewing a game’s design, encompassing diverse fields such as psychology, architecture, music, film, software engineering, theme park design, mathematics, anthropology, and more. Written by one of the world's top game designers, this book describes the deepest and most fundamental principles of game design, demonstrating how tactics used in board, card, and athletic games also work in video games. It provides practical instruction on creating world-class games that will be played again and again. View it here. A Practical Guide to Indie Game Marketing, by Joel Dreskin Marketing is an essential but too frequently overlooked or minimized component of the release plan for indie games. A Practical Guide to Indie Game Marketing provides you with the tools needed to build visibility and sell your indie games. With special focus on those developers with small budgets and limited staff and resources, this book is packed with tangible recommendations and techniques that you can put to use immediately. As a seasoned professional of the indie game arena, author Joel Dreskin gives you insight into practical, real-world experiences of marketing numerous successful games and also provides stories of the failures. View it here. An Architectural Approach to Level Design This is one of the first books to integrate architectural and spatial design theory with the field of level design. The book presents architectural techniques and theories for level designers to use in their own work. It connects architecture and level design in different ways that address the practical elements of how designers construct space and the experiential elements of how and why humans interact with this space. Throughout the text, readers learn skills for spatial layout, evoking emotion through gamespaces, and creating better levels through architectural theory. View it here. Learn more and download the ebook by clicking here. Did you know? GameDev.net and CRC Press also recently teamed up to bring GDNet+ Members up to a 20% discount on all CRC Press books. Learn more about this and other benefits here.
Sign in to follow this  
Followers 0
Juliean

Game engine gui design

23 posts in this topic

Hello,

so I'm currently writing the gui for my 2d game engine, and though everything is working fine for now, I wonder if there is any better way of designing this?

So i think on the basic everyone should agree:

I have a EditorObject-class, and from this class I inherit EditorImage, EditorWindow, EditorButton, EditorScrollbar, EditorToolbar, and more to come.

But, my question is now, how do I put this together the right way?

Right now I'm having a window for the tilesets and tile selection, and one that displays the map and lets me draw tiles on it. I achieved this by inheriting the classes WindowTileset and WindowTilemap from the EditorWindow-class. I just need to overload the constructor and the virtual Draw() and (important) Update()-functions, so there is no doubled code from this. Things are working way more neat than I'd have expected, but..

.. is this the right approach? What would you guys do here? If I keep on doing this I'm going to inherit a hell of a lot from the EditorWindow-class for every window I need (WindowNewProject, WindowDatabase ..), which is working, but again, isn't this a little overuse of OOP? What other concepts are there available, and are they useful in my context?
0

Share this post


Link to post
Share on other sites
I'd use an existing library instead of writing my own. Right now you're abusing OOP, I'd recommend you to look into composition. There is a great thread going on about this [url="http://www.gamedev.net/topic/629943-composition-heavy-oop-vs-pure-entity-component-systems/"]here[/url].
1

Share this post


Link to post
Share on other sites
I agree with Mussi that you should look into 3rd party libraries, as GUI systems can get quite massive, but if you really insist on doing this yourself you're going to have to look into some other programming concepts, because you are in fact abusing OOP quite horribly.

You should look into the Observer pattern and the Model-View-Controller model so you can decouple the actual visual representation of your GUI elements from the data they represent, and so you can create a generic method of accessing and modifying data through a GUI.

Note that this can become a massive amount of work for an entire GUI library, so you'd really be off better with a 3rd party library.
1

Share this post


Link to post
Share on other sites
Thanks to both of you,

I indeed insist on writing my own libary, so I'd just like to know more exactly when my OOP-abusion takes place.

Your talking about the derivations like WindowTileset, WindowTilemap, right? Or is my overlaying system bad, too? I've had a quick look at the observer-pattern and it seems like my base components like EditorImage, EditorSrollbar, just meet that criteria. EditorScrollbar e.g. holds three values, a minimum and a maximum, as well as a current one and manipulates that, without knowing what those values actually represent. Is this bad design, too? If yes, what benefits could I get from decoupling this?

Oh, not to forget, this gui right now is just being used for the game editor itself. Thats why I didn't want, though already reading into that other thread, to hijack it, as I thought this is a somewhat different topic. The editor itself is more static, so I quess graphics<->logic decoupling isn't that necessary.. right?

So in case just the "higher-level" derivations like WindowTileset that should be changed, how would I do that? Would I make a struct like this:

[CODE]
struct Tileset
{
EditorWindow* pWindow;
EditorImage* pTilesetImage;
EditorSelectRect* pSelectRect;
Update();
Draw();
}
[/CODE]

Would this be sufficient? Or do I really need to go with a component based system, or a true observer-pattern / model-view-controller? What are the benefits of this? I feel like my current approach is really practical to work with, expect the over-use of OOP when inheriting from EditorWindow.
0

Share this post


Link to post
Share on other sites
I agree that if you want to learn how to write a GUI system for yourself, apply composition well. Form objects can be usually be broken down into components intuitively. For instance, a clickable menu entry can be an aggregate of a TextEntry and a Button. Meaning, it's just a barebones class that contains objects of those two types. A scrollbar (just the bar itself, not the screen it scrolls) would be a Button and a Draggable entity with vertical/horizontal constraints added to it. Here, I've decoupled the components so that they will do very little (if at all) communication with each other. For a menu entry, the Button may just need to know the dimensions of the TextEntry so it can resize its "hot spot" accordingly. I'm not saying this is the best solution to go with, but it's a great improvement over using a large hierarchy of inherited classes.

I have written a older [url="http://www.gamedev.net/topic/629943-composition-heavy-oop-vs-pure-entity-component-systems/page__p__4971842#entry4971842"]post in this topic[/url] that Mussi was pointing to, but it describes my experience with adding some basic UI elements and how I've gotten around to decompose its functions, so it might be worth a look. I'm writing my own UI because I do not need anything very complex for my game.
1

Share this post


Link to post
Share on other sites
Definitely take a look at MVC and study it in detail

With MVC there's no need for you to define different classes for different types of windows for example. You would just have your 'EditorWindow' class (which you should maybe generalize to represent any Window, whether it's part of your editor or not) which is only worried about representing itself correctly to the user (hence being a 'View'). The window object absolutely does not care about which data it is representing, that's what the 'Model' behind the window should be taking care of.

This way you avoid unneeded inheritance for every single use case you might have, and allows for a much simpler, cleaner and easier to maintain GUI system.

Composition is also a crucial point of course when designing a GUI library, but the problem of designing your widgets/elements themselves well is still something different than designing the interaction between widgets and the use cases they occur in and the data they're supposed to represent.

If you want to see some examples of the MVC model you should take a look at Qt, which uses this extensively
1

Share this post


Link to post
Share on other sites
@CC Ricers:
[quote]For instance, a clickable menu entry can be an aggregate of a TextEntry and a Button[/quote]

[quote]A scrollbar (just the bar itself, not the screen it scrolls) would be a Button and a Draggable entity with vertical/horizontal constraints added to it[/quote]

Thats just how I was planning to handle things, except that my scrollbar still inherits from EditorObject, because, after all, isn't this a "base object" too? This drastically reduces the amount of code needed as well. Maybe I should show you what EditorObject looks like:
[CODE]
#pragma once
#include <Windows.h>
#include <vector>
#include "Input.h"
#include "Sprite.h"
using namespace std;
class EditorObject
{
public:
EditorObject(void);
virtual ~EditorObject(void);
void Setup(int iID, int iX, int iY, float fZ, int iWidth, int iHeight, Sprite* pSprite);
virtual bool Over(Vector2 vMousePosition); //mouse is pointing at this object?
virtual void Draw(float fZ);
virtual EditorObject* Check(Vector2 vMousePos); //return object at which the mouse is pointing
virtual bool Update(void);
virtual void UpdateSuper(int iOffX = 0, int iOffY = 0);
void SetX(int iX);
void SetY(int iY);
void SetSuperX(int iX);
void SetSuperY(int iY);
int GetID(void);
int GetX(void);
int GetY(void);
int GetWidth(void);
int GetHeight(void);
Sprite* GetSprite(void);
protected:
bool Activate(bool bActive, int iStateID = 0);
bool IsActive(int iStateID = -1, int iStateException = -1);
bool m_bActive;
int m_iActiveState;
int m_iX, m_iY, m_iOffsetX, m_iOffsetY, m_iSuperX, m_iSuperY;
int m_iWidth, m_iHeight;
float m_fZ;
Sprite* m_pSprite;
int m_iID;

Vector2 ProjectPosition(Vector2 vMousePos, bool bCap=true); //project a given point to object space
};
[/CODE]

So EditorObject describes a general object with variables that apply to every gui element. (position,size, a sprite object). The whole Super-thingy is for traversion, it spares me having to pass the holding objects x/y-coordinates all the time. ProjectPosition() is a helper function that outputs the mouse coordinates relative to the objects position, saves me a lot of math.

So I quess everyone would agree that I should at least inherit these classes from that:

EditorImage
EditorButton

If not, why?

If yes, why shouldn't I, example given, also inherit the Scrollbar from this?

The scrollbar, while being basically a composition of three buttons and a background-image, does have its own coordinates, destinctive size, needs to be drawn in relation to other objects, etc.. so whats exactly wrong about that or, better said: What are the benefits of composition here? What is such a huge improvement from having an extern controller handling the scrollbars usage to just having the Update() method do it? This is what, for example, the inherited scrollbar-class looks like:
[CODE]
#pragma once
#include "EditorButton.h"
#include "Timer.h"
class EditorScrollBar :
public EditorObject
{
public:
EditorScrollBar(void);
virtual ~EditorScrollBar(void);
void Setup(Sprite* pSprite, Texture* pFrame, int iID, int iX, int iY, float fZ, int iLength, bool bVertical);
void SetButtons(EditorButton* pUpperButton, EditorButton* pLowerButton, EditorButton* pMidButton);
void SetValues(int iMinVal, int iMaxVal);
void SetNowValue(int iNewValue);
int GetNowValue(void);
void Draw(float fZ);
bool Update(void);
void UpdateSuper(int iOffX = 0, int iOffY = 0);
private:
int m_iMinVal,m_iMaxVal,m_iNowVal;
Vector2 m_vTemp;
Timer m_cTimer;
EditorButton* m_pUpperButton, *m_pLowerButton, *m_pMidButton;
};
[/CODE]

Except that Setup() and SetButtons() could/should be moved to the constructor: Again, why would I want to composite instead of inherit here? The scrollbar class uses everything from its super-class, and just extents it. Do I really have such a misunderstanding of OOP-basics or is it some matter of opinion whether you see a scrollbar a base object here?

So I know that my EditorWindow->WindowTileset/WindowTilemap-classes are bad and I'll going to replace that with some composited objects here, but I really see to fail the point for such a basic objects as a scrollbar.

PS: Sry for bad spacing, code-tags killed it..

@Radikalizm:

Ok, that makes more sense to me for the window class, I'll aplly that to replace my WindowTileset etc.. inherited classes. Still, I don't see why I would want to do this to e.g. the scrollbar, or a button. Well maybe things will get more clear if I implement it for those said classes first. Edited by The King2
0

Share this post


Link to post
Share on other sites
Any GUI element/widget should inherit from a common Widget base class (EditorObject in your case), you're right about that since every widget will hold a set of similar data (position, id, rotation, etc.). So yes, the scrollbar should be inherited from your EditorObject class.



What I don't see here in your implementation is a widget hierarchy. The lack of this hierarchy is causing some of the problems you're having here I believe, and it makes you resort to some quite hacky and non OO implementations. Those "super" functions are some very obvious warning signals here -to be honest with you I have no idea what these are supposed to do, but from your description I can pretty much assume they are a hack-, just like that "check" function you have in your EditorObject class.

With a hierarchy you define a root widget which has all the widgets in your editor as children. Each of these widgets can have children of themselves as well, and the position of these children now becomes relative to their parents. The absolute position of a widget now becomes: relative position to parent + absolute position of parent.

If you look at the scrollbar example now you'll have the Scrollbar class which inherits the EditorObject class, and which is composed of 3 buttons which are all children of the scrollbar.

Sticking all of your behavioral code inside an update function of a widget instead of using MVC for example will force you to create a new class which inherits your scrollbar for each use case you might ever have, which will result in a huge amount of redundant code. I already explained this in my previous post.
Also, say you were to create a new class for every use case you ever encounter, and later on you need to make some changes to your base class declaration (your scrollbar for example). You'll now have to go back to every use case class of your scrollbar and update their declarations as well, which is just a huge time-waster.

Maybe it wouldn't be a bad idea to review your OO basics, since you're making some other violations against proper object-oriented design:

- Violation of the Single Responsibility Principle (SRP). Stick with SRP at all costs and make sure one class always is responsible for doing [b]one and only one[/b] task. Returning the widget which the mouse is pointing to is [b]not[/b] the responsibility of a widget!
- Improper constructor usage. 2-step initialization like you're applying here can be a dangerous practice as your class invariant is violated until you call the setup function in your EditorObject class. You only need to forget to call the setup class once after creating an EditorObject and you get sent straight to undefined-behaviour-land, which is not the happiest of places.
1

Share this post


Link to post
Share on other sites
[quote]What I don't see here in your implementation is a widget hierarchy. The lack of this hierarchy is causing some of the problems you're having here I believe, and it makes you resort to some quite hacky and non OO implementations. Those "super" functions are some very obvious warning signals here -to be honest with you I have no idea what these are supposed to do, but from your description I can pretty much assume they are a hack-, just like that "check" function you have in your EditorObject class.[/quote]

Well those "super"-functions are basically my scene hierachy, Take, as example the scrollbar:

The scrollbar, upon drawing, will call SetSuperX() and SetSuperY() for its buttons. On drawing, these variables are taking into account for the position where the button is drawn to. Same applies to the scrollbar itself, probably hold by a window, which is hold by the main frame. I actually adapted this from a project using an rpg-maker, that obviously lacked much of c++ functionality. Still, it is working, and except for having to overload the UpdateSuper()-method for every base object an making sure it is called for the parent-widget, its easy to use. However I'd still be glad to know about any better variante for handling a scene hierachie..?

[quote]With a hierarchy you define a root widget which has all the widgets in your editor as children. Each of these widgets can have children of themselves as well, and the position of these children now becomes relative to their parents. The absolute position of a widget now becomes: relative position to parent + absolute position of parent.[/quote]

Like i said, "super" basically does exactely that, but if there is an easier way, I'd like to know..

[quote]Sticking all of your behavioral code inside an update function of a widget instead of using MVC for example will force you to create a new class which inherits your scrollbar for each use case you might ever have, which will result in a huge amount of redundant code. I already explained this in my previous post.[/quote]

Thats a point I cannot follow. Ok, I've read up about normal widget/gui design and since most, if not all of them seem to use some sort of event - slot/signal - system, I've made a fundamental flaw right there. But in my application, I can use the scrollbar just as it is without rewriting it for each use case. From what I've experienced every toolbar is the same: You can click on the outer two buttons to scroll the bar up and down, or drag the middle button, or click anywhere else on the bar. And thats what my update-method does. It also sets the m_NowValue-variable between m_MinValue and m_MaxValue. Later on, I can access these values and do whatever it takes, whether its a bad oop-derived window-class, or a composited class using MVC. So while it is not the best oop-use, it still doesn't produce any redundand code or makes it hard to use, does it?

[quote]- Violation of the Single Responsibility Principle (SRP). Stick with SRP at all costs and make sure one class always is responsible for doing one and only one task. Returning the widget which the mouse is pointing to is not the responsibility of a widget![/quote]

How else would I handle this? It seemed logical to me that a widget should have the ability to return the widget it was pointing to, only including itself and its childern..

[CODE]- Improper constructor usage. 2-step initialization like you're applying here can be a dangerous practice as your class invariant is violated until you call the setup function in your EditorObject class. You only need to forget to call the setup class once after creating an EditorObject and you get sent straight to undefined-behaviour-land, which is not the happiest of places.[/CODE]

Ok, this is totally clear to me, its a bad habbit of mine. It does work well too because I'm using a factory class right now which stuffs all that together, but I'll remove it anyway.
0

Share this post


Link to post
Share on other sites
If you were to add an addChild() method to your EditorObject class which accepts another EditorObject, and if you were to maintain an actual list of children inside an EditorObject you could easily update your entire gui with only a single update call on the root widget. Within each update call in a widget you would traverse the list of children and do an update call on each of them individually, which gives you a nice recursive way of updating the gui.

Managing your gui in such a tree structure also makes your gui much easier to traverse from a programmer's point of view, as having access to a parent widget means having access to the entire subtree which that parent is root of.
I remain with my statement that using those super-methods is pretty much a hack.


Maybe I'm misinterpreting the way you use your update function in your gui elements, if that's the case just let me know. Right now, since I don't see any other way how you're updating your actual logic to manipulate your back-end data (eg. how does your scrollable window know that your scrollbar has been updated?), I'm assuming you're doing this in your update function.

The scrollbar example might not be the best example to explain the MVC principle, sorry for that. Let me try to explain it with a different example:
Let's take the simple example of a button. A button is both a visual representation of some dataset, and can manipulate a controller. Let's say you have a button on your GUI, and when you click this button a value gets added to an array you defined somewhere in your code for example. This array is of a fixed size however, and when this array reaches its limit the button should not be clickable anymore.

We separate this situation into a model, a view and a controller. The model is the array, which in our case can have 2 states: "Able to accept values" and "Not able to accept values". The view is our button, and depending on which state the model is in it can change state between "Enabled/Clickable" and "Disabled/Not-clickable". The controller is assigned to our button and it can manipulate our model (the array) by telling it that it should add a value to itself.

Now let's look at what happens when our button is clicked:
-The system managing your GUI gets a mouse-click event and checks whether the mouse position at the time of the click event was over a GUI element, and if so it sends an onClick message to said element. In our case we clicked the button, so our button will receive this message.
- Since the button received the onClick message it has to notify all its associated controllers, among them the controller for our array. The controller for the array sends a message to the model that it should be manipulated, and the model adds a value to the array.
- A value is added to the array, and the state of the array is evaluated. If a state change is triggered (ie. the array has reached its limit) it sends a message to all its views informing them of this state change.
- The button receives this state change message from the model and acts out its role as view. The button sets its state to disabled since no more values can be added to our array.


If you wanted to do all of this purely with inheritance you'd have to create a button class which would handle this entire process in its update system. Also, if you wanted your button to be able to control and represent multiple sets of data at once you'd have to create a separate case for that as well, whereas MVC allows a single controller to manipulate and a single view to represent/observe multiple models.
The update function for you GUI elements should only be responsible for making sure it is correctly represented in your GUI at all times, and should refrain from doing any actual logic manipulating your back-end data.



--- End example ---

On to your other questions:

Returning the gui element your mouse is pointing to should be the responsibility of the system managing your GUI. It is perfectly fine for a gui element to have a function which determines whether a point is inside its area (and that point could be the mouse position), but it's up to the system maintaining the GUI to determine which element(s) has/have been clicked, and to return that element to the system which requires it. Edited by Radikalizm
1

Share this post


Link to post
Share on other sites
Ok, things are much more clear to me now. Lets go through it:

[quote]
f you were to add an addChild() method to your EditorObject class which accepts another EditorObject, and if you were to maintain an actual list of children inside an EditorObject you could easily update your entire gui with only a single update call on the root widget. Within each update call in a widget you would traverse the list of children and do an update call on each of them individually, which gives you a nice recursive way of updating the gui.
Managing your gui in such a tree structure also makes your gui much easier to traverse from a programmer's point of view, as having access to a parent widget means having access to the entire subtree which that parent is root of.
I remain with my statement that using those super-methods is pretty much a hack.
[/quote]

I actually have a vector<EditorObject*> included to the EditorObject-class that I can add child objects too. I still felt like hardcoding certain consistant elements like the three buttons for the scrollbar makes things easier to work with. I'll have to overload the UpdateSuper()-method, but thats not a huge problem, since there is not such a huge amount of base objects derived from EditorObjects anymore after I got rid of the redundand ones..

Oh, by the way, I figured that what you mean that my update-method does is indeed the Update_Super-method, except I'm not passing the parents coordinates to the update-method but with SetSuperX() and SetSuperY(). Update_Super would just do the same thing for the (hard-coded) children.

[quote]Maybe I'm misinterpreting the way you use your update function in your gui elements, if that's the case just let me know. Right now, since I don't see any other way how you're updating your actual logic to manipulate your back-end data (eg. how does your scrollable window know that your scrollbar has been updated?), I'm assuming you're doing this in your update function.[/quote]

My windows knows about it from the return of Update(). If its true, it has been updated, So if m_pScrollbar()->Update() returns true, it calls m_pScrollbar->GetNowValue() to get the actual value and adjusts the content to that. It does that by setting the m_iOffSetX or Y variable, that is used in UpdateSuper() to set the according contents position.


[quote]If you wanted to do all of this purely with inheritance you'd have to create a button class which would handle this entire process in its update system. Also, if you wanted your button to be able to control and represent multiple sets of data at once you'd have to create a separate case for that as well, whereas MVC allows a single controller to manipulate and a single view to represent/observer multiple models.[/quote]

Well not quite, at least in my system. The Update()-method of the button determines its state: clicked, hold, hold+over, released, released+over (=activated). it returns true if any of these states apply, and the holding object then decides what to do with that, by checking if it has been activated. The object holding it might then call Down() to fix the button, Up() to release it and SetActive(bool) to make it unclickable/clickable. This is, example given, how I handle my tileset-toolbar right now:

[CODE]
EditorButton* pButton = m_pToolbar->GetActiveButton();
if(pButton == NULL || !pButton->Pressed() || !pButton->Over(Input::GetMousePos()))
return false;
switch(pButton->GetID())
{
case 0:
(*m_ppBrush)->SetErase();
break;
case 1:
{
pButton->Down();
PencilBrush* pPencilBrush = new PencilBrush(**m_ppBrush);
delete *m_ppBrush;
*m_ppBrush = pPencilBrush;
m_pToolbar->GetButton(2)->Up();
m_pToolbar->GetButton(3)->Up();
break;
}
case 2:
{
pButton->Down();
RectBrush* pRectBrush = new RectBrush(**m_ppBrush);
delete *m_ppBrush;
*m_ppBrush = pRectBrush;
m_pToolbar->GetButton(1)->Up();
m_pToolbar->GetButton(3)->Up();
break;
}
case 3:
{
pButton->Down();
BucketBrush* pBucketBrush = new BucketBrush(**m_ppBrush);
delete *m_ppBrush;
*m_ppBrush = pBucketBrush;
m_pToolbar->GetButton(1)->Up();
m_pToolbar->GetButton(2)->Up();
break;
}
}
[/CODE]

So other then having that a case-statement and knowing the button by ID (it's not a big deal), I can just call new Toolbar, push back a few new buttons, and that code above is all I need to get it to work.

--- MVC-explanation ---

Ok, so I've read what you explained, and MVC definately sounds like a concept that does fit perfecly here. I don't know how I'd go about implementing it right now but thats maybe because I haven't worked with messaging-systems at all until now. But, before I go ahead and screw my current approach, I'd like to ask once again: Do I really get that much advantage of using it? Sorry, I don't mean to be annoying or anything, I just like to question things. There are many worst-case-scenarios you described, which happend to me in my first try on writing a map editor years ago. I've overused OOP to an extent that it wasn't workable with, like you described, and the whole thing wasn't even working well. It didn't have the featureset I already have by this time, though the older one took much longer to develop. Maybe I didn't emphasise that enough, but the current system works flawlessly, so I'm not asking for an alternative because my current approach is unworkable, no, it works so well that I'm looking for a way of making things even easier to work with. So, in a nutshell, here is how the whole update-routine works (or will work after I got rid of the EditorWindow-derived classes):

- Main frame calls Update() on all of its widgets
- Update() first sets traversal coordinates for all its children by calling UpdateSuper() (sry, I just realized how confiusing this may appeal. I'll try to improve it)
- next, Update()- all of the children
- If widget without children is hit: perform a self-update (e.g. button deciding what state is in)
- If widget was activated, return true, else false
- If Update()-returns true: set children as active, perform destinctive actions (eg. set offset variable when scrollbar has changed), skip other children and self-update, else proceed

So now at this point I'm not sure how to proceed. Thinking about it, isn't that almost what MVC tells? Except that I don't let an extern controller regulate the basic actions like a button being clicked, but.. whats the point here? Every button will work the same so why would I want an extern button-controller when I can simply let the button handle itself? And again, I'm not talking about how the button manipulates that data, I'm just talking about the buttons states. But hold onm a second. Say if I where to make my widgets able of registering a controller, to that the button sends the information that it was activated, and let that controller decide how to manipulate the back-end data. Wouldn't that be almost what you were talking about? That would be my plan for now, composing the destinctive windows (tileset,tilemap), out of one or more widgets, having a controller, registering that controller to the widget and having it send information back to the controller. How does that sound, in combination with my above update procedure? Edited by The King2
0

Share this post


Link to post
Share on other sites
[quote name='The King2' timestamp='1345577914' post='4971942']
Say if I where to make my widgets able of registering a controller, to that the button sends the information that it was activated, and let that controller decide how to manipulate the back-end data.
[/quote]

That's basically the concept of using a controller yes, the button does not need to know what kind of controller it's maintaining, only that it is a controller, so any type of controller which could control any kind of model could be assigned to this button.

[quote name='The King2' timestamp='1345577914' post='4971942']
My windows knows about it from the return of Update(). If its true, it has been updated, So if m_pScrollbar()->Update() returns true, it calls m_pScrollbar->GetNowValue() to get the actual value and adjusts the content to that. It does that by setting the m_iOffSetX or Y variable, that is used in UpdateSuper() to set the according contents position.
[/quote]

In this case a window must explicitly know that it has a scrollbar which is manipulating it, which is not something you want in a flexible gui. What if you wanted to add a button to your window which scrolled down to a certain piece of content? With this method the window object would now also have to poll this button on each update to see whether it was clicked and update itself accordingly. Doesn't sound all too flexible, does it?
The same applies for the toolbar example you gave. Adding a button to the toolbar would require you to go in and edit the toolbar code to allow this new button to perform a certain task. With MVC you can add any generic button to any generic toolbar, and you can register a specific controller to that new button which completely defines its behaviour. No need to go in and edit your classes each time you want to add a certain bit of functionality for a specific use case.
The result of not having to go in and modify your code for widget behaviour is that you basically create a very simple environment where you can just compose your GUI by using completely generic widgets (buttons, scrollbars, images, windows, etc.), after which you assign models to them so they display the data they need to display and controllers so they can manipulate data. If you really wanted to you could do this entirely in a visual editor without once having to touch any piece of code.

[quote name='The King2' timestamp='1345577914' post='4971942']
I stepped away from this to hard-code the objects and overload the UpdateSuper()-method. This was most definately unevadable due to my design, since without any messaging system, I pretty much depend on specific objects to being certain methods called on directly.
[/quote]

This is a design flaw, and hardcoding everything in and making these objects which are supposed to be decoupled from one another explicitly know about eachother is not a solution. In the case of a bad design you should modify your design to something that is extensible and which works without hacks instead of adding more hacks to make the original design work.
Some form of messaging will be required eventually in a GUI system, so better to design it properly now instead of having to go back and adjust your design later on. MVC can provide a solution here since broadcasting of state changes and events is automatically implied as soon as one occurs.

Your current system might work now, but I can guarantee you that extending it and adding complex interactions to it will become a huge pain, both to implement and maintain.
1

Share this post


Link to post
Share on other sites
Ok, I've almost got it.

[quote]That's basically the concept of using a controller yes, the button does not need to know what kind of controller it's maintaining, only that it is a controller, so any type of controller which could control any kind of model could be assigned to this button.[/quote]

So I'd design a generic controller interface, but how would I go about sending messages to it? My first intuitive would be to write different generic message-method like button_clicked, scrollbar_moved, and overload these, but it sounds again a little messy. Maybe a general send_message()-method where I pass information on what type of object sent it? Or anything completely different? Before stepping ahead and starting implenting it, I want to make sure. And I do inherit from the generic controller for the certain use purposes, right, or is there still something different to it?

[quote]
In this case a window must explicitly know that it has a scrollbar which is manipulating it, which is not something you want in a flexible gui. What if you wanted to add a button to your window which scrolled down to a certain piece of content? With this method the window object would now also have to poll this button on each update to see whether it was clicked and update itself accordingly. Doesn't sound all too flexible, does it?
[/quote]


Flexibility wasn't my main purpose. Aside of my design flaws, I just made some deliberate simplifications as e.g. every window has two scrollbars (which might there or not) and a toolbar, etc.. well while I'm at it I might make it more flexible as well.

[quote]
The same applies for the toolbar example you gave. Adding a button to the toolbar would require you to go in and edit the toolbar code to allow this new button to perform a certain task. With MVC you can add any generic button to any generic toolbar, and you can register a specific controller to that new button which completely defines its behaviour. No need to go in and edit your classes each time you want to add a certain bit of functionality for a specific use case.
[/quote]


Not quite, as in the code I posted above (it's in the redundand WindowTileset-class but still) the button actions are handled, and my toolbar stores a vector<EditorButton*>, so all I'd really have to do is change that type of code. But since I might want to add other objects to the toolbar as well, I should make it more general, too.

[quote]This is a design flaw, and hardcoding everything in and making these objects which are supposed to be decoupled from one another explicitly know about eachother is not a solution. In the case of a bad design you should modify your design to something that is extensible and which works without hacks instead of adding more hacks to make the original design work.
Some form of messaging will be required eventually in a GUI system, so better to design it properly now instead of having to go back and adjust your design later on. MVC can provide a solution here since broadcasting of state changes and events is automatically implied as soon as one occurs.[/quote]

Ah, I slowly realize how much neater to work such a generic system was. Ok, so what if I made this:

- First, i call MainFrame->Update(). Update() now doesn't do anything more than traverse all the child objects, and so on.
- If the main controller receives any event (mouse-move, mouse-click) it will check recursively if an widget is underneath the mouse OR marked active (if I e.g. clicked on a button and hold the mouse, I don't want anything else happen unless the mouse is released, and even if it is, the release-message should still be sent to the button original held. Do I really need to keep like a extra pointer if an object is active and check that first, or is there any way to automatice that?) and send a message to the widget, like onClick(). (By the way, can I just send messages as a method, so therefore call m_vObjects[X].onClick() or do I need to use some more abstrusive design?)
- The object, eg. button does all self-management it needs (changing texture to represent pressed state, etc..) and then sents the controller an onClick()-message -> see question at the top.

Sounds good, at least to me. Well I'd be glad if you could explain to me how I should communicate with the controller, other than that I think I'll go that route, shouldn't I?
0

Share this post


Link to post
Share on other sites
Radikalizm went through a lot on showing you MVC examples to maintain a graphical interface and its parts, so I will tell you why it would make sense to move more towards components and avoid overuse of inheritance.

[quote name='The King2' timestamp='1345565134' post='4971872']
@CC Ricers:
[quote]For instance, a clickable menu entry can be an aggregate of a TextEntry and a Button[/quote]

[quote]A scrollbar (just the bar itself, not the screen it scrolls) would be a Button and a Draggable entity with vertical/horizontal constraints added to it[/quote]

Thats just how I was planning to handle things, except that my scrollbar still inherits from EditorObject, because, after all, isn't this a "base object" too? This drastically reduces the amount of code needed as well. Maybe I should show you what EditorObject looks like:

*snip*

So EditorObject describes a general object with variables that apply to every gui element. (position,size, a sprite object). The whole Super-thingy is for traversion, it spares me having to pass the holding objects x/y-coordinates all the time. ProjectPosition() is a helper function that outputs the mouse coordinates relative to the objects position, saves me a lot of math.

So I quess everyone would agree that I should at least inherit these classes from that:

EditorImage
EditorButton

If not, why?

If yes, why shouldn't I, example given, also inherit the Scrollbar from this?

The scrollbar, while being basically a composition of three buttons and a background-image, does have its own coordinates, destinctive size, needs to be drawn in relation to other objects, etc.. so whats exactly wrong about that or, better said: What are the benefits of composition here? What is such a huge improvement from having an extern controller handling the scrollbars usage to just having the Update() method do it? This is what, for example, the inherited scrollbar-class looks like:

*snip*

Except that Setup() and SetButtons() could/should be moved to the constructor: Again, why would I want to composite instead of inherit here? The scrollbar class uses everything from its super-class, and just extents it. Do I really have such a misunderstanding of OOP-basics or is it some matter of opinion whether you see a scrollbar a base object here?

So I know that my EditorWindow->WindowTileset/WindowTilemap-classes are bad and I'll going to replace that with some composited objects here, but I really see to fail the point for such a basic objects as a scrollbar.

[/quote]

It's true that eventually all your widgets need to have a base class in common- if the intent is to have a separate GUI system go through all the widgets and draw/update them each time, the system needs to know what counts as a widget, and be able to register objects of the Widget type.

What I don't favor is putting bunch of variables that are sprawling over the place inside the Widget class, when they can be split up and contained in their own classes or structures, which you can then use with more flexibility. For example, width, height and X and Y position can be stored in a Rectangle structure. The extent to how you define the visual appearance is up to you. Do you want the UI system to use one skin, or maybe give the ability to mix several skins, with some taking priority over the "default" skin? Whatever the case may be, this should be separate from the classes that define behavior.

Also, you have to see what makes each widget fundamentally unique. What makes a button a button? It's certainly not its size and position because all widgets have those. A button, like all other UI elements, is defined by its behavior. The Button class need not know it's position, just whether it's been clicked on, or not, and if clicked, trigger an event that would be passed up to the UI system to get the proper response.

The inheritance to a base object would exist simply to make it possible to queue all widgets, extract necessary information that a particular subsystem would need (like a sound player or graphics renderer), and have those subsystems do whatever they need with the information. The rendering system should not care what kind of widget the Button is, or even that it's a widget. You should just pass along to it the UI skin parameters to tell it what the element looks like and the Rectangle object to tell it where to draw the element.

As I mentioned before, I'm not making a terribly complex UI- all I need are some short menus, and a couple of buttons and dialog boxes here and there. But they all share a common objects through composition (Buttons, TextEntries and Backgrounds), and share a skin object that resides in the UI/screen manager, for a more consistent look throughout the game. Also, admittedly they take care of drawing themselves for now, so that's a big "don't do" on my part that I have to fix. But If I needed something more complex (and I was designing it myself), I would design a more elegant solution.
1

Share this post


Link to post
Share on other sites
It does indeed sound like you have the hang of it [img]http://public.gamedev.net//public/style_emoticons/default/smile.png[/img]

One example of communicating with a controller is letting a widget maintain a list of controllers. When an onClick event occurs (so your button's onClick() method is called) for example you could iterate over your list of controllers and notify each of them that they should perform their designated action. This will automatically start the chain reaction of updating both model and view.

The Qt library does this in a slightly different way which you already mentioned in some previous post I believe. They use the signal-slot mechanism to connect certain triggers or signals from a widget to a function or slot. This does of course require their own meta-object compiler with some custom C++ extensions, so unless you're ok with providing a quite advanced pre-compilation step for your project this isn't really an option.

In C# something similar is implemented with delegates which can be linked to events. Something similar could probably be built in C++, but I'd need to do some research on that before I could give you any details. Edited by Radikalizm
1

Share this post


Link to post
Share on other sites
@CC Ricers:

[quote]What I don't favor is putting bunch of variables that are sprawling over the place inside the Widget class, when they can be split up and contained in their own classes or structures, which you can then use with more flexibility. For example, width, height and X and Y position can be stored in a Rectangle structure. The extent to how you define the visual appearance is up to you. Do you want the UI system to use one skin, or maybe give the ability to mix several skins, with some taking priority over the "default" skin? Whatever the case may be, this should be separate from the classes that define behavior.[/quote]

Ok, I agree, I might want to put x, y, width and height into some sort of structure. Talking about the skin, I was just passing a texture pointer to the element, that represented the skin. Having the UI system itself handling the skins seems like a good idea, though. Didn't think about that.

[quote]Also, you have to see what makes each widget fundamentally unique. What makes a button a button? It's certainly not its size and position because all widgets have those. A button, like all other UI elements, is defined by its behavior. The Button class need not know it's position, just whether it's been clicked on, or not, and if clicked, trigger an event that would be passed up to the UI system to get the proper response.[/quote]

So you are talking about the button as being just the controller talking about MVC, right? Ah, I think I get it. Does that mean I'd have my baseclass EditorObject, which acts as a view, and can hold various amounts of controllers as well as the model. It accepts user inputs, but only redirects them to the controllers, which themself change the data in the model. So a button would be a normal Widget with a special controller that handles the button-specific tasks. Right? My head slowly starts to ache :(

One thing that I, however, really don't understand, is what the model exactly is. Is it some sort of template, or a certain data type that i define for each widget? Or is it like the buttons back-texture and image/text?

@Radikalizm:

[quote]One example of communicating with a controller is letting a widget maintain a list of controllers. When an onClick event occurs (so your button's onClick() method is called) for example you could iterate over your list of controllers and notify each of them that they should perform their designated action. This will automatically start the chain reaction of updating both model and view.[/quote]

Ok, that seems legit, but what I meant more specifically is how exactly do I tell the controller what exactly happend? Should I maintain a notify function for all widgets possible actions, like onButtonClick()?


At that point, though I think I still need a bit more, I want to thank you guys already for your help. I'll wait for your next answers, in the meanwhile I'll try to pseudo-code what I think this should look like..
0

Share this post


Link to post
Share on other sites
[quote name='The King2' timestamp='1345585366' post='4971990']
Should I maintain a notify function for all widgets possible actions, like onButtonClick()?
[/quote]

I wouldn't do that since you'd have to update your code in 2 locations whenever you want to add a definition for a widget, which could become quite a mess after a while, and which goes against the principle of self-containment in OOD.

Solving this problem can indeed be tricky, but it mostly depends on personal preference as there are many ways to solve it. You could design your controllers to accept a generic message structure which contains event arguments as a parameter for their update function (or whatever you want to call it). The burden of parsing this message and translating it into something which makes sense would then be on the controller.
Pressing or releasing a button could for example pass on a message containing a boolean value with the pressed state of the button. If the controller which receives this message can work with a single boolean value it can continue on happily, if it can't however you could let it print an error message, or you could just let it ignore the message.
0

Share this post


Link to post
Share on other sites
Ok, thanks, I'll try figure out what fits best once I've gotten that far.

So I gave it a try to somewhat code it out on a basic level, and that what I've gotten (I actually tried to cover the real MVC-pattern this time, if it doesn't work out that well, I'll go back to my old pattern):

[CODE]
class View
{
public:
View(Model* pModel);
virtual ~View(void);

void OnClick(void);
void OnOver(void);
void OnRelease(void);

void AddChild(Widget* pWidget);
void AddController(Controller*);

void Update(int x, int y); // traversiallyupdate childs
virtual void Draw(void);

protected:

vector<Controller*> m_vControllers
vector<View*> m_vChilds;
Model* m_pModel;
};
[/CODE]

So I'd have my widget some generic events like OnClick, an Update() and Draw()-method, a number of controllers, as well as some childs and the model its holding. I'm still confused about the model part, but I'll come to that later. Here is the controller:

[code]
class Controller
{
public:

Controller(Model* pModel);
virtual ~Controller(void);

virtual void SendMessage(wstring lpString);

protected:

Model* m_pModel;
}
[/code]


Well this basically knows that model it is holding, and has a method of sending a message to it. Thats all I need, if I understand that right. Now to the model

[code]
class Model
{
public:

Model();//??
virtual ~Model(void);

protected:
//??
}
[/code]


I've got no idea how to design the model in a generic pattern. Really, I can't even come up with any example. How would I design this in a way that I don't have to inherit from this class for every set of data I want to display, and not have to inherit widget accordingly? This would kill the whole purpose, I belive.

Some more questions:

- Where does the position/size goes to? The view, or the model?
- Do I inherit my Widgets from View, or do I really compose them out of views,models and controllers (by having a seperate widget class from which I inherit) or it the View actually the Widget?

My main problem however is the model. I can't figure that part out. I know what it basically is, but I don't know how I can code it. Edited by The King2
0

Share this post


Link to post
Share on other sites
e: did misread much, edit post

[CODE]
class View
{
...
void AddController(Controller*);
...
}
[/CODE]
I wouldn't do that, generally the view allows the controller to register "events", the view doesn't know about the controller directly.

[quote name='The King2' timestamp='1345588411' post='4972001']
I've got no idea how to design the model in a generic pattern. Really, I can't even come up with any example. How would I design this in a way that I don't have to inherit from this class for every set of data I want to display, and not have to inherit widget accordingly? This would kill the whole purpose, I belive.
[/quote]
Well, I think what you want to do is build your own gui framework. This means you build templates for the View. Templates for any controller / model is not a task of the windowing library afaik.
This means for the windowing library you need a class design for your gui elements and a messaging system, implementing the MVC pattern is not up to the library.

What do you want to do exactly, build a map editor? build a Settings- / Gamemenu build an in-game HUD?

If possible, use a windowing library, what you are doing here is trying to reinvent the wheel.


[quote name='CC Ricers' timestamp='1345582334' post='4971973']
What I don't favor is putting bunch of variables that are sprawling over the place inside the Widget class, when they can be split up and contained in their own classes or structures, which you can then use with more flexibility
[/quote]
While I agree that it makes sense to put that in a structure, I don't agree that it gives you more flexibilty. What should be so more flexible about this approach? Edited by Bluefirehawk
1

Share this post


Link to post
Share on other sites
Thank you,

but you misread what the main purpose was. Totally understandable, given that wall of posts, I'll tell you what I want to have. The main purpose of this is to bouilt a game editor. No only map, I would call it that. I decided to go the other way round this time and instead of implement the game and build the editor afterwards, making testing hard at first. I'd built the game editor first and only write the the pieces of game the editor is able to display/alter.

[quote]I wouldn't do that, generally the view allows the controller to register "events", the view doesn't know about the controller directly.[/quote]

How would I do that? I can think about it using function pointers, but this whole topic is new to me so I'd rather go with registering the controller directely, unless there is some huge drawback.

[quote]
If possible, use a windowing library, what you are doing here is trying to reinvent the wheel.

[/quote]

I really don't want to do that, as I'd like to get an understanding of how things work under the hood. You may call it a waste of time but I've learned quite a much only the last 24 hours, which might become usefull again later on.

[quote]
Well, I think what you want to do is build your own gui framework. This means you build templates for the View. Templates for any controller / model is not a task of the windowing library afaik.
This means for the windowing library you need a class design for your gui elements and a messaging system, implementing the MVC pattern is not up to the library.
[/quote]

Still, I need some basic implentation of a model, right? I've implemented the basics of this, and it really is much easier and cleaner then my last approach, but.. what about the model? Is it really a class like this:

[CODE]
class Model
{
Model();
virtual ~Model();

protected:
int m_X, m_Y, m_Width, m_iHeight;
}
[/CODE]

That like here holds the position and size of the widget, and from which I inherit in every special use case? Please, I'd really need an answer here. I've searched high and low but couldn't find a single example mentioning a concrete example of the model for that use case.
0

Share this post


Link to post
Share on other sites
[quote name='The King2' timestamp='1345632233' post='4972150']
Still, I need some basic implentation of a model, right? I've implemented the basics of this, and it really is much easier and cleaner then my last approach, but.. what about the model? Is it really a class like this:
[/quote]
Don't do that. The "Model" can be anything, it depends on your project that uses the window library. Also MVC is not the only pattern for window development. So while developing your windowing framework, you have to care didely squats about the MVC pattern.

Like I gave in the example, for a logfile viewer the model is the logfile reader/writer class. for a map editor, the model is the map. MVC is applied when you use your window framework for a project. Think of the Model as a command line program, the view as a pupped with no idea what to do and the controller as the puppeteer. Putting the position and size in the model makes no sense by definition. A Button isn't a model, a button is a subcomponent of the view.

[quote name='The King2' timestamp='1345632233' post='4972150']
[b]How would I do that?[/b] I can think about it using function pointers, but this whole topic is new to me so I'd rather go with registering the controller directely, unless there is some huge drawback
[/quote]
It is MVC half-assed. The whole idea behind MVC is that the View has no idea about the controller and the controller can be completely changed. In your implementation, the Controller has to have a certain interface to work.
You haven't worked with .Net windows.forms or AWT/SWING, have you? You can do it by function pointers or by event classes. Those are the two messaging systems of .Net and swing respectively.

[quote name='The King2' timestamp='1345632233' post='4972150']
The main purpose of this is to built a game editor.... I really don't want to do that, as I'd like to get an understanding of how things work under the hood. You may call it a waste of time but I've learned quite a much only the last 24 hours, which might become usefull again later on...
[/quote]
Seriously? Don't do the windowing library yourself. Just don't. Not if you want to do something else for the next few years.
This field is hugely complex, from the posts I read, you don't have enough skill to implement something halfways usable. To be honest, neither have I, nor about 90% of the people here.

You want to know how they work under the hood, you should at least know how the "hood" looks like.
I guess you are fairly new to programming, of course you learned much getting feedback on your design. But it is like you want to be a mechanic and your first job is to dis- and reassemble an ocean liner. It is not a good learning project.
You could as well have been asking how to reimplement the Source engine. You will learn much, yes. But such a project is stupid when you don't know your way around simple 3D problems and algorithms. You might learn more + have more fun implementing a program that starts with simple cubes.

There are better learning projects, for example your game editor. There you can learn how to use the MVC pattern, about messaging and delegating and so on. Then you see what a window library actually is and does.

From there on, there are good articles on how SWING works and their design choices to keep it platform indipendent. Also you might search for an article on Windows.Forms, and WPF.
The important lessons to take from the windowing libraries are their design choices/design patterns. Edited by Bluefirehawk
0

Share this post


Link to post
Share on other sites
Ah, thanks a lot, now things make sense.

[quote]
It is MVC half-assed. The whole idea behind MVC is that the View has no idea about the controller and the controller can be completely changed. In your implementation, the Controller has to have a certain interface to work.
[/quote]

Hmm seems like I might want to rethink this and learn something about about messaging systems. If the controller has to have a certain interface, its not a problem for me. As I said I don't want to write a widget libary used by other persons, but having a system that I can reuse in my projects.

[quote]
This field is hugely complex, from the posts I read, you don't have enough skill to implement something halfways usable. To be honest, neither have I, nor about 90% of the people here.
[/quote]

Admitately no, I don't have the skill to implent something that one would consider good. But I'd still say its usable, at least for me. My old system was pretty crappy, but it was working flawlessly, and I could have expandet it without many problems, to a certain extent. Now I've rebuilt things from scratch, and things work a lot easier, and provided what you just told me about MVC and how it doesn't apply to the gui-lib, I think I can work with this.

[quote]I guess you are fairly new to programming, of course you learned much getting feedback on your design. But it is like you want to be a mechanic and your first job is to dis- and reassemble an ocean liner. It is not a good learning project.[/quote]

Actually no, I'm not new to programming. I've just used to write things dirty, you know, just getting them to work quickly and not caring about design too much. I already created a 3d environment, and I'm familiar to the topic, as well as being able to solve 3d problems like you mentioned. I've stepped back to a 2d map editor, because I know almost everything about the plain logic of a 2d top-down rpg, as I've been working on a extreme complex 2d project for the rpg-maker xp for almost 5 years. I'm not talking about code design, just how things like a tilemap is organized, how collision detection works, etc..

So I see why you advice me to use a already existing libary and focus on other things, but it won't do me any favor. I've decided to step back to 2d to learn patterns like tackle something like a gui libary, in order to improve my code design.
0

Share this post


Link to post
Share on other sites
[quote name='Bluefirehawk' timestamp='1345621081' post='4972105']
[quote name='CC Ricers' timestamp='1345582334' post='4971973']
What I don't favor is putting bunch of variables that are sprawling over the place inside the Widget class, when they can be split up and contained in their own classes or structures, which you can then use with more flexibility
[/quote]
While I agree that it makes sense to put that in a structure, I don't agree that it gives you more flexibilty. What should be so more flexible about this approach?
[/quote]

What I meant is that it is easier to manage in the code, by re-using the variables/functions as a structure in other part of your code, instead of copy-pasting the declaration of multiple variables and passing a long list of function parameters. More importantly to me, though, is discovering new ways you can use the structure now that it's in a single unit.

For instance, I had variables for transition times in my screens, plus a transition update function. Each screen has custom times for their entering/exiting transitions, and the transitions are animated according to the time. When I grouped all the related transition code into a structure, I now had something that I can easily use elsewhere for things more than screens. I could apply it to a text object to make moving text, for example. Edited by CC Ricers
0

Share this post


Link to post
Share on other sites
I had a final look at the signal/slot-pattern like Qt uses it, and GOD is it awesome. I finally understand, not only in case of guis and widgets, why such messaging systems are that common. So I've downloaded a signal/slot-libary, and on top of that I'm going to built my gui. Yeah, I'll still do that, but just from all I learned from that will help me way past that project, I'll keep on it, even if it slows things down. Thanks to all of you who helped me :)
0

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!


Register a new account

Sign in

Already have an account? Sign in here.


Sign In Now
Sign in to follow this  
Followers 0