This worked!
Here’s the code, if anyone needs it:
My widget code looks like this:
struct LCDDisplay : TransparentWidget
{
MyModule *module;
LCDDisplay()
{
// LCD_DISPLAY_WIDTH and LCD_DISPLAY_HEIGHT are defined elsewhere
box.size = Vec(LCD_DISPLAY_WIDTH, LCD_DISPLAY_HEIGHT);
}
void draw(const DrawArgs &args) override
{
const auto vg = args.vg;
// Save the drawing context to restore later
nvgSave(vg);
if(module)
{
// Draw a rectangle that takes up the entire display for testing
nvgBeginPath(vg);
nvgRect(vg, 0, 0, LCD_DISPLAY_WIDTH, LCD_DISPLAY_HEIGHT);
nvgFillColor(vg, nvgRGBA(120, 20, 20, 100));
nvgFill(vg);
The LCDDisplay is added to my main module’s Widget like so:
LCDDisplay *lcd_display = new LCDDisplay();
lcd_display->module = module;
lcd_display->box.pos = mm2px(Vec(LCD_DISPLAY_X, LCD_DISPLAY_Y));
addChild(lcd_display);
So far, everything is pretty typical. Now I start to introduce the concept of an “engine”. There will only be one active engine. When an engine is active, it should be able to draw on the LCD screen. I created a base class called “Engine”:
struct Engine
{
virtual void LCDDraw(const Widget::DrawArgs &args) = 0;
};
Then I create engines that inherit from the Engine class. Here’s one example called “Foo”:
struct Foo : Engine
{
// Here I override the base class's LCDDraw function
void LCDDraw(const Widget::DrawArgs &args) override
{
const auto vg = args.vg;
// Here I would draw cool stuff.
// But for brevity sake, I'm just drawing another rectangle.
nvgBeginPath(vg);
nvgRect(vg, 0, 0, LCD_DISPLAY_WIDTH, LCD_DISPLAY_HEIGHT - 20);
nvgFillColor(vg, nvgRGBA(0, 20, 10, 100));
nvgFill(vg);
}
And finally, I have to call LCDDraw, which I do from within LCDDisplay::draw. (All of this code is repeated except for one additional line that I added at the end.)
struct LCDDisplay : TransparentWidget
{
MyModule *module;
LCDDisplay()
{
// LCD_DISPLAY_WIDTH and LCD_DISPLAY_HEIGHT are defined elsewhere
box.size = Vec(LCD_DISPLAY_WIDTH, LCD_DISPLAY_HEIGHT);
}
void draw(const DrawArgs &args) override
{
const auto vg = args.vg;
// Save the drawing context to restore later
nvgSave(vg);
if(module)
{
// Draw a rectangle that takes up the entire display for testing
nvgBeginPath(vg);
nvgRect(vg, 0, 0, LCD_DISPLAY_WIDTH, LCD_DISPLAY_HEIGHT);
nvgFillColor(vg, nvgRGBA(120, 20, 20, 100));
nvgFill(vg);
//
//
//
// Here is the new line of code...
module->selected_track->engine->LCDDraw(args);
//
//
//
//
Hope this is helpful!