Base classes for a GUI
Point and Size structures

I would go even further than @glampert and create Point and Size structures as well as a Rectangle one. Experience has shown that this kind of small classes are extremely useful and can be used at many places in a GUI library (for example, getting the coodinates of the mouse can return a Point, computing the centre of a rectangle too, etc...). Moreover, once you have Point and Size classes, you can overload some of their operators to implement expressive and unambiguous operations such as multiplication by an integer.

In the long run, you will see that it is easier to reason with these objects, and you can even return them from functions while you can't return x and y if they're not in a structure.

Back to the Rectangle

Here is a concrete example of what your class does but should be actually performed by a Rectangle class instead:


template &lt;typename T&gt;
bool pointInElement(T x, T y) {
    return (x &gt; this-&gt;x &amp;&amp; y &gt; this-&gt;y &amp;&amp; x &lt; this-&gt;x + this-&gt;width &amp;&amp; this-&gt;y &lt; this-&gt;y + this-&gt;height);
}



This should look like this, assuming that you have a Rectangle member named box and that your Rectangle class has a method named contains which takes a Point and returns a bool:

template&lt;typename T&gt;
bool pointInElement(const Point&lt;T&amp;&gt;&amp; point) const {
    return box.contains(point);
}


Constructor initialization list

Whenever possible, try to use the constructor initialization list. As it is now, your code constructs an Element instance, then assigns values to its fields. If you leave the job to the constructor initialization list, your object will be directly constructed with the appropriate values:

Element(int x, int y, int width, int height, Element* parent):
    x(x), y(y),
    width(width), height(height) {

    if (parent != nullptr) {
        parent-&gt;children.push_back(this);
    }
}


As you can see, it even allows to drop the this-&gt; needed to differentiate the variables. The syntax only allows the member names on the left and the name resolution picks the parameters first on the right.

About the virtual destructor

I bet that you will want runtime polymorphism with your widgets. In this case, follow @glampert's advice: make the destructor virtual and public. If it does not do anything, the simplest thing to do is to explicitly default it:

virtual ~Element() = default;


Now, if a destructor is public and virtual in a base class, then the derived class automagically have a virtual destructor, you don't have to write anything. Therefore, the simplest thing to do would be to simply remove the destructors from TopLevelWindow, Window and Button if they don't do anything more than Element's destructor; you program will then be correct but simpler.