3

So, I'm still working on my small GUI "library". (C++ with boost) The goal is to provide a simple solution for small SPI displays, using a Raspberry or some embedded board.

Thus, I ended up having a Widget class from which concrete widgets are derived. Examples would be a textbox or an image frame. Widgets can contain other widgets to allow groups. This is achieved via aggregation using a STL container. In the end, the complete GUI dataset can be seen as some kind of tree, with some nodes having child nodes.

Each widget shall have a draw-method which looks like

    void drawMe(brush *myBrush);

A brush provides primitive drawing methods like "setPixel" or "drawRectangle" This allows the widget to draw itself, using the methods provided by the brush. A widget first draws itself, then it invokes the drawMe-method of each child widget, if any.

Now lets talk about my problem. Each widget has its coordinates, relative to the parent. This is not enough, the brush needs the absolute coordinate of the widget, because a brush does not know anything about children or parents. A brush just provides methods like setPixel(int x, int y) and draws into a pixel buffer.

But I somehow have a bad feeling letting a widgets know its absolute coordinates. This feels wrong. On the other hand, at the moment a child does not know it is owned by a parent, thus, there's no way a widget can compute its absolute coordinates.

I can implement workaround in the brush, so that the brush supports multiple layers instead of just one canvas (the pixel buffer). A parent then has to set up the layers for its child. Sounds like a dirty hack.

Also, is it a good idea to et the parent know its child coordinates?

You see, I'm somewhere lost with this issues. There are GUI frameworks out there, like QT and stuff. So, my problem should be known and solved already. Do you have any suggestions? How would you implement the drawing process?

The whole project is about learning new stuff, mainly OOP paradigms. I like to hear your opinion on that.

  • Layers seem like a proper solution. What makes you think it's a hack? Also, what's wrong with parent widget knowing properties of it's children? It's seems like it should know (or even define) their coordinates to be able to draw them in their proper places. – scriptin Jan 2 '16 at 17:22
  • There is another solution for that. If your widgets are treated as simple containers (instead of the drawme method) you could implement a renderer wich renders each widget type. This has some advantages: Your widgets can easily be serialized and deserialized, your GUI is data-driven, and can be easily deployed to your target. It is easy to test. You don't clutter your widget code with target specific code. Animatons are also easier to achive. – thepacker Jan 2 '16 at 23:16
  • A long time ago I did the same thing and made this: woopsi.org/screenshots.html I recommend starting out by building a really good 2D graphics library (or finding an existing one) that can do clipping. That would have solved so many of my problems... – Ant Feb 3 '18 at 5:44
4

But I somehow have a bad feeling letting a widgets know its absolute coordinates. This feels wrong.

Good instincts. The data would be redundant and trivially computed from the combination of a parent widget and child widget's local coordinates. Less state often means less room for error (plus reduced memory use per widget).

1

I think that there is a key scenariio that you need to keep in mind.

The widgets should be able to redraw themselves

If you don't have this ability, then when a widget changes in some way, you only can call the root widget to do a full redraw (that, of course, can be optimized in some way, let's say a dirty flag).

So

On the other hand, at the moment a child does not know it is owned by a parent, thus, there's no way a widget can compute its absolute coordinates.

will be probably wrong . a child needs to know that it's owned by a parent, and also know the parent, at least to be able to trigger the parent update.

That would be something in the lines of the child asking the parent for a redraw, and then the parent doing the redraw, in a recursive way.

Also

because a brush does not know anything about children or parents. A brush just provides methods like setPixel(int x, int y) and draws into a pixel buffer.

is probably wrong. Of course the brush should know that. But probably you will need a higher order equivalent, that will know something about the widgets.

When you delete a widget, for instance, probably there was another widget that was hidden but the now deleted widget. And this widget needs to be drawn. Again, if there isn't a widget manager that knows something about this, your only option will be a massive call for all the widgets to be drawn.

This widget manager doesn't need to be your brush, but then it's another component that needs to know about the layout

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.