append with variable expansion or evaluation

Please excuse me if I'm using the wrong terms, and if so, let me know what the right terms are; I'd appreciate it.

I'm making a watch face that I want to have multiple different banners that are user selectable.
To save memory, I want the watch to only load the resource for the one that's selected.
A huge string of IF statements seemed horribly ineffecient so I made an array, and am using the value from the settings list to identify which item in the array to use
The items in the array are the resource IDs.
But I can't figure out how to get the correct ID appended to the end of the resource call (or whatever it is called).

I've tried a few different ways, and it just doesn't like it. Saves fine with no errors, but it won't run in the sim
(13) function initialize() {WatchFace.initialize();}

// Load your resources here
function onLayout(dc) {
var bannerID = App.getApp().getProperty("IM_banner");
Sys.println("banner ID=" + bannerID);
var bannerLabel = ["bannerAIP","bannerWC","bannerMUN","bannerRAC","bannerCHO","bannerLOU"];
Sys.println("bannerLabel=" + bannerLabel[bannerID]);

//banner = Ui.loadResource(Rez.Drawables.bannerWC);
var rez = bannerLabel[bannerID];
Sys.println(rez);
(25) banner = Ui.loadResource("Rez.Drawables." + rez);

}


banner ID=1
bannerLabel=bannerWC
bannerWC
Failed invoking <symbol>
UnexpectedTypeException: Expected Number/Float/Boolean/Long/Double, given String
initialize in C:\Users\N105811\workspace\IMwatch\source\IMwatchView.mc:13
onLayout in C:\Users\N105811\workspace\IMwatch\source\IMwatchView.mc:25
Unhandled Exception
  • You are making a small mistake in that you are trying to use a string to get a symbol.

    var rez = bannerLabel[bannerID];
    // rez is a string, but you need it to be a symbol...


    All you need to do is map from the value in the settings (a number presumably) to the resource identifier (a symbol), like this...

    // you could make this static/global and const if you wanted
    var _rez_table = [
    Rez.Drawables.bannerAIP,
    Rez.Drawables.bannerWC,
    Rez.Drawables.bannerMUN,
    Rez.Drawables.bannerRAC,
    Rez.Drawables.bannerCHO,
    Rez.Drawables.bannerLOU
    ];


    Then you access it just like you were doing for the strings...

    banner = Ui.loadResource(_rez_table[bannerID]);


    Travis
  • BOOM! Works like a charm!

    Since the resource is being loaded in onLayout(), will this function get called again if the user were to change the setting in the ConnectIQ app?
    Or do I need to force it to redraw the new banner (if it was changed at all) somewhere else?
  • It depends on how you want your application to behave. If it is okay for the bitmap to remain the same until the program is restarted, then you shouldn't need to do anything. If you want the change to take effect immediately, you'll need to force it.

    The function AppBase.onSettingsChanged() is called when Garmin Connect Mobile sends settings to the device. If you don't care to get fancy, you can just make banner a global variable, and update it when the settings change.

    var banner;

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

    function onSettingsChanged() {
    var bannerID = self.getProperty("IM_banner");
    $.banner = Ui.loadResource(_rez_table[bannerID]);
    }
    }


    Travis