add time format config

This commit is contained in:
Jenny Diomidova 2025-12-13 19:18:16 +01:00
parent e70ed9e885
commit 517f332ed2
6 changed files with 133 additions and 27 deletions

View File

@ -25,11 +25,14 @@
"watchapp": { "watchapp": {
"watchface": true "watchface": true
}, },
"messageKeys": [ "messageKeys": {
"BACKGROUND_COLOR", "BACKGROUND_COLOR": 10000,
"DIGIT_COLOR", "DIGIT_COLOR": 10001,
"FRAME_COLOR" "FRAME_COLOR": 10002,
], "TIME_FORMAT_OVERRIDE": 10010,
"12H_START": 10011,
"24H_START": 10012
},
"capabilities": [ "configurable" ], "capabilities": [ "configurable" ],
"resources": { "resources": {
"media": [ "media": [

View File

@ -39,19 +39,18 @@ protected:
TickTimerStart(HOUR_UNIT); TickTimerStart(HOUR_UNIT);
TickTimerStart(USE_SECONDS_INSTEAD_OF_MINUTES ? SECOND_UNIT : MINUTE_UNIT); TickTimerStart(USE_SECONDS_INSTEAD_OF_MINUTES ? SECOND_UNIT : MINUTE_UNIT);
UpdateTime(false); UpdateTime(false);
ApplySettings();
} }
void UpdateTime(bool animate=true) { void UpdateTime(bool animate=true) {
DateTime dateTime = DateTime::Now(); 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(); 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[0].SetDigitCount(is_24h ? 3 : 2);
digitLayers[1].SetDigitCount(is_24h ? 24 : 12); // digitLayers[1].SetDigitCount(is_24h ? 24 : 12);
digitLayers[2].SetDigitCount(6); // digitLayers[2].SetDigitCount(6);
digitLayers[3].SetDigitCount(10); // digitLayers[3].SetDigitCount(10);
this->digitLayers[0].RotateTo(hour / 10, animate); this->digitLayers[0].RotateTo(hour / 10, animate);
this->digitLayers[1].RotateTo(hour, animate); this->digitLayers[1].RotateTo(hour, animate);
this->digitLayers[2].RotateTo(minute / 10, animate); this->digitLayers[2].RotateTo(minute / 10, animate);
@ -61,33 +60,33 @@ protected:
void OnTick(tm &tick_time, TimeUnits units_changed) { void OnTick(tm &tick_time, TimeUnits units_changed) {
UpdateTime(true); UpdateTime(true);
} }
};
public:
namespace {
void ApplySettings() { void ApplySettings() {
Pebble::Window window = window_stack_get_top_window(); this->SetBackgroundColor(settings::GetBackgroundColor());
window.SetBackgroundColor(settings::GetBackgroundColor()); this->UpdateTime(true);
window.MarkDirty();
bitmaps::SetDigitColor(settings::GetDigitColor()); bitmaps::SetDigitColor(settings::GetDigitColor());
bitmaps::SetFrameColor(settings::GetFrameColor()); bitmaps::SetFrameColor(settings::GetFrameColor());
} }
};
void HandleMsg(DictionaryIterator *iter, void *context) { namespace {
void HandleMsg(DictionaryIterator* iter, void* context) {
settings::HandleMsg(iter); settings::HandleMsg(iter);
ApplySettings(); static_cast<MainWindow*>(context)->ApplySettings();
} }
} }
MAIN { MAIN {
bitmaps::Init(); bitmaps::Init();
settings::Load(); settings::Load();
app_message_register_inbox_received(HandleMsg);
app_message_open(64, 64); // inbox, outbox
MainWindow window; MainWindow window;
window.StackPush(true); 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(); app_event_loop();

View File

@ -1,3 +1,4 @@
#include <@rebble/sdk-c-utils/macros.h>
#include "settings.hpp" #include "settings.hpp"
// Built-in GColorFromRGBA doesn't seem to work in C++11 :( // Built-in GColorFromRGBA doesn't seem to work in C++11 :(
@ -16,28 +17,49 @@ namespace settings {
GColor backgroundColor = GColorWhite; GColor backgroundColor = GColorWhite;
GColor digitColor = GColorBlack; GColor digitColor = GColorBlack;
GColor frameColor = GColorBlack; GColor frameColor = GColorBlack;
int time_format_override = 0;
int time_12h_start = 1;
int time_24h_start = 0;
} }
void Save() { void Save() {
persist_write_data(MESSAGE_KEY_BACKGROUND_COLOR, &backgroundColor, sizeof(GColor)); 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_DIGIT_COLOR, &digitColor, sizeof(GColor));
persist_write_data(MESSAGE_KEY_FRAME_COLOR, &frameColor, 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() { void Load() {
persist_read_data(MESSAGE_KEY_BACKGROUND_COLOR, &backgroundColor, sizeof(GColor)); 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_DIGIT_COLOR, &digitColor, sizeof(GColor));
persist_read_data(MESSAGE_KEY_FRAME_COLOR, &frameColor, 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_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_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_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(); Save();
} }
GColor GetBackgroundColor() {return backgroundColor;} GColor GetBackgroundColor() {return backgroundColor;}
GColor GetDigitColor() {return digitColor;} GColor GetDigitColor() {return digitColor;}
GColor GetFrameColor() {return frameColor;} 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;
}
}
} }

View File

@ -5,8 +5,9 @@
namespace settings { namespace settings {
void Save(); void Save();
void Load(); void Load();
void HandleMsg(DictionaryIterator *iter); void HandleMsg(DictionaryIterator* iter);
GColor GetBackgroundColor(); GColor GetBackgroundColor();
GColor GetDigitColor(); GColor GetDigitColor();
GColor GetFrameColor(); GColor GetFrameColor();
int FormatHour(int hours);
} }

View File

@ -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", type: "submit",
defaultValue: "Save Settings", defaultValue: "Save Settings",

View File

@ -1,3 +1,48 @@
var Clay = require('pebble-clay'); var Clay = require('pebble-clay');
var clayConfig = require('./config'); var clayConfig = require('./config');
var clay = new Clay(clayConfig); 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
};