1 /* This is a small demo of the high-performance GUIX graphics framework. */
2
3 #include "demo_guix_home_automation.h"
4
5 /* Define the ThreadX demo thread control block and stack. */
6 TX_BYTE_POOL memory_pool;
7
8 #define CLOCK_TIMER 20
9
10 #define SCRATCHPAD_PIXELS (DISPLAY_1_X_RESOLUTION * DISPLAY_1_Y_RESOLUTION * 2)
11
12 /* Define memory for memory pool. */
13 GX_COLOR scratchpad[SCRATCHPAD_PIXELS];
14
15 GX_WINDOW_ROOT *root;
16
17 /* Define prototypes. */
18 VOID guix_setup(void);
19 extern UINT win32_graphics_driver_setup_24xrgb(GX_DISPLAY *display);
20 VOID clock_update();
21 VOID fade_in_home_window();
22 VOID fade_out_home_window();
23 VOID toggle_screen(GX_WIDGET *new_screen);
24
25 /* Define animation variable for screen slide animation. */
26 GX_ANIMATION slide_animation;
27
28 /* Define GX_PIXELMAP type variable to receive pixelmap data decoded from background jpeg. */
29 GX_PIXELMAP main_screen_bg;
30
31 /* Define application varaible to record current screen and overrall energy used today. */
32 APP_INFO app_info = { (GX_WIDGET *)&main_screen.main_screen_home_window, GX_NULL, 8746594 };
33
34 const GX_CHAR *day_names[7] = {
35 "Sunday",
36 "Monday",
37 "Tuesday",
38 "Wednesday",
39 "Thursday",
40 "Friday",
41 "Saturday"
42 };
43
44 const GX_CHAR *month_names[12] = {
45 "Jan",
46 "Feb",
47 "Mar",
48 "Apr",
49 "May",
50 "Jun",
51 "Jul",
52 "Aug",
53 "Sep",
54 "Oct",
55 "Nov",
56 "Dec"
57 };
58
59 /******************************************************************************************/
60 /* Application entry. */
61 /******************************************************************************************/
main(int argc,char ** argv)62 int main(int argc, char ** argv)
63 {
64 tx_kernel_enter();
65 return(0);
66 }
67
68 /******************************************************************************************/
69 /* Define memory allocator function. */
70 /******************************************************************************************/
memory_allocate(ULONG size)71 VOID *memory_allocate(ULONG size)
72 {
73 VOID *memptr;
74
75 if (tx_byte_allocate(&memory_pool, &memptr, size, TX_NO_WAIT) == TX_SUCCESS)
76 {
77 return memptr;
78 }
79 return NULL;
80 }
81
82 /******************************************************************************************/
83 /* Define memory de-allocator function. */
84 /******************************************************************************************/
memory_free(VOID * mem)85 void memory_free(VOID *mem)
86 {
87 tx_byte_release(mem);
88 }
89
90 /******************************************************************************************/
91 /* Define tx_application_define function. */
92 /******************************************************************************************/
tx_application_define(void * first_unused_memory)93 VOID tx_application_define(void *first_unused_memory)
94 {
95
96 /* create byte pool. */
97 tx_byte_pool_create(&memory_pool, "scratchpad", scratchpad,
98 SCRATCHPAD_PIXELS * sizeof(GX_COLOR));
99
100 guix_setup();
101 }
102
103 /******************************************************************************************/
104 /* Initiate and run GUIX. */
105 /******************************************************************************************/
guix_setup()106 VOID guix_setup()
107 {
108 /* Initialize GUIX. */
109 gx_system_initialize();
110
111 /* install our memory allocator and de-allocator */
112 gx_system_memory_allocator_set(memory_allocate, memory_free);
113
114 /* Configure display. */
115 gx_studio_display_configure(DISPLAY_1, win32_graphics_driver_setup_24xrgb,
116 LANGUAGE_ENGLISH, DISPLAY_1_THEME_1, &root);
117
118 /* Create the main screen and attach it to root window. */
119 gx_studio_named_widget_create("main_screen", (GX_WIDGET *)root, GX_NULL);
120
121 /* The screen control blocks in this case are statically defined, so
122 we can create them all at startup. It is also an option to dynamically
123 allocate the control block memory.
124 */
125
126 gx_studio_named_widget_create("lights_screen", GX_NULL, GX_NULL);
127 gx_studio_named_widget_create("lights_page_1", GX_NULL, GX_NULL);
128 gx_studio_named_widget_create("lights_page_2", GX_NULL, GX_NULL);
129 gx_studio_named_widget_create("lights_page_3", GX_NULL, GX_NULL);
130 gx_studio_named_widget_create("lights_page_4", GX_NULL, GX_NULL);
131 lights_screen_init();
132
133 gx_studio_named_widget_create("locks_screen", GX_NULL, GX_NULL);
134 gx_studio_named_widget_create("locks_page_1", GX_NULL, GX_NULL);
135 gx_studio_named_widget_create("locks_page_2", GX_NULL, GX_NULL);
136 gx_studio_named_widget_create("locks_page_3", GX_NULL, GX_NULL);
137 locks_screen_init();
138
139 gx_studio_named_widget_create("thermostat_screen", GX_NULL, GX_NULL);
140 gx_studio_named_widget_create("thermostat_page_1", GX_NULL, GX_NULL);
141 gx_studio_named_widget_create("thermostat_page_2", GX_NULL, GX_NULL);
142 gx_studio_named_widget_create("thermostat_page_3", GX_NULL, GX_NULL);
143 gx_studio_named_widget_create("thermostat_page_4", GX_NULL, GX_NULL);
144 thermostat_screen_init();
145
146 gx_studio_named_widget_create("weather_screen", GX_NULL, GX_NULL);
147 gx_studio_named_widget_create("win_Las_Vegas", GX_NULL, GX_NULL);
148 gx_studio_named_widget_create("win_New_York", GX_NULL, GX_NULL);
149 gx_studio_named_widget_create("win_San_Diego", GX_NULL, GX_NULL);
150 weather_screen_init();
151
152 gx_studio_named_widget_create("passcode_screen", GX_NULL, GX_NULL);
153
154 /* Create slide animation control block. */
155 gx_animation_create(&slide_animation);
156
157 /* Initialize "main_screen_by" varaible. */
158 memset(&main_screen_bg, 0, sizeof(GX_PIXELMAP));
159
160 /* Show the root window to make it and main screen visible. */
161 gx_widget_show(root);
162
163 /* Let GUIX run */
164 gx_system_start();
165 }
166
167 /******************************************************************************************/
168 /* Override the default event processing of "main_screen" to handle signals from my child */
169 /* widgets. */
170 /******************************************************************************************/
main_screen_event_process(GX_WINDOW * window,GX_EVENT * event_ptr)171 UINT main_screen_event_process(GX_WINDOW *window, GX_EVENT *event_ptr)
172 {
173 switch (event_ptr->gx_event_type)
174 {
175 case GX_EVENT_SHOW:
176 clock_update();
177
178 /* Start a timer to update current time. */
179 gx_system_timer_start((GX_WIDGET *)window, CLOCK_TIMER, GX_TICKS_SECOND, GX_TICKS_SECOND);
180
181 /* Call default event process. */
182 gx_window_event_process(window, event_ptr);
183 break;
184
185 case GX_SIGNAL(ID_LIGHTS, GX_EVENT_CLICKED):
186 on_footer_menu_clicked(ID_FOOTER_LIGHTS);
187 break;
188
189 case GX_SIGNAL(ID_THERMOSTAT, GX_EVENT_CLICKED):
190 on_footer_menu_clicked(ID_FOOTER_THERMOSTAT);
191 break;
192
193 case GX_SIGNAL(ID_LOCKS, GX_EVENT_CLICKED):
194 on_footer_menu_clicked(ID_FOOTER_LOCKS);
195 break;
196
197 case GX_SIGNAL(ID_WEATHER, GX_EVENT_CLICKED):
198 on_footer_menu_clicked(ID_FOOTER_WEATHER);
199 break;
200
201 case GX_EVENT_TIMER:
202 if (event_ptr->gx_event_payload.gx_event_timer_id == CLOCK_TIMER)
203 {
204 clock_update();
205 }
206 break;
207
208 default:
209 return gx_window_event_process(window, event_ptr);
210 }
211
212 return 0;
213 }
214
215 /******************************************************************************************/
216 /* Decode main screen background jpeg. */
217 /* The background jpeg is saved in the resource data in "raw" format, meaning it is still */
218 /* a jpeg encoded graphic image. We need to decode and color space convert the raw jpeg */
219 /* data to create a GUIX pixelmap before we can draw the image. */
220 /******************************************************************************************/
decode_main_screen_jpeg()221 static VOID decode_main_screen_jpeg()
222 {
223 GX_IMAGE_READER reader;
224 GX_PIXELMAP *map;
225
226 /* get a pointer to the raw jpeg data */
227 gx_context_pixelmap_get(GX_PIXELMAP_ID_HOME_BG, &map);
228
229 /* create an image reader object */
230 gx_image_reader_create(&reader, map->gx_pixelmap_data, map->gx_pixelmap_data_size, GX_COLOR_FORMAT_24XRGB, 0);
231
232 /* decode and color space convert the jpeg to produce a GUIX compatible pixelmap image */
233 gx_image_reader_start(&reader, &main_screen_bg);
234 }
235
236 /******************************************************************************************/
237 /* Override the default draw function of "main_screen". */
238 /******************************************************************************************/
main_screen_draw(GX_WINDOW * window)239 VOID main_screen_draw(GX_WINDOW *window)
240 {
241 gx_window_background_draw(window);
242
243 /* If this is the first time drawing, then we need to decompress the raw jpeg
244 image we use to paint the screen background
245 */
246 if (!main_screen_bg.gx_pixelmap_data)
247 {
248 decode_main_screen_jpeg();
249 }
250
251 /* unless something went wrong, the pixelmap data should now be populated in
252 GUIX pixelmap format
253 */
254 if (main_screen_bg.gx_pixelmap_data)
255 {
256 /* Draw background map. */
257 gx_canvas_pixelmap_draw(window->gx_widget_size.gx_rectangle_left,
258 window->gx_widget_size.gx_rectangle_top, &main_screen_bg);
259 }
260 gx_widget_children_draw(window);
261 }
262
263
264 /******************************************************************************************/
265 /* Fade out home window from main screen. */
266 /******************************************************************************************/
fade_out_home_window()267 VOID fade_out_home_window()
268 {
269 GX_EVENT my_event;
270
271 memset(&my_event, 0, sizeof(GX_EVENT));
272
273 /* "USER_EVENT_FADE_OUT_HOME_WINDOW" is an user defined event that will trigger a
274 set of actions. You are able to define those events and actions in studio. */
275 my_event.gx_event_type = USER_EVENT_FADE_OUT_HOME_WINDOW;
276 my_event.gx_event_target = (GX_WIDGET *)&main_screen;
277 gx_system_event_send(&my_event);
278 }
279
280 /******************************************************************************************/
281 /* Fade out home window to main screen. */
282 /******************************************************************************************/
fade_in_home_window(int event_type)283 VOID fade_in_home_window(int event_type)
284 {
285 GX_EVENT my_event;
286
287 memset(&my_event, 0, sizeof(GX_EVENT));
288
289 /* "USER_EVENT_FADE_IN_HOME_WINDOW" is an user defined event that will trigger a
290 set of actions. You are able to define those events and actions in studio. */
291 my_event.gx_event_type = USER_EVENT_FADE_IN_HOME_WINDOW;
292 my_event.gx_event_target = (GX_WIDGET *)&main_screen;
293 gx_system_event_send(&my_event);
294 }
295
296 /******************************************************************************************/
297 /* Switch to a new screen. */
298 /******************************************************************************************/
toggle_screen(GX_WIDGET * new_screen)299 VOID toggle_screen(GX_WIDGET *new_screen)
300 {
301 if (!new_screen || new_screen->gx_widget_id == app_info.current_screen->gx_widget_id)
302 {
303 /* no change. */
304 return;
305 }
306
307 /* Reset status of current screen. */
308 switch (app_info.current_screen->gx_widget_id)
309 {
310 case ID_LIGHTS_SCREEN:
311 lights_screen_reset();
312 break;
313
314 case ID_THERMOSTAT_SCREEN:
315 thermostat_screen_reset();
316 break;
317
318 case ID_LOCKS_SCREEN:
319 locks_screen_reset();
320 break;
321
322 case ID_WEATHER_SCREEN:
323 weather_screen_reset();
324 break;
325 }
326
327 if (app_info.current_screen == (GX_WIDGET *)&main_screen.main_screen_home_window)
328 {
329 /* If current screen is home window, fade out home window. */
330 fade_out_home_window();
331 }
332 else
333 {
334 /* Detach current screen. */
335 gx_widget_detach(app_info.current_screen);
336 }
337
338 /* Attach new screen. */
339 gx_widget_attach((GX_WIDGET *)&main_screen, new_screen);
340
341 /* Start child widget animations for new screen. */
342 switch (new_screen->gx_widget_id)
343 {
344 case ID_LIGHTS_SCREEN:
345 lights_screen_animation_start();
346 break;
347
348 case ID_THERMOSTAT_SCREEN:
349 thermostat_screen_animation_start();
350 break;
351
352 case ID_LOCKS_SCREEN:
353 locks_screen_animation_start();
354 break;
355
356 case ID_WEATHER_SCREEN:
357 weather_screen_animation_start();
358 break;
359 }
360
361 app_info.previous_screen = app_info.current_screen;
362 app_info.current_screen = new_screen;
363 }
364
365 /******************************************************************************************/
366 /* Update clock of main screen. */
367 /******************************************************************************************/
clock_update()368 VOID clock_update()
369 {
370 #ifdef WIN32
371 GX_RESOURCE_ID am_pm_id;
372 GX_CHAR date_string[20];
373 GX_STRING string;
374
375 SYSTEMTIME local_time;
376 GetLocalTime(&local_time);
377 if (local_time.wHour < 12)
378 {
379 am_pm_id = GX_STRING_ID_AM;
380 }
381 else
382 {
383 am_pm_id = GX_STRING_ID_PM;
384 }
385 gx_numeric_prompt_value_set(&main_screen.main_screen_hour, (GX_VALUE)local_time.wHour);
386 gx_numeric_prompt_value_set(&main_screen.main_screen_minute, (GX_VALUE)local_time.wMinute);
387 gx_prompt_text_id_set(&main_screen.main_screen_am_pm, am_pm_id);
388
389 sprintf(date_string, "%s, %s %02d", day_names[local_time.wDayOfWeek], month_names[local_time.wMonth - 1], local_time.wDay);
390 string.gx_string_ptr = date_string;
391 string.gx_string_length = sizeof(date_string) - 1;
392 gx_prompt_text_set_ext(&main_screen.main_screen_date, &string);
393
394 if (local_time.wSecond & 0x1)
395 {
396 gx_widget_fill_color_set(&main_screen.main_screen_lower_dot, GX_COLOR_ID_WHITE, GX_COLOR_ID_WHITE, GX_COLOR_ID_WHITE);
397 gx_widget_fill_color_set(&main_screen.main_screen_upper_dot, GX_COLOR_ID_WHITE, GX_COLOR_ID_WHITE, GX_COLOR_ID_WHITE);
398 }
399 else
400 {
401 gx_widget_fill_color_set(&main_screen.main_screen_lower_dot, GX_COLOR_ID_GRAY, GX_COLOR_ID_GRAY, GX_COLOR_ID_GRAY);
402 gx_widget_fill_color_set(&main_screen.main_screen_upper_dot, GX_COLOR_ID_GRAY, GX_COLOR_ID_GRAY, GX_COLOR_ID_GRAY);
403 }
404
405 #else
406
407 /* add embedded target RTC retrieval here */
408 #endif
409
410 app_info.overall_energy_today += 5;
411
412 /* Display the overall energy in use. */
413 gx_numeric_prompt_value_set(&lights_screen.lights_screen_overall_today, app_info.overall_energy_today);
414 gx_numeric_prompt_value_set(&thermostat_screen.thermostat_screen_overall_today, app_info.overall_energy_today);
415 }
416
417 /******************************************************************************************/
418 /* Custom defined draw function for radial slider widget. */
419 /* This custom radial slider draw function is to support filling selected circular */
420 /* track with pixelmap. */
421 /******************************************************************************************/
custom_radial_slider_draw(GX_RADIAL_SLIDER * slider)422 VOID custom_radial_slider_draw(GX_RADIAL_SLIDER *slider)
423 {
424 GX_PIXELMAP *map = GX_NULL;
425 GX_RESOURCE_ID map_id;
426 GX_RADIAL_SLIDER_INFO *info = &slider->gx_radial_slider_info;
427 INT xpos;
428 INT ypos;
429 INT angle = info->gx_radial_slider_info_current_angle;
430 GX_POINT inner_pt;
431 GX_POINT outer_pt;
432 GX_RECTANGLE dirty[3];
433 GX_CANVAS *canvas;
434 GX_RECTANGLE *size;
435 GX_VALUE xcenter;
436 GX_VALUE ycenter;
437
438 /* Call default widget draw. */
439 gx_widget_background_draw((GX_WIDGET *)slider);
440
441 size = &slider->gx_widget_size;
442
443 /* Pick up the pointer to the background pixelmap. */
444 gx_context_pixelmap_get(info->gx_radial_slider_info_background_pixelmap, &map);
445
446 if (map)
447 {
448 /* Draw background pixelmap. */
449 gx_canvas_pixelmap_draw(size->gx_rectangle_left, size->gx_rectangle_top, map);
450 }
451
452 /* Calculate radial slider center coordinates. */
453 xcenter = (GX_VALUE)(info->gx_radial_slider_info_xcenter + size->gx_rectangle_left);
454 ycenter = (GX_VALUE)(info->gx_radial_slider_info_ycenter + size->gx_rectangle_top);
455
456 /* Get the point on the inner circle of the track with given center point, radius and angle. */
457 gx_utility_circle_point_get(xcenter,
458 ycenter,
459 info->gx_radial_slider_info_radius - (info->gx_radial_slider_info_track_width >> 1),
460 angle,
461 &inner_pt);
462
463 /* Get the point on the outer circle of the track with given center point, radius and angle. */
464 gx_utility_circle_point_get(xcenter,
465 ycenter,
466 info->gx_radial_slider_info_radius + (info->gx_radial_slider_info_track_width >> 1),
467 angle,
468 &outer_pt);
469
470 /* Pickup drawing canvas. */
471 gx_widget_canvas_get(slider, &canvas);
472
473 if (angle != info->gx_radial_slider_info_max_angle)
474 {
475 map_id = light_selected_map_id_get(slider);
476
477 if (!map_id)
478 {
479 map_id = GX_PIXELMAP_ID_WHEEL_THERMOSTAT;
480 }
481
482 /* Get the pointer of the pixelmap for filling the selected circular track. */
483 gx_context_pixelmap_get(map_id, &map);
484
485 if (map)
486 {
487 xpos = size->gx_rectangle_left + 5;
488 ypos = size->gx_rectangle_top + 3;
489
490 memset(dirty, 0, sizeof(dirty));
491
492 /* Caculate clipping areas of the selected circular track. */
493 if (angle >= 180)
494 {
495 dirty[0].gx_rectangle_left = size->gx_rectangle_left;
496 dirty[0].gx_rectangle_top = outer_pt.gx_point_y;
497 dirty[0].gx_rectangle_right = xcenter;
498 dirty[0].gx_rectangle_bottom = size->gx_rectangle_bottom;
499
500 dirty[1].gx_rectangle_left = (inner_pt.gx_point_x + outer_pt.gx_point_x) >> 1;
501 dirty[1].gx_rectangle_top = inner_pt.gx_point_y;
502 dirty[1].gx_rectangle_right = xcenter;
503 dirty[1].gx_rectangle_bottom = outer_pt.gx_point_y - 1;
504 }
505 else if (angle >= 90)
506 {
507 dirty[0].gx_rectangle_left = size->gx_rectangle_left;
508 dirty[0].gx_rectangle_top = inner_pt.gx_point_y;
509 dirty[0].gx_rectangle_right = xcenter;
510 dirty[0].gx_rectangle_bottom = size->gx_rectangle_bottom;
511
512 dirty[1].gx_rectangle_left = size->gx_rectangle_left;
513 dirty[1].gx_rectangle_top = outer_pt.gx_point_y;
514 dirty[1].gx_rectangle_right = (inner_pt.gx_point_x + outer_pt.gx_point_x) >> 1;
515 dirty[1].gx_rectangle_bottom = inner_pt.gx_point_y - 1;
516 }
517 else if (angle >= 0)
518 {
519 dirty[0].gx_rectangle_left = size->gx_rectangle_left;
520 dirty[0].gx_rectangle_top = size->gx_rectangle_top;
521 dirty[0].gx_rectangle_right = xcenter;
522 dirty[0].gx_rectangle_bottom = size->gx_rectangle_bottom;
523
524 dirty[1].gx_rectangle_left = xcenter + 1;
525 dirty[1].gx_rectangle_top = size->gx_rectangle_top;
526 dirty[1].gx_rectangle_right = size->gx_rectangle_right;
527 dirty[1].gx_rectangle_bottom = outer_pt.gx_point_y;
528
529 dirty[2].gx_rectangle_left = xcenter + 1;
530 dirty[2].gx_rectangle_top = outer_pt.gx_point_y + 1;
531 dirty[2].gx_rectangle_right = (inner_pt.gx_point_x + outer_pt.gx_point_x) >> 1;
532 dirty[2].gx_rectangle_bottom = inner_pt.gx_point_y;
533 }
534 else
535 {
536 dirty[0].gx_rectangle_left = size->gx_rectangle_left;
537 dirty[0].gx_rectangle_top = size->gx_rectangle_top;
538 dirty[0].gx_rectangle_right = xcenter;
539 dirty[0].gx_rectangle_bottom = size->gx_rectangle_bottom;
540
541 dirty[1].gx_rectangle_left = xcenter + 1;
542 dirty[1].gx_rectangle_top = size->gx_rectangle_top;
543 dirty[1].gx_rectangle_right = size->gx_rectangle_right;
544 dirty[1].gx_rectangle_bottom = inner_pt.gx_point_y;
545
546 dirty[2].gx_rectangle_left = (inner_pt.gx_point_x + outer_pt.gx_point_x) >> 1;
547 dirty[2].gx_rectangle_top = inner_pt.gx_point_y + 1;
548 dirty[2].gx_rectangle_right = size->gx_rectangle_right;
549 dirty[2].gx_rectangle_bottom = outer_pt.gx_point_y;
550 }
551
552 /* Draw selected circular track with clipping. */
553 if (dirty[0].gx_rectangle_right > dirty[0].gx_rectangle_left &&
554 dirty[0].gx_rectangle_bottom > dirty[0].gx_rectangle_top)
555 {
556 gx_canvas_drawing_initiate(canvas, slider, &dirty[0]);
557 gx_canvas_pixelmap_draw(xpos, ypos, map);
558 gx_canvas_drawing_complete(canvas, GX_FALSE);
559 }
560
561 if (dirty[1].gx_rectangle_right > dirty[1].gx_rectangle_left &&
562 dirty[1].gx_rectangle_bottom > dirty[1].gx_rectangle_top)
563 {
564 gx_canvas_drawing_initiate(canvas, slider, &dirty[1]);
565 gx_canvas_pixelmap_draw(xpos, ypos, map);
566 gx_canvas_drawing_complete(canvas, GX_FALSE);
567 }
568
569 if (dirty[2].gx_rectangle_right > dirty[2].gx_rectangle_left &&
570 dirty[2].gx_rectangle_bottom > dirty[2].gx_rectangle_top)
571 {
572 gx_canvas_drawing_initiate(canvas, slider, &dirty[2]);
573 gx_canvas_pixelmap_draw(xpos, ypos, map);
574 gx_canvas_drawing_complete(canvas, GX_FALSE);
575 }
576 }
577 }
578
579 /* Pick up the pointer of the needle pixelmap. */
580 gx_context_pixelmap_get(slider->gx_radial_slider_info.gx_radial_slider_info_needle_pixelmap, &map);
581
582 if (map)
583 {
584 /* Calculate start coordicates for needle draw. */
585 xpos = (inner_pt.gx_point_x + outer_pt.gx_point_x) >> 1;
586 ypos = (inner_pt.gx_point_y + outer_pt.gx_point_y) >> 1;
587
588 xpos -= 15;
589 ypos -= 15;
590
591 /* Define needle draw area. */
592 gx_utility_rectangle_define(&dirty[0], xpos, ypos, xpos + map->gx_pixelmap_width - 1, ypos + map->gx_pixelmap_height - 1);
593
594 /* Initiates drawing on the specified canvas. */
595 gx_canvas_drawing_initiate(canvas, slider, &dirty[0]);
596
597 /* Draw needle pixelmap. */
598 gx_canvas_pixelmap_draw(xpos, ypos, map);
599
600 /* Completes drawing on the specified canvas. */
601 gx_canvas_drawing_complete(canvas, GX_FALSE);
602 }
603
604 /* Draw children widgets. */
605 gx_widget_children_draw((GX_WIDGET *)slider);
606 }
607
608 /******************************************************************************************/
609 /* Value format function for "hour" and "minute" prompt. */
610 /******************************************************************************************/
time_format(GX_NUMERIC_PROMPT * prompt,INT value)611 VOID time_format(GX_NUMERIC_PROMPT *prompt, INT value)
612 {
613 INT index = 0;
614
615 sprintf(prompt->gx_numeric_prompt_buffer, "%02d", value);
616 if (value < 10)
617 {
618 prompt->gx_numeric_prompt_buffer[index++] = '0';
619 }
620
621 /* Convert an integer value to ASCII string. */
622 gx_utility_ltoa(value, prompt->gx_numeric_prompt_buffer + index, GX_NUMERIC_PROMPT_BUFFER_SIZE);
623 }
624
625 /******************************************************************************************/
626 /* Calculate string length. */
627 /******************************************************************************************/
string_length_get(GX_CONST GX_CHAR * input_string,UINT max_string_length)628 UINT string_length_get(GX_CONST GX_CHAR* input_string, UINT max_string_length)
629 {
630 UINT length = 0;
631
632 if (input_string)
633 {
634 /* Traverse the string. */
635 for (length = 0; input_string[length]; length++)
636 {
637 /* Check if the string length is bigger than the max string length. */
638 if (length >= max_string_length)
639 {
640 break;
641 }
642 }
643 }
644
645 return length;
646 }
647