From c1c76f58d82e183258770e48658106f1b8e80140 Mon Sep 17 00:00:00 2001 From: ScottyDoesKnow Date: Sun, 14 Dec 2025 21:55:10 -0500 Subject: [PATCH 1/2] Added automatic quiet time widget and preferred replacement index --- package.json | 7 ++++ resources/data/QUIET_TIME.pdc | Bin 0 -> 287 bytes src/c/messaging.c | 10 ++++++ src/c/settings.c | 6 ++++ src/c/settings.h | 6 ++++ src/c/sidebar.c | 62 ++++++++++++++++++++++------------ src/c/sidebar_widgets.c | 37 ++++++++++++++------ src/c/sidebar_widgets.h | 3 +- src/pkjs/index.js | 11 ++++++ 9 files changed, 108 insertions(+), 34 deletions(-) create mode 100644 resources/data/QUIET_TIME.pdc diff --git a/package.json b/package.json index 9de7a453..77aec65a 100755 --- a/package.json +++ b/package.json @@ -40,6 +40,7 @@ "WeatherUVIndex", "SettingAltClockName", "SettingAltClockOffset", + "SettingAutoReplaceIndex", "SettingDisableAutobattery", "SettingBluetoothVibe", "SettingDisconnectIcon", @@ -48,6 +49,7 @@ "SettingColorSidebar", "SettingColorTime", "SettingDecimalSep", + "SettingDisableAutoQuietTime", "SettingHealthUseDistance", "SettingHealthUseRestfulSleep", "SettingHourlyVibe", @@ -199,6 +201,11 @@ "name": "HEALTH_HEART", "type": "raw" }, + { + "file": "data/QUIET_TIME.pdc", + "name": "QUIET_TIME", + "type": "raw" + }, { "file": "images/digit_leco_9.png", "name": "CLOCK_DIGIT_LECO_9", diff --git a/resources/data/QUIET_TIME.pdc b/resources/data/QUIET_TIME.pdc new file mode 100644 index 0000000000000000000000000000000000000000..efb79e4586990ecd3ca3cd2d0b5a8b59c91e087c GIT binary patch literal 287 zcmYL^zYoDs6otRmk40jWCd6Q7l~_z9bV5vKkyxaQMM~1aZonW6Oa_C6SegA%oIaHf zU-EM9x#!&1Z8luT0*eB9G9-A~A4oG~BhJ*gi4%QxV)-{@35;Pwo0;e_p`wM7NNSek zO^2fh@K_tJdLP1ogz9WoR1IOJgcL1&W%xLZL|qwWQ)k>^T@dw0g2!07(YmdYD|;SB f_*mM$Xu4&value->int32); @@ -147,6 +149,10 @@ void inbox_received_callback(DictionaryIterator *iterator, void *context) { settings.disableAutobattery = (bool)autobattery_tuple->value->int8; } + if(autoQuietTime_tuple != NULL) { + settings.disableAutoQuietTime = (bool)autoQuietTime_tuple->value->int8; + } + if(clockFont_tuple != NULL) { settings.clockFontId = clockFont_tuple->value->int8; } @@ -199,6 +205,10 @@ void inbox_received_callback(DictionaryIterator *iterator, void *context) { settings.activateDisconnectIcon = (bool)activateDisconnectIcon_tuple->value->int8; } + if(autoReplaceIndex_tuple != NULL) { + settings.autoReplaceIndex = autoReplaceIndex_tuple->value->int8; + } + // save the new settings to persistent storage Settings_saveToStorage(); diff --git a/src/c/settings.c b/src/c/settings.c index 9a9453c0..f311d1e5 100755 --- a/src/c/settings.c +++ b/src/c/settings.c @@ -35,6 +35,12 @@ void Settings_loadFromStorage() { settings.decimalSeparator = '.'; settings.showBatteryPct = true; + #ifdef PBL_ROUND + settings.autoReplaceIndex = 0; + #else + settings.autoReplaceIndex = 1; + #endif + // to correct settings migration bug (settings key v6), we must do another migration (nooooooooooo) if (persist_exists(SETTINGS_PERSIST_KEY)) { int version = 0; diff --git a/src/c/settings.h b/src/c/settings.h index 5354ded0..8a071b7a 100755 --- a/src/c/settings.h +++ b/src/c/settings.h @@ -58,6 +58,12 @@ typedef struct { bool healthUseDistance; bool healthUseRestfulSleep; char decimalSeparator; + + // quiet time widget settings + bool disableAutoQuietTime; // TODO only works with certain versions? + + // auto replace index preference + uint8_t autoReplaceIndex; } Settings; // Dynamic settings (calculated at runtime based on currently-selected widgets) diff --git a/src/c/sidebar.c b/src/c/sidebar.c index 8fcdcdd2..78b144fa 100755 --- a/src/c/sidebar.c +++ b/src/c/sidebar.c @@ -113,33 +113,39 @@ bool isAutoBatteryShown() { return false; } +bool isAutoQuietTimeShown() { + return return !settings.disableAutoQuietTime && quiet_time_is_active(); +} #ifdef PBL_ROUND -// returns the best candidate widget for replacement by the auto battery -// or the disconnection icon -int getReplacableWidget() { +// returns the best candidate widget for replacement by auto widgets +int getReplacableWidget(bool isDisconnect) { + // if any widgets are empty, it's an obvious choice if(settings.widgets[0] == EMPTY) { return 0; } else if(settings.widgets[2] == EMPTY) { return 2; } - if(settings.widgets[0] == WEATHER_CURRENT || settings.widgets[0] == WEATHER_FORECAST_TODAY) { - return 0; - } else if(settings.widgets[2] == WEATHER_CURRENT || settings.widgets[2] == WEATHER_FORECAST_TODAY) { - return 2; + // are there any bluetooth-enabled widgets? if so, they're the second-best + // candidates for disconnection + if(isDisconnect) { + if(settings.widgets[0] == WEATHER_CURRENT || settings.widgets[0] == WEATHER_FORECAST_TODAY) { + return 0; + } else if(settings.widgets[2] == WEATHER_CURRENT || settings.widgets[2] == WEATHER_FORECAST_TODAY) { + return 2; + } } - // if we don't have any of those things, just replace the left widget - return 0; + // if we don't have any of those things, replace the preferred widget + return settings.autoReplaceIndex; // TODO does PBL_ROUND only have two slots? Can't let them set 1 as auto replace index? } #else -// returns the best candidate widget for replacement by the auto battery -// or the disconnection icon -int getReplacableWidget() { +// returns the best candidate widget for replacement by auto widgets +int getReplacableWidget(bool isDisconnect) { // if any widgets are empty, it's an obvious choice for(int i = 0; i < 3; i++) { if(settings.widgets[i] == EMPTY) { @@ -148,15 +154,17 @@ int getReplacableWidget() { } // are there any bluetooth-enabled widgets? if so, they're the second-best - // candidates - for(int i = 0; i < 3; i++) { - if(settings.widgets[i] == WEATHER_CURRENT || settings.widgets[i] == WEATHER_FORECAST_TODAY) { - return i; + // candidates for disconnection + if(isDisconnect) { + for(int i = 0; i < 3; i++) { + if(settings.widgets[i] == WEATHER_CURRENT || settings.widgets[i] == WEATHER_FORECAST_TODAY) { + return i; + } } } - // if we don't have any of those things, just replace the middle widget - return 1; + // if we don't have any of those things, replace the preferred widget + return settings.autoReplaceIndex; } #endif @@ -169,14 +177,17 @@ void updateRoundSidebarRight(Layer *l, GContext* ctx) { bool showDisconnectIcon = !bluetooth_connection_service_peek(); bool showAutoBattery = isAutoBatteryShown(); + bool showAutoQuietTime = isAutoQuietTimeShown(); SidebarWidgetType displayWidget = settings.widgets[2]; - if((showAutoBattery || showDisconnectIcon) && getReplacableWidget() == 2) { + if((showAutoBattery || showDisconnectIcon || showAutoQuietTime) && getReplacableWidget(showDisconnectIcon) == 2) { if(showAutoBattery) { displayWidget = BATTERY_METER; } else if(showDisconnectIcon) { displayWidget = BLUETOOTH_DISCONNECT; + } else if(showAutoQuietTime) { + displayWidget = QUIET_TIME; } } @@ -189,13 +200,17 @@ void updateRoundSidebarLeft(Layer *l, GContext* ctx) { bool showDisconnectIcon = !bluetooth_connection_service_peek(); bool showAutoBattery = isAutoBatteryShown(); + bool showAutoQuietTime = isAutoQuietTimeShown(); + SidebarWidgetType displayWidget = settings.widgets[0]; - if((showAutoBattery || showDisconnectIcon) && getReplacableWidget() == 0) { + if((showAutoBattery || showDisconnectIcon || showAutoQuietTime) && getReplacableWidget(showDisconnectIcon) == 0) { if(showAutoBattery) { displayWidget = BATTERY_METER; } else if(showDisconnectIcon) { displayWidget = BLUETOOTH_DISCONNECT; + } else if(showAutoQuietTime) { + displayWidget = QUIET_TIME; } } @@ -239,6 +254,7 @@ void updateRectSidebar(Layer *l, GContext* ctx) { bool showDisconnectIcon = false; bool showAutoBattery = isAutoBatteryShown(); + bool showAutoQuietTime = isAutoQuietTimeShown(); // if the pebble is disconnected and activated, show the disconnect icon if(settings.activateDisconnectIcon) { @@ -253,13 +269,15 @@ void updateRectSidebar(Layer *l, GContext* ctx) { // do we need to replace a widget? // if so, determine which widget should be replaced - if(showAutoBattery || showDisconnectIcon) { - int widget_to_replace = getReplacableWidget(); + if(showAutoBattery || showDisconnectIcon || showAutoQuietTime) { + int widget_to_replace = getReplacableWidget(showDisconnectIcon); if(showAutoBattery) { displayWidgets[widget_to_replace] = getSidebarWidgetByType(BATTERY_METER); } else if(showDisconnectIcon) { displayWidgets[widget_to_replace] = getSidebarWidgetByType(BLUETOOTH_DISCONNECT); + } else if(showAutoQuietTime) { + displayWidgets[widget_to_replace] = getSidebarWidgetByType(QUIET_TIME); } } diff --git a/src/c/sidebar_widgets.c b/src/c/sidebar_widgets.c index 3fdff899..acf23dda 100755 --- a/src/c/sidebar_widgets.c +++ b/src/c/sidebar_widgets.c @@ -14,6 +14,7 @@ GDrawCommandImage* dateImage; GDrawCommandImage* disconnectImage; GDrawCommandImage* batteryImage; GDrawCommandImage* batteryChargeImage; +GDrawCommandImage* quietTimeImage; // fonts GFont smSidebarFont; @@ -76,6 +77,10 @@ SidebarWidget uvIndexWidget; int UVIndex_getHeight(); void UVIndex_draw(GContext* ctx, int yPosition); +SidebarWidget quietTimeWidget; +int QuietTime_getHeight(); +void QuietTime_draw(GContext* ctx, int yPosition); + #ifdef PBL_HEALTH GDrawCommandImage* sleepImage; GDrawCommandImage* stepsImage; @@ -105,6 +110,7 @@ void SidebarWidgets_init() { disconnectImage = gdraw_command_image_create_with_resource(RESOURCE_ID_DISCONNECTED); batteryImage = gdraw_command_image_create_with_resource(RESOURCE_ID_BATTERY_BG); batteryChargeImage = gdraw_command_image_create_with_resource(RESOURCE_ID_BATTERY_CHARGE); + quietTimeImage = gdraw_command_image_create_with_resource(RESOURCE_ID_QUIET_TIME); #ifdef PBL_HEALTH sleepImage = gdraw_command_image_create_with_resource(RESOURCE_ID_HEALTH_SLEEP); @@ -156,6 +162,9 @@ void SidebarWidgets_init() { beatsWidget.getHeight = Beats_getHeight; beatsWidget.draw = Beats_draw; + + quietTimeWidget.getHeight = QuietTime_getHeight; + quietTimeWidget.draw = QuietTime_draw; } void SidebarWidgets_deinit() { @@ -163,6 +172,7 @@ void SidebarWidgets_deinit() { gdraw_command_image_destroy(disconnectImage); gdraw_command_image_destroy(batteryImage); gdraw_command_image_destroy(batteryChargeImage); + gdraw_command_image_destroy(quietTimeImage); #ifdef PBL_HEALTH gdraw_command_image_destroy(stepsImage); @@ -249,25 +259,18 @@ SidebarWidget getSidebarWidgetByType(SidebarWidgetType type) { switch(type) { case BATTERY_METER: return batteryMeterWidget; - break; case BLUETOOTH_DISCONNECT: return btDisconnectWidget; - break; case DATE: return dateWidget; - break; case ALT_TIME_ZONE: return altTimeWidget; - break; case SECONDS: return secondsWidget; - break; case WEATHER_CURRENT: return currentWeatherWidget; - break; case WEATHER_FORECAST_TODAY: return weatherForecastWidget; - break; case WEEK_NUMBER: return weekNumberWidget; case WEATHER_UV_INDEX: @@ -282,9 +285,10 @@ SidebarWidget getSidebarWidgetByType(SidebarWidgetType type) { #endif case BEATS: return beatsWidget; + case QUIET_TIME: + return quietTimeWidget; default: return emptyWidget; - break; } } @@ -521,8 +525,6 @@ int BTDisconnect_getHeight() { void BTDisconnect_draw(GContext* ctx, int yPosition) { if(disconnectImage) { gdraw_command_image_recolor(disconnectImage, dynamicSettings.iconFillColor, dynamicSettings.iconStrokeColor); - - gdraw_command_image_draw(ctx, disconnectImage, GPoint(3 + SidebarWidgets_xOffset, yPosition)); } } @@ -888,7 +890,7 @@ void SleepTimer_draw(GContext* ctx, int yPosition) { } - +/***** Heart Rate Widget *****/ int HeartRate_getHeight() { if(settings.useLargeFonts) { @@ -951,3 +953,16 @@ void Beats_draw(GContext* ctx, int yPosition) { GTextAlignmentCenter, NULL); } + +/***** Quiet Time Widget *****/ + +int QuietTime_getHeight() { + return 26; +} + +void QuietTime_draw(GContext* ctx, int yPosition) { + if(quietTimeImage) { + gdraw_command_image_recolor(quietTimeImage, dynamicSettings.iconFillColor, dynamicSettings.iconStrokeColor); + gdraw_command_image_draw(ctx, quietTimeImage, GPoint(2 + SidebarWidgets_xOffset, yPosition)); + } +} diff --git a/src/c/sidebar_widgets.h b/src/c/sidebar_widgets.h index 1def1420..7f7e2178 100755 --- a/src/c/sidebar_widgets.h +++ b/src/c/sidebar_widgets.h @@ -32,7 +32,8 @@ typedef enum { STEP_COUNTER = 10, BEATS = 11, HEARTRATE = 12, - WEATHER_UV_INDEX = 13 + WEATHER_UV_INDEX = 13, + QUIET_TIME = 14 } SidebarWidgetType; typedef struct { diff --git a/src/pkjs/index.js b/src/pkjs/index.js index 680da9af..51c5dcfe 100755 --- a/src/pkjs/index.js +++ b/src/pkjs/index.js @@ -136,6 +136,17 @@ Pebble.addEventListener('webviewclosed', function(e) { } } + // TODO can't handle PBL_ROUND here to have different default + if(configData.auto_replace_index_setting) { + if(configData.auto_replace_index_setting == '0') { + dict.SettingAutoReplaceIndex = 0; + } else if (configData.auto_replace_index_setting == '2') { + dict.SettingAutoReplaceIndex = 2; + } else { + dict.SettingAutoReplaceIndex = 1; + } + } + // notification settings if(configData.hourly_vibe_setting) { if(configData.hourly_vibe_setting == 'yes') { From 8a0c941af51c2e32721b0b511c6fb0070bb15f9a Mon Sep 17 00:00:00 2001 From: ScottyDoesKnow Date: Sun, 14 Dec 2025 22:01:30 -0500 Subject: [PATCH 2/2] Stash-related error fix --- src/c/sidebar.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/c/sidebar.c b/src/c/sidebar.c index 78b144fa..218aab5e 100755 --- a/src/c/sidebar.c +++ b/src/c/sidebar.c @@ -114,7 +114,7 @@ bool isAutoBatteryShown() { } bool isAutoQuietTimeShown() { - return return !settings.disableAutoQuietTime && quiet_time_is_active(); + return !settings.disableAutoQuietTime && quiet_time_is_active(); } #ifdef PBL_ROUND