App: Layout + Drawable + Tap (TouchScreen)

Hello
Started this week looking to Connect IQ SDk, so i decided to build a small app just to test how things work.
The app, it's a simple calculator, just to do something useful.

My first problem, after designing all the buttons, what's the best approach to put everything in place and detect selections on each button.

1 - I know that i can define every button in the resources, then load and place them in the View, and with the tap event detect which button was touched, but it doesn't looks like very professional and very efficient.
2 - I can create a layout, and define all the bitmaps, and set the x,y coordinate and everything just get placed in the right place, but once again i have to detect the tap event and where.
3 - I can create a resource file where every bitmap is inside a drawable, and then place the id in the layout to draw everything in the view.

For what i read in the docs, i can use the selectable event, in the 3 approaches that i wrote, the third it's the only that can use the selectable? Or any of them can use it, but need some kind of tweak?

Now for testing i have this:
<drawables>
<bitmap id="LauncherIcon" filename="launcher_icon.png" />
<drawable-list id="background">
<shape type="rectangle" x="0" y="0" width="fill" height="fill" color="Gfx.COLOR_GREEN"></shape>
</drawable-list>
<drawable-list id="Number0">
<bitmap id="Number_0" x="15" y="15" filename="../drawables/N0.png"></bitmap>
</drawable-list>...

And this:
<layout id="MainLayout">
<drawable id="background" />
<drawable id="Number0" />
...


And i have some code for the tap events:
class CalcDelegate extends Ui.BehaviorDelegate {

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


function onTap(evt){
var clickEvt = evt;
System.println(">>>TAP: " + clickEvt.getCoordinates() + " >>> " + clickEvt.getType());
}


function onKey( evt ){
System.println(">>>KEY: " + evt.getKey());
}
}


It's this correct?
And now, what's the minimum that i have to do, to make the app detect the touchs in every button (numbers and operations)?


Thanks
  • I think you're missing the fourth option. You can use the layout to define the buttons and their placement, as well as the function that gets called when the button is pressed. Like this...

    <layout id="CalculatorLayout">
    <button x="4" y="4" width="20" height="20" background="Gfx.COLOR_BLACK" behavior="onOnePressed">
    <state id="stateDefault" bitmap="@Drawables.OneButton" />
    <state id="stateHighlighted" bitmap="@Drawables.PressedOneButton" />
    <state id="stateSelected" bitmap="@Drawables.PressedOneButton" />
    <state id="stateDisabled" color="Gfx.COLOR_BLACK" />
    </button>
    <button x="28" y="4" width="20" height="20" background="Gfx.COLOR_BLACK" behavior="onTwoPressed">
    <state id="stateDefault" bitmap="@Drawables.DefaultTwoButton" />
    <state id="stateHighlighted" bitmap="@Drawables.PressedTwoButton" />
    <state id="stateSelected" bitmap="@Drawables.PressedTwoButton" />
    <state id="stateDisabled" color="Gfx.COLOR_BLACK" />
    </button>

    <!-- ... -->
    </layout>


    Then you just need to have a BehaviorDelegate that implements the named behaviors...

    class CalculatorDelegate extends Ui.BehaviorDelegate
    {
    function initialize() {
    BehaviorDelegate.initialize();
    }

    function onOneButtonPressed() {
    // do stuff
    }

    function onTwoButtonPressed() {
    // do stuff
    }

    // ...
    }


    I haven't used this stuff much, but I know it is there and it is much cleaner than trying to write it all out yourself. The disadvantage of using layouts though is that they take up a bunch of memory relative to hand-coded stuff.

    Travis
  • Something else to note, is that based on your watch, there may only be 9 "tap regions" (this is the case for the va and ha-hr) and it's not really a full toch screen. You get the center of the region on the real device, but get the x/y in the sim. (so it's different.)

    See the UX Guilde in the SDK for info on this
  • Thanks
    @TRAVIS
    Tomorrow i'll test this.
    But like i wrote, this is just for testing/learning, so the memory usage isn't critical
    @jim
    I have a edge 1000, so the coordinates are real... Right?
  • I have a edge 1000, so the coordinates are real... Right?

    Yes. Some devices (the vivoactive, and maybe others) do have this limitation, so it is something to be aware of if you are testing on a physical device. You should be fine with the edge_1000.
  • Can i add a tag to the button to send a param/var to the method?
    Looking into the documents i can't see anything...

    Why i'm asking this, instead of add one method for each button, i was thinking creating a method and use the same method for all buttons and then in the function for the behavior only check the var/param value.

    Something like this:
    <layout id="CalculatorLayout">
    <button x="4" y="4" width="20" height="20" background="Gfx.COLOR_BLACK" behavior="onButtonPressed">
    <state id="stateDefault" bitmap="@Drawables.OneButton" />
    <state id="stateHighlighted" bitmap="@Drawables.PressedOneButton" />
    <state id="stateSelected" bitmap="@Drawables.PressedOneButton" />
    <state id="stateDisabled" color="Gfx.COLOR_BLACK" />
    <param name="checkParam">1</param>
    </button>...

    The function:
    function onButtonPressed(checkParam){
    if (checkParam == "1"){....
    }
  • I do not believe that this is possible using the built-in Button class. You should be able to create a derived button class that takes the provided :behavior parameter and an additional parameter, and packages up a closure to call the given function. The button will need to have access to the input delegate so the method can be created, but it could be done.

    Even if you don't do that, you will probably want to make a single function that takes a parameter, and call it from the various functions that take no arguments. This should reduce code size a little bit.