behaviorDelegate and Vivoactive4

Hi all,

I surely miss something but don't find what...

I try to understand what function of a behaviorDelegate is called when I push the upper button of a vivoactive4. So I overload all functions of inputDelegate and behaviorDelegate and put a println.
But when I start the simulator and push the button : nothing in the log !!... Same for holding pressure on screen.

class APICallDelegate extends WatchUi.BehaviorDelegate {

    function initialize() {
        BehaviorDelegate.initialize();
    }

    function onKey(evt) {
        var key = evt.getKey();
        System.println("Evt = " + evt + ", key=" + key);      // e.g. CLICK_TYPE_TAP = 0
        return true;
    }

    function onTap(clickEvent) {
		System.println("arg1");
		if (Application.Properties.getValue("TapLaunch") || selected_action == null) {
			self.onKey(new Toybox.WatchUi.KeyEvent(KEY_ENTER, PRESS_TYPE_ACTION));
		}
        return true;
    }

function onNextMode() {
		System.println("arg3");
		return false;
	}
function onNextPage() {
		System.println("arg4");
		return false;
	}
function onPreviousMode() {
		System.println("arg5");
		return false;
	}
function onPreviousPage() {
		System.println("arg6");
		return false;
	}
function onSelect() {
		System.println("arg7");
		return false;
	}

function onKeyPressed(keyEvent) {
		System.println("arg8");
		return false;
	}
function onKeyReleased(keyEvent) {
		System.println("arg9");
		return false;
	}
function onRelease(clickEvent) {
		System.println("arg10");
		return false;
	}
function onSelectable(selectableEvent) {
		System.println("arg11");
		return false;
	}
function onSwipe(swipeEvent) {
		System.println("arg12");
		return false;
	}


	function onHold(clickEvent) {
		System.println("arg20");
		self.onMenu();

        return true;
	}
	
	function onMenu() {
		System.println("arg21");
        ...

        return true;
    }

	function onBack() {
		System.println("arg22");
    	System.exit();
    }

  • My bet is that the delegate is being returned from getInitialView on a widget. In that case, the only input passed to the initial delegate is the select/enter behavior which, on a vivoactive4, that is a screen tap.

  • Your bet sounds good Wink. Yes it's a widget ! Is there a doc that explain the inputDelegate I returned with getInitialView is not triggering all function of the class ?

    Note that there is not only select/enter that is working, "menu" (a long press on right bottom button) work also.
    But, hold (long tap) doesn't work, neither right up button.

  • OK.

    Here the example code of a simple widget that try to push a view on tap or push button, and pop this 2nd view on tap or a button push :

    using Toybox.Application;
    using Toybox.WatchUi;
    
    var globalView;
    var globalDelegate;
    
    var display_releaseMessage = true;
    
    class DebugProjectApp extends Application.AppBase {
        function initialize() {
            AppBase.initialize();
        }
        
        function onStart(state) {
        }
        
        function onStop(state) {
        }
        
        function getInitialView() {
        	globalView = new DebugProjectView();
        	globalDelegate = new DebugProjectDelegate();
            return [ globalView, globalDelegate ];
        }  
    }
    
    class DebugProjectView extends WatchUi.View {
        function initialize() {
            View.initialize();
        }
        
        function onLayout(dc) {
            dc.setColor(Graphics.COLOR_BLACK, Graphics.COLOR_WHITE);
        	dc.drawText(dc.getWidth() / 2, dc.getHeight() / 2, Graphics.FONT_LARGE, "1st view", Graphics.TEXT_JUSTIFY_CENTER);
        }
        
        function onShow() {
        }
        
        function onUpdate(dc) {
        	dc.drawText(dc.getWidth() / 2, dc.getHeight() / 2, Graphics.FONT_LARGE, "1st view", Graphics.TEXT_JUSTIFY_CENTER);
        }
    
        function onHide() {
        }
    
    }
    
    class DebugProjectDelegate extends WatchUi.BehaviorDelegate {
    
        function initialize() {
            BehaviorDelegate.initialize();
        }
    
        function onKey(evt) {
            var key = evt.getKey();
            System.println("debug 1, key=" + key);      // e.g. CLICK_TYPE_TAP = 0
    	    WatchUi.pushView(new MessageView(), new MessageDelegate(), WatchUi.SLIDE_UP);
            return true;
        }
    
        function onTap(clickEvent) {
    		System.println("debug 2");
    	    WatchUi.pushView(new MessageView(), new MessageDelegate(), WatchUi.SLIDE_UP);
            return true;
        }
    
    	function onBack() {
    		System.println("debug 3");
        	System.exit();
        }
    }
    
    class MessageView extends WatchUi.View {
      function initialize() {
        View.initialize();
      }
    
      function onLayout(dc) {
        	dc.drawText(dc.getWidth() / 2, dc.getHeight() / 2, Graphics.FONT_LARGE, "2nd view", Graphics.TEXT_JUSTIFY_CENTER);
      }
      
      function onShow() {
    
      }
      
      function onUpdate(dc) {
        	dc.drawText(dc.getWidth() / 2, dc.getHeight() / 2, Graphics.FONT_LARGE, "2nd view", Graphics.TEXT_JUSTIFY_CENTER);
      }
    
    }
    
    class MessageDelegate extends WatchUi.BehaviorDelegate {
    
      function initialize() {
        BehaviorDelegate.initialize();
      }
    
      function onKey(t) {
        var key = t.getKey();
        System.println("debug 11, key=" + key);
    	WatchUi.popView(WatchUi.SLIDE_DOWN);
      }
    
      function onTap(t) {
        System.println("debug 12");
    	WatchUi.popView(WatchUi.SLIDE_DOWN);
      }
    
      function onBack() {
        System.println("debug 13");
    	WatchUi.popView(WatchUi.SLIDE_DOWN);
      }
    
    }

    So, with Vivoactive4

    When I tap, then tap. No pb : debug log is :
    debug 2
    debug 12

    When I tap, then push the up button. No pb, debug log is :
    debug 2
    debug 11, key=4

    When I push the up button. Nothing append, no log :

    When I push long on botom button, then push up button. No pb, debug log is :
    debug 1, key=7
    debug 11, key=4

    Travis, according your last message it seems you find it "normal", I re-read the "Class: Toybox.Application.AppBase" documentation. But it just say that providing InputDelegate is optionnal, but nothing else. Where can I find informations ?

  • Sorry, should've thought of the initial view of a widget, since I've had to deal with that kind of limitation when implementing a stopwatch widget.

    As you may have guessed, the reason why it works differently is because the initial view ("front page") of each widget is displayed as you scroll through the widget carousel. No further user interaction (other than changing settings) is possible until you "enter" the widget by pressing START (or tapping on the screen), and the widget pushes a 2nd view. (i.e. If a widget was able to intercept the UP and DOWN buttons, how would you be able to scroll to the next or previous widget?) Similarly, the BACK button is reserved for quickly returning to the watch face from any widget.

    And this gets more complicated with newer watches that support widget glances. Since the glance view serves as a lightweight front page, then the initial view of the widget is actually the 2nd view that the user sees.

    As far as documentation goes, the closest I could find was this:

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

    Widgets

    Widgets live in a carousel of views that can be summoned at any time. Widgets function very similarly to device apps. The main difference is that the initial view has some key navigation taken away so the user can quickly navigate to other widgets.

    The initial view of a widget should contain glanceable information, and should not be a menu of option. Menus cannot be navigated on button products because the up/down buttons have been repurposed.

    Glances

    Newer products have converted the widget display from a carousel of views to a list of active metrics. Each list entry, or glance, can provide a summary view to the user. If the user activates the glance, the app will launch.

  • OK, thanks a lot !

    However, I think there is something confusing with Vivoactive4. If you look at the exemple, le upper button is catched as KEY_ENTER. So, it's strange that it's not catched on the first view.

    On Vivoactive3, the tap and the button are both interpreted.

    But anyway, I understand, I have to test on each device to check the behavior.

    Thanks all.

  • Here's a simple delegate I use in a widget (widget specific code left out)

    class PiTempDelegate extends Ui.BehaviorDelegate {
    
        function initialize() {
            BehaviorDelegate.initialize();
        }
     
    	function onMenu() {
    		Sys.println("onMenu");
            //onMenu code
            return true;
    	}
    	
    	function onSelect() {
    		Sys.println("onSelect");
            //onSelect code
    		return true;
    	}
    	
        function onKey(evt) {
        	var lastKey=evt.getKey();
        	Sys.println("onKey="+lastKey);
        	if(lastKey==Ui.KEY_ENTER) {
                onKey(KEY_ENTER) code
    			return true;
    		}
        	return false;
    	}	
    }

    With a va4, a screen tap causes onSelect to be called, the upper right button, onKey with KEY_ENTER (returns true). long press of the lower right button, onMenu.

    Short press of the lower button calls onKey with KEY_ESC (returns false)

  • As I said in my previous message, yes top button is KEY_ENTER. That's also why I said it's a bit confusing. The KEY_ENTER is catched in initial view with all devices I have tested ... except on the Vivoactive4 !

    In another words, with your exemple if you use your class to return the inital inputDelegate with getInitialView(), you will see the "onKey=4" (KEY_ENTER = 4) output for all watches if you press the button that correspond to KEY_ENTER. But not with Vivoactive4 !

  • The code I posted works fine in the sim for the va4 and also on a real device.

    The value you return is important, so check those, and comment out the stuff you really don't need (onBack isn't needed at all, and Sytem.exit() doesn't work in widgets.)

  • Uh !?!  I can confirm you that your code doesn't work on the simulator in my side !

    Are you really use this class for initial view ? Can I see your getInitialView() function ?

    I use SDK 3.2.5, Windows.

  • check for updates to your devices. Could be it's expecting the click for the upper button in a different place.

    The return from getInitialView

    return [ view,new PiTempDelegate() ];

    And the upper button on the va4 works for other things I wrote.

    The widget with the delegate I posted only uses 1 view (so it's in the main view).