initial commit
This commit is contained in:
113
source/Background/IBackground.mc
Normal file
113
source/Background/IBackground.mc
Normal file
@ -0,0 +1,113 @@
|
||||
import Toybox.Application.Properties;
|
||||
import Toybox.Graphics;
|
||||
import Toybox.Lang;
|
||||
import Toybox.WatchUi;
|
||||
|
||||
class IBackground extends Drawable {
|
||||
|
||||
var Color as ColorType;
|
||||
var Hands as Array<IHand> = [];
|
||||
var Marks as Array<IMark> = [];
|
||||
|
||||
typedef BackgroundParams as {
|
||||
:Identifier as Object,
|
||||
:Color as ColorType,
|
||||
:Hands as Array<IHand.HandType>,
|
||||
};
|
||||
|
||||
enum BackgroundStyleType {
|
||||
SOLID_BACKGROUND,
|
||||
}
|
||||
|
||||
static function getBackground(style as BackgroundStyleType, options as BackgroundParams) as IBackground {
|
||||
switch (style) {
|
||||
case SOLID_BACKGROUND:
|
||||
default:
|
||||
return new SolidBackground(options);
|
||||
}
|
||||
}
|
||||
|
||||
function initialize(options as BackgroundParams) {
|
||||
var identifier = options[:Identifier];
|
||||
Drawable.initialize({:identifier => identifier});
|
||||
|
||||
Color = Properties.getValue(Lang.format("$1$/Background/Color", [identifier])) as ColorType;
|
||||
|
||||
for (var seconds = 0; seconds < 60; ++seconds) {
|
||||
var markType = IMark.getMarkType(seconds);
|
||||
|
||||
var markIdentifier = Lang.format("$1$/Marks/$2$", [identifier, markType]);
|
||||
var markStyle = Properties.getValue(Lang.format("$1$/Type", [markIdentifier])) as IMark.MarkStyleType;
|
||||
|
||||
var mark = IMark.getMark(markStyle, markType, {
|
||||
:Identifier => markIdentifier,
|
||||
:BackgroundColor => Color,
|
||||
:Color => Properties.getValue(Lang.format("$1$/Color", [markIdentifier])) as ColorType,
|
||||
:Seconds => seconds,
|
||||
:Size => markType == IMark.TERTIARY_MARK ? 0.033 : 0.1,
|
||||
});
|
||||
if (mark != null) {
|
||||
Marks.add(mark);
|
||||
}
|
||||
}
|
||||
|
||||
var hands = options[:Hands];
|
||||
for (var i = 0; i < hands.size(); ++i) {
|
||||
var handType = hands[i];
|
||||
|
||||
var handIdentifier = Lang.format("$1$/Hands/$2$", [identifier, handType]);
|
||||
var handStyle = Properties.getValue(Lang.format("$1$/Type", [handIdentifier])) as IHand.HandStyleType;
|
||||
var handColor = Properties.getValue(Lang.format("$1$/Color", [handIdentifier])) as ColorType;
|
||||
|
||||
// hand itself
|
||||
var hand = IHand.getHand(handStyle, {
|
||||
:Identifier => handIdentifier,
|
||||
:BackgroundColor => Color,
|
||||
:Color => handColor,
|
||||
:Type => handType,
|
||||
});
|
||||
if (hand != null) {
|
||||
Hands.add(hand);
|
||||
}
|
||||
// counter hand
|
||||
hand = IHand.getHand(handStyle, {
|
||||
:Identifier => handIdentifier,
|
||||
:BackgroundColor => Color,
|
||||
:Color => handColor,
|
||||
:Rotate => 180.0,
|
||||
:Type => handType,
|
||||
:Field => {
|
||||
:Radius => 0.1,
|
||||
},
|
||||
});
|
||||
if (hand != null) {
|
||||
Hands.add(hand);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function draw(dc as Dc) as Void {
|
||||
drawBackground(dc);
|
||||
for (var i = 0; i < Marks.size(); ++i) {
|
||||
Marks[i].draw(dc);
|
||||
}
|
||||
|
||||
var widths = [] as Array<Float>;
|
||||
var circleColor = null as ColorType;
|
||||
for (var i = 0; i < Hands.size(); ++i) {
|
||||
Hands[i].draw(dc);
|
||||
widths.add(Hands[i].Width);
|
||||
circleColor = Hands[i].Color;
|
||||
}
|
||||
|
||||
var center = getCenter(dc, [0, 0]);
|
||||
var circleWidth = max(widths) * min(center);
|
||||
dc.setColor(circleColor, circleColor);
|
||||
dc.fillCircle(center[0], center[1], circleWidth);
|
||||
|
||||
dc.setColor(Color, Color);
|
||||
dc.fillCircle(center[0], center[1], circleWidth * 0.5);
|
||||
}
|
||||
|
||||
function drawBackground(dc as Dc) as Void {}
|
||||
}
|
||||
15
source/Background/SolidBackground.mc
Normal file
15
source/Background/SolidBackground.mc
Normal file
@ -0,0 +1,15 @@
|
||||
import Toybox.Graphics;
|
||||
import Toybox.Lang;
|
||||
import Toybox.WatchUi;
|
||||
|
||||
class SolidBackground extends IBackground {
|
||||
|
||||
function initialize(options as IBackground.BackgroundParams) {
|
||||
IBackground.initialize(options);
|
||||
}
|
||||
|
||||
function drawBackground(dc as Dc) as Void {
|
||||
dc.setColor(Graphics.COLOR_TRANSPARENT, Color);
|
||||
dc.clear();
|
||||
}
|
||||
}
|
||||
21
source/Drawables.mc
Normal file
21
source/Drawables.mc
Normal file
@ -0,0 +1,21 @@
|
||||
import Toybox.Graphics;
|
||||
import Toybox.Lang;
|
||||
import Toybox.Math;
|
||||
|
||||
function fillSuperellipse(dc as Dc, start as Point2D, direction as Point2D, length as Float, width as Float) {
|
||||
var halfWidth = min(start) * width / 2.0;
|
||||
var perpendicular = [-direction[1], direction[0]] as Point2D;
|
||||
var end = [start[0] + direction[0] * length, start[1] + direction[1] * length];
|
||||
|
||||
// body part
|
||||
dc.fillPolygon([
|
||||
[start[0] + perpendicular[0] * halfWidth, start[1] + perpendicular[1] * halfWidth],
|
||||
[start[0] - perpendicular[0] * halfWidth, start[1] - perpendicular[1] * halfWidth],
|
||||
[end[0] - perpendicular[0] * halfWidth, end[1] - perpendicular[1] * halfWidth],
|
||||
[end[0] + perpendicular[0] * halfWidth, end[1] + perpendicular[1] * halfWidth],
|
||||
]);
|
||||
|
||||
// ends
|
||||
dc.fillCircle(start[0], start[1], halfWidth);
|
||||
dc.fillCircle(end[0], end[1], halfWidth);
|
||||
}
|
||||
7
source/Field.mc
Normal file
7
source/Field.mc
Normal file
@ -0,0 +1,7 @@
|
||||
import Toybox.Graphics;
|
||||
import Toybox.Lang;
|
||||
|
||||
typedef FieldParams as {
|
||||
:CenterShift as Point2D,
|
||||
:Radius as Float,
|
||||
};
|
||||
26
source/Hands/BatonHand.mc
Normal file
26
source/Hands/BatonHand.mc
Normal file
@ -0,0 +1,26 @@
|
||||
import Toybox.Graphics;
|
||||
import Toybox.Lang;
|
||||
|
||||
class BatonHand extends IHand {
|
||||
|
||||
function initialize(options as IHand.HandParams) {
|
||||
IHand.initialize(options);
|
||||
}
|
||||
|
||||
function drawHand(dc as Dc, start as Point2D, length as Float) as Void {
|
||||
var angle = Math.toRadians(getAngle(null) - 90);
|
||||
var direction = [Math.cos(angle), Math.sin(angle)] as Point2D;
|
||||
|
||||
// body part
|
||||
dc.setColor(Color, Color);
|
||||
fillSuperellipse(dc, start, direction, length, Width);
|
||||
|
||||
// fill
|
||||
dc.setColor(BackgroundColor, BackgroundColor);
|
||||
var holeStart = [
|
||||
start[0] + direction[0] * length * 0.33,
|
||||
start[1] + direction[1] * length * 0.33
|
||||
] as Point2D;
|
||||
fillSuperellipse(dc, holeStart, direction, length * 0.66, Width * 0.66);
|
||||
}
|
||||
}
|
||||
99
source/Hands/IHand.mc
Normal file
99
source/Hands/IHand.mc
Normal file
@ -0,0 +1,99 @@
|
||||
import Toybox.Graphics;
|
||||
import Toybox.Lang;
|
||||
import Toybox.System;
|
||||
import Toybox.WatchUi;
|
||||
|
||||
class IHand extends Drawable {
|
||||
|
||||
var BackgroundColor as ColorType;
|
||||
var CenterShift as Point2D;
|
||||
var Color as ColorType;
|
||||
var Radius as Float;
|
||||
var Rotate as Float;
|
||||
var Type as HandType;
|
||||
var Width as Float;
|
||||
|
||||
typedef HandParams as {
|
||||
:Identifier as Object,
|
||||
:Color as ColorType,
|
||||
:Rotate as Float,
|
||||
:Type as HandType,
|
||||
:Width as Float,
|
||||
:Field as FieldParams,
|
||||
};
|
||||
|
||||
enum HandType {
|
||||
OTHER_HAND = 0,
|
||||
HOURS_HAND = 1,
|
||||
MINUTES_HAND = 2,
|
||||
SECONDS_HAND = 3,
|
||||
}
|
||||
|
||||
enum HandStyleType {
|
||||
EMPTY_HANDS = 0,
|
||||
SIMPLE_HANDS = 1,
|
||||
BATON_HANDS = 2,
|
||||
}
|
||||
|
||||
static function getHand(style as HandStyleType, options as HandParams) as IHand? {
|
||||
switch (style) {
|
||||
case SIMPLE_HANDS:
|
||||
return new SimpleHand(options);
|
||||
case BATON_HANDS:
|
||||
return new BatonHand(options);
|
||||
case EMPTY_HANDS:
|
||||
default:
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
function initialize(options as HandParams) {
|
||||
Drawable.initialize({:identifier => options[:Identifier]});
|
||||
|
||||
// scene
|
||||
var field = getOrElse(options[:Field], {}) as FieldParams;
|
||||
CenterShift = getOrElse(field[:CenterShift], [0.0, 0.0]);
|
||||
Radius = 0.95 * getOrElse(field[:Radius], 1.0);
|
||||
|
||||
// properties
|
||||
BackgroundColor = options[:BackgroundColor];
|
||||
Color = options[:Color];
|
||||
Rotate = getOrElse(options[:Rotate], 0.0);
|
||||
Type = options[:Type];
|
||||
Width = Radius * getOrElse(options[:Witdh], 0.05);
|
||||
}
|
||||
|
||||
function draw(dc as Dc) as Void {
|
||||
var center = getCenter(dc, CenterShift);
|
||||
var length = Radius * min(center) * getLenght(Type);
|
||||
drawHand(dc, center, length);
|
||||
}
|
||||
|
||||
function drawHand(dc as Dc, start as Point2D, length as Float) as Void {}
|
||||
|
||||
function getAngle(angle as Float?) as Float? {
|
||||
var now = System.getClockTime();
|
||||
switch (Type) {
|
||||
case HOURS_HAND:
|
||||
angle = (now.hour % 12 + now.min / 60.0) * 30.0;
|
||||
break;
|
||||
case MINUTES_HAND:
|
||||
angle = now.min * 6.0;
|
||||
break;
|
||||
case SECONDS_HAND:
|
||||
angle = now.sec * 6.0;
|
||||
break;
|
||||
}
|
||||
|
||||
return angle + Rotate;
|
||||
}
|
||||
|
||||
function getLenght(handType as HandType) as Float {
|
||||
switch (handType) {
|
||||
case HOURS_HAND:
|
||||
return 0.7;
|
||||
default:
|
||||
return 1.0;
|
||||
}
|
||||
}
|
||||
}
|
||||
18
source/Hands/SimpleHand.mc
Normal file
18
source/Hands/SimpleHand.mc
Normal file
@ -0,0 +1,18 @@
|
||||
import Toybox.Graphics;
|
||||
import Toybox.Lang;
|
||||
|
||||
class SimpleHand extends IHand {
|
||||
|
||||
function initialize(options as IHand.HandParams) {
|
||||
IHand.initialize(options);
|
||||
}
|
||||
|
||||
function drawHand(dc as Dc, start as Point2D, length as Float) as Void {
|
||||
var angle = Math.toRadians(getAngle(null) - 90);
|
||||
dc.setColor(Color, Color);
|
||||
dc.drawLine(
|
||||
start[0], start[1],
|
||||
start[0] + length * Math.cos(angle), start[1] + length * Math.sin(angle)
|
||||
);
|
||||
}
|
||||
}
|
||||
29
source/Marks/ArabicMark.mc
Normal file
29
source/Marks/ArabicMark.mc
Normal file
@ -0,0 +1,29 @@
|
||||
import Toybox.Graphics;
|
||||
import Toybox.Lang;
|
||||
import Toybox.WatchUi;
|
||||
|
||||
class ArabicMark extends IMark {
|
||||
|
||||
var Font as FontType;
|
||||
|
||||
function initialize(options as IMark.MarkParams) {
|
||||
IMark.initialize(options);
|
||||
|
||||
Font = getOrElse(options[:Font], Graphics.FONT_SMALL);
|
||||
}
|
||||
|
||||
function drawMark(dc as Dc, start as Point2D, length as Float) as Void {
|
||||
var angle = getAngle();
|
||||
var text = secondsToText();
|
||||
var dimentions = dc.getTextDimensions(text, Font);
|
||||
|
||||
dc.setColor(Color, Graphics.COLOR_TRANSPARENT);
|
||||
dc.drawText(start[0] + length * InnerRadius * Math.cos(angle) - dimentions[0] / 2.0,
|
||||
start[1] + length * InnerRadius * Math.sin(angle) - dimentions[1] / 2.0,
|
||||
Font, text, Graphics.TEXT_JUSTIFY_LEFT);
|
||||
}
|
||||
|
||||
function secondsToText() as String? {
|
||||
return getHours().toString();
|
||||
}
|
||||
}
|
||||
19
source/Marks/DotMark.mc
Normal file
19
source/Marks/DotMark.mc
Normal file
@ -0,0 +1,19 @@
|
||||
import Toybox.Graphics;
|
||||
import Toybox.Lang;
|
||||
import Toybox.WatchUi;
|
||||
|
||||
class DotMark extends IMark {
|
||||
|
||||
function initialize(options as IMark.MarkParams) {
|
||||
IMark.initialize(options);
|
||||
}
|
||||
|
||||
function drawMark(dc as Dc, start as Point2D, length as Float) as Void {
|
||||
var angle = getAngle();
|
||||
|
||||
dc.setColor(Color, Graphics.COLOR_TRANSPARENT);
|
||||
dc.fillCircle(start[0] + length * InnerRadius * Math.cos(angle),
|
||||
start[1] + length * InnerRadius * Math.sin(angle),
|
||||
length * Size / 2.0);
|
||||
}
|
||||
}
|
||||
26
source/Marks/DoubleLineMark.mc
Normal file
26
source/Marks/DoubleLineMark.mc
Normal file
@ -0,0 +1,26 @@
|
||||
import Toybox.Graphics;
|
||||
import Toybox.Lang;
|
||||
import Toybox.WatchUi;
|
||||
|
||||
class DoubleLineMark extends IMark {
|
||||
|
||||
var Offset as Float = Math.toRadians(1.0);
|
||||
|
||||
function initialize(options as IMark.MarkParams) {
|
||||
IMark.initialize(options);
|
||||
}
|
||||
|
||||
function drawMark(dc as Dc, start as Point2D, length as Float) as Void {
|
||||
var angle = getAngle();
|
||||
|
||||
dc.setColor(Color, Color);
|
||||
dc.drawLine(start[0] + length * InnerRadius * Math.cos(angle - Offset),
|
||||
start[1] + length * InnerRadius * Math.sin(angle - Offset),
|
||||
start[0] + length * Radius * Math.cos(angle - Offset),
|
||||
start[1] + length * Radius * Math.sin(angle - Offset));
|
||||
dc.drawLine(start[0] + length * InnerRadius * Math.cos(angle + Offset),
|
||||
start[1] + length * InnerRadius * Math.sin(angle + Offset),
|
||||
start[0] + length * Radius * Math.cos(angle + Offset),
|
||||
start[1] + length * Radius * Math.sin(angle + Offset));
|
||||
}
|
||||
}
|
||||
122
source/Marks/IMark.mc
Normal file
122
source/Marks/IMark.mc
Normal file
@ -0,0 +1,122 @@
|
||||
import Toybox.Graphics;
|
||||
import Toybox.Lang;
|
||||
import Toybox.WatchUi;
|
||||
|
||||
class IMark extends Drawable {
|
||||
|
||||
var BackgroundColor as ColorType;
|
||||
var CenterShift as Point2D;
|
||||
var Color as ColorType;
|
||||
var InnerRadius as Float;
|
||||
var Radius as Float;
|
||||
var Seconds as Number;
|
||||
var Size as Float;
|
||||
|
||||
typedef MarkParams as {
|
||||
:Identifier as Object,
|
||||
:Color as ColorType,
|
||||
:Font as FontType, // not used
|
||||
:Seconds as Number,
|
||||
:Size as Float,
|
||||
:Field as FieldParams,
|
||||
};
|
||||
|
||||
enum MarkType {
|
||||
START_MARK = 0,
|
||||
PRIMARY_MARK = 1,
|
||||
SECONDARY_MARK = 2,
|
||||
TERTIARY_MARK = 3,
|
||||
}
|
||||
|
||||
enum MarkStyleType {
|
||||
EMPTY_MARK = 0,
|
||||
LINE_MARK = 1,
|
||||
DOUBLE_LINE_MARK = 2,
|
||||
DOT_MARK = 3,
|
||||
ARABIC_MARK = 4,
|
||||
ROMAN_MARK = 5,
|
||||
}
|
||||
|
||||
static function getMark(style as MarkStyleType, type as MarkType, options as MarkParams) as IMark? {
|
||||
switch (style) {
|
||||
case LINE_MARK:
|
||||
return new LineMark(options);
|
||||
case DOUBLE_LINE_MARK:
|
||||
return new DoubleLineMark(options);
|
||||
case DOT_MARK:
|
||||
return new DotMark(options);
|
||||
case ARABIC_MARK:
|
||||
return type == TERTIARY_MARK ? null : new ArabicMark(options);
|
||||
case ROMAN_MARK:
|
||||
return type == TERTIARY_MARK ? null : new RomanMark(options);
|
||||
case EMPTY_MARK:
|
||||
default:
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
static function getMarkType(seconds as Number) 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;
|
||||
}
|
||||
}
|
||||
|
||||
function initialize(options as MarkParams) {
|
||||
Drawable.initialize({:identifier => options[:Identifier]});
|
||||
|
||||
// scene
|
||||
var field = getOrElse(options[:Field], {}) as FieldParams;
|
||||
CenterShift = getOrElse(field[:CenterShift], [0.0, 0.0]);
|
||||
Radius = getOrElse(field[:Radius], 1.0);
|
||||
|
||||
// properties
|
||||
BackgroundColor = options[:BackgroundColor];
|
||||
Color = options[:Color];
|
||||
Seconds = options[:Seconds];
|
||||
Size = options[:Size];
|
||||
|
||||
// calculated
|
||||
InnerRadius = Radius * (1 - Size);
|
||||
}
|
||||
|
||||
function draw(dc as Dc) as Void {
|
||||
var center = getCenter(dc, CenterShift);
|
||||
var length = min(center);
|
||||
drawMark(dc, center, length);
|
||||
}
|
||||
|
||||
function drawMark(dc as Dc, start as Point2D, length as Float) as Void {}
|
||||
|
||||
function getAngle() as Float {
|
||||
return Math.toRadians(Seconds * 6.0 - 90);
|
||||
}
|
||||
|
||||
function getHours() as Number? {
|
||||
if (Seconds % 5 != 0) {
|
||||
return null;
|
||||
}
|
||||
|
||||
var hours = Seconds / 5;
|
||||
if (hours == 0) {
|
||||
return 12;
|
||||
}
|
||||
|
||||
return hours;
|
||||
}
|
||||
}
|
||||
20
source/Marks/LineMark.mc
Normal file
20
source/Marks/LineMark.mc
Normal file
@ -0,0 +1,20 @@
|
||||
import Toybox.Graphics;
|
||||
import Toybox.Lang;
|
||||
import Toybox.WatchUi;
|
||||
|
||||
class LineMark extends IMark {
|
||||
|
||||
function initialize(options as IMark.MarkParams) {
|
||||
IMark.initialize(options);
|
||||
}
|
||||
|
||||
function drawMark(dc as Dc, start as Point2D, length as Float) as Void {
|
||||
var angle = getAngle();
|
||||
|
||||
dc.setColor(Color, Color);
|
||||
dc.drawLine(start[0] + length * InnerRadius * Math.cos(angle),
|
||||
start[1] + length * InnerRadius * Math.sin(angle),
|
||||
start[0] + length * Radius * Math.cos(angle),
|
||||
start[1] + length * Radius * Math.sin(angle));
|
||||
}
|
||||
}
|
||||
41
source/Marks/RomanMark.mc
Normal file
41
source/Marks/RomanMark.mc
Normal file
@ -0,0 +1,41 @@
|
||||
import Toybox.Graphics;
|
||||
import Toybox.Lang;
|
||||
import Toybox.WatchUi;
|
||||
|
||||
class RomanMark extends ArabicMark {
|
||||
|
||||
function initialize(options as IMark.MarkParams) {
|
||||
ArabicMark.initialize(options);
|
||||
}
|
||||
|
||||
function secondsToText() as String? {
|
||||
switch (getHours()) {
|
||||
case 1:
|
||||
return "I";
|
||||
case 2:
|
||||
return "II";
|
||||
case 3:
|
||||
return "III";
|
||||
case 4:
|
||||
return "IV";
|
||||
case 5:
|
||||
return "V";
|
||||
case 6:
|
||||
return "VI";
|
||||
case 7:
|
||||
return "VII";
|
||||
case 8:
|
||||
return "VIII";
|
||||
case 9:
|
||||
return "IX";
|
||||
case 10:
|
||||
return "X";
|
||||
case 11:
|
||||
return "XI";
|
||||
case 12:
|
||||
return "XII";
|
||||
default:
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
47
source/Utils.mc
Normal file
47
source/Utils.mc
Normal file
@ -0,0 +1,47 @@
|
||||
import Toybox.Lang;
|
||||
import Toybox.Graphics;
|
||||
|
||||
// generic function for arrays
|
||||
function find(source as Array, searchFunction as Method(left, right) as Boolean) {
|
||||
if (source == null || source.size() == 0) {
|
||||
return null;
|
||||
}
|
||||
|
||||
var result = source[0];
|
||||
for (var i = 1; i < source.size(); ++i) {
|
||||
if (searchFunction.invoke(result, source[i])) {
|
||||
result = source[i];
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
// 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 _max(left as Numeric, right as Numeric) as Boolean {
|
||||
return left < right;
|
||||
}
|
||||
|
||||
function max(source as Array<Numeric>) as Numeric {
|
||||
return find(source, new Method($, :_max));
|
||||
}
|
||||
|
||||
function _min(left as Numeric, right as Numeric) as Boolean {
|
||||
return left > right;
|
||||
}
|
||||
|
||||
function min(source as Array<Numeric>) as Numeric {
|
||||
return find(source, new Method($, :_min));
|
||||
}
|
||||
|
||||
function getCenter(dc as Dc, shift as Point2D) as Point2D {
|
||||
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 background as IBackground;
|
||||
|
||||
function initialize() {
|
||||
WatchFace.initialize();
|
||||
|
||||
background = IBackground.getBackground(IBackground.SOLID_BACKGROUND, {
|
||||
:Identifier => "Main",
|
||||
:Hands => [IHand.HOURS_HAND, IHand.MINUTES_HAND, IHand.SECONDS_HAND],
|
||||
});
|
||||
}
|
||||
|
||||
// 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);
|
||||
}
|
||||
|
||||
// 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