From d75a0b235d6a64fceee46aced593b4523b68759b Mon Sep 17 00:00:00 2001 From: Evgenii Alekseev Date: Thu, 9 Oct 2025 14:37:45 +0300 Subject: [PATCH] initial commit --- .gitignore | 1 + manifest.xml | 35 +++++++++++++ monkey.jungle | 1 + resources/drawables/drawables.xml | 3 ++ resources/drawables/launcher_icon.svg | 5 ++ resources/layouts/layout.xml | 4 ++ resources/settings/properties.xml | 7 +++ resources/settings/settings.xml | 25 +++++++++ resources/strings/strings.xml | 16 ++++++ source/Hands/Hands.mc | 47 +++++++++++++++++ source/Hands/SimpleHands.mc | 48 +++++++++++++++++ source/Utils.mc | 20 ++++++++ source/wfApp.mc | 33 ++++++++++++ source/wfBackground.mc | 22 ++++++++ source/wfView.mc | 74 +++++++++++++++++++++++++++ 15 files changed, 341 insertions(+) create mode 100644 .gitignore create mode 100644 manifest.xml create mode 100755 monkey.jungle create mode 100755 resources/drawables/drawables.xml create mode 100755 resources/drawables/launcher_icon.svg create mode 100755 resources/layouts/layout.xml create mode 100755 resources/settings/properties.xml create mode 100755 resources/settings/settings.xml create mode 100644 resources/strings/strings.xml create mode 100644 source/Hands/Hands.mc create mode 100644 source/Hands/SimpleHands.mc create mode 100644 source/Utils.mc create mode 100644 source/wfApp.mc create mode 100644 source/wfBackground.mc create mode 100644 source/wfView.mc diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..e660fd9 --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +bin/ diff --git a/manifest.xml b/manifest.xml new file mode 100644 index 0000000..940e53d --- /dev/null +++ b/manifest.xml @@ -0,0 +1,35 @@ + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/monkey.jungle b/monkey.jungle new file mode 100755 index 0000000..87796c7 --- /dev/null +++ b/monkey.jungle @@ -0,0 +1 @@ +project.manifest = manifest.xml diff --git a/resources/drawables/drawables.xml b/resources/drawables/drawables.xml new file mode 100755 index 0000000..6302154 --- /dev/null +++ b/resources/drawables/drawables.xml @@ -0,0 +1,3 @@ + + + diff --git a/resources/drawables/launcher_icon.svg b/resources/drawables/launcher_icon.svg new file mode 100755 index 0000000..e80aa20 --- /dev/null +++ b/resources/drawables/launcher_icon.svg @@ -0,0 +1,5 @@ + + + + + diff --git a/resources/layouts/layout.xml b/resources/layouts/layout.xml new file mode 100755 index 0000000..a1dea68 --- /dev/null +++ b/resources/layouts/layout.xml @@ -0,0 +1,4 @@ + + + \ No newline at end of file diff --git a/resources/settings/properties.xml b/resources/settings/properties.xml new file mode 100755 index 0000000..ca0d9ef --- /dev/null +++ b/resources/settings/properties.xml @@ -0,0 +1,7 @@ + + + 0x000000 + 0xFF0000 + false + + diff --git a/resources/settings/settings.xml b/resources/settings/settings.xml new file mode 100755 index 0000000..47f6c80 --- /dev/null +++ b/resources/settings/settings.xml @@ -0,0 +1,25 @@ + + + + + @Strings.ColorBlack + @Strings.ColorDarkGray + @Strings.ColorLightGray + @Strings.ColorWhite + + + + + + @Strings.ColorBlack + @Strings.ColorBlue + @Strings.ColorRed + @Strings.ColorWhite + + + + + + + + diff --git a/resources/strings/strings.xml b/resources/strings/strings.xml new file mode 100644 index 0000000..1754403 --- /dev/null +++ b/resources/strings/strings.xml @@ -0,0 +1,16 @@ + + + wf + + Background Color + Foreground Color + Military Format for 24 Hour Time + + Black + Dark Gray + Light Gray + White + Blue + Red + + diff --git a/source/Hands/Hands.mc b/source/Hands/Hands.mc new file mode 100644 index 0000000..a7f2778 --- /dev/null +++ b/source/Hands/Hands.mc @@ -0,0 +1,47 @@ + import Toybox.Graphics; + import Toybox.Lang; + import Toybox.System; + import Toybox.WatchUi; + + class Hands extends Drawable { + + var CenterShift as [Float, Float]; + + enum HandType { + HOURS, + MINUTES, + SECONDS, + } + + typedef HandsParams as { + :CenterShift as [Float, Float], + }; + + function initialize(options as HandsParams) { + WatchUi.Drawable.initialize({}); + + CenterShift = getOrElse(options[:CenterShift], [0.0, 0.0]); + } + + function draw(dc as Dc) as Void { + var now = System.getClockTime(); + + var center = getCenter(dc); + var length = 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); + + var minutesAngle = now.min * 6.0; + drawHand(dc, center[0], center[1], minutesAngle, length, MINUTES); + + var secondsAngle = now.sec * 6.0; + drawHand(dc, center[0], center[1], secondsAngle, length, SECONDS); + } + + 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]]; + } + } \ No newline at end of file diff --git a/source/Hands/SimpleHands.mc b/source/Hands/SimpleHands.mc new file mode 100644 index 0000000..024c64f --- /dev/null +++ b/source/Hands/SimpleHands.mc @@ -0,0 +1,48 @@ +import Toybox.Graphics; +import Toybox.Lang; + +class SimpleHands extends Hands { + + var mColor as ColorType; + var mSecondsColor as ColorType; + + typedef SimpleHandsParams as { + :HandsParams as Hands.HandsParams, + :Color as ColorType, + :SecondsColor as ColorType, + }; + + function initialize(options as SimpleHandsParams) { + Hands.initialize(getOrElse(options[:HandsParams], {})); + + mColor = getOrElse(options[:Color], Graphics.COLOR_WHITE); + mSecondsColor = 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 Hands.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 Hands.HandType) as ColorType { + switch (handType) { + case Hands.SECONDS: + return mSecondsColor; + default: + return mColor; + } + } + + private function getLenght(handType as Hands.HandType) as Float { + switch (handType) { + case Hands.HOURS: + return 0.6; + default: + return 0.9; + } + } +} \ No newline at end of file diff --git a/source/Utils.mc b/source/Utils.mc new file mode 100644 index 0000000..24834ce --- /dev/null +++ b/source/Utils.mc @@ -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; + } +} \ No newline at end of file diff --git a/source/wfApp.mc b/source/wfApp.mc new file mode 100644 index 0000000..eacfada --- /dev/null +++ b/source/wfApp.mc @@ -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; +} \ No newline at end of file diff --git a/source/wfBackground.mc b/source/wfBackground.mc new file mode 100644 index 0000000..a620072 --- /dev/null +++ b/source/wfBackground.mc @@ -0,0 +1,22 @@ +import Toybox.Application; +import Toybox.Graphics; +import Toybox.Lang; +import Toybox.WatchUi; + +class Background extends WatchUi.Drawable { + + function initialize() { + var dictionary = { + :identifier => "Background" + }; + + Drawable.initialize(dictionary); + } + + function draw(dc as Dc) as Void { + // Set the background color then call to clear the screen + dc.setColor(Graphics.COLOR_TRANSPARENT, getApp().getProperty("BackgroundColor") as Number); + dc.clear(); + } + +} diff --git a/source/wfView.mc b/source/wfView.mc new file mode 100644 index 0000000..fe398d2 --- /dev/null +++ b/source/wfView.mc @@ -0,0 +1,74 @@ +import Toybox.Application; +import Toybox.Graphics; +import Toybox.Lang; +import Toybox.System; +import Toybox.WatchUi; + +class wfView extends WatchUi.WatchFace { + + private var hands as Hands; + + function initialize() { + WatchFace.initialize(); + hands = new SimpleHands({}); + } + + // 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 { + // // Get the current time and format it correctly + // var timeFormat = "$1$:$2$"; + // var clockTime = System.getClockTime(); + // var hours = clockTime.hour; + // if (!System.getDeviceSettings().is24Hour) { + // if (hours > 12) { + // hours = hours - 12; + // } + // } else { + // if (Application.Properties.getValue("UseMilitaryFormat")) { + // timeFormat = "$1$$2$"; + // hours = hours.format("%02d"); + // } + // } + // var timeString = Lang.format(timeFormat, [hours, clockTime.min.format("%02d")]); + + // // Update the view + // var view = View.findDrawableById("TimeLabel") as Text; + // view.setColor(Application.Properties.getValue("ForegroundColor") as Number); + // view.setText(timeString); + + // // Call the parent onUpdate function to redraw the layout + // View.onUpdate(dc); + // } + function onUpdate(dc as Dc) as Void { + dc.setColor(Graphics.COLOR_BLACK, Graphics.COLOR_BLACK); + dc.clear(); + + 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 { + } + +}