How to Show Alert Messages

Does Garmin have technique envisioned for how to show pop up alert message strings?

I'm thinking of alerts like on by 310. When I press start, it pops up "Timer Started" for about 2 seconds on top of whatever view I'm in. When there is a heart rate alert, it pops up "Heart Rate Too High". The heart rate alert will even pop up if I'm inside a menu.

Does Garmin intend to offer a widget for this when the audible and vibrate alerts are added or is this a feature that needs to be coded up on our own?
  • This is pretty simple to implement. Obviously it doesn't handle vibration or tones, but that would be pretty easy to add once the necessary API support is added.

    using Toybox.Graphics as Gfx;
    using Toybox.WatchUi as Ui;
    using Toybox.Timer as Timer;

    class Delegate extends Ui.InputDelegate
    {
    hidden var view;

    function initialize(view) {
    InputDelegate.initialize();
    self.view = view;
    }

    function onKey(evt) {
    view.dismiss();
    return true;
    }

    function onTap(evt) {
    view.dismiss();
    return true;
    }
    }

    class Alert extends Ui.View
    {
    hidden var timer;
    hidden var timeout;
    hidden var text;
    hidden var font;
    hidden var fgcolor;
    hidden var bgcolor;

    function initialize(params) {
    View.initialize();

    text = params.get(:text);
    if (text == null) {
    text = "Alert";
    }

    font = params.get(:font);
    if (font == null) {
    font = Gfx.FONT_MEDIUM;
    }

    fgcolor = params.get(:fgcolor);
    if (fgcolor == null) {
    fgcolor = Gfx.COLOR_BLACK;
    }

    bgcolor = params.get(:bgcolor);
    if (bgcolor == null) {
    bgcolor = Gfx.COLOR_WHITE;
    }

    timeout = params.get(:timeout);
    if (timeout == null) {
    timeout = 2000;
    }

    timer = new Timer.Timer();
    }

    function onShow() {
    timer.start(method(:dismiss), timeout, false);
    }

    function onHide() {
    timer.stop();
    }

    function onUpdate(dc) {
    var tWidth = dc.getTextWidthInPixels(text, font);
    var tHeight = dc.getFontHeight(font);

    var bWidth = tWidth + 14;
    var bHeight = tHeight + 14;

    var bX = (dc.getWidth() - bWidth) / 2;
    var bY = (dc.getHeight() - bHeight) / 2;

    dc.setColor(bgcolor, bgcolor);
    dc.fillRectangle(bX, bY, bWidth, bHeight);

    dc.setColor(fgcolor, bgcolor);
    for (var i = 0; i < 3; ++i) {
    bX += i;
    bY += i;
    bWidth -= (2 * i);
    bHeight -= (2 * i);

    dc.drawRectangle(bX, bY, bWidth, bHeight);
    }

    var tX = dc.getWidth() / 2;
    var tY = bY + bHeight / 2;

    dc.setColor(fgcolor, bgcolor);
    dc.drawText(tX, tY, font, text, Gfx.TEXT_JUSTIFY_CENTER | Gfx.TEXT_JUSTIFY_VCENTER);
    }

    function dismiss() {
    Ui.popView(SLIDE_IMMEDIATE);
    }

    function pushView(transition) {
    Ui.pushView(self, new Delegate(self), transition);
    }
    }


    To use it...

    function onSelect() {
    var alert = new Alert({
    :timeout => 2000,
    :font => Gfx.FONT_MEDIUM,
    :text => "onPreviousPage",
    :fgcolor => Gfx.COLOR_RED,
    :bgcolor => Gfx.COLOR_WHITE
    });

    alert.pushView(Ui.SLIDE_IMMEDIATE);

    return true;
    }
  • Hi Travis,

    Thanks for doing the work on this one!!!
  • Note. I've updated the onUpdate() function definition above. I had thought there was a bug with drawing text, but it was just a misunderstanding on my part. When drawing text, the y-coordinate provided is always the bottom of the text.
  • I was trying to implement Travis's code as a way to pop up an acknowledgement of a menu pick. Something like " High Alert Enabled" or "High Alert Disabled" for a toggling menu pick. I also wanted to return to the same menu level that was displayed prior to the menu pick so if it was 3 layers deep, you wouldn't need to navigate back down to enable the Low Alert.

    It seems that whenever a new view is pushed while a menu is displayed, it automatically executes a menu selection. Any pushView or switchView seems to cause the issue.

    If you create a new project in Eclipse called MenuAcknowledge and then edit the default MenuDelegate like is shown below and insert a file with Travis's Alert code, you will see that it executes the Menu 1 pick automatically after you manually pick Item 2. If you put the extra code in the Item 1 execution, you will get an infinite loop.

    Is this supposed to work this way or is this a bug? Is there something I'm supposed to do to to reset the menuDelegate in this case?

    using Toybox.WatchUi as Ui;
    using Toybox.System as Sys;
    using Toybox.Graphics as Gfx; //Need to add this too

    class MenuAcknowldgeMenuDelegate extends Ui.MenuInputDelegate {

    function onMenuItem(item) {
    if (item == :item_1) {
    Sys.println("item 1");


    } else if (item == :item_2) {
    Sys.println("item 2");

    // Insert Code from here.....
    // Repush the menu so the acknowledge message is on top of it and its ready for another pick
    Ui.pushView(new Rez.Menus.MainMenu(), new MenuAcknowldgeMenuDelegate(), Ui.SLIDE_UP);
    new Alert({
    :timeout => 2000,
    :font => Gfx.FONT_MEDIUM,
    :text => "Action 1 Sucessful",
    :fgcolor => Gfx.COLOR_RED,
    :bgcolor => Gfx.COLOR_WHITE
    });
    // .....to here

    }
    }
    }
  • I also wanted to return to the same menu level that was displayed prior to the menu pick so if it was 3 layers deep, you wouldn't need to navigate back down to enable the Low Alert.

    Menus have been reworked to allow submenus. This change will be in the next SDK release.

    Is this supposed to work this way or is this a bug? Is there something I'm supposed to do to to reset the menuDelegate in this case?

    This is a bug that I came across the other day as well. Thanks for the report, we'll get it fixed.
  • Former Member
    Former Member over 8 years ago
    Menus have been reworked to allow submenus. This change will be in the next SDK release.


    This is a bug that I came across the other day as well. Thanks for the report, we'll get it fixed.




    Hi,
    I'm not sure if this is still a bug or not, and not really understand the step for showing the alert, but I have tryied the travis code, and this didn't work for me ...
    do we need only to do :
    new Alert({
    :timeout => 2000,
    :font => Gfx.FONT_MEDIUM,
    :text => "Quick Brown Fox",
    :fgcolor => Gfx.COLOR_RED,
    :bgcolor => Gfx.COLOR_WHITE
    });


    ??
  • Hey TIBLAM,

    I don't think there is a bug here anymore as the menu system has been updated since then. If I understand your question correctly, then you are just trying to use the the code from "new Alert". To use that code you would need to build the class so that it can be utilized.

    -Coleman
  • Former Member
    Former Member over 8 years ago
    Yes, I build the class, and I call it (not from a menu, but in a method that contains an mSession.addLap() ) , and it makes nothing.

    I'm surprised by the way to use it. I was awaiting a thing like

    var alertView = new Alert({
    :timeout => 2000,
    :font => Gfx.FONT_MEDIUM,
    :text => "Quick Brown Fox",
    :fgcolor => Gfx.COLOR_RED,
    :bgcolor => Gfx.COLOR_WHITE
    });
    pushView (alertView, some delegate but which one as Alert contains his proper delegate, Ui.Slide_right) ;



    I just put :

    new Alert({
    :timeout => 2000,
    :font => Gfx.FONT_MEDIUM,
    :text => "Quick Brown Fox",
    :fgcolor => Gfx.COLOR_RED,
    :bgcolor => Gfx.COLOR_WHITE
    });


    and nothing appears, but it seems to be the good implementation, because this is how MoxyRoger has implemented it.
  • I don't know if this code works or not, but it should. You don't need to explicitly push the view because the Alert class pushes itself and a delegate in Alert.initialize().