handling bimaps for Garmin watch face

Hello, I am new to Garmin watch faces.

I have started bulding one, and i would like to know how to handle bitmaps.

i can load the background image for my watch, and then the complications for hours, minutes and seconds.

But they are static, i want to know how to display them dynamically according to the current time.

and wether i should do that in the onUpdate() function or somwhere else.

Thank you)

  • Even if my watch face does complications, I just use the standard API calls for the time.  And yes, do it in onUpdate.

    in VS Code, do a Monkey C:New project and then watch face, and you'll see a very basic example of displaying the time.

    If you want "seconds all the time", look into onPartialUpdate.  See https://forums.garmin.com/developer/connect-iq/f/discussion/5156/1hz-watch-faces---q-a

    onPartialUpdate isn't available on AMOLED devices.

    Once you have the time, again in onUpdate, you can change the bitmaps based on the time.  A different on at different times.

  •  thank you for your reply.

    yeah i have succeded the first steps and already starting working on it.

    tha app was dispalying the background and the complications all in the center, but now when i tried to make the complication's positions dynamic somehow am stcuk and the complications are no longer displayed:

    <

    import Toybox.Graphics;
    import Toybox.Lang;
    import Toybox.System;
    import Toybox.WatchUi;


    class Garmin_watchView extends WatchUi.WatchFace {

    var background_bitmap;
    var timeLocX;
    var timeLocY;
    var hourComplication;
    var minuteComplication;
    var secondComplication;
    var batteryComplication;
    var stepsComplication;
    var heartComplication;

    function initialize() {
    WatchFace.initialize();

    background_bitmap = new WatchUi.Bitmap({
    :rezId=>Rez.Drawables.background_bitmap,
    :locX=>0,
    :locY=>0
    });

    hourComplication = new WatchUi.Bitmap({
    :rezId=>Rez.Drawables.hourComplication,
    :locX=>0,
    :locY=>0
    });

    minuteComplication = new WatchUi.Bitmap({
    :rezId=>Rez.Drawables.minuteComplication,
    :locX=>0,
    :locY=>0
    });

    secondComplication = new WatchUi.Bitmap({
    :rezId=>Rez.Drawables.secondComplication,
    :locX=>0,
    :locY=>0
    });

    batteryComplication = new WatchUi.Bitmap({
    :rezId=>Rez.Drawables.batteryComplication,
    :locX=>0,
    :locY=>0
    });

    stepsComplication = new WatchUi.Bitmap({
    :rezId=>Rez.Drawables.stepsComplication,
    :locX=>0,
    :locY=>0
    });

    heartComplication = new WatchUi.Bitmap({
    :rezId=>Rez.Drawables.heartComplication,
    :locX=>0,
    :locY=>0
    });
    timeLocX = 300;
    timeLocY = 180;
    }

    // Load your resources here
    function onLayout(dc as Dc) as Void {

    setLayout(Rez.Layouts.WatchFace(dc));
    }

    // Called when this View is brought to the foreground. Restore
    // the state of this View and prepare it to be shown. This includes
    // loading resources into memory.
    function onShow() as Void {
    }

    // Update the view
    function onUpdate(dc as Dc) as Void {
    dc.clear();
    // Draw the background image
    background_bitmap.draw(dc);
    drawWatchFace(dc);

    var clockTime = System.getClockTime();
    var timeString = Lang.format("$1$:$2$", [clockTime.hour, clockTime.min.format("%02d")]);
    dc.setColor(Graphics.COLOR_BLACK, Graphics.COLOR_TRANSPARENT);
    dc.drawText(
    timeLocX,
    timeLocY,
    Graphics.FONT_MEDIUM,
    timeString,
    Graphics.TEXT_JUSTIFY_CENTER
    );

    }
    // Called when this View is removed from the screen. Save the
    // state of this View here. This includes freeing resources from
    // memory.
    function onHide() as Void {
    }

    // The user has just looked at their watch. Timers and animations may be started here.
    function onExitSleep() as Void {
    }

    // Terminate any active timers and prepare for slow updates.
    function onEnterSleep() as Void {
    }

    function drawWatchFace(dc) {
    var currentTime = System.getClockTime();
    var centerX = dc.getWidth() / 2;
    var centerY = dc.getHeight() / 2;
    var radius = 100; // Adjust the radius as needed

    // Calculate the angles for hour, minute, and second
    var hourAngle = (360 / 12) * (currentTime.hour % 12);
    var minuteAngle = (360 / 60) * currentTime.min;
    var secondAngle = (360 / 60) * currentTime.sec;

    // Calculate the X and Y coordinates for each complication
    var hourComplicationX = centerX + (radius * Math.cos(Math.toRadians(hourAngle)));
    var hourComplicationY = centerY + (radius * Math.sin(Math.toRadians(hourAngle)));

    var minuteComplicationX = centerX + (radius * Math.cos(Math.toRadians(minuteAngle)));
    var minuteComplicationY = centerY + (radius * Math.sin(Math.toRadians(minuteAngle)));

    var secondComplicationX = centerX + (radius * Math.cos(Math.toRadians(secondAngle)));
    var secondComplicationY = centerY + (radius * Math.sin(Math.toRadians(secondAngle)));

    // Draw the hour complication bitmap
    dc.drawBitmap(hourComplicationX, hourComplicationY, hourComplication);

    // Draw the minute complication bitmap
    dc.drawBitmap(minuteComplicationX, minuteComplicationY, minuteComplication);

    // Draw the second complication bitmap
    dc.drawBitmap(secondComplicationX, secondComplicationY, secondComplication);
    }
    }

    >

  • Ok, so you aren't using Complications, and it's just an analog WF for now.  Have you looked at the analog sample in the SDK?  

  • am not sure about what you mean with analog WF.

    the analog sample is the default watch with numeric time shown when you first launch the app?

  • In the SDK folder, there is a folder called "samples", and one of those sample projects is named "analog"

  • in the sdk folder i have bin folder and resources folder and none of them contains samples.

    i will try to look elsewhere  for the folder.

  • i have seen on my ubuntu machine but now am workin with my windows one and i found it under Windows: %APPDATA%\Garmin\ConnectIQ\Sdks.

    I will check it.

    thank you)

  • wow this already looks complicated, and in my case i am not drawing them.

    i already have images for the hour, minute and second and i should make them rotate over the background image...

  • is this something i can consider or is it a waste of resources? the idea is to load images with different angles since i couldn't figure out how to rotate clock ticks images until now

    <

    var hourHandImages[12];
    var minuteHandImages[60];
    var secondHandImages[60];

    function initialize() {
    // Initialize hour hand images
    for (var i = 0; i < 12; i++) {
    hourHandImages[i] = new WatchUi.Bitmap({
    :rezId => Rez.Images.hourHandImage[i],
    :locX => 0,
    :locY => 0
    });
    }

    // Initialize minute hand images
    for (var i = 0; i < 60; i++) {
    minuteHandImages[i] = new WatchUi.Bitmap({
    :rezId => Rez.Images.minuteHandImage[i],
    :locX => 0,
    :locY => 0
    });
    }

    // Initialize second hand images
    for (var i = 0; i < 60; i++) {
    secondHandImages[i] = new WatchUi.Bitmap({
    :rezId => Rez.Images.secondHandImage[i],
    :locX => 0,
    :locY => 0
    });
    }

    // Other initialization code
    }

    function onUpdate(dc as Dc) as Void {
    // Get the current time
    var currentTime = System.getTime();

    // Get the hour, minute, and second values
    var hour = currentTime.hour;
    var minute = currentTime.min;
    var second = currentTime.sec;

    // Draw the hour hand
    hourHandImages[hour].draw(dc, hourLocX, hourLocY);

    // Draw the minute hand
    minuteHandImages[minute].draw(dc, minuteLocX, minuteLocY);

    // Draw the second hand
    secondHandImages[second].draw(dc, secondLocX, secondLocY);


    }

    >