1 
2 #include "demo_guix_home_automation.h"
3 
4 /* Define lock information struture. */
5 typedef struct LOCK_INFO_STRUCT{
6     GX_BOOL lock_enabled; /* Mark if lock function is enabled. */
7     GX_BOOL lock_all; /* Mark if all locks are enabled. */
8 }LOCK_INFO;
9 
10 /* Define door information structure. */
11 typedef struct DOOR_INFO_STRUCT{
12     LOCKS_DOOR_BASE_CONTROL_BLOCK *door; /* Pointer to locks controller widget. */
13     GX_BOOL locked; /* Locks status. */
14 }DOOR_INFO;
15 
16 /* Lock controller widget is based on "locks door base" widgets.
17    This is a list of lock controller widget and the lock status of those widgets. */
18 static DOOR_INFO door_widget_list[] = {
19     { &locks_page_1.locks_page_1_front_door, GX_TRUE },
20     { &locks_page_2.locks_page_2_patio_door, GX_TRUE},
21     { &locks_page_2.locks_page_2_upper_deck_door, GX_TRUE },
22     { &locks_page_3.locks_page_3_lower_deck_door, GX_TRUE },
23     { GX_NULL, 0}
24 };
25 
26 /* Lock controller widget is based on "locks door base" widgets.
27    This is a list of all lock controller widgets. */
28 static CONTROLLER_BASE_CONTROL_BLOCK *lock_controller_list[] = {
29     &locks_page_1.locks_page_1_security_alarm,
30     &locks_page_1.locks_page_1_front_door.base,
31     &locks_page_2.locks_page_2_patio_door.base,
32     &locks_page_2.locks_page_2_upper_deck_door.base,
33     &locks_page_3.locks_page_3_lower_deck_door.base,
34     GX_NULL
35 };
36 
37 /* Initialize lock information. */
38 static LOCK_INFO lock_info = { GX_TRUE, GX_TRUE };
39 
40 extern GX_ANIMATION slide_animation;
41 extern int screen_animation_count;
42 
43 /******************************************************************************************/
44 /* Custom button select function.                                                         */
45 /******************************************************************************************/
lock_button_select(GX_BUTTON * button)46 static VOID lock_button_select(GX_BUTTON *button)
47 {
48     GX_WIDGET *child = button->gx_widget_first_child;
49 
50     while (child)
51     {
52         gx_widget_style_add(child, GX_STYLE_DRAW_SELECTED);
53 
54         child = child->gx_widget_next;
55     }
56 
57     gx_button_select(button);
58 }
59 
60 /******************************************************************************************/
61 /* Custom button deselect function.                                                       */
62 /******************************************************************************************/
lock_button_deselect(GX_BUTTON * button,GX_BOOL generate)63 static VOID lock_button_deselect(GX_BUTTON *button, GX_BOOL generate)
64 {
65     GX_WIDGET *child = button->gx_widget_first_child;
66 
67     while (child)
68     {
69         gx_widget_style_remove(child, GX_STYLE_DRAW_SELECTED);
70 
71         child = child->gx_widget_next;
72     }
73 
74     gx_button_deselect(button, generate);
75 }
76 
77 /******************************************************************************************/
78 /* Update text of "Enabled/Disabled" button.                                              */
79 /******************************************************************************************/
update_enable_disable_button_text()80 static VOID update_enable_disable_button_text()
81 {
82     GX_RESOURCE_ID text_id;
83 
84     if (lock_info.lock_enabled)
85     {
86         text_id = GX_STRING_ID_ENABLED;
87     }
88     else
89     {
90         text_id = GX_STRING_ID_DISABLED;
91     }
92 
93     gx_prompt_text_id_set(&locks_page_1.locks_page_1_enable_disable_text, text_id);
94 }
95 
96 /******************************************************************************************/
97 /* Update appearance of "Lock All/Unlock All" button.                                     */
98 /******************************************************************************************/
update_lock_unlock_button_appearance()99 static VOID update_lock_unlock_button_appearance()
100 {
101     GX_RESOURCE_ID text_id;
102     GX_RESOURCE_ID lock_normal_bg;
103     GX_RESOURCE_ID lock_selecgted_bg;
104     GX_RESOURCE_ID lock_normal_icon;
105     GX_RESOURCE_ID lock_selected_icon;
106     GX_RESOURCE_ID color_id;
107 
108     /* Set appearance properties with regard to different lock status. */
109     if (lock_info.lock_enabled)
110     {
111         if (lock_info.lock_all)
112         {
113             text_id = GX_STRING_ID_UNLOCK_ALL;
114             lock_normal_bg = GX_PIXELMAP_ID_LOCKS_ROUND_BTN_SMALL_ACTIVE;
115             lock_selecgted_bg = GX_PIXELMAP_ID_LOCKS_ROUND_BTN_SMALL_ACTIVE_HOVER;
116             lock_normal_icon = GX_PIXELMAP_ID_LOCKS_ICON_BTN_SMALL_CLOSED_LOCK;
117             lock_selected_icon = GX_PIXELMAP_ID_LOCKS_ICON_BTN_SMALL_CLOSED_LOCK_HOVER;
118             color_id = GX_COLOR_ID_BLUE;
119         }
120         else
121         {
122             text_id = GX_STRING_ID_LOCK_ALL;
123             lock_normal_bg = GX_PIXELMAP_ID_LOCKS_ROUND_BTN_SMALL;
124             lock_selecgted_bg = GX_PIXELMAP_ID_LOCKS_ROUND_BTN_SMALL_HOVER;
125             lock_normal_icon = GX_PIXELMAP_ID_LOCKS_ICON_BTN_SMALL_OPEN_LOCK;
126             lock_selected_icon = GX_PIXELMAP_ID_LOCKS_ICON_BTN_SMALL_OPEN_LOCK_HOVER;
127             color_id = GX_COLOR_ID_GREEN;
128         }
129     }
130     else
131     {
132         text_id = GX_STRING_ID_ACTIVE;
133         lock_normal_bg = GX_PIXELMAP_ID_LOCKS_ROUND_BTN_SMALL;
134         lock_selecgted_bg = GX_PIXELMAP_ID_LOCKS_ROUND_BTN_SMALL_HOVER;
135         lock_normal_icon = GX_PIXELMAP_ID_LOCKS_ICON_BTN_SMALL_CAMERA;
136         lock_selected_icon = GX_PIXELMAP_ID_LOCKS_ICON_BTN_SMALL_CAMERA_HOVER;
137         color_id = GX_COLOR_ID_GREEN;
138     }
139 
140     /* Set child prompt text. */
141     gx_prompt_text_id_set(&locks_page_1.locks_page_1_lock_unlock_text, text_id);
142 
143     /* Set child prompt text color. */
144     gx_prompt_text_color_set(&locks_page_1.locks_page_1_lock_unlock_text, color_id, color_id, color_id);
145 
146     /* Set child prompt fill color. */
147     gx_widget_fill_color_set(&locks_page_1.locks_page_1_lock_unlock_text, color_id, color_id, color_id);
148 
149     /* Set child icon pixelmaps. */
150     gx_icon_pixelmap_set(&locks_page_1.locks_page_1_lock_unlock_icon, lock_normal_icon, lock_selected_icon);
151 
152     /* Set child icon fill colors. */
153     gx_widget_fill_color_set(&locks_page_1.locks_page_1_lock_unlock_icon, color_id, color_id, color_id);
154 
155     /* Set "Lock All/Unlock All" button pixelmaps. */
156     gx_pixelmap_button_pixelmap_set(&locks_page_1.locks_page_1_button_lock, lock_normal_bg, lock_selecgted_bg, lock_normal_bg);
157 }
158 
159 /******************************************************************************************/
160 /* lock/unlock one doors.                                                                 */
161 /******************************************************************************************/
lock_unlock_one_door(LOCKS_DOOR_BASE_CONTROL_BLOCK * base,GX_BOOL lock)162 static VOID lock_unlock_one_door(LOCKS_DOOR_BASE_CONTROL_BLOCK *base, GX_BOOL lock)
163 {
164     GX_RESOURCE_ID button_normal_icon;
165     GX_RESOURCE_ID button_selected_icon;
166     GX_RESOURCE_ID lock_normal_icon;
167     GX_RESOURCE_ID lock_selected_icon;
168     GX_RESOURCE_ID lock_text_id;
169     GX_WIDGET *child;
170     GX_RESOURCE_ID color_id;
171     GX_PIXELMAP_BUTTON *button = &base->locks_door_base_button_lock;
172 
173     /* Set appearance properties with regard different lock status. */
174     if (lock)
175     {
176         button_normal_icon = GX_PIXELMAP_ID_LOCKS_ROUND_BTN_BIG_ACTIVE;
177         button_selected_icon = GX_PIXELMAP_ID_LOCKS_ROUND_BTN_BIG_ACTIVE_HOVER;
178         lock_normal_icon = GX_PIXELMAP_ID_LOCKS_ICON_BTN_CLOSED_LOCK;
179         lock_selected_icon = GX_PIXELMAP_ID_LOCKS_ICON_BTN_CLOSED_LOCK_HOVER;
180         lock_text_id = GX_STRING_ID_LOCKED;
181         color_id = GX_COLOR_ID_BLUE;
182     }
183     else
184     {
185         button_normal_icon = GX_PIXELMAP_ID_LOCKS_ROUND_BTN_BIG;
186         button_selected_icon = GX_PIXELMAP_ID_LOCKS_ROUND_BTN_BIG_HOVER;
187         lock_normal_icon = GX_PIXELMAP_ID_LOCKS_ICON_BTN_OPEN_LOCK;
188         lock_selected_icon = GX_PIXELMAP_ID_LOCKS_ICON_BTN_OPEN_LOCK_HOVER;
189         lock_text_id = GX_STRING_ID_UNLOCKED;
190         color_id = GX_COLOR_ID_GREEN;
191     }
192 
193     child = button->gx_widget_first_child;
194 
195     while (child)
196     {
197         switch (child->gx_widget_type)
198         {
199         case GX_TYPE_ICON:
200             /* Set child icon background. */
201             gx_icon_pixelmap_set((GX_ICON *)child, lock_normal_icon, lock_selected_icon);
202             break;
203 
204         case GX_TYPE_PROMPT:
205             /* Set child prompt text. */
206             gx_prompt_text_id_set((GX_PROMPT *)child, lock_text_id);
207 
208             /* Set child prompt text color. */
209             gx_prompt_text_color_set((GX_PROMPT *)child, color_id, color_id, color_id);
210             break;
211         }
212 
213         /* Set child widget fill color. */
214         gx_widget_fill_color_set(child, color_id, color_id, color_id);
215 
216         child = child->gx_widget_next;
217     }
218 
219     gx_pixelmap_button_pixelmap_set(button, button_normal_icon, button_selected_icon, button_normal_icon);
220 }
221 
222 /******************************************************************************************/
223 /* lock/unlock all doors.                                                                 */
224 /******************************************************************************************/
lock_unlock_all_doors(GX_BOOL lock)225 static VOID lock_unlock_all_doors(GX_BOOL lock)
226 {
227     DOOR_INFO *info = door_widget_list;
228 
229     while (info->door)
230     {
231         /* Lock/Ulock one door. */
232         lock_unlock_one_door(info->door, lock);
233 
234         info++;
235     }
236 }
237 
238 /******************************************************************************************/
239 /* Event handler for "Enabled/Disabled" button click.                                     */
240 /******************************************************************************************/
on_enabled_disabled_security_alarm()241 static VOID on_enabled_disabled_security_alarm()
242 {
243     if (lock_info.lock_enabled)
244     {
245         lock_info.lock_enabled = GX_FALSE;
246     }
247     else
248     {
249         lock_info.lock_enabled = GX_TRUE;
250     }
251 
252     /* Update button text. */
253     update_enable_disable_button_text();
254 
255     /* Update button appearance. */
256     update_lock_unlock_button_appearance();
257 }
258 
259 /******************************************************************************************/
260 /* Event handler for "Lock All"/"Unlock All" button click.                                */
261 /******************************************************************************************/
on_lock_unlock_all()262 static VOID on_lock_unlock_all()
263 {
264     if (lock_info.lock_enabled)
265     {
266         if (lock_info.lock_all)
267         {
268             lock_info.lock_all = GX_FALSE;
269         }
270         else
271         {
272             lock_info.lock_all = GX_TRUE;
273         }
274 
275         lock_unlock_all_doors(lock_info.lock_all);
276     }
277     else
278     {
279         lock_info.lock_enabled = GX_TRUE;
280     }
281 
282     /* Update button text. */
283     update_enable_disable_button_text();
284 
285     /* Update button appearance. */
286     update_lock_unlock_button_appearance();
287 }
288 
289 /******************************************************************************************/
290 /* Event handler for "Lock" button click.                                                 */
291 /******************************************************************************************/
on_lock_button_clicked(LOCKS_DOOR_BASE_CONTROL_BLOCK * base)292 static VOID on_lock_button_clicked(LOCKS_DOOR_BASE_CONTROL_BLOCK *base)
293 {
294     DOOR_INFO *info = door_widget_list;
295 
296     while (info->door)
297     {
298         if (info->door == base)
299         {
300             /* Switch lock status. */
301             if (info->locked)
302             {
303                 info->locked = GX_FALSE;
304             }
305             else
306             {
307                 info->locked = GX_TRUE;
308             }
309 
310             lock_unlock_one_door(base, info->locked);
311             break;
312         }
313 
314         info++;
315     }
316 }
317 
318 /******************************************************************************************/
319 /* Event handler for lock close button click.                                             */
320 /******************************************************************************************/
on_close_button_clicked(LOCKS_DOOR_BASE_CONTROL_BLOCK * base)321 static VOID on_close_button_clicked(LOCKS_DOOR_BASE_CONTROL_BLOCK *base)
322 {
323     /* detach lock button. */
324     gx_widget_detach(&base->locks_door_base_button_lock);
325 
326     /* detach close button. */
327     gx_widget_detach(&base->locks_door_base_button_close);
328 
329     /* attach open button. */
330     gx_widget_attach((GX_WIDGET *)base, &base->locks_door_base_button_open);
331 }
332 
333 /******************************************************************************************/
334 /* Event handler for lock open button click.                                              */
335 /******************************************************************************************/
on_open_button_clicked(LOCKS_DOOR_BASE_CONTROL_BLOCK * base)336 static VOID on_open_button_clicked(LOCKS_DOOR_BASE_CONTROL_BLOCK *base)
337 {
338     /* attach lock button. */
339     gx_widget_attach((GX_WIDGET *)base, &base->locks_door_base_button_lock);
340 
341     /* attach close button. */
342     gx_widget_attach((GX_WIDGET *)base, &base->locks_door_base_button_close);
343 
344     /* detach open button. */
345     gx_widget_detach(&base->locks_door_base_button_open);
346 }
347 
348 /******************************************************************************************/
349 /* Override the default event processing of "locks_page_1" to handle signals from my      */
350 /* child widgets.                                                                         */
351 /******************************************************************************************/
locks_page_1_event_process(GX_WINDOW * window,GX_EVENT * event_ptr)352 UINT locks_page_1_event_process(GX_WINDOW *window, GX_EVENT *event_ptr)
353 {
354     switch (event_ptr->gx_event_type)
355     {
356     case GX_SIGNAL(ID_BUTTON_ENABLE_DISABLE, GX_EVENT_CLICKED):
357         on_enabled_disabled_security_alarm();
358         break;
359 
360     case GX_SIGNAL(ID_BUTTON_LOCK_UNLOCK_ALL, GX_EVENT_CLICKED):
361         on_lock_unlock_all();
362         break;
363 
364     default:
365         return gx_window_event_process(window, event_ptr);
366     }
367 
368     return 0;
369 }
370 
371 /******************************************************************************************/
372 /* Override the default event processing of templates based "locks_door_base" to handle   */
373 /* signals from my child widgets.                                                         */
374 /******************************************************************************************/
locks_door_base_event_process(GX_WINDOW * window,GX_EVENT * event_ptr)375 UINT locks_door_base_event_process(GX_WINDOW *window, GX_EVENT *event_ptr)
376 {
377     switch (event_ptr->gx_event_type)
378     {
379     case GX_SIGNAL(ID_LOCK_BUTTON, GX_EVENT_CLICKED):
380         on_lock_button_clicked((LOCKS_DOOR_BASE_CONTROL_BLOCK *)window);
381         break;
382 
383     case GX_SIGNAL(ID_CLOSE, GX_EVENT_CLICKED):
384         on_close_button_clicked((LOCKS_DOOR_BASE_CONTROL_BLOCK *)window);
385         break;
386 
387     case GX_SIGNAL(ID_OPEN, GX_EVENT_CLICKED):
388         on_open_button_clicked((LOCKS_DOOR_BASE_CONTROL_BLOCK *)window);
389         break;
390 
391     default:
392         return gx_window_event_process(window, event_ptr);
393     }
394 
395     return 0;
396 }
397 
398 /******************************************************************************************/
399 /* Hide some children of lock widget.                                                     */
400 /******************************************************************************************/
hide_locks_children(CONTROLLER_BASE_CONTROL_BLOCK * widget)401 static VOID hide_locks_children(CONTROLLER_BASE_CONTROL_BLOCK *widget)
402 {
403     GX_WIDGET *child = widget->gx_widget_first_child;
404 
405     while (child)
406     {
407         if (child->gx_widget_id != ID_STATUS)
408         {
409             gx_widget_hide(child);
410         }
411 
412         child = child->gx_widget_next;
413     }
414 }
415 
416 /******************************************************************************************/
417 /* Start animation for lock widget.                                                       */
418 /******************************************************************************************/
start_lock_children_animation(CONTROLLER_BASE_CONTROL_BLOCK * widget)419 static VOID start_lock_children_animation(CONTROLLER_BASE_CONTROL_BLOCK *widget)
420 {
421     GX_WIDGET *child = widget->gx_widget_first_child;
422 
423     while (child)
424     {
425         if (child->gx_widget_id != ID_STATUS)
426         {
427             gx_widget_show(child);
428         }
429 
430         child = child->gx_widget_next;
431     }
432 
433     /* Disable drag slide animation before screen item animations complete. */
434     gx_animation_drag_disable(&slide_animation, (GX_WIDGET *)&locks_screen.base.screen_base_slide_win);
435 
436     /* Disabled pagination buttons before screen item animations complete. */
437     pagination_button_enable_disable((GX_WINDOW *)&locks_screen.base, GX_FALSE);
438 
439     /* Slide in controller title. */
440     title_animation_start(widget);
441 }
442 
443 /******************************************************************************************/
444 /* Reset locks screen.                                                                    */
445 /******************************************************************************************/
locks_screen_reset()446 VOID locks_screen_reset()
447 {
448     DOOR_INFO *info = door_widget_list;
449 
450     while (info->door)
451     {
452         if (info->door->base.gx_widget_status & GX_STATUS_VISIBLE)
453         {
454             /* Hide child widgets for lock controller. */
455             hide_locks_children(&info->door->base);
456         }
457 
458         info++;
459     }
460 
461     /* Hide child widgets for security alarm controller. */
462     hide_locks_children(&locks_page_1.locks_page_1_security_alarm);
463 }
464 
465 /******************************************************************************************/
466 /* Start animation for locks screen      .                                                */
467 /******************************************************************************************/
locks_screen_animation_start()468 VOID locks_screen_animation_start()
469 {
470     CONTROLLER_BASE_CONTROL_BLOCK *lock_controller;
471     INT index = 0;
472 
473     while (1)
474     {
475         lock_controller = lock_controller_list[index];
476 
477         if (lock_controller)
478         {
479             if (lock_controller->gx_widget_status & GX_STATUS_VISIBLE)
480             {
481                 /* lock controller is get visible. */
482                 if (!(lock_controller->controller_base_title.gx_widget_status & GX_STATUS_VISIBLE))
483                 {
484                     /* Title of the lock controller is not visible, which means lock page switched.
485                        start children animations for the lock controller. */
486                     start_lock_children_animation(lock_controller);
487                 }
488             }
489             else
490             {
491                 /* Hide some child widgets for invisible lock controllers.
492                    Next time the lock controller get visible, those widgets will show with animations. */
493                 hide_locks_children(lock_controller);
494             }
495 
496             index++;
497         }
498         else
499         {
500             break;
501         }
502     }
503 }
504 
505 /******************************************************************************************/
506 /* Stop all animations in locks screen.                                                   */
507 /******************************************************************************************/
locks_screen_animation_stop()508 VOID locks_screen_animation_stop()
509 {
510     CONTROLLER_BASE_CONTROL_BLOCK* lock_controller;
511     INT index = 0;
512 
513     while (1)
514     {
515         lock_controller = lock_controller_list[index];
516 
517         if (lock_controller)
518         {
519             if (lock_controller->gx_widget_status & GX_STATUS_VISIBLE)
520             {
521                 gx_animation_delete(GX_NULL, (GX_WIDGET*)lock_controller);
522             }
523 
524             index++;
525         }
526         else
527         {
528             break;
529         }
530     }
531 
532     screen_animation_count = 0;
533 }
534 
535 /******************************************************************************************/
536 /* Initiate lock screen information.                                                      */
537 /******************************************************************************************/
locks_screen_init()538 VOID locks_screen_init()
539 {
540     DOOR_INFO *info = door_widget_list;
541     LOCKS_DOOR_BASE_CONTROL_BLOCK *door;
542     while (info->door)
543     {
544         door = info->door;
545 
546         /* Detach lock open button, this button will be attached when
547            lock is closed. */
548         gx_widget_detach((GX_WIDGET *)&door->locks_door_base_button_open);
549 
550         /* Set custom button select/deselect handler for lock buttons. */
551         door->locks_door_base_button_lock.gx_button_select_handler = (VOID(*)(GX_WIDGET *))lock_button_select;
552         door->locks_door_base_button_lock.gx_button_deselect_handler = (VOID(*)(GX_WIDGET *, GX_BOOL))lock_button_deselect;
553 
554         /* Hide some child widgets for invisible lock controllers.
555            Next time the lock controller get visible, those widgets will show with animations. */
556         hide_locks_children(&door->base);
557 
558         info++;
559     }
560 
561     /* Hide some child widgets for invisible security alarm controller.
562        Next time the security alarm controller is visible, those widgets will show with animations. */
563     hide_locks_children(&locks_page_1.locks_page_1_security_alarm);
564 
565     /* Set text for lock controllers. */
566     locks_title_init();
567 
568     /* Set custom button select/deselect handler for enabled/disabled and lock/unlock buttons. */
569     locks_page_1.locks_page_1_button_enable_diable.gx_button_select_handler = (VOID(*)(GX_WIDGET *))lock_button_select;
570     locks_page_1.locks_page_1_button_enable_diable.gx_button_deselect_handler = (VOID(*)(GX_WIDGET *, GX_BOOL))lock_button_deselect;
571     locks_page_1.locks_page_1_button_lock.gx_button_select_handler = (VOID(*)(GX_WIDGET *))lock_button_select;
572     locks_page_1.locks_page_1_button_lock.gx_button_deselect_handler = (VOID(*)(GX_WIDGET *, GX_BOOL))lock_button_deselect;
573 
574     /* Set "Add Lock" widget text. */
575     gx_prompt_text_id_set(&locks_screen.base.screen_base_add_text, GX_STRING_ID_ADD_LOCK);
576 }
577