initial commit

This commit is contained in:
2025-10-09 14:37:45 +03:00
commit 62d4800830
15 changed files with 364 additions and 0 deletions

View File

@ -0,0 +1,32 @@
import Toybox.Graphics;
import Toybox.Lang;
import Toybox.WatchUi;
class IBackground extends Drawable {
typedef BackgroundParams as {
:Identifier as Object,
};
enum BackgroundStyleType {
SOLID_BACKGROUND,
}
static function getBackground(style as BackgroundStyleType) as IBackground {
switch (style) {
case SOLID_BACKGROUND:
default:
return new SolidBackground({});
}
}
function initialize(options as BackgroundParams) {
Drawable.initialize({:identifier => options[:Identifier]});
}
function draw(dc as Dc) as Void {
drawBackground(dc);
}
function drawBackground(dc as Dc) as Void {}
}

View File

@ -0,0 +1,24 @@
import Toybox.Graphics;
import Toybox.Lang;
import Toybox.WatchUi;
class SolidBackground extends IBackground {
var Color as ColorType;
typedef SolidBackgroundParams as {
:BackgroundParams as IBackground.BackgroundParams,
:Color as ColorType,
};
function initialize(options as SolidBackgroundParams) {
IBackground.initialize(getOrElse(options[:BackgroundParams], {}));
Color = getOrElse(options[:Color], Graphics.COLOR_BLACK);
}
function drawBackground(dc as Dc) as Void {
dc.setColor(Graphics.COLOR_TRANSPARENT, Color);
dc.clear();
}
}

63
source/Hands/IHands.mc Normal file
View File

@ -0,0 +1,63 @@
import Toybox.Graphics;
import Toybox.Lang;
import Toybox.System;
import Toybox.WatchUi;
class IHands extends Drawable {
var CenterShift as [Float, Float];
var Radius as Float;
typedef HandsParams as {
:CenterShift as [Float, Float],
:Identifier as Object,
:Radius as Float,
};
enum HandType {
HOURS_HAND,
MINUTES_HAND,
SECONDS_HAND,
}
enum HandStyleType {
SIMPLE_HANDS,
}
static function getHands(style as HandStyleType) as IHands {
switch (style) {
case SIMPLE_HANDS:
default:
return new SimpleHands({});
}
}
function initialize(options as HandsParams) {
Drawable.initialize({:identifier => options[:Identifier]});
CenterShift = getOrElse(options[:CenterShift], [0.0, 0.0]);
Radius = getOrElse(options[:Radius], 0.9);
}
function draw(dc as Dc) as Void {
var now = System.getClockTime();
var center = getCenter(dc);
var length = Radius * min(center[0], center[1]);
var hourAngle = (now.hour % 12 + now.min / 60.0) * 30.0;
drawHand(dc, center[0], center[1], hourAngle, length, HOURS_HAND);
var minutesAngle = now.min * 6.0;
drawHand(dc, center[0], center[1], minutesAngle, length, MINUTES_HAND);
var secondsAngle = now.sec * 6.0;
drawHand(dc, center[0], center[1], secondsAngle, length, SECONDS_HAND);
}
function drawHand(dc as Dc, x as Float, y as Float, angle as Float, length as Float, handType as HandType) as Void {}
function getCenter(dc as Dc) as [Float, Float] {
return [dc.getWidth() / 2.0 + CenterShift[0], dc.getHeight() / 2.0 + CenterShift[1]];
}
}

View File

@ -0,0 +1,48 @@
import Toybox.Graphics;
import Toybox.Lang;
class SimpleHands extends IHands {
var Color as ColorType;
var SecondsColor as ColorType;
typedef SimpleHandsParams as {
:HandsParams as IHands.HandsParams,
:Color as ColorType,
:SecondsColor as ColorType,
};
function initialize(options as SimpleHandsParams) {
IHands.initialize(getOrElse(options[:HandsParams], {}));
Color = getOrElse(options[:Color], Graphics.COLOR_WHITE);
SecondsColor = getOrElse(options[:SecondsColor], Graphics.COLOR_RED);
}
function drawHand(dc as Dc, x as Float, y as Float, angle as Float, length as Float, handType as IHands.HandType) as Void {
var rad = (angle - 90) * Math.PI / 180.0;
var color = getColor(handType);
length *= getLenght(handType);
dc.setColor(color, color);
dc.drawLine(x, y, x + length * Math.cos(rad), y + length * Math.sin(rad));
}
private function getColor(handType as IHands.HandType) as ColorType {
switch (handType) {
case SECONDS_HAND:
return SecondsColor;
default:
return Color;
}
}
private function getLenght(handType as IHands.HandType) as Float {
switch (handType) {
case HOURS_HAND:
return 0.7;
default:
return 1.0;
}
}
}

20
source/Utils.mc Normal file
View File

@ -0,0 +1,20 @@
import Toybox.Lang;
typedef Numeric as Number or Float or Long or Double;
// no types here, because this is generic, which are not supported by language
function getOrElse(value, defaultValue) {
if (value == null) {
return defaultValue;
} else {
return value;
}
}
function min(left as Numeric, right as Numeric) as Numeric {
if (left < right) {
return left;
} else {
return right;
}
}

33
source/wfApp.mc Normal file
View File

@ -0,0 +1,33 @@
import Toybox.Application;
import Toybox.Lang;
import Toybox.WatchUi;
class wfApp extends Application.AppBase {
function initialize() {
AppBase.initialize();
}
// onStart() is called on application start up
function onStart(state as Dictionary?) as Void {
}
// onStop() is called when your application is exiting
function onStop(state as Dictionary?) as Void {
}
// Return the initial view of your application here
function getInitialView() as [Views] or [Views, InputDelegates] {
return [ new wfView() ];
}
// New app settings have been received so trigger a UI update
function onSettingsChanged() as Void {
WatchUi.requestUpdate();
}
}
function getApp() as wfApp {
return Application.getApp() as wfApp;
}

49
source/wfView.mc Normal file
View File

@ -0,0 +1,49 @@
import Toybox.Application;
import Toybox.Graphics;
import Toybox.Lang;
import Toybox.System;
import Toybox.WatchUi;
class wfView extends WatchUi.WatchFace {
private var hands as IHands;
private var background as IBackground;
function initialize() {
WatchFace.initialize();
hands = IHands.getHands(IHands.SIMPLE_HANDS);
background = IBackground.getBackground(IBackground.SOLID_BACKGROUND);
}
// Load your resources here
function onLayout(dc as Dc) as Void {
}
// 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 {
background.draw(dc);
hands.draw(dc);
}
// 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 {
}
}