initial commit
This commit is contained in:
41
source/Background/IBackground.mc
Normal file
41
source/Background/IBackground.mc
Normal file
@ -0,0 +1,41 @@
|
||||
import Toybox.Graphics;
|
||||
import Toybox.Lang;
|
||||
import Toybox.WatchUi;
|
||||
|
||||
class IBackground extends Drawable {
|
||||
|
||||
var Marks as Array<IMark> = new Array();
|
||||
|
||||
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]});
|
||||
|
||||
for (var s = 0; s < 60; s += 5) {
|
||||
Marks.add(IMark.getMark(IMark.LINE_MARK));
|
||||
}
|
||||
}
|
||||
|
||||
function draw(dc as Dc) as Void {
|
||||
drawBackground(dc);
|
||||
for (var i = 0; i < Marks.size(); ++i) {
|
||||
Marks[i].draw(dc);
|
||||
}
|
||||
}
|
||||
|
||||
function drawBackground(dc as Dc) as Void {}
|
||||
}
|
||||
78
source/Background/Marks/IMark.mc
Normal file
78
source/Background/Marks/IMark.mc
Normal file
@ -0,0 +1,78 @@
|
||||
import Toybox.Graphics;
|
||||
import Toybox.Lang;
|
||||
import Toybox.WatchUi;
|
||||
|
||||
class IMark extends Drawable {
|
||||
|
||||
var CenterShift as [Float, Float];
|
||||
var Color as ColorType;
|
||||
var Radius as Float;
|
||||
var Seconds as Number;
|
||||
|
||||
typedef MarkParams as {
|
||||
:Identifier as Object,
|
||||
:Type as MarkType,
|
||||
:Seconds as Number,
|
||||
:Color as ColorType,
|
||||
:HandsParams as IHands.HandsParams,
|
||||
};
|
||||
|
||||
enum MarkType {
|
||||
START_MARK,
|
||||
PRIMARY_MARK,
|
||||
SECONDARY_MARK,
|
||||
TERTIARY_MARK,
|
||||
}
|
||||
|
||||
enum MarkStyleType {
|
||||
LINE_MARK,
|
||||
DOT_MARK,
|
||||
ARABIC_MARK,
|
||||
}
|
||||
|
||||
static function getMark(style as MarkStyleType) as IMark {
|
||||
switch (style) {
|
||||
case LINE_MARK:
|
||||
default:
|
||||
return new LineMark({});
|
||||
}
|
||||
}
|
||||
|
||||
function initialize(options as MarkParams) {
|
||||
Drawable.initialize({:identifier => options[:Identifier]});
|
||||
|
||||
CenterShift = getOrElse(getOrElse(options[:HandsParams], {}), [0.0, 0.0]);
|
||||
Color = getOrElse(options[:Color], Graphics.COLOR_WHITE);
|
||||
Radius = getOrElse(options[:Radius], 1.0);
|
||||
Seconds = options[:Seconds];
|
||||
}
|
||||
|
||||
function draw(dc as Dc) as Void {
|
||||
var center = getCenter(dc, CenterShift);
|
||||
drawMark(dc, center[0], center[1]);
|
||||
}
|
||||
|
||||
function drawMark(dc as Dc, x as Float, y as Float) as Void {}
|
||||
|
||||
function getMarkType() as MarkType {
|
||||
switch (Seconds) {
|
||||
case 0:
|
||||
return START_MARK;
|
||||
case 15:
|
||||
case 30:
|
||||
case 45:
|
||||
return PRIMARY_MARK;
|
||||
case 5:
|
||||
case 10:
|
||||
case 20:
|
||||
case 25:
|
||||
case 35:
|
||||
case 40:
|
||||
case 50:
|
||||
case 55:
|
||||
return SECONDARY_MARK;
|
||||
default:
|
||||
return TERTIARY_MARK;
|
||||
}
|
||||
}
|
||||
}
|
||||
20
source/Background/Marks/LineMark.mc
Normal file
20
source/Background/Marks/LineMark.mc
Normal file
@ -0,0 +1,20 @@
|
||||
import Toybox.Graphics;
|
||||
import Toybox.Lang;
|
||||
import Toybox.WatchUi;
|
||||
|
||||
class LineMark extends IMark {
|
||||
|
||||
var InnerRadius as Float = 0.9;
|
||||
|
||||
function initialize(options as IMark.MarkParams) {
|
||||
IMark.initialize(options);
|
||||
}
|
||||
|
||||
function drawMark(dc as Dc, x as Float, y as Float) as Void {
|
||||
var angle = Math.toRadians(Seconds * 6.0);
|
||||
|
||||
dc.setColor(Color, Graphics.COLOR_TRANSPARENT);
|
||||
dc.drawLine(x + InnerRadius * Math.cos(angle), y + InnerRadius * Math.sin(angle),
|
||||
x + Radius * Math.cos(angle), y + Radius * Math.sin(angle));
|
||||
}
|
||||
}
|
||||
24
source/Background/SolidBackground.mc
Normal file
24
source/Background/SolidBackground.mc
Normal 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();
|
||||
}
|
||||
}
|
||||
59
source/Hands/IHands.mc
Normal file
59
source/Hands/IHands.mc
Normal file
@ -0,0 +1,59 @@
|
||||
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, CenterShift);
|
||||
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 {}
|
||||
}
|
||||
48
source/Hands/SimpleHands.mc
Normal file
48
source/Hands/SimpleHands.mc
Normal 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 color = getColor(handType);
|
||||
angle = Math.toRadians(angle - 90);
|
||||
length *= getLenght(handType);
|
||||
|
||||
dc.setColor(color, color);
|
||||
dc.drawLine(x, y, x + length * Math.cos(angle), y + length * Math.sin(angle));
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
||||
}
|
||||
23
source/Utils.mc
Normal file
23
source/Utils.mc
Normal file
@ -0,0 +1,23 @@
|
||||
import Toybox.Lang;
|
||||
import Toybox.Graphics;
|
||||
|
||||
// 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;
|
||||
}
|
||||
}
|
||||
|
||||
function getCenter(dc as Dc, shift as [Float, Float]) as [Float, Float] {
|
||||
return [dc.getWidth() / 2.0 + shift[0], dc.getHeight() / 2.0 + shift[1]];
|
||||
}
|
||||
33
source/wfApp.mc
Normal file
33
source/wfApp.mc
Normal 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
49
source/wfView.mc
Normal 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 {
|
||||
}
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user