embedded-menu icon indicating copy to clipboard operation
embedded-menu copied to clipboard

Color menu selection is not correctly redrawn on Rgb565 display.

Open kareled opened this issue 1 year ago • 4 comments

Hello, first of all, thank you very much for your crate. I'm trying to use it on hardware with rgb565 display. I'm using your examples for inspiration. I'm using theme support for color menu (not being able to get bicolor display working on the hardware), but I have strange issue with it. It looks like only selected menu item is constantly redrawn (which is correct and nice) but when movement happen, the code does not correctly redraw previous selection to the background/text colors but leaves it there. This creates an artifact of selection growing bigger and bigger how you move down thorough the menu items. The only solution for now for me is to insert display.clear(...) in between calls menu update and menu draw:

        menu.update(display);
        display.clear(Rgb565::WHITE);
        menu.draw(display).unwrap();

unfortunately due to machine and LCD speed, this creates kind of "flashing" menu and is not looking too nice. Any idea how to fix this behavior is highly appreciated!

kareled avatar Feb 10 '24 23:02 kareled

It looks like only selected menu item is constantly redrawn

Hello, I'm not sure I understand your problem. Currently, if you call menu.draw() everything should be redrawn. Your best bet, if you have the memory for it, is to render into a frame buffer first, and send the complete frame to the display in one go.

bugadani avatar Feb 11 '24 07:02 bugadani

I'm sorry for not being clear or mixing too much into one report. What I'd like to solve is best shown on the attached picture. If you go down with rectangular selectors it leaves its background color on the unselected menu items. On the picture "Value 3" item is currently selected. Theme is set as:

impl Theme for SetupTheme {
    type Color = Rgb565;

    fn text_color(&self) -> Self::Color {
        Rgb565::BLACK
    }

    fn selected_text_color(&self) -> Self::Color {
        Rgb565::WHITE
    }

    fn selection_color(&self) -> Self::Color {
        //Rgb565::CSS_LIGHT_BLUE
        Rgb565::RED
    }
}

and my question is how this happen or what's broken exactly here. I'm especially curious since the driver for underlaying LCD is written by me so is there any chance some required functionality is not implemented there yet and your code just hit it? Thanks!

menu_issue

kareled avatar Feb 12 '24 06:02 kareled

It looks like only selected menu item is constantly redrawn

[...] Currently, if you call menu.draw() everything should be redrawn. [...]

My claim above was completely wrong. Later testing shows that clearly. I'm sorry about this misleading remark.

kareled avatar Feb 12 '24 06:02 kareled

and my question is how this happen or what's broken exactly here.

embedded-menu only draws what it has to. Where you see white, or the unexpected red on your image, those pixels are generally not updated by the library. This issue should be even more visible is you have a longer menu that needs to scroll, and I think the visual result is similar to ghosting on ePaper displays. Clearing the whole screen is a good way to avoid the issue.

I'm not immediately sure what to do about the flashing. Your issue is a classic graphical rendering problem that is usually solved by double buffering (drawing into memory, not immediately to the display), and most of what I can think of would still result in flashing, just maybe in smaller areas on the display.

You should check if your LCD supports something helpful here. Either a hardware-accelerated way to clear the display, so you don't have to push out two frames for every one you want to draw, or see if it has some display memory and a way for you to hold off picture update until the UI is ready.

bugadani avatar Feb 12 '24 08:02 bugadani