supporting both physical button and touch input

I find it very hard to support "correct"/user friendly input for an app across different devices.

On example:

I made it work with behaviordelegate. As an example let's look at onSelect. Works fine on devices with physical select button.

But/and It also "works" on devices without select button. For example on edge devices (ee2) a touch of the screen generates onSelect. This could be OK, though I don't like it.

And on watches ie: fr965 that both are touch screen and have a physical select button it kind of works: either I click the button or when I touch the screen anywhere an onSelect event is generated.

However I'd like to be more user friendly and be able to know where the screen was tapped, and react accordingly. This could be achieved by disabling the onSelect (for example by removing the onSelect method using an annotation) and thus onTap will be called when the screen is touched, which is good, but when a user clicks the physical button then nothing happens.

Ideally I would hope that I could disable the translation of taps to onSelect from the code. Or onTap should be called before onSelect. But to my knowledge none of this is possible. Are they?

So the only way I can think of supporting "both" touch and physical buttons is by adding a stupid, unnecessary user setting where they can disable the physical buttons. When they chose this setting then onSelect would return false => onTap will be called.

Does anyone have a good solution for this?

  • I also agree. It would even be better if there was an official documentation about these things and we shouldn't need users who remember from 5 years ago how certain devices differ from the rest.

  • Supporting double clicks for vivoactive3 is not that hard in my case. 
    Known issues: after 25 days getTimer might cause funny things when it turns over.
    // vivoactice 3 has no lap/back button, it needs to be triggered by double click
    (:no_key_behavior_onback) const DOUBLE_CLICK_MS = 300;
    (:no_key_behavior_onback) private var lastClicked as Number = 0;
    (:no_key_behavior_onback) public function onTap(clickEvent as ClickEvent) as Boolean {
    log("onTap: " + isTouchDisabled + ", " + clickEvent.getType());
    var result = doAction(true);
    if (!result) {
    var now = System.getTimer();
    if (now <= lastClicked) {
    _view.onLap();
    return true;
    } else {
    lastClicked = now + DOUBLE_CLICK_MS;
    }
    }
    return result;
    }
    (:key_behavior_onback) public function onTap(clickEvent as ClickEvent) as Boolean {
    log("onTap: " + isTouchDisabled + ", " + clickEvent.getType());
    return doAction(true);
    }
     
    Supporting fr630 is a bit more complicated. I guess I could make 2 separate onKey functions with excludeAnnotations here too.
    (:no_key_id_lap) const HAS_LAP_KEY = false;
    (:key_id_lap) const HAS_LAP_KEY = true;
    public function onKey(keyEvent as KeyEvent) as Boolean {
    var key = keyEvent.getKey();
    log("onKey: " + key + ", " + keyEvent.getType());
    switch (key) {
    case KEY_ENTER:
    case KEY_START:
    // on devices that have ENTER key but it's not mapped to SELECT behavior (i.e: venusq, vivoactive3)
    return _view.onSelect();
    case KEY_LAP:
    // optimization: prepend "HAS_LAP_KEY &&" so it only compiles the call to onLap() when we can get here
    return HAS_LAP_KEY && _view.onLap();
    case KEY_ESC:
    if (HAS_LAP_KEY) {
    if (LOG) {
    log("KEY_ESC: LAP KEY exists in device");
    }
    // because this device has a LAP key, we don't want to interpret BACK as a LAP if timerActive
    return _view.hikerView.timerActive ? true : doAction(false);
    }
    }
    return doAction(false);
    }
    I have a feeling that once I'll give up on behaviors and only use InputDelegate things might get even easier (even though it might be a bit more complicated to get all the buttons for all the devices in onKey.
  • > Supporting double clicks for vivoactive3 is not that hard in my case. 

    Yeah I don't think any of this stuff is hard to implement, like I said toughest part is knowing or deciding what to do in the first place.

    It is kind of a pain imo. There really should be something like BEHAVIOR_LAP which abstracts this stuff for the CIQ dev, but that wouldn't work with the current design, since two separate behaviors would be triggered for a single key in many cases, and the framework has no way to indicate "combined" or simultaneous behaviors.

    > It would even be better if there was an official documentation about these things and we shouldn't need users who remember from 5 years ago how certain devices differ from the rest.

    Yeah I wish this stuff was in the CIQ documentation too.

    The sim doesn't even model this stuff properly. e.g. For vivoactive3, if you test with a data field:

    - clicking on the device button does start / stop the timer (but the activity control buttons on the activity data dialog are not appropriately updated as they would be if you pressed those buttons instead)

    - double tapping the screen does not take a lap

    Also, the sim doesn't show that vivoactive3 widgets cannot use the button (it actually shows the opposite, which is very misleading). In my case, I only found that out when a user of my app contacted me to say it doesn't work on Vivoactive 3. In hindsight I could've read the manual :/.

    I do think it's too bad that in order to effectively develop for CIQ, you can't just read the documentation and use the simulator. You also have to:

    - read the device manuals (at least the overview with the button functions)

    - try stuff on some of the real devices

    - read years of forum posts

    I don't like that a lot of knowledge is locked up in the forum or the heads of forum posters.

    A lot of these problems do go away if you just don't support the super old devices (which is seemingly what Garmin wants anyway). Vivoactive 3 is 8 years old, which is ancient in tech years. Even Garmin users tend to change their watch after 10 years or so.

    Just going back to an old Garmin watch I used 5 years ago is a painful experience as the UI is incredibly sluggish compared to a newer Garmin. I borrowed a vivoactive 3 from a friend and the touch experience is incredibly clunky (as is the UI/UX in general).

    For all of our complaining about Garmin, at least they have actually improved the user experience over the years.