Struggling a bit with Views and how stuff gets on the screen

I'm trying to get a layer working and I'm hitting an error/warning that seems.. off.

WARNING: fenix6xpro: /home/ciq/src/source/views/OverlayView.mc:54: Unable to detect scope for the symbol reference 'width'.
WARNING: fenix6xpro: /home/ciq/src/source/views/OverlayView.mc:54: Unable to detect scope for the symbol reference 'height'.

I've assumed I'm doing something wrong but the example code in WatchfaceAnimation in the samples directory seems to do the same and runs without this error. 


// lines 106-110 in source/AnimationWatchFaceView.mc

        _drawLayer = new WatchUi.Layer({
            :locX=>_drawLayerArea[0],
            :locY=>_drawLayerArea[1],
            :width=>_drawLayerArea[2],
            :height=>_drawLayerArea[3]});
            
// My code
    var layer = new Ui.Layer({
      :locX       => 140,
      :locY       => 140,
      :width      => 140,
      :height     => 140,
      :visibility => true,
    });

Now when I leave out the width/height it doesn't complain but I can't seem to get anything on the screen. I paint the whole screen blue and than I want the layer to be white and be painted.. yet my screen stays all blue.

Full code can be found here: gitlab.com/.../OverlayView.mc

  • You have to paint the whole screen in onUpdate(), even if it seems inefficient, because system notifications (for example) can overwrite what you're currently displaying, and you don't want those external changes to stay on the screen indefinitely.

    To address your specific issue, afaik View.onUpdate() is what causes layers/layout to be rendered, whether you added layers programmatically or whether a layout was defined in XML.

    EDIT: Just calling clearScreen() (which clears the dc and the layer) in onUpdate() is sufficient for what you want. Calling View.onUpdate() is incorrect as that overrides the previous clearing of the dc to a blue background color.

  • if you use

    import ... as Ui;

    use

    Ui....

    instead  of

    WatchUi...

    and warning will disapear

  • Woahhh. Hold on.. Ok.. this works.

    But what I don't understand is why you want me to call View.ionUpdate(). From my experiments and how I read the onUpdate() docs:

    > If a class that extends View does not implement this function then any Drawable objects contained in the View will automatically be drawn.

    If you don't have a layout (so there aren't any drawables) it just blacks out the screen. And I notice this too. When I clear the screen it should turn blue and you have a black screen.. When I don't call the View.onUpdate() I do get my pretty blue blackground.

    Which leads me to ask: Should a View *always* have a layout?

  • I can't see all code in gitlab

    54 line is

    function onShow() {

  • Oh you're right and I'm totally wrong above. It's calling ldc.clear() (clearing your layer) which paints the layer white, not View.onUpdate(). View.onUpdate actually does just render layouts (and not layers).

    All you need is this:

      function onUpdate(dc as Gfx.Dc) {
        System.println("onUpdate");
        clearScreen(dc);
      }

    However, it's not true that "ldc.clear()" doesn't do much. You need it for your code to work (assuming you want the layer to be white).

    Sorry, jumped to conclusions. I'll update my comment.

    For anyone else reading this thread, here's onLayout() and clearScreen():

      function onLayout(dc as Gfx.Dc) {
        System.println("onLayout");
    
        self.width  = dc.getWidth();
        self.height = dc.getHeight();
        self.layer  = new Ui.Layer({
          :locX       => 140,
          :locY       => 140,
          //:width      => 140,
          //:height     => 140,
          :visibility => true,
        });
        addLayer(self.layer);
        clearScreen(dc);
      }
    
    function clearScreen(dc) {
        dc.setColor(Graphics.COLOR_BLUE, Graphics.COLOR_BLUE);
        dc.clear();
    
        var ldc = self.layer.getDc();
        ldc.setColor(Graphics.COLOR_WHITE, Graphics.COLOR_WHITE);
        // Doesn't do much
        ldc.clear();
        // This just paints the whole screen white
        //dc.clear();
        dc.setColor(Graphics.COLOR_BLACK, Graphics.COLOR_BLUE);
      }

    Obviously calling clearScreen() in onLayout() is unnecessary.

  • I'm trying to get a layer working and I'm hitting an error/warning that seems.. off.

    WARNING: fenix6xpro: /home/ciq/src/source/views/OverlayView.mc:54: Unable to detect scope for the symbol reference 'width'.
    WARNING: fenix6xpro: /home/ciq/src/source/views/OverlayView.mc:54: Unable to detect scope for the symbol reference 'height'.

    I've assumed I'm doing something wrong but the example code in WatchfaceAnimation in the samples directory seems to do the same and runs without this error. 

    I tried building with both the latest stable CIQ SDK and the beta, as well as with different levels of type checking, but I don't see those exact warnings. (I do see other stuff though.)

  • Guessing that it might have something to do with the fact that you have class members named width and height tho (not to be Captain Obvious)

  • You are very right, so the comment was removed :) During my tests it seemed like it wasn't doing much, although I wasn't sure of the dc of a layer was the same as the dc of the view. So I was toying with that to see if it yielded success. I was actually expecting it to draw the layer. Which it didn't until after your remarks. If one removes it it doesn't pain the layer on the screen.

    Unrelated, dc stands for Drawing Canvas?.

    I'm still a bit baffled tho. Why does it DO paint the dc for the view with clearScreen() in onLayout(), but it doesn't do anything for the layer. Yet, when we move the whole shebang to onUpdate() it works. They both have access to the dc object, they both call the same code, one would expect the exact same result..