Struct with child struct

Started by
12 comments, last by Boogiwoogie 11 years, 3 months ago

Hi

I am pondering how I should implement a GUI class. I figured I should have a root parent and then have child windows attached to that root parent. But how should the parent and the child be connected? Should I "new" each child and put a pointer to the child on the vector? Should the vector itself be a pointer to a vector which can hold children? What makes more sense, heap or stack or something in between?


struct GuiWindow
{
WinParam parameters;
std::vector<WindowObject> WindowObjects;
std::vector<GuiWindow> ChildWindows;
}

struct GuiWindow
{
WinParam parameters;
std::vector<*WindowObject> WindowObjects;
std::vector<*GuiWindow> ChildWindows;
}

struct GuiWindow
{
WinParam parameters;
std::vector<WindowObject> *WindowObjects;
std::vector<GuiWindow> *ChildWindows;
}

struct GuiWindow
{
WinParam parameters;
std::vector<*WindowObject> *WindowObjects;
std::vector<*GuiWindow> *ChildWindows;
}

Advertisement
Chances are very small that your child elements will actually all be of the same type. You might have child buttons, child text boxes, child scrollbars, etc. Since you can't stuff different derived objects into a vector of base objects by value, you need to make a vector of (smart) pointers. And since a window with child elements is a pretty common use case, I'd go with holding the vector by value rather than by pointer.

I presume where you've written *Type you actually meant Type*.

The simplest solution is the first. If you need polymorphism, then the second option (corrected for the above) is what you want - though use smart pointers if possible. Making the vectors pointers is unnecessary.

What makes more sense, heap or stack or something in between?

[/quote]

If you can allocate objects on the stack, do. However, don't bend over backwards to achieve this, the heap is fine too. Particularly for a GUI, you aren't likely to be allocating often so performance probably isn't a concern.

The main thing is to ensure you leverage RAII where possible so your GUI doesn't leak - hence the smart pointer suggestion.

You might also consider going with some form of immediate mode GUI, and doing away with the class structure altogether.

It's not necessarily a panacea, but it's a concept well worth wrapping your mind around. IMGUIs also tend to be much simpler than traditional retained GUI frameworks, especially for small-scale projects.

Tristam MacDonald. Ex-BigTech Software Engineer. Future farmer. [https://trist.am]

As rip-off mentioned, it's Type* not *Type. Also, a vector of pointers is completely proper, but a pointer to a vector is definitely not what you want.
struct GuiWindow
{
WinParam parameters;
std::vector<WindowObject*> WindowObjects;
std::vector<GuiWindow*> ChildWindows;
}

But isn't a Window a type of object itself? Most widget-based GUIs have buttons and text entry fields and pop-up windows and child-windows and toolbars and tooltips are inherit from the same base class. Either 'inherit' in the C++ sense, or in just the 'concept' of inheritance, without C++ inheritance.

So:
class WindowObject //Also often called 'widgets', but not always.
{
    public:
    WindowObject(WindowObject *parent);

    //Overridable function to handle a mouse click. The default implementation forwards it to whatever child window
    //at that location, and that child returns true if it handled the event, or false if it ignored it, letting
    //the event propagate to the bottom of the child hierarchy (which is visibly the widgets 'on top' of everything), before
    //bubbling back up through all the parent windows.
    virtual bool onMouseClick(const MouseClickEvent &mouseClick);
    virtual bool onMouseMove(const MouseMoveEvent &mouseMove);
    virtual bool onKeyPress(const KeyPressEvent &keyPress);
    virtual bool onShow();
    virtual bool onHide(); 
    
    //...and a half-dozen other events.

    private:
    unsigned int posX, posY; //Relative to the parent's position.
    unsigned int width, height;
    std::vector<WindowObject*> children; //Any buttons, sub-windows, pop-up windows, side-panels, text edits, text objects, image objects, etc...
};
You might also consider going with some form of immediate mode GUI, and doing away with the class structure altogether.

It's not necessarily a panacea, but it's a concept well worth wrapping your mind around. IMGUIs also tend to be much simpler than traditional retained GUI frameworks, especially for small-scale projects.

This made no sense to me at all. Is there a tutorial that explains this concept better?

[quote name='Tispe' timestamp='1358276246' post='5021887']
This made no sense to me at all. Is there a tutorial that explains this concept better?[/quote]

Try mollyrocket's video introducing IMGUI.

Tristam MacDonald. Ex-BigTech Software Engineer. Future farmer. [https://trist.am]

The Sol IMGUI tutorials walk you through creating some, using SDL.

Looking into IMGUI I find it hard to belive it is "that much" simpler then the standard RMGUI as it claims. Because every button, window, slide, label and list still needs to be defined somewhere. IMGUI just puts that away and says "it is not my responsibility", but then IMGUI is not a GUI is it? It is just a wrapper for a sprite or text drawcall...

If I were to try and roll my own IMGUI class I still need a place that retains all info on the layout of the GUI, what textures different buttons have etc. And what better place to keep that information other then inside the IMGUI class? Then the IMGUI class suddenly transforms into a RMGUI class.

I just don't get it is what I am trying to say :p

So... how does people do IMGUI in terms of defining the gui layout? Say I have windows that contain 20 buttons, a health bar, a text edit box, some labels, check boxes and so on. Where would I go about saving where each of these wedgets gets placed on the screen? I surely can't have each widget as a global or static variable? So is it implied that the IMGUI class should contain a std::vector<widget*> which holds this info?

I think it is just too easy to claim the IMGUI class is not responsible for saving this data. What am I missing here?

This topic is closed to new replies.

Advertisement