Skip to main content

Position and size

Large parts of the UI setup of common TouchGFX application can be created with the TouchGFX Designer, but typically you also need to write a bit by hand. For example to do more animations or create a dynamic setup of Widgets that depends on user events or configuration data.

When you start that task it can be an advantage to know a few of the methods in the classes that can help.

All Widgets in the TouchGFX framework are subclasses of the Drawable class. This class contains the general methods for controlling size and position.

Widget hierarchy (partial)

You build up your user interface of many instances of Widget objects. These objects are added as members to a View subclass. The View class is subclass of the Screen class.

Screen hierarchy

The Screen class containes a Container member. This is called the root container. The root container is initialized to start in (0,0) and fill the entire display area (width = HAL::DISPLAY_WIDTH, height = HAL::DISPLAY_HEIGHT).

Adding Widgets

Widgets are added to a View by creating members in the View class. Here we add a Box called myBox:

Screen1View.hpp
#include <gui_generated/screen1_screen/Screen1ViewBase.hpp>
#include <gui/screen1_screen/Screen1Presenter.hpp>
#include <touchgfx/widgets/Box.hpp>

class Screen1View : public Screen1ViewBase
{
public:
Screen1View();
virtual ~Screen1View() {}
virtual void setupScreen();
virtual void tearDownScreen();
protected:
Box myBox;
};

To use the Box in your code, you must include Box.hpp unless it was already included in the base class header file.

To get the Box Widget drawn you must add it to the scene graph (a tree of the Widgets in the Screen).

A tree of Widgets

This is done with the add function. Typically in setupScreen:

Screen1View.cpp
#include <gui/screen1_screen/Screen1View.hpp>

Screen1View::Screen1View()
{
}

void Screen1View::setupScreen()
{
Screen1ViewBase::setupScreen();
add(myBox);
}

The add method on Screen calls add on the root container:

void add(Drawable& d)
{
container.add(d);
}

If you have another Container in your Screen you can add widgets to that by calling add on the Container:

void Screen1View::setupScreen()
{
...
myContainer.add(myBox);
}

Setting size and position

Most Widgets have a default position of (0,0), and width and height zero. This means that it is almost always required to set the size and position of a Widget.

The basic method to set the position is the setXY method:

   myBox.setXY(10, 10); // Put myBox in x=10, y=10

The width and height can be set with the setWidthHeight method. Or the setWidth, setHeight methods:

   myBox.setWidthHeight(200, 100); // Give myBox a width of 200, height 100

The two can be combined with the setPosition method:

   myBox.setPosition(10, 10, 200, 100); // Put myBox in x=10, y=10, with a width of 200, height 100

Helper methods

The class drawable has helper methods that can assist in setting up drawables:

API reference for the Drawable class

Expanding

The Drawable::expand() method makes a Widget (a Drawable) the same size as its parent. You can set a margin. The Widget is put in the upper left corner (plus margin):

   myBox.expand(10); // Put myBox in x=10, y=10, same size as parent except for margin of 10 pix

Centering

The Drawable::centerX()), Drawable::centerY()), Drawable::center() methods centers a Widget inside its parent (horizontally, vertically, and both):

   myBox.centerX(); // Center myBox horizontally in its parent

Invalidation

When you change the size of a Widget you must invalidate the parts of the screen that needs to be redrawn. If you are making a widget bigger, you can just invalidate the new size. If you are making a Widget smaller, you should invalidate it before changing the size:

   // Expand the Box, invalidate after to get the new size redrawn
myBox.expand(10);
myBox.invalidate();
...
// Reduce the Box to small size, invalidate before, to get background redrawn
myBox.invalidate();
myBox.myBox.setPosition(10, 10, 200, 100);

Remember that when you invalidate a Widget, the area on the screen that is occupied by the Widget (at that time) is redrawn in the next draw phase. This means if you invalidate a Widget, and then make it smaller, the parts of other widgets (behind) that are now visible, will be redrawn, not only the Widget that you invalidate.

Moving

The Drawable class has a method Drawable::moveRelative(int16_t x, int16_t y) to move a Widget on the screen from one position to another. This can be used as part of an animation or just to rearrange parts of the user interface.

Drawable::moveRelative(int16_t x, int16_t y) calls invalidate, so we don't have to do that:

    myBox.moveRelative(1, 0); // Move 1 pixel to the right

Another method is Drawable::moveTo(int16_t x, int16_t y) which moves the Widget to the specified position:

    myBox.moveTo(100, 100); // Move to 100, 100 from current position

This method also calls invalidate.