Lamp-Da 0.1
A compact lantern project
Loading...
Searching...
No Matches
indexable_behavior.hpp
Go to the documentation of this file.
1
5#ifndef INDEXABLE_BEHAVIOR_MANAGER_H
6#define INDEXABLE_BEHAVIOR_MANAGER_H
7
9
10//
11// note: this code is included as-is by:
12// - user/indexable_functions.h
13//
14
15#include <cstdint>
16namespace lampda::user {
17
18void button_clicked_default(const uint8_t clicks)
19{
20 // Handle default common behavior
22 {
23 // some event is already handled
24 return;
25 }
26
27 auto manager = get_context();
28
29 switch (clicks)
30 {
31 case 2: // 2 clicks: next mode
32 if (manager.state.isInFavoriteMockGroup)
33 {
34 // if in favorite, next favorite
35 manager.state.lastFavoriteStep += 1;
36 // sanity check, if it fails, quit favorites
37 manager.state.isInFavoriteMockGroup = manager.jump_to_favorite(manager.state.lastFavoriteStep, false);
38 }
39 else
40 {
41 if (manager.state.isLastScrollAGroupChange and manager.lamp.now - manager.state.lastScrollStopped < 2000)
42 {
43 // last action was a group change & timer did not run out yet:
44 // change group
45 manager.next_group();
46
47 // prevent further jumps
48 manager.state.isLastScrollAGroupChange = false;
49 }
50 else
51 {
52 // else: just change mode
53 manager.next_mode();
54 }
55 }
56 break;
57
58 case 3: // 3 clicks: next group or quit favorite group
59 if (manager.state.isInFavoriteMockGroup)
60 {
61#ifdef LMBD_SIMULATION
62 fprintf(stderr, "Exit fake favorite group\n");
63#endif
64 // reset favorite indicator
65 manager.state.isInFavoriteMockGroup = false;
66 // return to previous state
67 manager.set_active_group(manager.state.beforeFavoriteGroupIndex);
68 manager.set_active_mode(manager.state.beforeFavoriteModeIndex);
69
70 // blip to indicate favorite mode exit
71 manager.blip(250);
72 }
73 else
74 {
75 // true next group
76 manager.next_group();
77 }
78 break;
79
80 case 4: // 4 clicks: jump to favorite
81
82 if (not manager.state.isInFavoriteMockGroup)
83 {
84 // jump and save last used mode
85 if (manager.jump_to_favorite(manager.state.lastFavoriteStep, true))
86 {
87 manager.state.isInFavoriteMockGroup = true;
88 // blip to indicate favorite mode enter
89 manager.blip(250);
90 }
91 }
92 break;
93 }
94
95#ifdef LMBD_SIMULATION
96 {
97 int _groupId = manager.get_active_group();
98 int _modeId = manager.get_active_mode();
99 fprintf(stderr, "group %d *mode %d\n", _groupId, _modeId);
100 if (manager.everySunsetCallback[_groupId][_modeId])
101 fprintf(stderr, " - hasSunsetAnimation\n");
102 if (manager.everyBrightCallback[_groupId][_modeId])
103 fprintf(stderr, " - hasBrightCallback\n");
104 if (manager.everyCustomRamp[_groupId][_modeId])
105 fprintf(stderr, " - hasCustomRamp\n");
106 if (manager.state.rampHandler.animEffect)
107 fprintf(stderr, " - has anim effect\n");
108 if (manager.everyRequireUserThread[_groupId][_modeId])
109 fprintf(stderr, " - requireUserThread\n");
110 if (manager.everySystemCallbacks[_groupId][_modeId])
111 fprintf(stderr, " - hasSystemCallbacks\n");
112 if (manager.everyButtonCustomUI[_groupId][_modeId])
113 fprintf(stderr, " - hasButtonCustomUI\n");
114 }
115#endif
116}
117
118void button_hold_default(const uint8_t clicks, const bool isEndOfHoldEvent, const uint32_t holdDuration)
119{
120 // Handle default common behavior
121 if (default_behaviors::button_hold(clicks, isEndOfHoldEvent, holdDuration))
122 {
123 // some event is already handled
124 return;
125 }
126
127 auto manager = get_context();
128 auto& rampHandler = manager.state.rampHandler;
129
130 switch (clicks)
131 {
132 case 4: // 4 click+hold: configure favorite
133 if (not isEndOfHoldEvent)
134 {
135 // lock to prevent addition of favorite from favorite & if we are deleting favorites
136 // the second case can happen when the user delete all favorites
137 if (not manager.state.isInFavoriteMockGroup && not manager.state.isInDeleteFavorite)
138 {
139 // no new favorite in favorite
140 manager.animate_favorite_pick(holdDuration, 1500);
141 }
142 else
143 {
144 // remove current favorite
145 manager.animate_favorite_delete(holdDuration, 2000);
146 }
147 }
148 else
149 {
150 manager.state.isInDeleteFavorite = false;
151 }
152 break;
153
154 case 6: // 6 click+hold: scroll across modes and group
155 // no scroll in favorite
156 if (not manager.state.isInFavoriteMockGroup)
157 {
158 // register end of scroll
159 if (isEndOfHoldEvent)
160 {
161 // update release time
162 manager.state.lastScrollStopped = manager.lamp.now;
163 }
164 else
165 {
166 manager.handle_scroll_modes(holdDuration);
167 }
168 }
169 break;
170
171 default:
172 break;
173 }
174}
175
176namespace __private_elk {
177
183void handle_pattern_select_command(const uint8_t patternIndex, const uint32_t requestedColor = 0)
184{
185 // ignore if not on
187 return;
188
189 // get manager and execute a mode or group change
190 auto manager = get_context();
191 if (manager.get_hidden_groups_count() <= 0)
192 {
193 platform::lampda_print("Cannot use bluetooth control without an hidden bluetooth group");
194 return;
195 }
196
197 const auto bluetoothGroup = manager.template get_group_id_of_mode<modes::bluetooth::ColorControlMode>();
198 if (bluetoothGroup < 0)
199 {
200 platform::lampda_print("Cannot find the bluetooth group and modes");
201 return;
202 }
203
204 const auto availableModes = manager.get_modes_count();
205 if (availableModes <= patternIndex)
206 {
207 platform::lampda_print("Unimplemented pattern id %d", patternIndex);
208 return;
209 }
210
211 manager.set_active_group(bluetoothGroup);
212 manager.set_active_mode(patternIndex);
213
214 // sanity check
215 const int trueIndex = manager.template get_mode_id<modes::bluetooth::ColorControlMode>();
216 assert(trueIndex == 0 && "Bluetooth group should have the programmable color output as the first group index");
217
218 // handle special programmable group mode
219 if (patternIndex == 0)
220 {
221 auto& modeState = manager.template get_state_of_mode<modes::bluetooth::ColorControlMode>();
222 modeState.color = requestedColor;
223 }
224}
225
226} // namespace __private_elk
227
228void handle_elk_command(const utils::ELK::Package& elkControlCommand)
229{
230 // Handle default common behavior
231 if (default_behaviors::handle_elk_command(elkControlCommand))
232 {
233 // some event is already handled
234 return;
235 }
236
237 switch (elkControlCommand.type)
238 {
240 {
241 const uint32_t color =
242 elkControlCommand.data[0] << 16 | elkControlCommand.data[1] << 8 | elkControlCommand.data[2];
243 __private_elk::handle_pattern_select_command(0, color);
244 break;
245 }
247 {
248 __private_elk::handle_pattern_select_command(elkControlCommand.data[0] + 1);
249 break;
250 }
251 // unhandled
252 default:
253 {
254 platform::lampda_print("Unsupported ELK message type");
255 break;
256 }
257 }
258}
259
260} // namespace lampda::user
261
262#endif
Define assertions helpers.
void handle_pattern_select_command(const uint8_t patternIndex, const uint32_t requestedColor=0)
Handle a pattern change command.
Definition: indexable_behavior.hpp:183
bool is_in_output_state()
return true if the system is in output mode
Definition: behavior.cpp:137
void lampda_print(const char *format,...)
Definition: print.cpp:43
bool button_hold(const uint8_t clicks, const bool isEndOfHoldEvent, const uint32_t holdDuration)
must be called by the lampda::user::button_hold_default
Definition: default_behavior.hpp:197
bool button_clicked(const uint8_t clicks)
must be called by the lampda::user::button_clicked_default
Definition: default_behavior.hpp:172
Contains code handling custom user mode functions for indexable strips.
Definition: default_behavior.hpp:15
void handle_elk_command(const utils::ELK::Package &elkControlCommand)
Handle a ELK BLE package.
Definition: indexable_behavior.hpp:228
void button_hold_default(const uint8_t, const bool, const uint32_t)
Called to handle button click+hold events for user mode behaviors.
Definition: indexable_behavior.hpp:118
void button_clicked_default(const uint8_t)
Called to handle button click events for default user mode behaviors.
Definition: indexable_behavior.hpp:18
@ PATTERN_SELECT
select a display pattern in a list
@ COLOR_SELECT
set output as a target color
Definition: elk_decoder.h:33