Vertically Center Icon in IconMenuItem using Menu2

I am using IconMenuItem with a Menu2 class. I cannot get the icons to vertically center (and align to the text). Here is my code snippet:

***************************************************************************

rootMenuView = new WatchUi.Menu2({:title=>$.appName}); 

var myMenuIcon = new WatchUi.Bitmap({:rezId=>Rez.Drawables.menuSettings});

var mySyncIcon = new WatchUi.Bitmap({:rezId=>Rez.Drawables.menuSync});  

rootMenuView.addItem(new WatchUi.IconMenuItem("Settings","","settingsID", myMenuIcon, {:alignment=>WatchUi.MenuItem.MENU_ITEM_LABEL_ALIGN_LEFT}));

rootMenuView.addItem(new WatchUi.IconMenuItem("Sync","","syncID", mySyncIcon, {:alignment=> WatchUi.MenuItem.MENU_ITEM_LABEL_ALIGN_LEFT}));

*****************************************************************************

Icons are aligned to top of menu item while text is vertically centered. Testing on a Forerunner 965 (sim and device). Any help would be greatly appreciated. 

        

  • To close this thread out, using Monkey C code "out of the box" aligns the icon to the top (both in the simulator and on device). However, you can create a custom icon class that overrides this behavior and vertically centers the icon. If you take a screenshot and  measure pixels, the code does not perfectly vertically center, but is not noticeable in the UI. Garmin menus also have the same result (slightly skewed to the top) with their icons. I would not have noticed if I wasn't having this issue. I think the dc menuItem height is not returned accurately (likely the issue with large fonts).

    In case anyone cares, here is the code I use in my custom icon class which I pass to IconMenuItem as the icon parameter:

    class CustomIcon extends WatchUi.Drawable {
            // This constant data stores the color state list.
            private var iconColor;
            private var iconType;
            private var iconImage;

            function initialize(_iconColor, _iconType, _iconImage) {
                Drawable.initialize({});
                iconColor = _iconColor;
                iconType = _iconType;
                iconImage = _iconImage;
            }

            function draw(dc) {

                if (iconType.equals("image")) {
                    var icon = WatchUi.loadResource(iconImage);
                    var iconWidthHeight;

                    // Calculate Width Height of Icon based on drawing area
                    if (dc.getHeight() > dc.getWidth()) {
                        iconWidthHeight = iconMenuWidthPercent * dc.getHeight();
                    } else {
                        iconWidthHeight = iconMenuWidthPercent * dc.getWidth();
                    }
                   
                    dc.setColor(Graphics.COLOR_TRANSPARENT, Graphics.COLOR_TRANSPARENT);
                    //dc.drawBitmap(dc.getWidth() / 2 - (icon.getWidth() / 2), (dc.getHeight() / 2) - (icon.getHeight() / 2), icon);
                    var bitmapY = (dc.getHeight() / 2) - (iconWidthHeight / 2);
                    dc.drawScaledBitmap((dc.getWidth() / 2) - (iconWidthHeight / 2), bitmapY, iconWidthHeight, iconWidthHeight, icon);

                }
            }
        }

    *Code Notes:

    1.) I have a global variable => iconMenuWidthPercent that scales my icons to a percentage of the menu drawing area. I tried a few values and am using 60%. This is what looks best to me; no specific math formula for this.

    2.) My icons have height = width; in some cases there is padding if width or height of image does not match due to image having an oblong shape. The code would need to be adjusted if icon height <> icon width. Icons will be skewed otherwise. I may correct this in the future.

    3.) I am using an iconType parameter because I intend to extend to allow for drawing shapes in the future.

    Now, I need to figure out how to submit a bug to Garmin for Large Fonts. My eyes are old and would be nice to have the menu work with this option.

  • To close this thread out, using Monkey C code "out of the box" aligns the icon to the top (both in the simulator and on device). However, you can create a custom icon class that overrides this behavior and vertically centers the icon. If you take a screenshot and measure pixels, the code does not perfectly vertically center an icon (slightly skewed to the top) but is not noticeable in the UI. Garmin menus also have the same result with their icons. I would not have noticed if I wasn't having this issue. I think the dc menuItem height is not returned accurately (likely the issue with large fonts).

    I do prefer to use code vs XML, as I change menus dynamically in my application. This may be possible with XML but have not spent time to investigate, as I do this in my spare time.

    In case anyone cares, here is the code I use in my custom icon class which I pass to IconMenuItem as the icon parameter:

    class CustomIcon extends WatchUi.Drawable {
            // This constant data stores the color state list.
            private var iconColor;
            private var iconType;
            private var iconImage;

            function initialize(_iconColor, _iconType, _iconImage) {
                Drawable.initialize({});
                iconColor = _iconColor;
                iconType = _iconType;
                iconImage = _iconImage;
            }

            function draw(dc) {

                if (iconType.equals("image")) {
                    var icon = WatchUi.loadResource(iconImage);
                    var iconWidthHeight;

                    // Calculate Width Height of Icon based on drawing area
                    if (dc.getHeight() > dc.getWidth()) {
                        iconWidthHeight = iconMenuWidthPercent * dc.getHeight();
                    } else {
                        iconWidthHeight = iconMenuWidthPercent * dc.getWidth();
                    }
                   
                    dc.setColor(Graphics.COLOR_TRANSPARENT, Graphics.COLOR_TRANSPARENT);
                    //dc.drawBitmap(dc.getWidth() / 2 - (icon.getWidth() / 2), (dc.getHeight() / 2) - (icon.getHeight() / 2), icon);
                    var bitmapY = (dc.getHeight() / 2) - (iconWidthHeight / 2);
                    dc.drawScaledBitmap((dc.getWidth() / 2) - (iconWidthHeight / 2), bitmapY, iconWidthHeight, iconWidthHeight, icon);

                }
            }
        }

    *Code Notes:

    1.) I have a global variable => iconMenuWidthPercent that scales my icons to a percentage of the menu drawing area. I tried a few values and am using 60%. This is what looks best to me; no specific math formula for this.

    2.) My icons have height = width; in some cases there is padding if width or height of image does not match due to image having an oblong shape. The code would need to be adjusted if icon height <> icon width. Icons will be skewed otherwise. I may adjust the code to account for this in the future.

    3.) I am using an iconType parameter because I intend to extend to allow for drawing shapes in the future.

    Now, I need to figure out how to submit a bug to Garmin for Large Fonts. My eyes are old and would be nice to have the menu work with this option.

  • Now, I need to figure out how to submit a bug to Garmin for Large Fonts.

    Post in the Connect IQ > Connect IQ Bug Reports forum.

  • That for the bug for the alignment from code.

    If there's the same alignment issue for all (ciq code, city XML, native) when big fonts are enabled, then maybe also in the Garmin customer support fir fr965, but I see little chance it will reach the team who could fix it. Let's be honest, they probably have hundreds of bigger bugs

  • Why do you assume it’s also a problem for native menus?

    EDIT: my bad, tnorman33 did say that it’s a problem with native menus too. At least on my 955, it seems like much more of a problem with CIQ menus than native menus. I can easily notice the problem in CIQ, and I don’t think I’d notice the problem on native menus unless I took a screenshot and counted pixels. Maybe it’s 2 separate, yet related problems, one in native code and one in CIQ. And maybe the CIQ team can address the problem in their code even if the native problem can’t be addressed by them.

    if that was the case, I would’ve expected tnorman33 to say something in the OP like, “strangely enough, the icons in my watch’s native menus are also misaligned”. Doesn’t seem like the kind of thing that would escape one’s notice. But the OP is written as if this is only a problem they see in CIQ.

    You could also test that for yourself real quick by enabling large fonts on your device, if you were truly interested.

    I happen to think it’s more likely that it’s *not* a problem for native menus, otherwise Garmin would’ve noticed already and fixed it. Given that the global settings menu has icons, it would be very noticeable to testers and end users if the icons were misaligned.

    I tried to recreate this problem on my 955 and:

    - your app (Wordle) has the same icon misalignment problem with large fonts enabled (but it’s fine with large fonts disabled), same as what was observed for 965

    - system menus (like the global settings menu) are fine, with and without large fonts

    Ofc it’s not an apple-to-apples comparison, since 955 (MIP) and 965 (AMOLED) have somewhat different UIs. For example, my 955 only ever shows 3 menu items at once, both with and without large fonts. But 955 does have the problem with your CIQ app, and it doesn’t have the problem with native menus, which suggests that it’s at least possible that it’s a bug in CIQ.

    I see little chance it will reach the team who could fix it

    Idk, it’s a start. If it were me, I’d prefer to report the bug somewhere as opposed to assuming it won’t be fixed. I already assume that nothing I report will be fixed tbh, but that doesn’t stop me from reporting stuff. I guess that’s the definition of insanity.

    You know it’s funny that the longer any given poster has been on these forums, the more likely they are to either minimize bugs or tell people not to bother reporting them bc they won’t get fixed. I see this both in and out of the dev forums, and also in communities for other products. There’s a certain prolific poster here who used to report every CIQ bug when CIQ was new. They were enthusiastic about trying to get things fixed! It only took a couple of years for them to do a 180 and switch to a default mode of dismissing every single bug report as user error, not important (bc it doesn’t affect them), or probably won’t be fixed. If 1 person made a bug report or feature request, their response would be that nobody else has this problem or wants this feature. If many people made a bug report or feature request, their response to the latest poster would be that people have asked for this for years, so don’t expect it to happen now.

    I really don’t see the harm in reporting this to the CIQ team. In a perfect world, even if it’s not a problem with their stuff, they would be nice enough to forward the bug report to the right team, or at least to tell us the correct place to report the bug. Unless we as developers / users are expected not only to be beta testers but also to do the job of triaging bugs.

  •  - With Large Fonts disabled - if you take screenshots of the native menu's and zoom in to count pixels, the vertical spacing between the top and bottom of text is equal. The spacing between the top and bottom of icons (both my menu icons and Garmin's native menu icons is not equal.) There are more pixels between the bottom of the icon and menu bottom (assuming that is the highlighted area of the new forerunner menu design) the between the top of the icon and top of the menu. It would be very hard to observe this on non-Highlighted menu (like 955). I wouldn't have noticed this on the new highlighted menus if it wasn't for the original problem that caused me to look at this detail. I would consider that this was possibly by design (like a small descent padding) but I don't observe it with text in the menu. 

    Honestly, it was more of an observation than anything else. I would be fine if Garmin simply made large fonts work identical to how "non-Large" fonts work.

  • Fair enough. It’s possible that my 955 has the same issue with native menus, but it’s not as noticeable to me as in flocsy’s app. 

    It does sound like this problem is still more prominent in CIQ than it is in native menus, which might suggest that it could be fixed in CIQ even if it can’t be fixed in native code (at least by the CIQ team.)

    I think if the native menus looked as bad as the CIQ menus, when fonts are large, then the problem would've been noticed by now.

    Then again, flocsy is right that there's probably a lot of bugs that Garmin doesn't have time to look (and/or does not care about.)

    Either way, I would still report it.