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 }