@@ -18,6 +18,7 @@ FlashLight::FlashLight(System::SystemTask& systemTask, Controllers::BrightnessCo
1818 : wakeLock(systemTask), brightnessController {brightnessController} {
1919
2020 previousBrightnessLevel = brightnessController.Level ();
21+ currentMode = Mode::Off;
2122 brightnessController.Set (Controllers::BrightnessController::Levels::Low);
2223
2324 flashLight = lv_label_create (lv_scr_act (), nullptr );
@@ -51,14 +52,31 @@ FlashLight::FlashLight(System::SystemTask& systemTask, Controllers::BrightnessCo
5152}
5253
5354FlashLight::~FlashLight () {
55+ if (taskRefresh != nullptr ) {
56+ lv_task_del (taskRefresh);
57+ }
5458 lv_obj_clean (lv_scr_act ());
5559 lv_obj_set_style_local_bg_color (lv_scr_act (), LV_OBJ_PART_MAIN, LV_STATE_DEFAULT, LV_COLOR_BLACK);
5660 brightnessController.Set (previousBrightnessLevel);
5761}
5862
5963void FlashLight::SetColors () {
60- lv_color_t bgColor = isOn ? LV_COLOR_WHITE : LV_COLOR_BLACK;
61- lv_color_t fgColor = isOn ? Colors::lightGray : LV_COLOR_WHITE;
64+ lv_color_t bgColor;
65+ lv_color_t fgColor;
66+
67+ if (currentMode == Mode::Off) {
68+ bgColor = LV_COLOR_BLACK;
69+ fgColor = LV_COLOR_MAROON;
70+ } else if (currentMode == Mode::Red) {
71+ bgColor = LV_COLOR_RED;
72+ fgColor = LV_COLOR_BLACK;
73+ } else if (currentMode == Mode::White) {
74+ bgColor = LV_COLOR_WHITE;
75+ fgColor = LV_COLOR_GRAY;
76+ } else {
77+ bgColor = LV_COLOR_WHITE;
78+ fgColor = LV_COLOR_GRAY;
79+ }
6280
6381 lv_obj_set_style_local_bg_color (lv_scr_act (), LV_OBJ_PART_MAIN, LV_STATE_DEFAULT, bgColor);
6482 lv_obj_set_style_local_text_color (flashLight, LV_LABEL_PART_MAIN, LV_STATE_DEFAULT, fgColor);
@@ -85,23 +103,47 @@ void FlashLight::SetIndicators() {
85103}
86104
87105void FlashLight::Toggle () {
88- isOn = !isOn;
89- SetColors ();
90- if (isOn) {
91- brightnessController.Set (brightnessLevel);
106+ // Clean up strobe task if leaving strobe mode
107+ if (currentMode == Mode::Strobe && taskRefresh != nullptr ) {
108+ lv_task_del (taskRefresh);
109+ taskRefresh = nullptr ;
110+ }
111+
112+ if (currentMode == Mode::Off) {
113+ currentMode = Mode::Red;
114+ } else if (currentMode == Mode::Red) {
115+ currentMode = Mode::White;
116+ } else if (currentMode == Mode::White) {
117+ currentMode = Mode::Strobe;
92118 } else {
119+ currentMode = Mode::Off;
120+ }
121+
122+ // Create strobe task if entering strobe mode
123+ if (currentMode == Mode::Strobe) {
124+ taskRefresh = lv_task_create (RefreshTaskCallback, 150 , LV_TASK_PRIO_MID, this );
125+ }
126+
127+ SetColors ();
128+
129+ if (currentMode == Mode::Off) {
93130 brightnessController.Set (Controllers::BrightnessController::Levels::Low);
131+ } else if (currentMode != Mode::Strobe) {
132+ brightnessController.Set (brightnessLevel);
94133 }
95134}
96135
97136bool FlashLight::OnTouchEvent (Pinetime::Applications::TouchEvents event) {
98137 using namespace Pinetime ::Controllers;
99138
139+ if (currentMode == Mode::Off || currentMode == Mode::Strobe) {
140+ return false ;
141+ }
142+
100143 auto SetState = [this ]() {
101- if (isOn) {
102- brightnessController.Set (brightnessLevel);
103- }
144+ brightnessController.Set (brightnessLevel);
104145 SetIndicators ();
146+ SetColors ();
105147 };
106148
107149 if (event == TouchEvents::SwipeLeft) {
@@ -127,3 +169,20 @@ bool FlashLight::OnTouchEvent(Pinetime::Applications::TouchEvents event) {
127169
128170 return false ;
129171}
172+
173+ void FlashLight::Refresh () {
174+ if (currentMode == Mode::Strobe) {
175+ static bool strobeOn = false ;
176+ strobeOn = !strobeOn;
177+
178+ lv_color_t bgColor = strobeOn ? LV_COLOR_WHITE : LV_COLOR_BLACK;
179+ lv_obj_set_style_local_bg_color (lv_scr_act (), LV_OBJ_PART_MAIN, LV_STATE_DEFAULT, bgColor);
180+
181+ // Make sure backgroundAction stays on top (and clickable)
182+ lv_obj_move_foreground (backgroundAction);
183+
184+ // Set next callback time based on current state
185+ // 150ms on, 350ms off (2Hz, 30% duty cycle)
186+ lv_task_set_period (taskRefresh, strobeOn ? 150 : 350 );
187+ }
188+ }
0 commit comments