I have recently written an app which uses a Menu2 CustomMenu and during development found many bugs which I had to work around.
The bugs differ across devices / device families and in the sim.
The following short piece of code can be used to demonstrate many of these bugs:
import Toybox.Lang; import Toybox.WatchUi; import Toybox.Graphics; var menu; var number = true; class CMenuInitFocusDelegate extends WatchUi.BehaviorDelegate { function initialize() { BehaviorDelegate.initialize(); } function onMenu() as Boolean { // $.dch is a global set to the watch dc height. menu = new WatchUi.CustomMenu($.dch/6, 0xAAAAAA, { :focus => 8}); menu.addItem(new CMI(:x, "zero")); menu.addItem(new CMI(:x, "one")); menu.addItem(new CMI(:x, "two")); menu.addItem(new CMI(:x, "three")); menu.addItem(new CMI(:x, "four")); menu.addItem(new CMI(:x, "five")); menu.addItem(new CMI(:x, "six")); menu.addItem(new CMI(:x, "seven")); menu.addItem(new CMI(:x, "eight")); menu.addItem(new CMI(:x, "nine")); menu.addItem(new CMI(:x, "ten")); menu.addItem(new CMI(:x, "eleven")); menu.addItem(new CMI(:x, "twelve")); WatchUi.pushView(menu, new CMD(), WatchUi.SLIDE_UP); return true; } } class CMI extends WatchUi.CustomMenuItem { var _label; function initialize(id, label) { CustomMenuItem.initialize(id, {}); _label = label; } function draw(dc) { dc.setColor(0, 0); dc.clear(); if (isFocused()) { dc.setColor(0xff0000,0); } else { dc.setColor(0xffffff,0); } dc.drawText(dc.getWidth()/2, dc.getHeight()/2, Graphics.FONT_XTINY, _label, Graphics.TEXT_JUSTIFY_CENTER | Graphics.TEXT_JUSTIFY_VCENTER); } } class CMD extends WatchUi.Menu2InputDelegate { function initialize() { Menu2InputDelegate.initialize(); } function onSelect(item) { var d; do { d = $.menu.deleteItem(0); } while (d == true); if ($.number) { menu.addItem(new CMI(:x, "0")); menu.addItem(new CMI(:x, "1")); menu.addItem(new CMI(:x, "2")); menu.addItem(new CMI(:x, "3")); menu.addItem(new CMI(:x, "4")); menu.addItem(new CMI(:x, "5")); menu.addItem(new CMI(:x, "6")); menu.addItem(new CMI(:x, "7")); menu.addItem(new CMI(:x, "8")); menu.setFocus(3); $.number = false; } else { menu.addItem(new CMI(:x, "zero")); menu.addItem(new CMI(:x, "one")); menu.addItem(new CMI(:x, "two")); menu.addItem(new CMI(:x, "three")); menu.addItem(new CMI(:x, "four")); menu.addItem(new CMI(:x, "five")); menu.addItem(new CMI(:x, "six")); menu.addItem(new CMI(:x, "seven")); menu.addItem(new CMI(:x, "eight")); menu.addItem(new CMI(:x, "nine")); menu.addItem(new CMI(:x, "ten")); menu.addItem(new CMI(:x, "eleven")); menu.addItem(new CMI(:x, "twelve")); $.number = true; menu.setFocus(6); } System.println("onSelect " + $.number); WatchUi.requestUpdate(); // Only seems to be needed on vivo/venu } }
Here are the main bugs that this code can be used to re-produce:
- On vivoactive and venu watches, the focus is off by one when calling setFocus() or setting the initial focus with :focus in the options. So, with the code above which sets the focus to 8, the focus actually goes to the 7th menu item. And rather than focus going to 3rd and 6th item, it goes to 2nd and 5th.
- In the sim, for vivoactive and venu devices neither the initial focus or setFocus() appear to work. Nothing gets focussed, and the screen starts scrolled right off the top.
- On outdoor watches, e.g. fenix/epix, setFocus() does not work. It works in the sim for these watches.
- On touchscreen outdoor watches, tapping the title or footer causes the menu to scroll back to the last focussed item.
- The code above works on most real watches and swaps the menu each time a menu item is selected (taking into consideration the bugs mentioned above).
- On a va3, despite the requestUpdate() the menu is not re-drawn until you scroll, so you see the wrong menu. The requestUpdate does not seem needed at all on outdoor and forerunner watches, but is needed on others to get the menu re-drawn (maybe just in the sim).
- In the sim, the behaviour is mostly wrong and varies from device to device.
- It works on watches with buttons.
- On watches with buttons and touch screens it works when the buttons are used, but when the touchscreen is used to select a menu item, the menu is updated and the correct item is focussed, but the menu does not scroll at all so the focussed item may not be seen. And if you select an item at the bottom which is not on the other menu, the screen goes blank since the items which do exist are off the top of the screen. The correct item is focussed, even if you cannot see it due to not scrolling.
- On touchscreen watches such as vivo and venu, nothing gets focussed, although the menu scrolls in the same way as in b.
It appears that only forerunners handle this code correctly. All other devices I tried had one more more problems.