Graphics tutorial / drawLine() query

Hi all,

I am trying to draw lines on my watch face and it simply is not happening for me. In fact, none of the dc methods for drawing do anything at all.

I am able to draw using layout.xml. Everything in the xml files is drawn yet everything I try to draw using dc calls does not get drawn.

Where am I going wrong?
  • My code:
    // Update the view
    function onUpdate(dc) {
    // testing
    dc.clear();
    dc.setColor(Gfx.COLOR_BLUE, Gfx.COLOR_WHITE);
    dc.fillRectangle(0, 0, widthX, widthY);

    // test draw line
    dc.setColor(Gfx.COLOR_WHITE, Gfx.COLOR_TRANSPARENT);
    dc.setPenWidth(5);
    //dc.drawLine(5,5,25,25);
    dc.drawRectangle(5, 5, 25, 25);

    dc.drawText(5, 5, Gfx.FONT_SMALL, "test123", Gfx.TEXT_JUSTIFY_CENTER);
    }
  • layout.xml
    <layout id="WatchFace">
    <drawable id="watchFace"></drawable>
    <label id="watchBrand" x="center" y="15" font="Gfx.FONT_SMALL" justification="Gfx.TEXT_JUSTIFY_CENTER" color="Gfx.COLOR_WHITE"></label>
    </layout>


    watchface.xml
    <resources>
    <drawable-list id="watchFace" background="Gfx.COLOR_TRANSPARENT">
    <shape type="rectangle" x="2" y="2" width="144" height="201" border_width="2" border_color="FFFFFF" color="000000" />
    <shape type="polygon" x="0" y="0" points="[[3,0],[10,7],[7,10],[0,3]]" border_color="FFFFFF" color="FFFFFF"/>
    <shape type="polygon" x="0" y="0" points="[[145,0],[148,3],[141,10],[138,7]]" border_color="FFFFFF" color="FFFFFF"/>
    <shape type="polygon" x="0" y="0" points="[[138,198],[141,195],[148,202],[145,205]]" border_color="FFFFFF" color="FFFFFF"/>
    <shape type="polygon" x="0" y="0" points="[[0,202],[7,195],[10,198],[3,205]]" border_color="FFFFFF" color="FFFFFF"/>
    <shape type="circle" x="39" y="72" radius="31" border_width="1" border_color="FFFFFF" color="555555"/>
    <shape type="circle" x="109" y="72" radius="31" border_width="1" border_color="FFFFFF" color="555555"/>
    <shape type="circle" x="109" y="72" radius="31" border_width="1" border_color="FFFFFF" color="555555"/>
    <shape type="circle" x="74" y="154" radius="31" border_width="1" border_color="FFFFFF" color="555555"/>
    <shape type="circle" x="center" y="center" radius="2" border_width="1" border_color="FFFFFF" color="FFFFFF"/>
    </drawable-list>
    </resources>
  • This is how it all looks:



    And finally sorry for multiple posts, when I put all the text in the same post I get an error about not being able to access the forum.
  • Are any of the dc calls you have working, and is it just the drawLine() that doesn't? If you are just doing dc calls, you don't need a layout, but if you use one, the order that you do things is important. When the layout is displayed, it will wipe out anything you did with dc calls, for example, so you only want dc calls after the layout is displayed. Maybe post the whole .mc and not just the dc calls?

    Ok, I see the screen shot - it looks to me that you do the dc calls and then lose everything when the layout is displayed....
  • Your code isn't complete since you don't show what widthX and widthY are (that name doesn't really make sense to me anyway, so I'm betting it is not what you want). Additionally, calling dc.clear() without setting the color doesn't make sense. After you do that, it seems that you are trying to clear the screen with a fillRectangle() call.

    I modified your code slightly so that it doesn't do these weird things, and so it displays something on a round watch face...

    function onUpdate(dc) {
    // testing
    dc.setColor(Gfx.COLOR_BLUE, Gfx.COLOR_RED);
    dc.clear();

    // test draw line
    dc.setColor(Gfx.COLOR_WHITE, Gfx.COLOR_TRANSPARENT);
    dc.setPenWidth(5);
    //dc.drawLine(5,5,25,25);
    dc.drawRectangle(100, 100, 25, 25);

    dc.drawText(150, 150, Gfx.FONT_SMALL, "test123", Gfx.TEXT_JUSTIFY_CENTER);
    }


    You mention layouts, but the code that you posted above does not draw the layout. If you are drawing to the dc and calling the base class to draw the layout, you should really be showing that in your code.

    it looks to me that you do the dc calls and then lose everything when the layout is displayed....

    Yes. I agree. Clearly the code snippet is not the code that is being used to draw the linked image.

    The rule is that if you are going to use layouts and draw directly with dc calls, you need to be sure to do the direct draws on top of the layout[/i]. This means that the dc calls need to happen after the layout is drawn (typically done via a call to View.onUpdate(dc)).

    Travis
  • Ignore widthX and widthY, they are declared and calculated earlier in the code. I just can't seem to post more than a certain number of lines in my replies because the forum keeps giving me an error. :(

    None of the dc calls below do anything as you can see in the screenshot. If setLayout is called by onLayout, when is the appropriate time to use dc calls to draw the layout?

    If I comment out the call to setLayout, so that function onLayout does absolutely nothing, my watchface becomes a blank black screen.

    // Load your resources here
    function onLayout(dc) {
    setLayout(Rez.Layouts.WatchFace(dc));
    }

    function onUpdate(dc) {
    dc.clear();
    dc.setColor(Gfx.COLOR_BLUE, Gfx.COLOR_WHITE);
    dc.fillRectangle(0, 0, widthX, widthY);

    dc.setColor(Gfx.COLOR_WHITE, Gfx.COLOR_TRANSPARENT);
    dc.setPenWidth(5);

    dc.drawRectangle(5, 5, 25, 25);

    dc.drawText(5, 5, Gfx.FONT_SMALL, "test123", Gfx.TEXT_JUSTIFY_CENTER);
    View.onUpdate(dc);
    }
  • You cannot call View.onUpdate(dc) after any calls to dc.

    Call dc statements after the View.onUpdate call.

    It is recommended that you use only one of the two drawing mechanisms:

    layouts or dc.

    Using the two together is tricky, but if you do, make sure to call any statements using dc after the View.onUpdate.

    Also then don't call dc.clear() as it will undo whatever was drawn in the layout by the View.onUpdate call.
  • Like Hermo said, delete the View.onUpdate(dc) from where it is, and replace the dc.clear() with View.onUpdate(dc).
  • Assuming that widthX and widthY are what I think, moving the View.onUpdate() call up to replace the call to dc.clear() isn't sufficient. The first dc.fillRectangle() call is essentially a call to dc.clear() and it needs to be removed as well.
  • True, I missed that one! And in fact, even without layouts, the dc.clear() and the dc.fillRectangle() would be redundant, if widthX and widthY are the dc's width and height.