import Toybox.Graphics; import Toybox.Lang; import Toybox.Math; import Toybox.System; import Toybox.WatchUi; class KittieCatsView extends WatchUi.WatchFace { private var theme = null; private var backgroundHi; private var backgroundLo; private var armHour; private var armMinute; private var armSecond; private var minuteOrnamentLo; private var icons; private var iconSize; private var screenCenterX; private var screenCenterY; private var sleepTime; private var wakeTime; private var highPowerMode = true; function initialize() { WatchFace.initialize(); } function onLayout(dc as Dc) as Void { self.screenCenterX = Math.floor(dc.getWidth() / 2); self.screenCenterY = Math.floor(dc.getHeight() / 2); } function onShow() as Void { var currentTheme = ThemeManager.getInstance().getCurrentTheme(); if (currentTheme != self.theme) { self.theme = currentTheme; self.backgroundHi = Application.loadResource(self.theme.BackgroundHi); self.backgroundLo = Application.loadResource(self.theme.BackgroundLo); self.armHour = Application.loadResource(self.theme.ArmHour); self.armMinute = Application.loadResource(self.theme.ArmMinute); self.armSecond = Application.loadResource(self.theme.ArmSecond); self.minuteOrnamentLo = self.theme.MinuteOrnamentLo != null ? Application.loadResource(self.theme.MinuteOrnamentLo) : null; self.icons = Application.loadResource(Rez.Drawables.Icons); self.iconSize = self.icons.getHeight(); } var profile = UserProfile.getProfile(); self.sleepTime = profile.sleepTime; self.wakeTime = profile.wakeTime; } function onHide() as Void { } function onUpdate(dc as Dc) as Void { var isSleepMode = self.isSleepMode(); var highPowerMode = !isSleepMode && self.highPowerMode; var clockTime = System.getClockTime(); var complications = ComplicationSubscriber.getSnapshot(); dc.setColor(Graphics.COLOR_BLACK, Graphics.COLOR_BLACK); dc.clear(); dc.drawBitmap(0, 0, highPowerMode ? self.backgroundHi : self.backgroundLo); if (highPowerMode) { // --- Icons --- self.drawIcon(dc, 0, 104, 145); self.drawIcon(dc, 1, 170, 300); self.drawIcon(dc, 2, 170, 335); self.drawIcon(dc, 3, 237, 335); } // --- Arms --- var hourTint = highPowerMode ? self.theme.ArmHourTintHi : isSleepMode ? self.theme.ArmHourTintSleep : self.theme.ArmHourTintLo; var minuteTint = highPowerMode ? self.theme.ArmMinuteTintHi : isSleepMode ? self.theme.ArmMinuteTintSleep : self.theme.ArmMinuteTintLo; // Base the hour arm on minutes as well, to prevent the arm from staying on the // current hour tick mark right up until the 59th minute self.drawArm(dc, self.armHour, 0, (clockTime.hour * 60) + clockTime.min, 720, hourTint); self.drawArm(dc, self.armMinute, 0, clockTime.min, 60, minuteTint); if (highPowerMode) { self.drawArm(dc, self.armSecond, 75, clockTime.sec, 60, null); // --- Complications --- dc.setColor(Graphics.COLOR_BLACK, Graphics.COLOR_TRANSPARENT); self.drawValue(dc, 116, 186, Graphics.FONT_XTINY, complications.HeartRate, "-", Graphics.TEXT_JUSTIFY_CENTER | Graphics.TEXT_JUSTIFY_VCENTER); self.drawValue(dc, 195, 313, Graphics.FONT_XTINY, complications.Steps, "-", Graphics.TEXT_JUSTIFY_LEFT | Graphics.TEXT_JUSTIFY_VCENTER); self.drawValue(dc, 195, 346, Graphics.FONT_XTINY, complications.BodyBattery, "-", Graphics.TEXT_JUSTIFY_LEFT | Graphics.TEXT_JUSTIFY_VCENTER); self.drawValue(dc, 261, 346, Graphics.FONT_XTINY, complications.Stress, "-", Graphics.TEXT_JUSTIFY_LEFT | Graphics.TEXT_JUSTIFY_VCENTER); } else if (self.minuteOrnamentLo != null) { var angle = (clockTime.min.toFloat() / 60 * (Math.PI * 2)) - (Math.PI / 2); var x = Math.cos(angle) * self.theme.MinuteOrnamentOffset + screenCenterX; var y = Math.sin(angle) * self.theme.MinuteOrnamentOffset + screenCenterY; dc.drawBitmap(x - (self.minuteOrnamentLo.getWidth() / 2), y, self.minuteOrnamentLo); } } function onExitSleep() as Void { self.highPowerMode = true; } function onEnterSleep() as Void { self.highPowerMode = false; } private function isSleepMode() as Boolean { // Since isSleepMode is deprecated, base it on the wake and sleep times. Unfortunately this means // the display will never be in high power mode between those times even if desired. // Can't figure out how to check for the locked state either. // Might want to check for DND mode instead if this is annoying. var now = Time.now(); var today = Time.today(); if (now.greaterThan(today.add(self.sleepTime)) || now.lessThan(today.add(self.wakeTime))) { return true; } return false; } private function drawArm(dc as Dc, bitmap as BitmapType, armOffset as Lang.Numeric, value as Lang.Numeric, max as Lang.Numeric, tintColor as Lang.Numeric or Null) as Void { var offsetX = Math.floor(bitmap.getWidth() / 2); var offsetY = bitmap.getHeight().toFloat() + armOffset; var rotation = new Graphics.AffineTransform(); rotation.translate(offsetX, offsetY); rotation.rotate(((Math.PI * 2) / max) * value); rotation.translate(-offsetX, -offsetY); dc.drawBitmap2(screenCenterX - offsetX, screenCenterY - offsetY, bitmap, { :tintColor => tintColor, :filterMode => Graphics.FILTER_MODE_BILINEAR, :transform => rotation }); } private function drawValue(dc as Dc, x as Lang.Numeric, y as Lang.Numeric, font as Graphics.FontType, value as Lang.Number or Null, nullText as Lang.Object, justification as Graphics.TextJustification or Lang.Number) as Void { dc.drawText(x, y, font, value == null ? nullText : value.format("%d"), justification); } /* private function drawShadowedValue(dc as Dc, x as Lang.Numeric, y as Lang.Numeric, font as Graphics.FontType, text as Lang.Object or Null, nullText as Lang.Object, justification as Graphics.TextJustification or Lang.Number, textColor as Graphics.ColorType, shadowColor as Graphics.ColorType, shadowOffset as Lang.Numeric) as Void { dc.setColor(shadowColor, Graphics.COLOR_TRANSPARENT); dc.drawText(x + shadowOffset, y + shadowOffset, font, text == null ? nullText : text, justification); dc.setColor(textColor, Graphics.COLOR_TRANSPARENT); dc.drawText(x, y, font, text == null ? nullText : text, justification); } */ private function drawIcon(dc as Dc, iconIndex as Lang.Numeric, x as Lang.Numeric, y as Lang.Numeric) { dc.drawBitmap2(x - (iconIndex * self.iconSize), y, self.icons, { :bitmapX => iconIndex * self.iconSize, :bitmapWidth => self.iconSize, :bitmapHeight => self.iconSize }); } }