1 /* This is a small demo of the high-performance GUIX graphics framework. */
2
3 #include "demo_guix_smart_watch.h"
4
5 #define MEMORY_POOL_BUFFER_SIZE DISPLAY_1_X_RESOLUTION * DISPLAY_1_Y_RESOLUTION * 8
6 #define ANIMATION_MIN_SLIDING_DIST 5
7
8 extern UINT win32_graphics_driver_setup_24xrgb(GX_DISPLAY* display);
9
10 /* Define prototypes. */
11 VOID start_guix(VOID);
12 VOID root_window_draw(GX_WINDOW* root);
13 UINT root_window_event_process(GX_WINDOW* window, GX_EVENT* event_ptr);
14 VOID demo_thread_entry(ULONG thread_input);
15
16 /* Create stack and control block for demo thread. */
17 static TX_THREAD demo_thread;
18 static ULONG demo_thread_stack[1024];
19
20 /* Define variables. */
21 GX_WINDOW_ROOT *root;
22 TIME system_time = {12, 9, 4, 15, 35, 0};
23 static INT screen_clock_record_hour = -1;
24 static INT screen_clock_record_minute = -1;
25 static TX_BYTE_POOL memory_pool;
26 static GX_UBYTE memory_pool_buffer[MEMORY_POOL_BUFFER_SIZE];
27
28 static GX_ANIMATION slide_animation;
29 static GX_EVENT slide_pen_down_event;
30 static GX_BOOL slide_pen_down_valid = GX_FALSE;
31
32 /* Define screen lists for slide animation. */
33 static GX_WIDGET *container_screen_list[] = {
34 (GX_WIDGET*)&page_1_container_screen,
35 (GX_WIDGET*)&page_2_container_screen,
36 (GX_WIDGET*)&page_3_container_screen,
37 GX_NULL
38 };
39
40 static GX_WIDGET* page_1_screen_list[] = {
41 (GX_WIDGET*)&message_screen,
42 (GX_WIDGET*)&music_screen,
43 (GX_WIDGET*)&weather_screen,
44 (GX_WIDGET*)&SanDiego_weather_screen,
45 (GX_WIDGET*)&LosAngeles_weather_screen,
46 (GX_WIDGET*)&SanFrancisco_weather_screen,
47 GX_NULL
48 };
49
50 static GX_WIDGET* page_2_screen_list[] = {
51 (GX_WIDGET*)&clock_1_screen,
52 (GX_WIDGET*)&clock_2_screen,
53 (GX_WIDGET*)&home_screen,
54 (GX_WIDGET*)&clock_3_screen,
55 (GX_WIDGET*)&clock_4_screen,
56 (GX_WIDGET*)&clock_5_screen,
57 GX_NULL
58 };
59
60 static GX_WIDGET* page_3_screen_list[] = {
61 (GX_WIDGET*)&yoga_screen,
62 (GX_WIDGET*)&ekg_screen,
63 (GX_WIDGET*)&fitness_screen,
64 (GX_WIDGET*)&calories_screen,
65 (GX_WIDGET*)&run_screen,
66 (GX_WIDGET*)&stand_screen,
67 GX_NULL
68 };
69
70 #ifndef WIN32
71 #define USE_CANVAS_FOR_SCREEN_SLIDE_ANIMATION
72 #endif
73
74 #ifdef USE_CANVAS_FOR_SCREEN_SLIDE_ANIMATION
75 #define ANIMATION_CANVAS_WIDTH (258 * 2)
76 #define ANIMATION_CANVAS_HEIGHT (289 * 2)
77
78 GX_COLOR animation_canvas_memory[ANIMATION_CANVAS_WIDTH * ANIMATION_CANVAS_HEIGHT];
79 GX_CANVAS animation_canvas;
80 GX_WINDOW_ROOT animation_root;
81 #endif
82
83 /******************************************************************************************/
84 /* Application entry. */
85 /******************************************************************************************/
main(int argc,char ** argv)86 int main(int argc, char** argv)
87 {
88 tx_kernel_enter();
89 return(0);
90 }
91
92 /******************************************************************************************/
93 /* Define memory allocator function. */
94 /******************************************************************************************/
memory_allocate(ULONG size)95 VOID *memory_allocate(ULONG size)
96 {
97 VOID *memptr;
98
99 if (tx_byte_allocate(&memory_pool, &memptr, size, TX_NO_WAIT) == TX_SUCCESS)
100 {
101 return memptr;
102 }
103 return NULL;
104 }
105
106 /******************************************************************************************/
107 /* Define memory de-allocator function. */
108 /******************************************************************************************/
memory_free(VOID * mem)109 VOID memory_free(VOID *mem)
110 {
111 tx_byte_release(mem);
112 }
113
114 /******************************************************************************************/
115 /* Define tx_application_define function. */
116 /******************************************************************************************/
tx_application_define(void * first_unused_memory)117 VOID tx_application_define(void *first_unused_memory)
118 {
119 tx_thread_create(&demo_thread, "Demo Thread", demo_thread_entry, 0,
120 demo_thread_stack, sizeof(demo_thread_stack),
121 GX_SYSTEM_THREAD_PRIORITY + 1,
122 GX_SYSTEM_THREAD_PRIORITY + 1, TX_NO_TIME_SLICE, TX_AUTO_START);
123 }
124
125 /******************************************************************************************/
126 /* Initiate and run GUIX. */
127 /******************************************************************************************/
demo_thread_entry(ULONG thread_input)128 VOID demo_thread_entry(ULONG thread_input)
129 {
130 #ifdef USE_CANVAS_FOR_SCREEN_SLIDE_ANIMATION
131 GX_RECTANGLE size;
132 #endif
133
134 /* Create byte pool*/
135 tx_byte_pool_create(&memory_pool, "memory_pol", memory_pool_buffer, MEMORY_POOL_BUFFER_SIZE);
136
137 /* Initialize GUIX. */
138 gx_system_initialize();
139
140 /* Assign memory alloc/free functions. */
141 gx_system_memory_allocator_set(memory_allocate, memory_free);
142
143 /* Configure display. */
144 gx_studio_display_configure(DISPLAY_1, win32_graphics_driver_setup_24xrgb, LANGUAGE_ENGLISH, DISPLAY_1_THEME_1, &root);
145
146 /* Create main screens. */
147 gx_studio_named_widget_create("main_screen", (GX_WIDGET *)root, GX_NULL);
148 gx_studio_named_widget_create("home_button", (GX_WIDGET*)root, GX_NULL);
149 gx_studio_named_widget_create("page_1_container_screen", GX_NULL, GX_NULL);
150 gx_studio_named_widget_create("page_2_container_screen", (GX_WIDGET *)&main_screen, GX_NULL);
151 gx_studio_named_widget_create("page_3_container_screen", GX_NULL, GX_NULL);
152
153 /* Create page 1 screens. */
154 gx_studio_named_widget_create("message_screen", GX_NULL, GX_NULL);
155 gx_studio_named_widget_create("music_screen", GX_NULL, GX_NULL);
156 gx_studio_named_widget_create("weather_screen", (GX_WIDGET *)&page_1_container_screen, GX_NULL);
157 gx_studio_named_widget_create("SanDiego_weather_screen", GX_NULL, GX_NULL);
158 gx_studio_named_widget_create("LosAngeles_weather_screen", GX_NULL, GX_NULL);
159 gx_studio_named_widget_create("SanFrancisco_weather_screen", GX_NULL, GX_NULL);
160
161 /* Create page 2 screens. */
162 gx_studio_named_widget_create("home_screen", (GX_WIDGET *)&page_2_container_screen, GX_NULL);
163 gx_studio_named_widget_create("clock_1_screen", GX_NULL, GX_NULL);
164 gx_studio_named_widget_create("clock_2_screen", GX_NULL, GX_NULL);
165 gx_studio_named_widget_create("clock_3_screen", GX_NULL, GX_NULL);
166 gx_studio_named_widget_create("clock_4_screen", GX_NULL, GX_NULL);
167 gx_studio_named_widget_create("clock_5_screen", GX_NULL, GX_NULL);
168
169 /* Create page 3 screens. */
170 gx_studio_named_widget_create("calories_screen", GX_NULL, GX_NULL);
171 gx_studio_named_widget_create("ekg_screen", GX_NULL, GX_NULL);
172 gx_studio_named_widget_create("fitness_screen", (GX_WIDGET *)&page_3_container_screen, GX_NULL);
173 gx_studio_named_widget_create("run_screen", GX_NULL, GX_NULL);
174 gx_studio_named_widget_create("stand_screen", GX_NULL, GX_NULL);
175 gx_studio_named_widget_create("yoga_screen", GX_NULL, GX_NULL);
176 screens_initialize();
177
178 gx_studio_named_widget_create("screen_slide_parent", GX_NULL, GX_NULL);
179
180 /* Reset root window draw function. */
181 gx_widget_draw_set((GX_WIDGET *)root, root_window_draw);
182
183 /* Reset root window event process function. */
184 gx_widget_event_process_set((GX_WIDGET *)root, root_window_event_process);
185
186 /* Create slide animation control block. */
187 gx_animation_create(&slide_animation);
188
189 #ifdef USE_CANVAS_FOR_SCREEN_SLIDE_ANIMATION
190 gx_canvas_create(&animation_canvas, GX_NULL,
191 root->gx_window_root_canvas->gx_canvas_display,
192 GX_CANVAS_SIMPLE,
193 ANIMATION_CANVAS_WIDTH, ANIMATION_CANVAS_HEIGHT,
194 animation_canvas_memory, ANIMATION_CANVAS_WIDTH * ANIMATION_CANVAS_HEIGHT * sizeof(GX_COLOR));
195
196 gx_utility_rectangle_define(&size, 0, 0, ANIMATION_CANVAS_WIDTH - 1, ANIMATION_CANVAS_HEIGHT - 1);
197 gx_window_root_create(&animation_root, "animation_root", &animation_canvas, GX_STYLE_BORDER_NONE, GX_NULL, &size);
198 gx_canvas_hide(&animation_canvas);
199
200 gx_canvas_hardware_layer_bind(&animation_canvas, 2);
201 #endif
202
203 /* Show the root window. */
204 gx_widget_show(root);
205
206 /* start GUIX thread */
207 gx_system_start();
208 }
209
210 /******************************************************************************************/
211 /* Find visible screen from screen list. */
212 /******************************************************************************************/
find_visible_screen_of_screen_list(GX_WIDGET ** screen_list)213 static GX_WIDGET *find_visible_screen_of_screen_list(GX_WIDGET **screen_list)
214 {
215 INT index = 0;
216 while (screen_list[index])
217 {
218 if (screen_list[index]->gx_widget_status & GX_STATUS_VISIBLE)
219 {
220 return screen_list[index];
221 }
222
223 index++;
224 }
225
226 return GX_NULL;
227 }
228
229 /******************************************************************************************/
230 /* Get page list by specified container screen. */
231 /******************************************************************************************/
get_page_screen_list(GX_WIDGET * screen_container)232 static GX_WIDGET **get_page_screen_list(GX_WIDGET *screen_container)
233 {
234 GX_WIDGET** page_list = GX_NULL;
235
236 switch (screen_container->gx_widget_id)
237 {
238 case ID_PAGE_1_CONTAINER_SCREEN:
239 page_list = page_1_screen_list;
240 break;
241
242 case ID_PAGE_2_CONTAINER_SCREEN:
243 page_list = page_2_screen_list;
244 break;
245
246 case ID_PAGE_3_CONTAINER_SCREEN:
247 page_list = page_3_screen_list;
248 break;
249 }
250
251 return page_list;
252 }
253
254 /******************************************************************************************/
255 /* Get screen container by specified screen. */
256 /******************************************************************************************/
get_screen_container(GX_WIDGET * screen)257 static GX_WIDGET *get_screen_container(GX_WIDGET* screen)
258 {
259 GX_WIDGET** screen_list;
260 INT index = 0;
261 INT j;
262
263 while (container_screen_list[index])
264 {
265 screen_list = get_page_screen_list(container_screen_list[index]);
266 j = 0;
267
268 while (screen_list[j])
269 {
270 if (screen_list[j] == screen)
271 {
272 return container_screen_list[index];
273 }
274 j++;
275 }
276 index++;
277 }
278
279 return GX_NULL;
280 }
281
282 /******************************************************************************************/
283 /* Enable vertical slide animation. */
284 /******************************************************************************************/
enable_vertical_slide_animation()285 static GX_BOOL enable_vertical_slide_animation()
286 {
287 GX_ANIMATION_INFO slide_animation_info;
288
289 memset(&slide_animation_info, 0, sizeof(GX_ANIMATION_INFO));
290 slide_animation_info.gx_animation_parent = (GX_WIDGET*)&main_screen;
291 slide_animation_info.gx_animation_style = GX_ANIMATION_SCREEN_DRAG | GX_ANIMATION_VERTICAL | GX_ANIMATION_WRAP | GX_ANIMATION_BLOCK_MOVE;
292 slide_animation_info.gx_animation_id = SCREEN_DRAG_ANIMATION_ID;
293 slide_animation_info.gx_animation_frame_interval = 20 / GX_SYSTEM_TIMER_MS;
294 slide_animation_info.gx_animation_slide_screen_list = container_screen_list;
295 slide_animation_info.gx_animation_start_alpha = 255;
296 slide_animation_info.gx_animation_end_alpha = 255;
297 #ifdef USE_CANVAS_FOR_SCREEN_SLIDE_ANIMATION
298 gx_animation_canvas_define(&slide_animation, &animation_canvas);
299 #endif
300
301 gx_animation_drag_enable(&slide_animation, (GX_WIDGET*)&main_screen, &slide_animation_info);
302
303 return GX_SUCCESS;
304 }
305
306 /******************************************************************************************/
307 /* Enable horizontal slide animation. */
308 /******************************************************************************************/
enable_horizontal_slide_animation()309 static GX_BOOL enable_horizontal_slide_animation()
310 {
311 GX_ANIMATION_INFO slide_animation_info;
312
313 memset(&slide_animation_info, 0, sizeof(GX_ANIMATION_INFO));
314
315 /* Find the visible page container screen. */
316 slide_animation_info.gx_animation_parent = find_visible_screen_of_screen_list(container_screen_list);
317
318 if (slide_animation_info.gx_animation_parent)
319 {
320 slide_animation_info.gx_animation_style = GX_ANIMATION_SCREEN_DRAG | GX_ANIMATION_HORIZONTAL | GX_ANIMATION_WRAP | GX_ANIMATION_BLOCK_MOVE;
321 slide_animation_info.gx_animation_id = SCREEN_DRAG_ANIMATION_ID;
322 slide_animation_info.gx_animation_frame_interval = 20 / GX_SYSTEM_TIMER_MS;
323 slide_animation_info.gx_animation_slide_screen_list = get_page_screen_list(slide_animation_info.gx_animation_parent);
324 slide_animation_info.gx_animation_start_alpha = 255;
325 slide_animation_info.gx_animation_end_alpha = 255;
326 #ifdef USE_CANVAS_FOR_SCREEN_SLIDE_ANIMATION
327 gx_animation_canvas_define(&slide_animation, &animation_canvas);
328 #endif
329
330 /* Enable slide animation for the visible page container screen. */
331 gx_animation_drag_enable(&slide_animation, slide_animation_info.gx_animation_parent, &slide_animation_info);
332
333 return GX_SUCCESS;
334 }
335
336 return GX_FALSE;
337 }
338
339 /******************************************************************************************/
340 /* Update system clock. */
341 /******************************************************************************************/
system_clock_update()342 static VOID system_clock_update()
343 {
344 #ifdef WIN32
345 SYSTEMTIME local_time;
346 GetLocalTime(&local_time);
347
348 system_time.month = local_time.wMonth;
349 system_time.day = local_time.wDay;
350 system_time.day_of_week = local_time.wDayOfWeek;
351 system_time.hour = local_time.wHour;
352 system_time.minute = local_time.wMinute;
353 system_time.second = local_time.wSecond;
354 #else
355 system_time.second++;
356 if (system_time.second >= 60)
357 {
358 system_time.second = 0;
359 system_time.minute++;
360
361 if (system_time.minute >= 60)
362 {
363 system_time.minute = 0;
364 }
365 }
366 #endif
367 }
368
369 /******************************************************************************************/
370 /* Clear time record of screens. */
371 /******************************************************************************************/
clear_screen_clock_record()372 VOID clear_screen_clock_record()
373 {
374 screen_clock_record_hour = -1;
375 screen_clock_record_minute = -1;
376 }
377
378 /******************************************************************************************/
379 /* Update screen clock. */
380 /******************************************************************************************/
screen_clock_update(GX_NUMERIC_PROMPT * hour,GX_NUMERIC_PROMPT * minute,GX_PROMPT * second)381 VOID screen_clock_update(GX_NUMERIC_PROMPT *hour, GX_NUMERIC_PROMPT *minute, GX_PROMPT *second)
382 {
383 GX_RESOURCE_ID text_color_id;
384
385 if (screen_clock_record_hour != system_time.hour)
386 {
387 gx_numeric_prompt_value_set(hour, system_time.hour);
388 screen_clock_record_hour = system_time.hour;
389 }
390
391 if (screen_clock_record_minute != system_time.minute)
392 {
393 gx_numeric_prompt_value_set(minute, system_time.minute);
394 screen_clock_record_minute = system_time.minute;
395 }
396
397 if (second)
398 {
399 if (system_time.second & 0x1)
400 {
401 text_color_id = GX_COLOR_ID_WHITE;
402 }
403 else
404 {
405 text_color_id = GX_COLOR_ID_GRAY;
406 }
407
408 gx_prompt_text_color_set(second, text_color_id, text_color_id, text_color_id);
409 }
410 }
411
412 /******************************************************************************************/
413 /* Send event to current screen. */
414 /******************************************************************************************/
send_event_to_current_screen(INT event_type)415 static VOID send_event_to_current_screen(INT event_type)
416 {
417 GX_EVENT myevent;
418 GX_WIDGET *parent;
419
420 /* Find visible screen container. */
421 parent = find_visible_screen_of_screen_list(container_screen_list);
422
423 /* Find visible screen. */
424 parent = find_visible_screen_of_screen_list(get_page_screen_list(parent));
425
426 if (parent)
427 {
428 memset(&myevent, 0, sizeof(GX_EVENT));
429 myevent.gx_event_type = event_type;
430 myevent.gx_event_target = parent;
431 parent->gx_widget_event_process_function(parent, &myevent);
432 }
433 }
434
435 /******************************************************************************************/
436 /* Slide to home screen. */
437 /******************************************************************************************/
slide_to_home_screen()438 static VOID slide_to_home_screen()
439 {
440 GX_WIDGET *current_screen_container;
441 GX_WIDGET *target_screen_container;
442 GX_WIDGET *current_screen;
443 GX_WIDGET *target_screen = (GX_WIDGET *)&home_screen;
444
445 /* Find the visible page container screen. */
446 current_screen_container = find_visible_screen_of_screen_list(container_screen_list);
447
448 /* Find visible screen. */
449 current_screen = find_visible_screen_of_screen_list(get_page_screen_list(current_screen_container));
450
451 if (current_screen == target_screen)
452 {
453 return;
454 }
455
456 target_screen_container = get_screen_container(target_screen);
457
458 if (current_screen_container == target_screen_container)
459 {
460 page_screen_slide(current_screen, target_screen);
461 }
462 else
463 {
464 container_screen_slide(current_screen, target_screen);
465 }
466 }
467
468 /******************************************************************************************/
469 /* Start animation to slide from current screen to the specified screen of the same page. */
470 /******************************************************************************************/
page_screen_slide(GX_WIDGET * current_screen,GX_WIDGET * target_screen)471 VOID page_screen_slide(GX_WIDGET *current_screen, GX_WIDGET *target_screen)
472 {
473 GX_WIDGET *screen_container;
474 GX_WIDGET **screen_list;
475 INT current_screen_index = 0;
476 INT target_screen_index = 0;
477 INT index = 0;
478 GX_ANIMATION *animation;
479 GX_ANIMATION_INFO animation_info;
480 GX_RECTANGLE *parent_size;
481 GX_RECTANGLE size;
482 INT width;
483 INT distance;
484
485 if (slide_animation.gx_animation_status != GX_ANIMATION_IDLE)
486 {
487 return;
488 }
489
490 send_event_to_current_screen(USER_EVENT_ANIMATION_STOP);
491
492 /* Find the visible page container screen. */
493 screen_container = find_visible_screen_of_screen_list(container_screen_list);
494
495 /* Find screen list for the visible screen container. */
496 screen_list = get_page_screen_list(screen_container);
497
498 while (screen_list[index])
499 {
500 if (screen_list[index] == current_screen)
501 {
502 current_screen_index = index;
503 }
504 else if (screen_list[index] == target_screen)
505 {
506 target_screen_index = index;
507 }
508
509 index++;
510 }
511
512 parent_size = &screen_container->gx_widget_size;
513 width = parent_size->gx_rectangle_right - parent_size->gx_rectangle_left + 1;
514 distance = width * (target_screen_index - current_screen_index);
515
516 size = *parent_size;
517
518 if (target_screen_index > current_screen_index)
519 {
520 size.gx_rectangle_right = size.gx_rectangle_left + distance + width - 1;
521 }
522 else
523 {
524 size.gx_rectangle_left = size.gx_rectangle_right + distance - width + 1;
525 }
526
527 gx_widget_resize(&screen_slide_parent, &size);
528
529 memset(&animation_info, 0, sizeof(GX_ANIMATION_INFO));
530 animation_info.gx_animation_frame_interval = 1;
531 animation_info.gx_animation_id = SCREEN_SLIDE_ANIMATION_ID;
532 animation_info.gx_animation_steps = 300 / GX_SYSTEM_TIMER_MS;
533 animation_info.gx_animation_start_alpha = 255;
534 animation_info.gx_animation_end_alpha = 255;
535 animation_info.gx_animation_parent = screen_container;
536 animation_info.gx_animation_target = (GX_WIDGET *)&screen_slide_parent;
537 animation_info.gx_animation_start_position.gx_point_x = size.gx_rectangle_left;
538 animation_info.gx_animation_start_position.gx_point_y = size.gx_rectangle_top;
539 animation_info.gx_animation_end_position.gx_point_x= size.gx_rectangle_left - distance;
540 animation_info.gx_animation_end_position.gx_point_y = size.gx_rectangle_top;
541 animation_info.gx_animation_style = GX_ANIMATION_TRANSLATE | GX_ANIMATION_BLOCK_MOVE;
542
543 index = current_screen_index;
544 while (1)
545 {
546 gx_widget_attach(&screen_slide_parent, screen_list[index]);
547
548 size.gx_rectangle_left = parent_size->gx_rectangle_left + (width * (index - current_screen_index));
549 size.gx_rectangle_right = size.gx_rectangle_left + width - 1;
550 gx_widget_resize(screen_list[index], &size);
551
552 if (index == target_screen_index)
553 {
554 break;
555 }
556
557 if (current_screen_index < target_screen_index)
558 {
559 index++;
560 }
561 else
562 {
563 index--;
564 }
565 }
566
567 if (gx_system_animation_get(&animation) == GX_SUCCESS)
568 {
569 gx_animation_start(animation, &animation_info);
570 }
571 }
572
573 /******************************************************************************************/
574 /* Start animation to slide from current screen to the specified screen of another page. */
575 /******************************************************************************************/
container_screen_slide(GX_WIDGET * current_screen,GX_WIDGET * target_screen)576 VOID container_screen_slide(GX_WIDGET* current_screen, GX_WIDGET* target_screen)
577 {
578 GX_WIDGET *current_screen_container;
579 GX_WIDGET *target_screen_container;
580 GX_WIDGET **screen_list;
581 INT current_screen_index = 0;
582 INT target_screen_index = 0;
583 INT index = 0;
584 GX_ANIMATION* animation;
585 GX_ANIMATION_INFO animation_info;
586 GX_RECTANGLE *parent_size;
587 GX_RECTANGLE size;
588 INT height;
589 INT distance;
590 GX_WIDGET* child = GX_NULL;
591
592 if (slide_animation.gx_animation_status != GX_ANIMATION_IDLE)
593 {
594 return;
595 }
596
597 send_event_to_current_screen(USER_EVENT_ANIMATION_STOP);
598
599 /* Find the visible page container screen. */
600 current_screen_container = find_visible_screen_of_screen_list(container_screen_list);
601 target_screen_container = get_screen_container(target_screen);
602
603 gx_widget_first_child_get(target_screen_container, &child);
604 if (child != target_screen)
605 {
606 gx_widget_detach(child);
607 gx_widget_attach(target_screen_container, target_screen);
608 gx_widget_shift(target_screen,
609 target_screen_container->gx_widget_size.gx_rectangle_left - target_screen->gx_widget_size.gx_rectangle_left,
610 target_screen_container->gx_widget_size.gx_rectangle_top - target_screen->gx_widget_size.gx_rectangle_top, GX_FALSE);
611 }
612
613 /* Find screen list for the visible screen container. */
614 screen_list = container_screen_list;
615
616 while (screen_list[index])
617 {
618 if (screen_list[index] == current_screen_container)
619 {
620 current_screen_index = index;
621 }
622 else if (screen_list[index] == target_screen_container)
623 {
624 target_screen_index = index;
625 }
626
627 index++;
628 }
629
630 parent_size = &main_screen.gx_widget_size;
631 height = parent_size->gx_rectangle_bottom - parent_size->gx_rectangle_top + 1;
632 distance = height * (target_screen_index - current_screen_index);
633
634 size = *parent_size;
635
636 if (target_screen_index > current_screen_index)
637 {
638 size.gx_rectangle_bottom = size.gx_rectangle_top + distance + height - 1;
639 }
640 else
641 {
642 size.gx_rectangle_top = size.gx_rectangle_bottom + distance - height + 1;
643 }
644
645 gx_widget_resize(&screen_slide_parent, &size);
646
647 memset(&animation_info, 0, sizeof(GX_ANIMATION_INFO));
648 animation_info.gx_animation_frame_interval = 1;
649 animation_info.gx_animation_id = SCREEN_SLIDE_ANIMATION_ID;
650 animation_info.gx_animation_steps = 300 / GX_SYSTEM_TIMER_MS;
651 animation_info.gx_animation_start_alpha = 255;
652 animation_info.gx_animation_end_alpha = 255;
653 animation_info.gx_animation_parent = (GX_WIDGET *)&main_screen;
654 animation_info.gx_animation_target = (GX_WIDGET *)&screen_slide_parent;
655 animation_info.gx_animation_start_position.gx_point_x = size.gx_rectangle_left;
656 animation_info.gx_animation_start_position.gx_point_y = size.gx_rectangle_top;
657 animation_info.gx_animation_end_position.gx_point_x = size.gx_rectangle_left;
658 animation_info.gx_animation_end_position.gx_point_y = size.gx_rectangle_top - distance;
659 animation_info.gx_animation_style = GX_ANIMATION_TRANSLATE | GX_ANIMATION_BLOCK_MOVE;
660
661 index = current_screen_index;
662
663 while(1)
664 {
665 gx_widget_attach(&screen_slide_parent, screen_list[index]);
666
667 size.gx_rectangle_top = parent_size->gx_rectangle_top + (height * (index - current_screen_index));
668 size.gx_rectangle_bottom = size.gx_rectangle_top + height - 1;
669 gx_widget_resize(screen_list[index], &size);
670
671 if (index == target_screen_index)
672 {
673 break;
674 }
675
676 if (current_screen_index < target_screen_index)
677 {
678 index++;
679 }
680 else
681 {
682 index--;
683 }
684 }
685
686 if (gx_system_animation_get(&animation) == GX_SUCCESS)
687 {
688 gx_animation_start(animation, &animation_info);
689 }
690 }
691
692 /******************************************************************************************/
693 /* Override the default drawing of the home button. */
694 /******************************************************************************************/
root_home_button_draw(GX_PIXELMAP_BUTTON * widget)695 VOID root_home_button_draw(GX_PIXELMAP_BUTTON* widget)
696 {
697 if (widget->gx_widget_style & GX_STYLE_BUTTON_PUSHED)
698 {
699 gx_pixelmap_button_draw(widget);
700 }
701 }
702
703 /******************************************************************************************/
704 /* Override the default drawing of the root window. */
705 /******************************************************************************************/
root_window_draw(GX_WINDOW * root)706 VOID root_window_draw(GX_WINDOW* root)
707 {
708 GX_PIXELMAP* map = GX_NULL;
709
710 /* Call default root window draw. */
711 gx_window_draw(root);
712
713 gx_context_pixelmap_get(GX_PIXELMAP_ID_MICROSOFT_AZURE_LOGO, &map);
714
715 if (map)
716 {
717 /* Draw logo. */
718 gx_canvas_pixelmap_draw(15, 15, map);
719 }
720
721 gx_context_pixelmap_get(GX_PIXELMAP_ID_WATCH, &map);
722
723 if (map)
724 {
725 /* Draw smart watch frame. */
726 gx_context_fill_color_set(GX_COLOR_ID_WHITE);
727 gx_canvas_pixelmap_draw((DISPLAY_1_X_RESOLUTION - map->gx_pixelmap_width) >> 1, 0, map);
728 }
729 }
730
731 /******************************************************************************************/
732 /* Override the default event processing of the root window to handle signals from my */
733 /* child widgets. */
734 /******************************************************************************************/
root_window_event_process(GX_WINDOW * window,GX_EVENT * event_ptr)735 UINT root_window_event_process(GX_WINDOW *window, GX_EVENT *event_ptr)
736 {
737 switch (event_ptr->gx_event_type)
738 {
739 case GX_SIGNAL(ID_HOME_BUTTON, GX_EVENT_CLICKED):
740 slide_to_home_screen();
741 break;
742
743 default:
744 return gx_window_root_event_process((GX_WINDOW_ROOT*)window, event_ptr);
745 }
746
747 return 0;
748 }
749
750 /******************************************************************************************/
751 /* Override the default event processing of the "main_screen" to handle signals from my */
752 /* child widgets. */
753 /******************************************************************************************/
main_screen_event_process(GX_WINDOW * window,GX_EVENT * event_ptr)754 UINT main_screen_event_process(GX_WINDOW* window, GX_EVENT* event_ptr)
755 {
756 UINT status = GX_SUCCESS;
757 INT horizontal_dist;
758 INT vertical_dist;
759 GX_WIDGET *parent;
760
761 switch (event_ptr->gx_event_type)
762 {
763 case GX_EVENT_SHOW:
764
765 /* Update system time. */
766 system_clock_update();
767
768 /* Start a timer to update time. */
769 gx_system_timer_start(window, SYSTEM_CLOCK_TIMER_ID, GX_TICKS_SECOND, GX_TICKS_SECOND);
770
771 status = gx_window_event_process(window, event_ptr);
772
773 if(home_screen.gx_widget_status & GX_STATUS_VISIBLE)
774 {
775 gx_sprite_start(&home_screen.home_screen_sprite, 0);
776 }
777 break;
778
779 case GX_EVENT_TIMER:
780 if (event_ptr->gx_event_payload.gx_event_timer_id == SYSTEM_CLOCK_TIMER_ID)
781 {
782 system_clock_update();
783 music_play_progress_update();
784 }
785 break;
786
787 case GX_EVENT_PEN_DOWN:
788 if (slide_animation.gx_animation_status == GX_ANIMATION_IDLE)
789 {
790 /* Reserve pen down event for later use. */
791 slide_pen_down_event = *event_ptr;
792 slide_pen_down_valid = GX_TRUE;
793 }
794 break;
795
796 case GX_EVENT_PEN_DRAG:
797 if (slide_animation.gx_animation_status == GX_ANIMATION_IDLE && slide_pen_down_valid)
798 {
799 horizontal_dist = GX_ABS(slide_pen_down_event.gx_event_payload.gx_event_pointdata.gx_point_x - event_ptr->gx_event_payload.gx_event_pointdata.gx_point_x);
800 vertical_dist = GX_ABS(slide_pen_down_event.gx_event_payload.gx_event_pointdata.gx_point_y - event_ptr->gx_event_payload.gx_event_pointdata.gx_point_y);
801
802 if ((horizontal_dist > ANIMATION_MIN_SLIDING_DIST) || vertical_dist > ANIMATION_MIN_SLIDING_DIST)
803 {
804 if (horizontal_dist > vertical_dist)
805 {
806 /* Horizontal slide direction. */
807 status = enable_horizontal_slide_animation();
808 }
809 else
810 {
811 /* Vertical slide direction. */
812 status = enable_vertical_slide_animation();
813 }
814
815 if (status == GX_SUCCESS)
816 {
817 send_event_to_current_screen(USER_EVENT_ANIMATION_STOP);
818
819 parent = slide_animation.gx_animation_info.gx_animation_parent;
820
821 /* Pass pen down and pen drag event to slide animation parent to process sliding animation. */
822 parent->gx_widget_event_process_function(parent, &slide_pen_down_event);
823 parent->gx_widget_event_process_function(parent, event_ptr);
824 }
825 }
826 }
827 break;
828
829 case GX_EVENT_ANIMATION_COMPLETE:
830 if (event_ptr->gx_event_sender == SCREEN_DRAG_ANIMATION_ID)
831 {
832 /* Disable slide animation. */
833 gx_animation_drag_disable(&slide_animation, slide_animation.gx_animation_info.gx_animation_parent);
834
835 send_event_to_current_screen(USER_EVENT_ANIMATION_START);
836 }
837 else if (event_ptr->gx_event_sender == SCREEN_SLIDE_ANIMATION_ID)
838 {
839 gx_widget_attach(screen_slide_parent.gx_widget_parent, screen_slide_parent.gx_widget_last_child);
840 parent = screen_slide_parent.gx_widget_first_child;
841 while (parent)
842 {
843 gx_widget_detach(parent);
844 parent = parent->gx_widget_next;
845 }
846 gx_widget_detach(&screen_slide_parent);
847 send_event_to_current_screen(USER_EVENT_ANIMATION_START);
848 }
849 break;
850
851 case GX_EVENT_PEN_UP:
852 if (slide_animation.gx_animation_status == GX_ANIMATION_IDLE)
853 {
854 /* Disable slide animation. */
855 gx_animation_drag_disable(&slide_animation, slide_animation.gx_animation_info.gx_animation_parent);
856 }
857 slide_pen_down_valid = GX_FALSE;
858 break;
859
860 default:
861 return gx_window_event_process((GX_WINDOW*)window, event_ptr);
862 }
863
864 return status;
865 }