By dave | November 12, 2020

Taking over the display from a renderer

TcMenu allows you to take over the display from the renderer very easily, once you own the display, you will be called back at regular intervals by the rendering class, and it is your responsibility to update the display at this time (if there are changes that require redrawing). You should never update the screen outside of these callbacks, as doing so would interfere with TcMenu rendering.

There are two choices in this case, a functional approach based on providing a callback function, or an object oriented approach, where you provide an extension of CustomDrawing to the renderer. Below we discuss both.

Functional approach to take over display

To use a regular function callback to take over the display:


In this case you must provide a method with the following signature:

// This will be called frequently by the renderer class
// here we give control back when the button is clicked.
void myDisplayCallback(unsigned int encoderValue, RenderPressMode clicked) {
    // At this point clicked is the status of the select button
    // encoderValue is the current value of the rotary encoder

Once you own the display, the provided function will be called frequently by the renderer, you can check if anything needs drawing, and if so draw it at this point. You also have the current value of the rotary encoder available to you in encoderValue, along with the state of the encoder switch in clicked which is one of the values listed in the comment above.

When conditions change such that you no longer need display control:


Functional approach to capturing display timeout / reset

You can also add a callback function that will be informed when the menu is reset after timing out, by default this happens after 30 seconds of inactivity. This is useful if you don’t want to display the menu all the time. First define the function:

// this function will be called when the menu becomes inactive.
void onMenuBeingReset() {
    // for example in here we could take over the display when the
    // menu is inactive.

Then add the function as the callback:


If you want to change the threshold for becoming inactive:


Or even turn off the reset / inactivity support altogether:


The original purpose of the reset / inactivity support was for complex menus, where if the user left the system deeply nested several menus down, after a timeout it would return to the root of the structure ready for the next user.

Object oriented approach to display management

If we extend the class CustomDrawing and provide that instance to the renderer, then we can both handle taking over the display and reset events at the same time. See custom drawing class in reference docs. Here we present a simple way to extend it.

class MyCustomDrawing : public CustomDrawing {
    virtual ~CustomDrawing() = default;

    void reset() override {
        // if we get here the display has been reset because
        // of a timeout of the user interface for example to
        // take over the display

    void started(BaseMenuRenderer* currentRenderer) override {
        // take over display has just been called, and we
        // now need to do any initial activity
        // for example here we may clear the display and 
        // print the title
        lcd.print("Super Device");

    void renderLoop(unsigned int currentValue, RenderPressMode userClick) override {
        // At this point clicked is the status of the select button
        // encoderValue is the current value of the rotary encoder
        // for example to exit when the user clicks
        if(userClick) renderer.giveBackDisplay();
        // for example to update a menu based on current value of the encoder.
        // don't forget you could call changePrecision in started(..) 
} myDrawingClass;

Once we’ve created an instance of the class (always at global scope), then we can pass this reference to the renderer as follows:


Then to take over the display, use the no parameter version of the method:


Setting the speed of rendering

You can adjust the number of update cycles per second by calling setUpdatesPerSecond on the renderer, it takes place immediately, even if already started.

Other pages within this category

comments powered by Disqus

This site uses cookies to analyse traffic, serve ads by Google AdSense (non-personalized in EEA/UK), and to record consent. We also embed Twitter, Youtube and Disqus content on some pages, these companies have their own privacy policies.

Our privacy policy applies to all pages on our site

Should you need further guidance on how to proceed: External link for information about cookie management.

Send a message

Please use the forum for help with UI & libraries.

This message will be securely transmitted to our servers.