By dave | September 12, 2019

Rendering with TcMenu to TFT, LCD and OLED

TcMenu supports a wide range of rendering devices, from HD44780 based units using our LiquidCrystal fork through to mono OLED’s and full colour TFT displays using the Adafruit_GFX library.

In order to achieve such a wide range of displays the renderer describes things in terms of menu items, active positions, editors and dialogs. This allows each renderer to convert these concepts into something that works for it’s needs.

You can also easily take over the display to draw your own screen at any time. This is such a large subject, it deserves a page of its own.

Common functions on most renderers

Type: BaseMenuRenderer in BaseRenderers.h

Most renderers are based on the same base class, and have common functionality.

See the reference documentation for base renderer

Presenting a dialog to the user

Type: BaseDialog in BaseDialog.h

It is also possible to present a simple dialog for either information, or Yes / No question onto almost all supported displays. Along with this you can optionally decide to let the dialog show on any remote connections, taking over the top of the display similar to an Alert Box.

Firstly, if we are interested in the outcome of the dialog, we must give the dialog a function to call us back upon when complete:

// this method is called when the dialog is dismissed.
void onDialogFinished(ButtonType btnPressed, void* /*userdata*/) {        
    if(btnPressed != BTNTYPE_OK) {
        // do something if OK was pressed.

Next we get hold of the dialog and initialise it. Here we choose a dialog with OK and CANCEL as options:

    BaseDialog* dlg = renderer.getDialog();
    dlg->setButtons(BTNTYPE_OK, BTNTYPE_CANCEL, 1);

Now we call the show method to make the dialog take over the screen

    dlg->show(pgmHeaderText, remoteAllowed, onDialogFinished); // true = shows on remote sessions.
  • pgmHeaderText is the header text for the dialog
  • remoteAllowed true if should appear on all remote controls
  • onDialogFinished an optional callback when a button is pressed to dismiss the dialog

Lastly we can copy some text into the second line of the dialog (not program memory):


TitleWidget for presenting state in icon form

For all displays including LiquidCrystal we support the concept of title widgets. Title widgets allow a small icon to be presented in the title area that can have a number of states. A non exhaustive list of examples of this:

  • Wifi signal strength indicator (see the esp8266 example).
  • Current Connection status icon (see many of the examples).
  • Power or battery indicator.

Here’s an example OLED display showing two widgets:

OLED display showing tcMenu with title widgets

Screen shot of menu showing title widgets - upper right

Each TitleWidget has an array of icons that represent the states. Each icon should first be defined:

const uint8_t iconData1[] PROGMEM = { 0, 0, 0 etc };
const uint8_t iconData2[] PROGMEM = { 0, 0, 0 etc };

Following this, we then define the array of icons:

const uint8_t* const iconsData[] PROGMEM = { iconData1, iconData2 };

Lastly we then define a TitleWidget that represents this icon state:

TitleWidget iconsWidget(iconsData, numOfIcons, width, height [, &optionalNextWidget]);

The optionalNextWidget is a pointer to the next widget, if you only have one you don’t provide it.

Now we set the first widget as follows:


To change the state of a widget, simply call it’s setter method:


Default icon sets

There are default icons for both WiFi strength and connection state included that work for a wide range of displays.

Icons for low resolution displays such as Nokia 5110:

#include "stockIcons/wifiAndConnectionIcons8x7.h"

Icons for higher resolution displays such as TFT and OLED:

#include "stockIcons/wifiAndConnectionIcons16x10.h"

Icons for 5x8 LiquidCrystal / HD44780 displays:

#include "stockIcons/wifiAndConnectionIconsLCD.h"

In each file there are two icon sets defined.

// a set of wifi icons, 0 is not connected, 1..4 are low to high strength
const uint8_t* const iconsWifi[] PROGMEM = { iconWifiNotConnected, iconWifiLowSignal, iconWifiMedSignal, iconWifiStrongSignal, iconWifiBestSignal };

// a boolean not connected (0) or connected (1) icon    
const uint8_t* const iconsConnection[] PROGMEM = { iconDisconnected, iconConnected };

Display configuration for bitmapped displays (AdaGfx and U8G2)

We can set the font, color, and spacing around items on a bitmap display by adjusting the configuration. All bitmapped displays based on Adafruit_GFX and U8G2 require a graphics configuration. The menu designer will attempt to add sensible defaults for you, but in many cases, you’ll need to tweak these settings to get the best results.

For Adafruit_GFX based displays the configuration type is AdaColorGfxMenuConfig and fonts are of type GFXfont*. There are many fonts provided with the library, and you can use any of those or create one. You can also set the text magnification.

For U8G2 based displays the configuration type is U8g2GfxMenuConfig and fonts are of type const uint8_t*. Again there are many provided fonts with the library that you can use. There is no text magnification with u8g2 so it should always be 1.

For Adafruit graphics colours are defined as 16 bit, and we have an RGB(r, g, b) macro that can be used. Where values are between 0 and 255. BLACK and WHITE are always defined.

Padding structures can be easily defined using this function:

makePadding(MenuPadding& padding, int top, int right, int bottom, int left)

These are the fields that are available in the configuration structure.:

template<typename FONTPTR> struct ColorGfxMenuConfig {
    uint32_t bgTitleColor;
    uint32_t fgTitleColor;
    MenuPadding titlePadding;
    FONTPTR titleFont;

    uint32_t bgItemColor;
    uint32_t fgItemColor;
    MenuPadding itemPadding;
    FONTPTR itemFont;

    uint32_t bgSelectColor;
    uint32_t fgSelectColor;
    uint32_t widgetColor;
    MenuPadding widgetPadding;

    const uint8_t* activeIcon;
    const uint8_t* editIcon;
    uint8_t editIconWidth;
    uint8_t editIconHeight;
    uint8_t titleBottomMargin;
    uint8_t titleFontMagnification;
    uint8_t itemFontMagnification;

To override the graphics configuration there are two options, you can either completely define your own structure, or you can adjust a few values on the existing one that the designer provides:

Create your own graphics config from scratch

  • In your sketch create a variable of the appropriate type for your display.
  • Ensure the setup of the config is BEFORE calling setupMenu() during initialisation.
  • Fully populate the fields - this is imperative as it’s a struct type.
  • The fonts can be NULL as can the activeIcon and editIcon. This implies the default values.
  • In the designer’s code generator window, put the name of the config variable into the CONFIG property.
  • See the examples for more on how to override configuration.

Modify designer provided graphics config

In this case, leave the graphics config variable blank in the code generator dialog, this means that the config will be provided by the designer. For all Adafruit and U8g2 options the designer will create a config variable called gfxConfig.

Knowing this, you can modify any values on this configuration directly after the setupMenu() initialisation call, otherwise they would be overwritten. For example to change the background color to red and adjust title padding:

void setup() {
    // other setup
    gfxConfig.bgItemColor = RGB(255, 0, 0);
    makePadding(gfxConfig.titlePadding, 5, 5, 5, 5);

Back to tcMenu main page

Other pages within this category

comments powered by Disqus

We use cookies to analyse traffic and to personalise content. We also embed Twitter, Youtube and Disqus content on some pages, these companies have their own privacy policies.

Please see our privacy policy should you need more information or wish to adjust your settings.

Send a message

This message will be securely transmitted to Nutricherry LTD servers.