1 
2 #include "demo_guix_home_automation.h"
3 
4 #define MIN_DEGREE 40
5 #define MAX_DEGREE 120
6 
7 /* Define thermostat controller information structure. */
8 typedef struct THERMOSTAT_INFO_STRUCT{
9     THERMOSTAT_BASE_CONTROL_BLOCK *controller; /* Pointer to thermostat controller. */
10     GX_CHAR *cold_heat_text; /* Temperature description text. */
11     GX_RESOURCE_ID cold_heat_icon; /* ID of the temperature icon. */
12     INT radial_angle; /* Current value of the thermostat radial slider. */
13     INT power; /* Engery in use. */
14     INT enabled; /* Flag if the thermostat controller is enabled. */
15 }THERMOSTAT_INFO;
16 
17 /* This is a list of thermostat controler widgets and property values applied to those widgets. */
18 static THERMOSTAT_INFO thermostat_info_list[] = {
19     { &thermostat_page_1.thermostat_page_1_kitchen, "cooling", GX_PIXELMAP_ID_BOX_ICON_COLD, 230, 0, GX_TRUE },
20     { &thermostat_page_1.thermostat_page_1_master_bedroom, "heating", GX_PIXELMAP_ID_BOX_ICON_HEAT, -50, 0, GX_TRUE },
21     { &thermostat_page_2.thermostat_page_2_kids_bedroom, "heading", GX_PIXELMAP_ID_BOX_ICON_HEAT, 90, 0, GX_TRUE },
22     { &thermostat_page_2.thermostat_page_2_living_room, "cooling", GX_PIXELMAP_ID_BOX_ICON_COLD, 180, 0, GX_TRUE },
23     { &thermostat_page_3.thermostat_page_3_dinning_room, "heating", GX_PIXELMAP_ID_BOX_ICON_HEAT, 0, 0, GX_TRUE },
24     { &thermostat_page_3.thermostat_page_3_outdoor_patio, "cooling", GX_PIXELMAP_ID_BOX_ICON_COLD, 180, 0, GX_TRUE },
25     { &thermostat_page_4.thermostat_page_4_office, "heading", GX_PIXELMAP_ID_BOX_ICON_HEAT, 0, 0, GX_TRUE },
26     { GX_NULL, "", 0, 0, 0, 0 }
27 };
28 
29 /* This variable is used for screen slide animation. */
30 extern GX_ANIMATION slide_animation;
31 extern int screen_animation_count;
32 
33 /******************************************************************************************/
34 /* Retrieve thermostat information with specified thermostat controller.                  */
35 /******************************************************************************************/
thermostat_info_get(THERMOSTAT_BASE_CONTROL_BLOCK * controller)36 static THERMOSTAT_INFO *thermostat_info_get(THERMOSTAT_BASE_CONTROL_BLOCK *controller)
37 {
38     THERMOSTAT_INFO *info = thermostat_info_list;
39 
40     while (info->controller)
41     {
42         if (info->controller == controller)
43         {
44             return info;
45         }
46         info++;
47     }
48 
49     return GX_NULL;
50 }
51 
52 /******************************************************************************************/
53 /* Update bottom information of thermostat screen.                                        */
54 /******************************************************************************************/
thermostat_screen_bottom_info_update()55 static VOID thermostat_screen_bottom_info_update()
56 {
57     THERMOSTAT_INFO *info = thermostat_info_list;
58     INT energy_in_use = 0;
59     INT enabled = 0;
60     INT disabled = 0;
61 
62     while (info->controller)
63     {
64         if (info->enabled)
65         {
66             energy_in_use += info->power;
67             enabled++;
68         }
69         else
70         {
71             disabled++;
72         }
73         info++;
74     }
75 
76     /* Display the number of enabled thermostat controllers. */
77     gx_numeric_prompt_value_set(&thermostat_screen.thermostat_screen_num_on, enabled);
78 
79     /* Display the number of disabled thermostat controllers. */
80     gx_numeric_prompt_value_set(&thermostat_screen.thermostat_screen_num_off, disabled);
81 
82     /* Display the value of energy in use. */
83     gx_numeric_prompt_value_set(&thermostat_screen.thermostat_screen_energy_in_use, energy_in_use);
84 }
85 
86 /******************************************************************************************/
87 /* Update information of specified thermostat controller.                                 */
88 /******************************************************************************************/
thermostat_controller_info_update(THERMOSTAT_INFO * info,int radial_angle)89 static VOID thermostat_controller_info_update(THERMOSTAT_INFO *info, int radial_angle)
90 {
91     THERMOSTAT_BASE_CONTROL_BLOCK *controller = info->controller;
92     INT angle;
93     INT angle_range = (MAX_ANGLE - MIN_ANGLE);
94     INT value;
95     INT xpos;
96     GX_RESOURCE_ID icon;
97     GX_RESOURCE_ID text_id;
98 
99     angle = MAX_ANGLE - radial_angle;
100 
101     value = MIN_DEGREE + angle * (MAX_DEGREE - MIN_DEGREE) / angle_range;
102 
103     /* Set thermostat value in center of the thermostat radial slider. */
104     gx_numeric_prompt_value_set(&controller->thermostat_base_center_value, value);
105 
106     if (value < 100)
107     {
108         xpos = 185;
109     }
110     else
111     {
112         xpos = 200;
113     }
114 
115     xpos += controller->base.gx_widget_size.gx_rectangle_left;
116 
117     gx_widget_shift(&controller->thermostat_base_dot_lable, xpos - controller->thermostat_base_dot_lable.gx_widget_size.gx_rectangle_left, 0, GX_TRUE);
118 
119     if (value < 90)
120     {
121         icon = GX_PIXELMAP_ID_BOX_ICON_COLD;
122         text_id = GX_STRING_ID_COOLING;
123     }
124     else
125     {
126         icon = GX_PIXELMAP_ID_BOX_ICON_HEAT;
127         text_id = GX_STRING_ID_HEATING;
128     }
129 
130     /* Set temperature icon. */
131     gx_icon_pixelmap_set(&controller->thermostat_base_cold_heat_icon, icon, icon);
132 
133     /* Set temperature description text. */
134     gx_prompt_text_id_set(&controller->thermostat_base_cold_heat_text, text_id);
135 
136     info->power = angle * MAX_POWER / angle_range;
137 }
138 
139 /******************************************************************************************/
140 /* Event handler for close button click.                                                  */
141 /* Hide thermostat radial slider and show open button.                                    */
142 /******************************************************************************************/
on_close_button_clicked(THERMOSTAT_BASE_CONTROL_BLOCK * base)143 static VOID on_close_button_clicked(THERMOSTAT_BASE_CONTROL_BLOCK *base)
144 {
145     THERMOSTAT_INFO *info = thermostat_info_get(base);
146 
147     if (info && info->enabled)
148     {
149         info->enabled = GX_FALSE;
150 
151         /* detach radial slider. */
152         gx_widget_detach(&base->thermostat_base_radial_slider);
153 
154         /* detach icon ruller. */
155         gx_widget_detach(&base->thermostat_base_ruller_thermostat);
156 
157         gx_widget_detach(&base->thermostat_base_button_close);
158 
159         /* attach open button. */
160         gx_widget_attach((GX_WIDGET *)base, &base->thermostat_base_button_open);
161 
162         thermostat_screen_bottom_info_update();
163     }
164 }
165 
166 /******************************************************************************************/
167 /* Event handler for open button click.                                                   */
168 /* Show thermostat radial slider and hide open button.                                    */
169 /******************************************************************************************/
on_open_button_clicked(THERMOSTAT_BASE_CONTROL_BLOCK * base)170 static VOID on_open_button_clicked(THERMOSTAT_BASE_CONTROL_BLOCK *base)
171 {
172     THERMOSTAT_INFO *info = thermostat_info_get(base);
173 
174     if (info && (!info->enabled))
175     {
176         info->enabled = GX_TRUE;
177 
178         /* attach icon ruller. */
179         gx_widget_attach((GX_WIDGET *)base, &base->thermostat_base_ruller_thermostat);
180 
181         gx_widget_attach((GX_WIDGET *)base, &base->thermostat_base_button_close);
182 
183         /* attach radial slider. */
184         gx_widget_attach((GX_WIDGET *)base, &base->thermostat_base_radial_slider);
185 
186         /* detach open button. */
187         gx_widget_detach(&base->thermostat_base_button_open);
188 
189         thermostat_screen_bottom_info_update();
190     }
191 }
192 
193 /******************************************************************************************/
194 /* Reset status of one thermostat controller.                                             */
195 /******************************************************************************************/
thermostat_controller_reset(THERMOSTAT_BASE_CONTROL_BLOCK * widget)196 static VOID thermostat_controller_reset(THERMOSTAT_BASE_CONTROL_BLOCK *widget)
197 {
198     GX_WIDGET *child;
199 
200     /* Hide child widgets. */
201     child = widget->base.gx_widget_first_child;
202     while (child)
203     {
204         gx_widget_hide(child);
205         child = child->gx_widget_next;
206     }
207 
208     /* Reset the value of thermostat radial slider. */
209     gx_radial_slider_angle_set(&widget->thermostat_base_radial_slider, MAX_ANGLE);
210 
211     /* Reset the text value in center of the thermostat radial slider. */
212     gx_numeric_prompt_value_set(&widget->thermostat_base_center_value, 40);
213 }
214 
215 /******************************************************************************************/
216 /* Reset status of all thermostat controllers.                                            */
217 /******************************************************************************************/
thermostat_screen_reset()218 VOID thermostat_screen_reset()
219 {
220     THERMOSTAT_INFO *info = thermostat_info_list;
221 
222     while (info->controller)
223     {
224         if (info->controller->base.gx_widget_status & GX_STATUS_VISIBLE)
225         {
226             /* Reset status of one thermostat controller. */
227             thermostat_controller_reset(info->controller);
228         }
229 
230         info++;
231     }
232 }
233 
234 /******************************************************************************************/
235 /* Start animation for thermostat screen.                                                 */
236 /******************************************************************************************/
thermostat_screen_animation_start()237 VOID thermostat_screen_animation_start()
238 {
239     THERMOSTAT_INFO *info = thermostat_info_list;
240     CONTROLLER_BASE_CONTROL_BLOCK *base;
241     GX_WIDGET *child;
242 
243     while (info->controller)
244     {
245         if (info->controller->base.gx_widget_status & GX_STATUS_VISIBLE)
246         {
247             base = &info->controller->base;
248 
249             if (!(base->controller_base_title.gx_widget_status & GX_STATUS_VISIBLE))
250             {
251                 /* Disable drag slide animation before child widget animations complete. */
252                 gx_animation_drag_disable(&slide_animation, (GX_WIDGET *)&thermostat_screen.base.screen_base_slide_win);
253 
254                 /* Disable pagination buttons before child widget animations complete. */
255                 pagination_button_enable_disable((GX_WINDOW *)&thermostat_screen.base, GX_FALSE);
256 
257                 /* Slide in controller title. */
258                 title_animation_start(&info->controller->base);
259 
260                 if (info->enabled)
261                 {
262                     /* Start animation to move radial slider from current value to the target value. */
263                     gx_radial_slider_animation_start(&info->controller->thermostat_base_radial_slider, info->radial_angle);
264                 }
265 
266                 /* Show child widgets. */
267                 child = base->gx_widget_first_child;
268                 while (child)
269                 {
270                     gx_widget_show(child);
271                     child = child->gx_widget_next;
272                 }
273             }
274         }
275         else
276         {
277             thermostat_controller_reset(info->controller);
278         }
279 
280         info++;
281     }
282 }
283 
284 /******************************************************************************************/
285 /* Stop all animations in thermostat screen.                                              */
286 /******************************************************************************************/
thermostat_screen_animation_stop()287 VOID thermostat_screen_animation_stop()
288 {
289     THERMOSTAT_INFO* info = thermostat_info_list;
290 
291     while (info->controller)
292     {
293         if (info->controller->base.gx_widget_status & GX_STATUS_VISIBLE)
294         {
295             gx_animation_delete(GX_NULL, (GX_WIDGET *)&info->controller->base);
296         }
297 
298         info++;
299     }
300 
301     screen_animation_count = 0;
302 }
303 
304 
305 /******************************************************************************************/
306 /* Callback function of radial slider, which is called after every animation step.        */
307 /******************************************************************************************/
thermostat_radial_slider_value_update(GX_RADIAL_SLIDER * slider)308 VOID thermostat_radial_slider_value_update(GX_RADIAL_SLIDER *slider)
309 {
310     THERMOSTAT_INFO *info = thermostat_info_get((THERMOSTAT_BASE_CONTROL_BLOCK *)slider->gx_widget_parent);
311 
312     if (info && (slider->gx_widget_status & GX_STATUS_VISIBLE))
313     {
314         info->radial_angle = slider->gx_radial_slider_info.gx_radial_slider_info_current_angle;
315 
316         /* Update thermostat information values in thermostat controller. */
317         thermostat_controller_info_update(info, info->radial_angle);
318 
319         /* Update thermostat information values in bottom of the thermostat screen. */
320         thermostat_screen_bottom_info_update();
321     }
322 }
323 
324 /******************************************************************************************/
325 /* Override the default event processing of templates based on "thermostat_base" to       */
326 /* handle signals from my  child widgets.                                                 */
327 /******************************************************************************************/
thermostat_base_event_process(GX_WINDOW * window,GX_EVENT * event_ptr)328 UINT thermostat_base_event_process(GX_WINDOW *window, GX_EVENT *event_ptr)
329 {
330     switch (event_ptr->gx_event_type)
331     {
332     case GX_SIGNAL(ID_RADIAL_SLIDER, GX_EVENT_SLIDER_VALUE):
333         thermostat_radial_slider_value_update(&((THERMOSTAT_BASE_CONTROL_BLOCK *)window)->thermostat_base_radial_slider);
334         break;
335 
336     case GX_SIGNAL(ID_CLOSE, GX_EVENT_CLICKED):
337         on_close_button_clicked((THERMOSTAT_BASE_CONTROL_BLOCK *)window);
338         break;
339 
340     case GX_SIGNAL(ID_OPEN, GX_EVENT_CLICKED):
341         on_open_button_clicked((THERMOSTAT_BASE_CONTROL_BLOCK *)window);
342         break;
343 
344     default:
345         return gx_window_event_process(window, event_ptr);
346     }
347 
348     return 0;
349 }
350 
351 /******************************************************************************************/
352 /* Initiate thermostat screen information.                                                */
353 /******************************************************************************************/
thermostat_screen_init()354 VOID thermostat_screen_init()
355 {
356     THERMOSTAT_INFO *info = thermostat_info_list;
357 
358     while (info->controller)
359     {
360         gx_widget_detach(&info->controller->thermostat_base_button_open);
361 
362         /* Reset status of thermostat controller. */
363         thermostat_controller_reset(info->controller);
364 
365         info++;
366     }
367 
368     /* Initialize title text for each thermostat controllers. */
369     thermostat_title_init();
370 
371     /* Set "Add Thermostat" widget text. */
372     gx_prompt_text_id_set(&thermostat_screen.base.screen_base_add_text, GX_STRING_ID_ADD_ROOM);
373 }