Menu2 question

Hi, 

In menu2inputdelegate there is an onselect method. But this only triggers code if someone really selects that menuitem.

I am looking for a way to put code behind the event that a menuitem is shown on screen for the 1st time... 

Is there a way to do that? 

(Use Case: I am author of the garmoticz plugin which is basically a frontend for domoticz. So the menu should show all devices and if the device is shown in the menu i'd like it to refresh te status, but only for that specific device to prevent too many url calls)

  • ah, misunderstood... that makes sense.

    So you're stuck using the CustomMenuItem class, and you're trying to figure out what the "regular" MenuItem height is for all devices so you can recreate the same look of a Menu2 object?

    Unfortunately, it looks like another API gap for this use case... but for what it's worth, my fr965 shows 3 full MenuItems and about a half of an item up top and a half of an item at the bottom while I scroll through my Menu2 view, so we could call it roughly 4 items being shown on the screen at a time.

    for your initial build/testing, maybe you could set your item heights to dc.getHeight()/4, and then pick an appropriate font based on the screen size. Smaller font for smaller screens, etc. I'm not sure if you'll be able to get the actual height of the MenuItem class for all devices via the API.

    the only other thing I can think of is if you scrape the device reference guide, and maybe steal the heights from the "Data Field" section of each device... I don't know if there is any correlation between Menu2's and Data Field layouts; they're obviously completely different concepts, but it might give the user a similar vibe based on their device? You might be stuck just giving the users a well-designed CustomMenu and not worry too much about making it look like exactly like a native Menu2.

    developer.garmin.com/.../

  • the only other "interesting" thing I have found is this page in the "User Experience Guidelines" section for the Fenix 2022 series, which incorporates some of the newer watch models like the Epix gen 2, Fenix 7, and some forerunner devices... I don't see any new guidelines for the newest devices in 2023 tho.

    https://developer.garmin.com/connect-iq/user-experience-guidelines/fenix-2022/ 

    In that link there are a couple images related to menu design guidelines, but unfortunately, I don't see any height dimensions there either. I wonder if someone from Garmin could pipe in and just give you the absolute height in pixels of a MenuItem for each device. Otherwise, I would just do your best and calculate the height yourself so either 3 or 4 items are  displayed at a time while you scroll.

    I agree that having an onItemSelected callback would be a nice feature to add to the Menu2 object.

  • Tx for thinking along with me...

    about

    "You might be stuck just giving the users a well-designed CustomMenu and not worry too much about making it look exactly like a native Menu2."

    I am not worried about it not looking exactly like a native menu2 menu.

    Issue is that at least on a 265, the device itselfs adds a very nice light blue bar in the background of the current item in the menu. Which looks visually very nice. But you can't switch it off and if you use another height than the default height of a menu item then this blue bar in the background no longer aligns with menuitem and then it looks very ugly.

    about " I would just do your best and calculate the height yourself so either 3 or 4 items are  displayed at a time while you scroll.":

    I've found out on the 265 the correct height is 139. (on a screen of 416x416). So dividing the max getheight by 3 or 4 won't work.  If the height only differs 1 or 2 pixels, the menu already becomse ugly. It should really align with the blue bar in the background on devices like 265. 

    I think i'm gonna file a bug report. cause now i'm thinking about it: If you have CustomMenuItem, it doesn'n make sense that blue selection bar on these amoled devices has a different height than the menuitem height you select in the custom menu... Basically this makes the CustomMenuItem unusable on the 265. (and i just tested: 965 and 265s look just as ugly...)

  • It think you should be able to find the correct menu height for each device if you look into the simulator.json

  • Where can I find that file?

  • see, I knew someone smarter with more experience would pipe in lol... I did not know about the blue bar feature... I feel like those should be off by default in a CustomMenu... it almost feels like a Menu2 design feature that bled into the CustomMenu object by accident... Anyway, on my Windows 10 machine, I was able to find those files, per device, in the following folder:

    %USER%\AppData\Roaming\Garmin\ConnectIQ\Devices\DEVICE_NAME\simulator.json

    where DEVICE_NAME is a directory for each device you have downloaded the sdk for.

    I have not checked what's in the files yet, but wanted to get the info over to you.

  • in the epix2 simulator.json, I see the following:

    "menu2": {
                    "customTitle": {
                        "height": 70,
                        "width": 178,
                        "x": 120,
                        "y": 21
                    },
                    "doneButtons": {
                        "bottom": true,
                        "top": true
                    },
                    "focusArrowPoints": [
                        {
                            "x": 25,
                            "y": 0
                        },
                        {
                            "x": 29,
                            "y": 0
                        },
                        {
                            "x": 29,
                            "y": 91
                        },
                        {
                            "x": 25,
                            "y": 91
                        },
                        {
                            "x": 25,
                            "y": 0
                        }
                    ],
                    "items": {
                        "checks": [
                            {
                                "alignment": "left",
                                "disabledIconFile": "menu2_check_off.png",
                                "enabledIconFile": "menu2_check_on.png",
                                "x": 0,
                                "y": 40
                            },
                            {
                                "alignment": "right",
                                "disabledIconFile": "menu2_check_off.png",
                                "enabledIconFile": "menu2_check_on.png",
                                "x": 282,
                                "y": 40
                            }
                        ],
                        "divider": 0,
                        "icons": {
                            "check": "left",
                            "icon": "left",
                            "leftLocation": {
                                "height": 80,
                                "width": 60,
                                "x": 0,
                                "y": 29
                            },
                            "rightLocation": {
                                "height": 80,
                                "width": 60,
                                "x": 282,
                                "y": 29
                            },
                            "toggle": "right"
                        },
                        "item": {
                            "height": 131,
                            "labelFont": "small",
                            "subLabelFont": "tiny",
                            "width": 380,
                            "xOffset": 36,
                            "xOffsetItem": 36
                        },
                        "region": {
                            "height": 131,
                            "width": 343,
                            "x": 0,
                            "y": 0
                        },
                        "stringWidths": {
                            "basic": 343,
                            "check": 200,
                            "icon": 200,
                            "toggle": 315
                        },
                        "toggles": [
                            {
                                "alignment": "left",
                                "disabledIconFile": "dtoggle_off.png",
                                "enabledIconFile": "dtoggle_on.png",
                                "x": 0,
                                "y": 27
                            },
                            {
                                "alignment": "right",
                                "disabledIconFile": "dtoggle_off.png",
                                "enabledIconFile": "dtoggle_on.png",
                                "x": 325,
                                "y": 27
                            }
                        ]
                    },
                    "mode": "touchButton",
                    "title": {
                        "height": 131,
                        "width": 416,
                        "x": 0,
                        "y": 0
                    },
                    "titleString": {
                        "font": "tiny",
                        "width": 295,
                        "x": 208,
                        "y": 62
                    }
                }

    I guess you could search for menu2 and find the nested "item" field for each device... I think that looks pretty accurate, for epix2 it's 131 (line 69 of the code snippet)

    EDIT: I just searched the fr265 device, and it looks like the height is 100... which doesn't match what you found on your device of 139.

  • I tried to poke around the json file and see if there might be any paddings anywhere that would add up to the 139 number you got through trial and error, but I'm coming up short... have you been able to test on the actual fr265 device, or are you still working in the simulator? I know I've seen jim mention over and over that the simulator doesn't always replicate the real devices 100%, so I'm curious if these heights are off in the simulator json vs the real devices.. or if the MenuItem auto sizes itself if you add a subLabel to it?

    there's an nLists_Blue.png file in that directory which looks like this, is that what you're seeing in the CustomMenu?


    have you tried explicitly passing in :theme=>null as part of your options Dictionary when you initialize your CustomMenu? I wonder if at the very least you could turn it off...
    https://developer.garmin.com/connect-iq/api-docs/Toybox/WatchUi/CustomMenu.html#initialize-instance_function

    initialize(itemHeight as Lang.Number, backgroundColor as Graphics.ColorType, options as { :focus as Lang.Number, :focusItemHeight as Lang.Number or Null, :title as WatchUi.Drawable, :footer as WatchUi.Drawable, :foreground as WatchUi.Drawable, :icon as Graphics.BitmapType or WatchUi.Drawable or Lang.Symbol, :titleItemHeight as Lang.Number or Null, :footerItemHeight as Lang.Number or Null, :theme as WatchUi.MenuTheme or Null } or Null)
    
    Parameters:
    
    itemHeight — (Lang.Number) — The pixel height of menu items rendered by this menu.
    backgroundColor — (Lang.Number) — The color that will be used to fill the background of the menu.
    options — (Lang.Dictionary) — A Dictionary of options. Can be null
    :focus — (Lang.Number) — The index of the CheckboxMenuItem that should have initial focus. (optional)
    :focusItemHeight — (Lang.Number) — The pixel height of the center menu item of this menu. This option is ignored on products with touch screens. (optional)
    :title — (WatchUi.Drawable) — A Drawable that will render the title area. (optional)
    :footer — (WatchUi.Drawable) — A Drawable that will render the area after the final item in the menu.(optional)
    :foreground — (WatchUi.Drawable) — A Drawable to render on top of menu items. (optional)
    :titleItemHeight — (Lang.Number) — The pixel height of the header menu item of this menu (optional)
    :footerItemHeight — (Lang.Number) — The pixel height of the footer menu item of this menu. (optional)
    :icon — (Graphics.BitmapType, WatchUi.Drawable, Lang.Symbol) — the default icon for the menu incase menuitem do not have it populated
    :theme — (Lang.Number) — The menu theme, or null for no theme. Defaults to MENU_THEME_DEFAULT.

  • I calculated the 139 on the simulator

    and indeed that blue box is what I see on all menu’s on the 265… 

  • Note that in the past I've found some bugs in some of the simulator.json files, so if something doesn't look good then try to check it on other device, to see first thst you're indeed looking at the right data, then if it is the right data and it doesn't match in one device but does on other devices then it's probably a bug in the json.