Can someone please demonstrate a working example of Ui.animate?

Former Member
Former Member
I can't figure it out.
  • using Toybox.Application as App;
    using Toybox.Graphics as Gfx;
    using Toybox.WatchUi as Ui;

    class TestDelegate extends Ui.InputDelegate
    {
    hidden var parent;

    function initialize(parent) {
    self.parent = parent;
    }

    function onKey(evt) {
    return parent.animate();
    }

    function onTap(evt) {
    return parent.animate();
    }
    }

    class TestView extends Ui.View
    {
    hidden var drawable;

    function initialize() {
    }

    function onLayout(dc) {
    drawable = new Ui.Text({
    :locX => 100,
    :locY => 10,
    :text => "X",
    :color => Gfx.COLOR_WHITE,
    :font => Gfx.FONT_XTINY,
    :justification => Gfx.TEXT_JUSTIFY_CENTER | Gfx.TEXT_JUSTIFY_VCENTER
    });
    }

    function animate() {
    Ui.animate(drawable, :locY, Ui.ANIM_TYPE_EASE_IN_OUT, 10, 138, 5, null);
    }

    function onShow() {
    }

    function onUpdate(dc) {
    dc.setColor(Gfx.COLOR_WHITE, Gfx.COLOR_BLACK);
    dc.clear();

    drawable.draw(dc);
    }

    function onHide() {
    }
    }

    class TestApp extends App.AppBase
    {
    function initialize() {
    }

    function onStart(state) {
    }

    function getInitialView() {
    var view = new TestView();

    return [ view, new TestDelegate(view) ];
    }

    function onStop(state) {
    }
    }


    I'm pretty sure that anything in a layout is a Drawable, so you could easily load up a layout and then animate the drawables described within.
  • FYI, this only appears to work with the :locX and :locY properties.
  • Former Member
    Former Member over 10 years ago
    Thanks Travis, that's great. It's all makes perfect sense once you see an example. Any chance you could show how to do this on a circle specified from an xml file? :)

    I will be attempting it myself, but I'm proving slow to master a proper understanding of the xml resources.... among other things, ahem.
  • Unfortunately, a drawable list specified in the xml is does not extend Ui.Drawable. From the looks of the pseudo-assembly generated by the compiler (you can generate this by compiling with -g), its draw(dc) method simply gets the dimensions of the display context and then calls drawComplex(dc, pX, pY, pWidth, pHeight). That method is code generated by the resource compiler, and all it does is draw each of the sub-parts (which are themselves not drawables).

    If you want to use the animation system, you have to use something that inherits from Drawable. If you want to use the resource system to describe where an object is, you have to use a kludge. You have to load a resource that has labels in it, and then use the label information to build up the information necessary to create a drawable. This wouldn't be necessary if this enhancement were implemented, but I'm not sure it ever will.

    Here is the code that I ended up with to animate a circle which was described in a resource file...

    <layout id="Circle">
    <!-- just used for its position information -->
    <label x="20" y="20" />

    <!-- this is the radius and fill flag -->
    <label x="15" y="1" />
    </layout>


    class MyCircle extends Ui.Drawable
    {
    hidden var radius;
    hidden var fill;
    hidden var color;

    function initialize(params) {
    Ui.Drawable.initialize(params);

    radius = params.get(:radius);
    if (radius == null) {
    radius = 10;
    }

    fill = params.get(:fill);
    if (fill == null) {
    fill = false;
    }

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

    function draw(dc) {
    dc.setColor(color, Gfx.COLOR_TRANSPARENT);

    if (fill) {
    dc.fillCircle(locX, locY, radius);
    }
    else {
    dc.drawCircle(locX, locY, radius);
    }
    }
    }


    class TestView extends Ui.View
    {
    hidden var drawable;


    function initialize() {

    }

    function onLayout(dc) {
    var layout = new Rez.Layouts.Circle(dc);

    var x = layout[0].locX;
    var y = layout[0].locY;
    var radius = layout[1].locX;
    var fill = layout[1].locY;

    drawable = new MyCircle({
    :locX => x,
    :locY => y,
    :radius => radius,
    :fill => fill,
    :color => Gfx.COLOR_RED
    });
    }
  • Former Member
    Former Member over 10 years ago
    Thanks once again for a thorough answer. In regards to your enhancement, I believe I may have a method closer to the ideal. I will post it now, so probably there when you read this.