How do I draw a simple heading arrow in the centre of the screen?

I’m been using tskf’s offline gps map for a while and I think it’s a brilliant data field but I would like to see if I could add a heading arrow (the code is open source) as I feel it would be perfect for me then.

The datafield does show your position as a red dot in the middle of the screen and appears to be generated simply by just these bits of code in the function onUpdate(dc) part of the lone MC file.

dc.setColor(0xFF0000, -1);

dc.fillRectangle(x-2, y-2, 4,4);

Not being a coder (although I have tried scratch) I have no idea if that is the case but I was wondering if it would be possible to replace that with a small heading arrow instead in the same position and if so how? I’d be very grateful for some help.

P.S: Just in case you think I might be being lazy asking like this I have tried to do it myself for a few days by looking at the samples and documentation then typing stuff out on eclipse but I can’t find myself understanding it very well. 

P.P.S: I would ask tskf themselves but I don’t want to bother them seeing as the field doesn’t appear to have been updated for over a year now.

  • Here's a simple view I put together to draw the arrow.  There's a timer where onUpdate is called every second, and the angle changes each time the timer ticks.

    import Toybox.Graphics;
    import Toybox.WatchUi;
    
    class triangleView extends WatchUi.View {
        var width, height,centerW,centerH;
        var angle=0;
    
        function initialize() {
            View.initialize();
    
    		var timer= new Timer.Timer();
    		timer.start( method(:onTimer),1000, true );
        }
    
        function onLayout(dc as Dc) as Void {
            width=dc.getWidth();
            centerW=width/2;
            height=dc.getHeight();
            centerH=height/2;
        }
    
        function onShow() as Void {
        }
    
        // Update the view
        function onUpdate(dc as Dc) as Void {
            dc.setColor(Graphics.COLOR_BLACK, Graphics.COLOR_BLACK);
            dc.clear();
            dc.setColor(Graphics.COLOR_WHITE, Graphics.COLOR_BLACK);
            dc.drawText(centerW,centerH,Graphics.FONT_MEDIUM,"Angle="+angle,Graphics.TEXT_JUSTIFY_CENTER|Graphics.TEXT_JUSTIFY_VCENTER);
            
            var angleC = (angle/360.0);
            angleC=angleC * Math.PI * 2;
            var ptC=generateHandCoordinates([centerW,centerH], angleC, (width/2)-2,0, 1);
            dc.fillCircle(ptC[2][0],ptC[2][1],2);
    
            var angleL=angle-5;
            if(angleL<0) {angleL=360+angleL;}
            angleL = (angleL/360.0) * Math.PI * 2;
            var ptL=generateHandCoordinates([centerW,centerH], angleL, (width/2)-(width/15),0, 1);
            dc.fillCircle(ptL[2][0],ptL[2][1],2);   
    
            var angleR=(angle+5)%360;
            angleR = (angleR/360.0) * Math.PI * 2;
            var ptR=generateHandCoordinates([centerW,centerH], angleR, (width/2)-(width/15),0, 1);
            dc.fillCircle(ptR[2][0],ptR[2][1],2);
    
            dc.setColor(Graphics.COLOR_ORANGE, Graphics.COLOR_BLACK);
            dc.fillPolygon([[ptC[2][0],ptC[2][1]],[ptR[2][0],ptR[2][1]],[ptL[2][0],ptL[2][1]],[ptC[2][0],ptC[2][1]]]);      
    
        }
    
        function onTimer() {
            WatchUi.requestUpdate();
            angle=(angle+1)%360;
        }
    
        function onHide() as Void {
        }
    
        private function generateHandCoordinates(centerPoint,angle, handLength, tailLength, width) {
            // Map out the coordinates of the watch hand
            var coords = [[-(width / 2), tailLength],
                          [-(width / 2), -handLength],
                          [width / 2, -handLength],
                          [width / 2, tailLength]];
            var result = new [4];
            var cos = Math.cos(angle);
            var sin = Math.sin(angle);
    
            // Transform the coordinates
            for (var i = 0; i < 4; i++) {
                var x = (coords[i][0] * cos) - (coords[i][1] * sin) + 0.5;
                var y = (coords[i][0] * sin) + (coords[i][1] * cos) + 0.5;
    
                result[i] = [centerPoint[0] + x, centerPoint[1] + y];
            }
    
            return result;
        }
    
    }
    It uses generateHandCoordinates() from the analog sample.
    I calculate the corners and draw a white dot, then the triangle in orange
    Here's how it looks in the sim:
  • As the original question was for having it in the center of the screen, I made some changes to the onUpdate() function I posted, and how it works is determined by the value of onEdge.  If true, it's on the edge as it was before.  If false, it's in the center of the screen.

        var onEdge=false;

        // Update the view
        function onUpdate(dc as Dc) as Void {
            dc.setColor(Graphics.COLOR_BLACK, Graphics.COLOR_BLACK);
            dc.clear();
            dc.setColor(Graphics.COLOR_WHITE, Graphics.COLOR_BLACK);
            var y=(onEdge) ? centerH : centerH/2;
            var w=(onEdge) ? 2 : 3;

            dc.drawText(centerW,y,Graphics.FONT_MEDIUM,"Angle="+angle,Graphics.TEXT_JUSTIFY_CENTER|Graphics.TEXT_JUSTIFY_VCENTER);
           
            var angleC = (angle/360.0);
            angleC=angleC * Math.PI * 2;
            var ptC=(onEdge)
                ? generateHandCoordinates([centerW,centerH], angleC, (width/2)-2,0, 1)
                : generateHandCoordinates([centerW,centerH], angleC, 15,10, 1);
            dc.fillCircle(ptC[2][0],ptC[2][1],2);

            var angleL=(onEdge) ? angle-5 : angle-45;
            if(angleL<0) {angleL=360+angleL;}
            angleL = (angleL/360.0) * Math.PI * 2;
            var ptL=(onEdge)
                ? generateHandCoordinates([centerW,centerH], angleL, (width/2)-(width/15),0, 1)
                : generateHandCoordinates([centerW,centerH], angleL,15,10, 1);

            dc.fillCircle(ptL[w][0],ptL[w][1],2);

            var angleR=(onEdge) ? (angle+5)%360 : (angle+45)%360;
            angleR = (angleR/360.0) * Math.PI * 2;
            var ptR=(onEdge)
                ? generateHandCoordinates([centerW,centerH], angleR, (width/2)-(width/15),0, 1)
                : generateHandCoordinates([centerW,centerH], angleR,15,10, 1);
            dc.fillCircle(ptR[w][0],ptR[w][1],2);

            dc.setColor(Graphics.COLOR_ORANGE, Graphics.COLOR_BLACK);
            dc.fillPolygon([[ptC[2][0],ptC[2][1]],[ptR[w][0],ptR[w][1]],[ptL[w][0],ptL[w][1]],[ptC[2][0],ptC[2][1]]]);      

        }
    Here's how onEdge=false looks