diff --git a/package.json b/package.json index 281ac75..8551adc 100644 --- a/package.json +++ b/package.json @@ -25,11 +25,14 @@ "watchapp": { "watchface": true }, - "messageKeys": [ - "BACKGROUND_COLOR", - "DIGIT_COLOR", - "FRAME_COLOR" - ], + "messageKeys": { + "BACKGROUND_COLOR": 10000, + "DIGIT_COLOR": 10001, + "FRAME_COLOR": 10002, + "TIME_FORMAT_OVERRIDE": 10010, + "12H_START": 10011, + "24H_START": 10012 + }, "capabilities": [ "configurable" ], "resources": { "media": [ diff --git a/src/c/main.cpp b/src/c/main.cpp index 2ae0a86..89e8045 100644 --- a/src/c/main.cpp +++ b/src/c/main.cpp @@ -39,19 +39,18 @@ protected: TickTimerStart(HOUR_UNIT); TickTimerStart(USE_SECONDS_INSTEAD_OF_MINUTES ? SECOND_UNIT : MINUTE_UNIT); UpdateTime(false); + ApplySettings(); } void UpdateTime(bool animate=true) { DateTime dateTime = DateTime::Now(); - int hour = dateTime.GetHour(); + int hour = settings::FormatHour(dateTime.GetHour()); int minute = USE_SECONDS_INSTEAD_OF_MINUTES ? dateTime.GetSecond() : dateTime.GetMinute(); - bool is_24h = clock_is_24h_style(); - if (!is_24h) hour %= 12; - digitLayers[0].SetDigitCount(is_24h ? 3 : 2); - digitLayers[1].SetDigitCount(is_24h ? 24 : 12); - digitLayers[2].SetDigitCount(6); - digitLayers[3].SetDigitCount(10); + // digitLayers[0].SetDigitCount(is_24h ? 3 : 2); + // digitLayers[1].SetDigitCount(is_24h ? 24 : 12); + // digitLayers[2].SetDigitCount(6); + // digitLayers[3].SetDigitCount(10); this->digitLayers[0].RotateTo(hour / 10, animate); this->digitLayers[1].RotateTo(hour, animate); this->digitLayers[2].RotateTo(minute / 10, animate); @@ -61,33 +60,33 @@ protected: void OnTick(tm &tick_time, TimeUnits units_changed) { UpdateTime(true); } -}; - -namespace { + +public: void ApplySettings() { - Pebble::Window window = window_stack_get_top_window(); - window.SetBackgroundColor(settings::GetBackgroundColor()); - window.MarkDirty(); + this->SetBackgroundColor(settings::GetBackgroundColor()); + this->UpdateTime(true); bitmaps::SetDigitColor(settings::GetDigitColor()); bitmaps::SetFrameColor(settings::GetFrameColor()); } +}; - void HandleMsg(DictionaryIterator *iter, void *context) { +namespace { + void HandleMsg(DictionaryIterator* iter, void* context) { settings::HandleMsg(iter); - ApplySettings(); + static_cast(context)->ApplySettings(); } } MAIN { bitmaps::Init(); settings::Load(); - app_message_register_inbox_received(HandleMsg); - app_message_open(64, 64); // inbox, outbox - MainWindow window; window.StackPush(true); - ApplySettings(); + + app_message_set_context(&window); + app_message_register_inbox_received(HandleMsg); + app_message_open(64, 64); // inbox, outbox app_event_loop(); diff --git a/src/c/settings.cpp b/src/c/settings.cpp index 1bccebb..86a1217 100644 --- a/src/c/settings.cpp +++ b/src/c/settings.cpp @@ -1,3 +1,4 @@ +#include <@rebble/sdk-c-utils/macros.h> #include "settings.hpp" // Built-in GColorFromRGBA doesn't seem to work in C++11 :( @@ -16,28 +17,49 @@ namespace settings { GColor backgroundColor = GColorWhite; GColor digitColor = GColorBlack; GColor frameColor = GColorBlack; + int time_format_override = 0; + int time_12h_start = 1; + int time_24h_start = 0; } void Save() { persist_write_data(MESSAGE_KEY_BACKGROUND_COLOR, &backgroundColor, sizeof(GColor)); persist_write_data(MESSAGE_KEY_DIGIT_COLOR, &digitColor, sizeof(GColor)); persist_write_data(MESSAGE_KEY_FRAME_COLOR, &frameColor, sizeof(GColor)); + persist_write_data(MESSAGE_KEY_TIME_FORMAT_OVERRIDE, &time_format_override, sizeof(int)); + persist_write_data(MESSAGE_KEY_12H_START, &time_12h_start, sizeof(int)); + persist_write_data(MESSAGE_KEY_24H_START, &time_24h_start, sizeof(int)); } void Load() { persist_read_data(MESSAGE_KEY_BACKGROUND_COLOR, &backgroundColor, sizeof(GColor)); persist_read_data(MESSAGE_KEY_DIGIT_COLOR, &digitColor, sizeof(GColor)); persist_read_data(MESSAGE_KEY_FRAME_COLOR, &frameColor, sizeof(GColor)); + persist_read_data(MESSAGE_KEY_TIME_FORMAT_OVERRIDE, &time_format_override, sizeof(int)); + persist_read_data(MESSAGE_KEY_12H_START, &time_12h_start, sizeof(int)); + persist_read_data(MESSAGE_KEY_24H_START, &time_24h_start, sizeof(int)); } - void HandleMsg(DictionaryIterator *iter) { + void HandleMsg(DictionaryIterator* iter) { if (auto tuple = dict_find(iter, MESSAGE_KEY_BACKGROUND_COLOR)) backgroundColor = GColorFromHEX(tuple->value->int32); if (auto tuple = dict_find(iter, MESSAGE_KEY_DIGIT_COLOR)) digitColor = GColorFromHEX(tuple->value->int32); if (auto tuple = dict_find(iter, MESSAGE_KEY_FRAME_COLOR)) frameColor = GColorFromHEX(tuple->value->int32); + if (auto tuple = dict_find(iter, MESSAGE_KEY_TIME_FORMAT_OVERRIDE)) time_format_override = tuple->value->int8; + if (auto tuple = dict_find(iter, MESSAGE_KEY_12H_START)) time_12h_start = tuple->value->int8; + if (auto tuple = dict_find(iter, MESSAGE_KEY_24H_START)) time_24h_start = tuple->value->int8; Save(); } GColor GetBackgroundColor() {return backgroundColor;} GColor GetDigitColor() {return digitColor;} GColor GetFrameColor() {return frameColor;} + + int FormatHour(int hour) { + const bool is_24h = time_format_override ? time_format_override == 24 : clock_is_24h_style(); + if (is_24h) { + return (hour + 24 - time_24h_start) % 24 + time_24h_start; + } else { + return (hour + 12 - time_12h_start) % 12 + time_12h_start; + } + } } \ No newline at end of file diff --git a/src/c/settings.hpp b/src/c/settings.hpp index 3b62e9c..541388f 100644 --- a/src/c/settings.hpp +++ b/src/c/settings.hpp @@ -5,8 +5,9 @@ namespace settings { void Save(); void Load(); - void HandleMsg(DictionaryIterator *iter); + void HandleMsg(DictionaryIterator* iter); GColor GetBackgroundColor(); GColor GetDigitColor(); GColor GetFrameColor(); + int FormatHour(int hours); } diff --git a/src/pkjs/config.js b/src/pkjs/config.js index 0a5a879..d0e590c 100644 --- a/src/pkjs/config.js +++ b/src/pkjs/config.js @@ -29,6 +29,42 @@ module.exports = [ }, ] }, + { + type: "section", + items: [ + { + type: "heading", + defaultValue: "Time Format", + }, + { + label: "Time Format", + messageKey: "TIME_FORMAT_OVERRIDE", + type: "select", + options: [ + {label: "Use system", value: 0}, + {label: "12 hour", value: 12}, + {label: "24 hour", value: 24}, + ], + defaultValue: 0, + }, + { + label: "12h Range", + description: "Most people want '1:00 to 12:59'. Some countries use '0:00 to 11:59' instead.", + messageKey: "12H_START", + type: "select", + options: Array.from({length: 12}, (_, i) => ({value: i, label: `${i}:00 to ${i + 11}:59`})), + defaultValue: 1, + }, + { + label: "24h Range", + description: "Most people want '0:00 to 23:59'.", + messageKey: "24H_START", + type: "select", + options: Array.from({length: 24}, (_, i) => ({value: i, label: `${i}:00 to ${i + 23}:59`})), + defaultValue: 0, + }, + ] + }, { type: "submit", defaultValue: "Save Settings", diff --git a/src/pkjs/index.js b/src/pkjs/index.js index 9a8e20b..fbdbe47 100644 --- a/src/pkjs/index.js +++ b/src/pkjs/index.js @@ -1,3 +1,48 @@ var Clay = require('pebble-clay'); var clayConfig = require('./config'); -var clay = new Clay(clayConfig); \ No newline at end of file +var clay = new Clay(clayConfig); + + +// Patch `select` to return integers instead of strings + +function disable() { + if (this.$manipulatorTarget.get('disabled')) { return this; } + this.$element.set('+disabled'); + this.$manipulatorTarget.set('disabled', true); + return this.trigger('disabled'); +} + +function enable() { + if (!this.$manipulatorTarget.get('disabled')) { return this; } + this.$element.set('-disabled'); + this.$manipulatorTarget.set('disabled', false); + return this.trigger('enabled'); +} + +function hide() { + if (this.$element[0].classList.contains('hide')) { return this; } + this.$element.set('+hide'); + return this.trigger('hide'); +} + +function show() { + if (!this.$element[0].classList.contains('hide')) { return this; } + this.$element.set('-hide'); + return this.trigger('show'); +} + +clay.components.select.manipulator = { + get: function() { + return parseInt(this.$manipulatorTarget.get('value')); + }, + set: function(value) { + if (this.get() === value) { return this; } + this.$manipulatorTarget.set('value', value); + return this.trigger('change'); + }, + disable: disable, + enable: enable, + hide: hide, + show: show +}; + \ No newline at end of file