Screen not properly redraw

Hi all,

I have a strange redraw behaviour in my DataField

In my onUpdate method I have several dc.drawText() to write values that are fetched from Activity.info object. 

I don't know why but the first time values change previous values still below new ones. 

Any idea on how solve this? 

Thanks!

  • Without knowing the code, I assume:
    the functions in an IQ app might not/do not work synchronously. It happens, that a value build in oncompute() for a variable is not the same as for the same variable build in another function… It could differ by a second.

    (And the values are probably written by more than one function. If there was only one single drawText() in onUpdate(), this could not occur. Edge devices clear the whole screen before redrawn in onUpdate.)

  • Do you clear the screen right away in onUpdate()?  What colors are you using?  COLOR_TRANSPARENT?

  • Yes, I do have a Background drawable class that gets background color with getBackgroundColor() method and set it this way:

    dc.setColor(Graphics.COLOR_TRANSPARENT, getBackgroundColor());
    dc.clear();
    Every component (that extends from drawable class) then do 
    dc.setColor(_color, Graphics.COLOR_TRANSPARENT); // where _color is the current foreground color, e.g. COLOR_BLACK
    dc.drawText();
    Do you see something wrong with my code? 
  • First thing I'd do is

    dc.setColor( getBackgroundColor(), getBackgroundColor());
    dc.clear();

    And for the setColor before the drawText, don't use COLOR_TRANSPARENT, but the color you want.  If the background is black, use white, or v/v

  • yes, you're right... it seems that COLOR_TRANSPARENT was the issue...

  • It's interesting that the docs suggest clearing the screen with COLOR_TRANSPARENT should work. I guess not in this case.

    [https://developer.garmin.com/connect-iq/api-docs/Toybox/Graphics/Dc.html#clear-instance_function]

    Erase the screen using the background color.

    Note:

    Starting form version 3.1.0, COLOR_TRANSPARENT will also be honored as background color, which will cause the value of pixels in the clip region to be replaced by COLOR_TRANSPARENT. For example, this can be used to clear the transparent overlay layer so animation background is visible.

  • I don't see any contradiction. On the contrary. It is written black on white that using transparent as background will not clear what's below, but show it ("visible"). Besides the code above didn't clear, just used transparent as a background in drawText, which behaved exactly as expected: you see the font as the foreground color, and where there's no font, there you "see" the "background" color, which being transparent means you see what was drawn below it.

  • I don't see any contradiction. On the contrary. It is written black on white that using transparent as background will not clear what's below, but show it ("visible")

    The doc for dc.clear() literally says that if you use COLOR_TRANSPARENT as a background colour for dc.clear(), it will cause

    the value of pixels in the clip region to be replaced by COLOR_TRANSPARENT

    I think the key word here is "replaced".

    You might be reading too much into the example that follows:

    For example, this can be used to clear the transparent overlay layer so animation background is visible.

    Note that this refers to:

    - multiple layers

    - a background layer that should remain visible

    - a foreground layer that is cleared

    It seems to me that if there is a single layer, then as the doc says you should be able to call dc.clear() while the background colour is transparent, and all the pixels in the dc should be replaced with the transparent colour, which means that everything which was visible in the dc region should be wiped out.

    Besides the code above didn't clear

    Well, I don't know all the details of the code, but I'm just going by this comment:

    Yes, I do have a Background drawable class that gets background color with getBackgroundColor() method and set it this way:

    dc.setColor(Graphics.COLOR_TRANSPARENT, getBackgroundColor());
    dc.clear();
    Every component (that extends from drawable class) then do 
    dc.setColor(_color, Graphics.COLOR_TRANSPARENT); // where _color is the current foreground color, e.g. COLOR_BLACK
    dc.drawText();

    Assuming:

    - there is only one layer 

    - the background class is drawn before any of the other classes (which call drawText)

    - there is no clipping area set in the background class before dc.clear() is called (i.e. dc.clear() applies to the entire data field area)

    I would expect dc.clear() (with a transparent background colour) to work as documented: all the pixels in the current clip region (meaning the entire data field) should be replaced with COLOR_TRANSPARENT, meaning that the black pixels from the previous update should replaced with transparent pixels, and there should be no problem with text from the current update overlapping text from the previous update

    Maybe I'm misunderstanding the documentation or the code though.

    If there's a single layer in the code, then I think the documentation is wrong.

    If there's multiple layers in the code, then the documentation could still be right.

  • You brought the irrelevant part of the documentation into this thread, as there was no mention of layer previously and the code that was given doesn't use transparent background color for clear, only for drawText.

    I would expect dc.clear() (with a transparent background colour) to work as documented: all the pixels in the current clip region (meaning the entire data field) should be replaced with COLOR_TRANSPARENT, meaning that the black pixels from the previous update should replaced with transparent pixels, and there should be no problem with text from the current update overlapping text from the previous update

    Replacing a pixel's color to transparent has a meaning only if there's some other layer below it that becomes visible. Drawing over a color with transparent IN THE SAME LAYER will not change it's color to "transparent" for 2 reasons:

    1. mainly because the whole point of drawing a letter with transparent background is to make whatever was drawn at the same place previously in the same layer visible.

    2. what would you expect to see when you clear the page with transparent background? The inside mechanics of the watch or the skin of your arm? Or maybe the bones?

  • 2. what would you expect to see when you clear the page with transparent background? The inside mechanics of the watch or the skin of your arm? Or maybe the bones?

    There's already a background underneath the data field, which is black or white. That's what I expect to see.

    You do realize that if your data field doesn't draw anything at all (and doesn't clear the dc), then the watch actually doesn't display the inside of the watch, your skin, or your bones, it displays the data field background. Interesting how that works, huh?

    If calling dc.clear() with a transparent background is not supposed to do anything, then why would the doc say:

    > Starting form version 3.1.0, COLOR_TRANSPARENT will also be honored as background color, which will cause the value of pixels in the clip region to be replaced by COLOR_TRANSPARENT.

    If it's only supposed to work with more than 1 layer, where you clear any layer other than the bottom-most layer, that doesn't make much sense to me either. Why special-case behaviour which would be more useful if it worked the same in all cases?

    I could be wrong, and I could be misinterpreting the docs. But the apparent behaviour of dc.clear() (which to be fair has been mentioned/observed before) combined with the text of the docs doesn't make sense to me.

    I'll test it out on in the sim and a real device, and if dc.clear() with a background colour of COLOR_TRANSPARENT doesn't actually clear anything, then I'll file a bug report asking for clarification of the docs.