How to know Data field size at run time?

I am upgrading an old app that still detects the data field size and device manually, having plenty of redundant code that should be done by resources...

I assume there is a way to know both the data field size and the device where the data field is running, but I haven't been able to figure it out. Right now I'm doing this. I could add device name as resource string, but that wouldn't help much because I would still have to figure out the data field size. The reason why I need this is that I am using the full height and most of the width of the data field.

The code monster now looks something like this...

function is(dc) {
         var width = dc.getWidth();
         var height = dc.getHeight();
         
         if ((width == 119) && (height == 78 || height == 79)) {
             return "edge1000small";
         } else if (width == 240) {
             return "edge1000large";
         } else if (width == 400 || width == 199) {
             return "edge1000largelandscape";
         } else if (width == 132) {
             return "edge1000smalllandscape";
        } else if (width == 200) {
             return "edge520large";....

  • That's one way to do it, but I generally would do that in onLayout() (only needs to be done there and not each time onUpdate() is called).

    As far as device, you can also use jungles so the device is known at compile time vs run time.

  • It looks like you're using the dc dimensions and maybe the obscurity flags to generate a string, and then later using that string to decide how to draw your data field. Unfortunately, the way you're doing it requires you to have code for each device you support compiled into the app (wasting memory).

    I think a better way would be to use jungles (as @jim_m_58 mentioned) and to separate your device-specific drawing/layout code in device-specific source files. This is how I've approached this problem in the past.

    As an example, you would create a monkey.jungle file with entries for the devices you intend to support, like this:

    project.manifest = manifest.xml
    
    base.sourcePath=source/*.mc
    
    edge520.sourcePath=$(base.sourcePath);source/edge520/*.mc
    edge530.sourcePath=$(base.sourcePath);source/edge530/*.mc
    edge820.sourcePath=$(base.sourcePath);source/edge820/*.mc
    edge830.sourcePath=$(base.sourcePath);source/edge830/*.mc
    edge_1000.sourcePath=$(base.sourcePath);source/edge_1000/*.mc
    edge1030.sourcePath=$(base.sourcePath);source/edge1030/*.mc
    edge1030bontrager.sourcePath=$(edge1030.sourcePath)
    
    ## more of this as needed

    Then you add code for each implementation you want to support:

    /* source/edge_1000/DataField.mc */
    using Toybox.WatchUi;
    
    class MyDataField extends WatchUi.DataField
    {
        // any variables that you may need to display
        // your data properly
    
        function initialize() {
            DataField.initialize();
        }
        
        function onLayout(dc) {
            // setup your variables for the layout
    
            if ((width == 119) && (height == 78 || height == 79)) {
                // edge1000 small portrait
            } else if (width == 240) {
                // edge1000 large portrait
            } else if (width == 400 || width == 199) {
                // edge1000 large landscape
            } else if (width == 132) {
                // edge1000 small landscape
            } else {
                // hmmm
            }
        }
        
        function onUpdate(dc) {
            // do whatever you need to draw
        }
    }

    If you have common code, say to calculate the values to display, avoid the urge to duplicate that code across the device-specific files. It will become a maintenance headache. Try to keep stuff that is truly device-specific in those files, and put common code in the common files.

  • Thanks. That Jungle part is something I've kind of struggled to understand when looking at samples and manuals. The app works now so I should be safe to refactor it now before next upgrade.

    The ammount of code is very small so memory and performance are not an issue. I'm kind of worried that managing it in 7 or so duplicates is even more complicated, but I'll see that once I've refactored the current two classes to at least four.