Ticket Created
over 4 years ago

WERETECH - 10551

Custom Menu renders differently in Simulator and Real Device on touch screen devices

Custom Menu from Menu2 subsystem renders differently in Simulator and on Real Device when targeting touchscreen-based devices (tested on Vivoactive 3 and Venu Sq).

When on Simulator, extra 2 pixels added in between all menu items, including Title and Footer (see simulator screenshots and device photos in "screenshots" folder of project archive).

Notice double lines separating menu items in simulator, and single line when the same app run on device.

Note that issue get kind of masked when CustomMenu background color is set to the same color as divider lines, for example when divider lines drawn in black, and CustomMenu background color set to black, too - lines just appear a bit thicker.

This does not happen for devices with no touch screen (tested in simulator on Fenix 5x and Fenix 6x Pro).

We created simple test project that demonstrates this bug (source code in ZIP file provided for your convenience). Custom menu item draws 1-pixel divider line at the top and at the bottom of dc, and it is expected that these lines appear with no extra spacing when two consequent menu items are rendered. It works exactly as expected on real devices, and does not in simulator.

You can find relevant part of CustomMenu-related code at the end of this message.

Test project and screenshots in ZIP archive:

https://mega.nz/file/UoohWILa#DHCJ84qheUtFd78a2Cl7xGHAllNrgR4H4-OjqdY9efs

--- Related test code below:

using Toybox.WatchUi;
using Toybox.Graphics;
using Toybox.System;

function pushTestCustomMenu() {
    var devSettings = System.getDeviceSettings();
    var customMenu = new TestCustomMenu(devSettings.screenHeight/4, Graphics.COLOR_WHITE, {});
    customMenu.addItem(new TestCustomMenuItem(:item1, "Item 1"));
    customMenu.addItem(new TestCustomMenuItem(:item2, "Item 2"));
    customMenu.addItem(new TestCustomMenuItem(:item3, "Item 3"));
    customMenu.addItem(new TestCustomMenuItem(:item4, "Item 4"));
    customMenu.addItem(new TestCustomMenuItem(:item5, "Item 5"));
    WatchUi.pushView(customMenu, new TestCustomMenuDelegate(), WatchUi.SLIDE_LEFT);
}

class TestCustomMenu extends WatchUi.CustomMenu {

    function initialize(itemHeight, backgroundColor, options) {
        WatchUi.CustomMenu.initialize(itemHeight, backgroundColor, options);
    }

    function drawTitle(dc) {
        dc.setColor(Graphics.COLOR_WHITE, Graphics.COLOR_BLACK);
        dc.clear();
        dc.drawText(dc.getWidth()/2, dc.getHeight()/2, Graphics.FONT_XTINY, "Custom Title", Graphics.TEXT_JUSTIFY_CENTER | Graphics.TEXT_JUSTIFY_VCENTER);
    }

    function drawFooter(dc) {
        dc.setColor(Graphics.COLOR_BLACK, Graphics.COLOR_WHITE);
        dc.clear();
        dc.setPenWidth(1);
        dc.drawLine(0, 0, dc.getWidth(), 0);
    }
}

class TestCustomMenuItem extends WatchUi.CustomMenuItem {
    var label;

    function initialize(identifier, _label) {
        CustomMenuItem.initialize(identifier, {});
        label = _label;
    }

    function draw(dc) {
        dc.setColor(Graphics.COLOR_BLACK, Graphics.COLOR_WHITE);
        dc.clear();
        dc.drawText(dc.getWidth()/2, dc.getHeight()/2, Graphics.FONT_XTINY, label, Graphics.TEXT_JUSTIFY_CENTER | Graphics.TEXT_JUSTIFY_VCENTER);
        dc.setPenWidth(1);
        dc.drawLine(0, 0, dc.getWidth(), 0);
        dc.drawLine(0, dc.getHeight() - 1, dc.getWidth(), dc.getHeight() - 1);
    }
}

class TestCustomMenuDelegate extends WatchUi.Menu2InputDelegate {
    function initialize() {
        Menu2InputDelegate.initialize();
    }

    function onBack() {
        WatchUi.popView(WatchUi.SLIDE_RIGHT);
    }

    function onWrap(key) {
        return false;
    }
}