1
2 #include "demo_guix_home_automation.h"
3
4 /* Define light information structure. */
5 typedef struct LIGHTS_INFO_STRUCT{
6 LIGHTS_BASE_CONTROL_BLOCK *light; /* Pointer to the light controller. */
7 GX_RESOURCE_ID color_text_id; /* Description of the light color. */
8 INT radial_angle; /* Current value of the light control radial slider. */
9 INT power; /* Energy use of the light. */
10 GX_RESOURCE_ID selected_map_id; /* ID of the pixelmap for filling the selected part of the radial slider. */
11 GX_BOOL enabled; /* On/Off status of the light. */
12 }LIGHT_INFO;
13
14 /* Information about light in various rooms. */
15 static LIGHT_INFO light_info_list[] = {
16 { &lights_page_1.lights_page_1_kitchen, GX_STRING_ID_COLD_WHITE, 37, 0, GX_PIXELMAP_ID_WHEEL_WHITE_COLD, GX_TRUE},
17 { &lights_page_1.lights_page_1_master_bedroom, GX_STRING_ID_RGB_LIGHT, 100, 0, GX_PIXELMAP_ID_WHEEL_RED, GX_TRUE },
18 { &lights_page_2.lights_page_2_kids_bedroom, GX_STRING_ID_RGB_LIGHT, 29, 0,GX_PIXELMAP_ID_WHEEL_GREEN, GX_TRUE },
19 { &lights_page_2.lights_page_2_living_room, GX_STRING_ID_RGB_LIGHT, 29, 0, GX_PIXELMAP_ID_WHEEL_BLUE_DARK, GX_TRUE },
20 { &lights_page_3.lights_page_3_dinning_room, GX_STRING_ID_WARM_WHITE, 37, 0, GX_PIXELMAP_ID_WHEEL_WHITE_WARM, GX_TRUE },
21 { &lights_page_3.lights_page_3_outdoor_patio, GX_STRING_ID_RGB_LIGHT, 99, 0, GX_PIXELMAP_ID_WHEEL_BLUE_LIGHT, GX_TRUE },
22 { &lights_page_4.lights_page_4_office, GX_STRING_ID_RGB_LIGHT, 28, 0, GX_PIXELMAP_ID_WHEEL_PURPLE, GX_TRUE },
23 { GX_NULL, 0, 0, 0, 0, 0}
24 };
25
26 extern GX_ANIMATION slide_animation;
27 extern int screen_animation_count;
28
29 UINT string_length_get(GX_CONST GX_CHAR* input_string, UINT max_string_length);
30
31 /******************************************************************************************/
32 /* Retrieve light information with the specified light controller pointer. */
33 /******************************************************************************************/
light_info_get(LIGHTS_BASE_CONTROL_BLOCK * light)34 static LIGHT_INFO *light_info_get(LIGHTS_BASE_CONTROL_BLOCK *light)
35 {
36 LIGHT_INFO *info = light_info_list;
37
38 while (info->light)
39 {
40 if (info->light == light)
41 {
42 return info;
43 }
44
45 info++;
46 }
47
48 return GX_NULL;
49 }
50
51 /******************************************************************************************/
52 /* Retrieve selected pixelmap id for slider in light screen. */
53 /******************************************************************************************/
light_selected_map_id_get(GX_RADIAL_SLIDER * slider)54 GX_RESOURCE_ID light_selected_map_id_get(GX_RADIAL_SLIDER *slider)
55 {
56 LIGHT_INFO *info = light_info_list;
57
58 while (info->light)
59 {
60 if (&info->light->lights_base_radial_slider == slider)
61 {
62 return info->selected_map_id;
63 }
64
65 info++;
66 }
67
68 return 0;
69 }
70
71 /******************************************************************************************/
72 /* Update bottom information of light screen. */
73 /******************************************************************************************/
update_bottom_info_of_lights()74 static VOID update_bottom_info_of_lights()
75 {
76 LIGHT_INFO *info = light_info_list;
77 int energy_in_use = 0;
78 int enabled = 0;
79 int disabled = 0;
80
81 /* Calculate the total enery in use and the number of enabled/disabled lights. */
82 while (info->light)
83 {
84 if (info->enabled)
85 {
86 energy_in_use += info->power;
87 enabled++;
88 }
89 else
90 {
91 disabled++;
92 }
93
94 info++;
95 }
96
97 /* Display the number of enabled lights. */
98 gx_numeric_prompt_value_set(&lights_screen.lights_screen_num_on, enabled);
99
100 /* Display the number of disabled lights. */
101 gx_numeric_prompt_value_set(&lights_screen.lights_screen_num_off, disabled);
102
103 /* Display the total energy in use. */
104 gx_numeric_prompt_value_set(&lights_screen.lights_screen_energy_in_use, energy_in_use);
105 }
106
107 /******************************************************************************************/
108 /* Update information for specified light. */
109 /******************************************************************************************/
power_value_update(LIGHT_INFO * info,int radial_angle)110 static VOID power_value_update(LIGHT_INFO *info, int radial_angle)
111 {
112 INT angle;
113 INT angle_range = (MAX_ANGLE - MIN_ANGLE);
114 INT value;
115 INT xpos;
116
117 /* Calcualte the light intensity. */
118 angle = MAX_ANGLE - radial_angle;
119 value = angle * 100 / angle_range;
120
121 /* Display the light intensity. */
122 gx_numeric_prompt_value_set(&info->light->lights_base_power_percent_value, value);
123
124 if (value < 10)
125 {
126 xpos = 165;
127 }
128 else if (value < 100)
129 {
130 xpos = 179;
131 }
132 else
133 {
134 xpos = 192;
135 }
136
137 xpos += info->light->base.gx_widget_size.gx_rectangle_left;
138
139 /* Shift light intensity widget to make it in the center of the radial slider. */
140 gx_widget_shift(&info->light->lights_base_precent_lable, xpos - info->light->lights_base_precent_lable.gx_widget_size.gx_rectangle_left, 0, GX_TRUE);
141
142 /* Calcualte the energy of the light. */
143 value = angle * MAX_POWER / angle_range;
144 info->power = value;
145
146 /* Display the energy of the light. */
147 gx_numeric_prompt_value_set(&info->light->lights_base_power_value, value);
148 }
149
150 /******************************************************************************************/
151 /* Event handler for light close button click. */
152 /* This function detaches light control radial slider, attaches light open button, */
153 /* and updates light information in bottom area. */
154 /******************************************************************************************/
on_close_button_clicked(LIGHTS_BASE_CONTROL_BLOCK * base)155 static VOID on_close_button_clicked(LIGHTS_BASE_CONTROL_BLOCK *base)
156 {
157 LIGHT_INFO *info = light_info_get(base);
158
159 if (info && info->enabled)
160 {
161 info->enabled = GX_FALSE;
162
163 /* detach radial slider. */
164 gx_widget_detach(&base->lights_base_radial_slider);
165
166 /* detach icon ruller. */
167 gx_widget_detach(&base->lights_base_icon_ruller);
168
169 gx_widget_detach(&base->lights_base_button_close);
170
171 /* attach open button. */
172 gx_widget_attach((GX_WIDGET *)base, &base->lights_base_button_open);
173
174 update_bottom_info_of_lights();
175 }
176 }
177
178 /******************************************************************************************/
179 /* Event handler for light open button click. */
180 /* This function attaches light control radial slider, attaches light close button, */
181 /* and updates light information in bottom area. */
182 /******************************************************************************************/
on_open_button_clicked(LIGHTS_BASE_CONTROL_BLOCK * base)183 static VOID on_open_button_clicked(LIGHTS_BASE_CONTROL_BLOCK *base)
184 {
185 LIGHT_INFO *info = light_info_get(base);
186
187 if (info && (!info->enabled))
188 {
189 info->enabled = GX_TRUE;
190
191 /* attach icon ruller. */
192 gx_widget_attach((GX_WIDGET *)base, &base->lights_base_icon_ruller);
193
194 gx_widget_attach((GX_WIDGET *)base, &base->lights_base_button_close);
195
196 /* attach radial slider. */
197 gx_widget_attach((GX_WIDGET *)base, &base->lights_base_radial_slider);
198
199 /* detach open button. */
200 gx_widget_detach(&base->lights_base_button_open);
201
202 update_bottom_info_of_lights();
203 }
204 }
205
206 /******************************************************************************************/
207 /* Reset status of light. */
208 /******************************************************************************************/
light_status_reset(LIGHT_INFO * info)209 static VOID light_status_reset(LIGHT_INFO *info)
210 {
211 GX_WIDGET *child;
212
213 /* Hide all children of light controller. */
214 child = info->light->base.gx_widget_first_child;
215 while (child)
216 {
217 gx_widget_hide(child);
218 child = child->gx_widget_next;
219 }
220
221 /* Reset light control radial slider value. */
222 gx_radial_slider_angle_set(&info->light->lights_base_radial_slider, MAX_ANGLE);
223
224 /* Reset light intensity value. */
225 gx_numeric_prompt_value_set(&info->light->lights_base_power_percent_value, 0);
226
227 /* Reset light energy value. */
228 gx_numeric_prompt_value_set(&info->light->lights_base_power_value, 0);
229 }
230
231 /******************************************************************************************/
232 /* Reset status of light screen. */
233 /******************************************************************************************/
lights_screen_reset()234 VOID lights_screen_reset()
235 {
236 LIGHT_INFO *info = light_info_list;
237
238 while (info->light)
239 {
240 if (info->light->base.gx_widget_status & GX_STATUS_VISIBLE)
241 {
242 light_status_reset(info);
243 }
244
245 info++;
246 }
247 }
248
249 /******************************************************************************************/
250 /* Start children animations for visible light controller, this function is called when */
251 /* light pages switched. */
252 /******************************************************************************************/
lights_screen_animation_start()253 VOID lights_screen_animation_start()
254 {
255 LIGHT_INFO *info = light_info_list;
256 GX_WIDGET *child;
257
258 while (info->light)
259 {
260 if (info->light->base.gx_widget_status & GX_STATUS_VISIBLE)
261 {
262 /* Light controller is visible. */
263
264 if (!(info->light->base.controller_base_title.gx_widget_status & GX_STATUS_VISIBLE))
265 {
266 /* Title of the light controller is not visible, which means light page switched.
267 start children animations for the light controller. */
268
269 /* Disable drag slide animation before screen item animations complete. */
270 gx_animation_drag_disable(&slide_animation, (GX_WIDGET *)&lights_screen.base.screen_base_slide_win);
271
272 /* Disable pagination buttons to avoid button click while animations is on. */
273 pagination_button_enable_disable((GX_WINDOW *)&lights_screen.base, GX_FALSE);
274
275 /* Slide in light controller title. */
276 title_animation_start(&info->light->base);
277
278 if (info->enabled)
279 {
280 /* If the light controller is on, start animation to move light control radial slider from initial
281 value to current value. */
282 gx_radial_slider_animation_start(&info->light->lights_base_radial_slider, info->radial_angle);
283 }
284
285 /* Show children of the light controller. */
286 child = info->light->base.gx_widget_first_child;
287 while (child)
288 {
289 gx_widget_show(child);
290 child = child->gx_widget_next;
291 }
292 }
293 }
294 else
295 {
296 /* Reset status of light controller. */
297 light_status_reset(info);
298 }
299
300 info++;
301 }
302 }
303
304 /******************************************************************************************/
305 /* Stop all animations in lights screen. */
306 /******************************************************************************************/
lights_screen_animation_stop()307 VOID lights_screen_animation_stop()
308 {
309 LIGHT_INFO *info = light_info_list;
310
311 while (info->light)
312 {
313 if (info->light->base.gx_widget_status & GX_STATUS_VISIBLE)
314 {
315 /* Light controller is visible. */
316 gx_animation_delete(GX_NULL, (GX_WIDGET *)&info->light->base);
317 }
318
319 info++;
320 }
321
322 screen_animation_count = 0;
323 }
324
325 /******************************************************************************************/
326 /* Callback function of radial slider, which is called after every animation step. */
327 /******************************************************************************************/
radial_slider_value_update(GX_RADIAL_SLIDER * slider)328 VOID radial_slider_value_update(GX_RADIAL_SLIDER *slider)
329 {
330 LIGHT_INFO *info = light_info_get((LIGHTS_BASE_CONTROL_BLOCK *)slider->gx_widget_parent);
331
332 if (info && (slider->gx_widget_status & GX_STATUS_VISIBLE))
333 {
334 info->radial_angle = slider->gx_radial_slider_info.gx_radial_slider_info_current_angle;
335
336 /* Update light energy value. */
337 power_value_update(info, info->radial_angle);
338
339 /* Update summary light information in bottom. */
340 update_bottom_info_of_lights();
341 }
342 }
343
344 /******************************************************************************************/
345 /* Format function of numeric prompt. */
346 /******************************************************************************************/
power_value_format(GX_NUMERIC_PROMPT * prompt,INT value)347 VOID power_value_format(GX_NUMERIC_PROMPT *prompt, INT value)
348 {
349 INT index;
350
351 gx_utility_ltoa(value / 10000, prompt->gx_numeric_prompt_buffer, GX_NUMERIC_PROMPT_BUFFER_SIZE);
352
353 index = string_length_get(prompt->gx_numeric_prompt_buffer, GX_NUMERIC_PROMPT_BUFFER_SIZE);
354 prompt->gx_numeric_prompt_buffer[index++] = '.';
355
356 gx_utility_ltoa(value % 10000, prompt->gx_numeric_prompt_buffer + index, GX_NUMERIC_PROMPT_BUFFER_SIZE - index);
357 }
358
359 /******************************************************************************************/
360 /* Override the default event processing of templates based on "lights_base" to handle */
361 /* signals from my child widgets. */
362 /******************************************************************************************/
lights_base_event_process(GX_WINDOW * window,GX_EVENT * event_ptr)363 UINT lights_base_event_process(GX_WINDOW *window, GX_EVENT *event_ptr)
364 {
365 switch (event_ptr->gx_event_type)
366 {
367 case GX_SIGNAL(ID_RADIAL_SLIDER, GX_EVENT_SLIDER_VALUE):
368 radial_slider_value_update(&((LIGHTS_BASE_CONTROL_BLOCK *)window)->lights_base_radial_slider);
369 break;
370
371 case GX_SIGNAL(ID_CLOSE, GX_EVENT_CLICKED):
372 on_close_button_clicked((LIGHTS_BASE_CONTROL_BLOCK *)window);
373 break;
374
375 case GX_SIGNAL(ID_OPEN, GX_EVENT_CLICKED):
376 on_open_button_clicked((LIGHTS_BASE_CONTROL_BLOCK *)window);
377 break;
378
379 default:
380 return gx_window_event_process(window, event_ptr);
381 }
382
383 return 0;
384 }
385
386 /******************************************************************************************/
387 /* Initiate light screen information. */
388 /******************************************************************************************/
lights_screen_init()389 VOID lights_screen_init()
390 {
391 LIGHT_INFO *info = light_info_list;
392
393 while (info->light)
394 {
395 /* Set light color text. */
396 gx_prompt_text_id_set(&info->light->lights_base_color_text, info->color_text_id);
397
398 /* detach open button. */
399 gx_widget_detach(&info->light->lights_base_button_open);
400
401 light_status_reset(info);
402
403 info++;
404 }
405
406 lights_title_init();
407
408 /* Set add button text to "ADD LIGHT". */
409 gx_prompt_text_id_set(&lights_screen.base.screen_base_add_text, GX_STRING_ID_ADD_LIGHT);
410 }