Wednesday, November 18, 2020

Building a Garmin Watch Widget | Part 3: The UI

Once I had my Sun Compass Widget calculating the correct azimuth for the Sun, I was left with one more challenge: rendering this information graphically. My plan was to generate a simplified compass dial and then plot the current location of the Sun on it. The first hurdle was to realize I had to stop using XML based layouts and program the UI directly using the Dc object. The second challenge was learning how to convert polar to rectangular coordinates. With these obstacles surmounted, the UI came together with ease:

The above UI is drawn using a this strategy:

 for(degrees = 0; degrees < 365; degrees++) {
   var color = i % 90 == 0 ? "red" : "gray";
   drawDot(degrees, color);
 var start = pol2rect(watchFaceWidth / 2, azimuth);
 var end   = pol2rect((watchFaceWidth / 2) - 5, azimuth);
 drawLine(start, end, "yellow");

In short: once you can think of a round watch dial as a polar coordinate space, working with it becomes a breeze.

Looking at the above UI, I realized that along with creating a compass I'd also started down the path of creating a solar clock. For example, when the Sun is due South, it's solar noon. To build on this idea, I added markings for sunrise and sunset.

In the above UI, the red dots represent cardinal directions, the yellow line represents the position of the sun and the green lines represent sunrise and sunset. You can tell this screenshot was taken about an hour after sunrise. You can also tell this was taken in the winter when the day is relatively short and the Sun will never be due East or West.

I built the above app for my watch, loaded it on my Vivoactive 4 and spent a week field testing it in the Blue Ridge Mountains.

Generally, the widget performed well. It loaded quickly and always displayed accurate information. The biggest shortcoming: the effort needed to derive my current direction. To figure this out, I had to either stop and rotate my body until the yellow mark lined up with the Sun, take off my watch and line the yellow mark up up with the Sun, or attempt to do this translation mentally. While in motion, none of those options were ideal. I wanted the watch to do the work, not me. So I added the following feature.

By default, the widget shows a North-is-up view:

Clicking the top watch button rotates through a series of variations. It shows the compass with the sun ahead, to the right, behind and to the left of me:

The idea is that I can re-orient the display to roughly match where the Sun is relative to me at that moment. For example if the Sun is roughly behind me, I can click through until the compass dial shows this, and then use the cardinal markings to learn my direction.  This view is sticky, so re-checking the Sun Compass a few minutes later doesn't require me clicking through the options again.

I've now got this version running on my watch and I psyched to field test it. Once I'm satisfied with the UI, I'll finish off this project by uploading it to the Garmin IQ Store so others can give the widget a try.

As always, check out the code for this project on github.

No comments:

Post a Comment