1 #include "demo_guix_smart_watch.h"
2 
3 /* Extern system time.  */
4 extern TIME system_time;
5 
6 /* Define local variables.  */
7 static INT minute_needle_angle = 30;
8 static INT hour_needle_angle = 60;
9 
10 /******************************************************************************************/
11 /* Update watch hands.                                                                    */
12 /******************************************************************************************/
clock_gauge_update(CLOCK_SCREEN_TEMPLATE_CONTROL_BLOCK * template)13 static VOID clock_gauge_update(CLOCK_SCREEN_TEMPLATE_CONTROL_BLOCK* template)
14 {
15     INT hour_angle;
16     INT minute_angle;
17     GX_BOOL mark_dirty = GX_FALSE;
18 
19     minute_angle = system_time.minute * 6;
20 
21     if (minute_angle != minute_needle_angle)
22     {
23         minute_needle_angle = minute_angle;
24         mark_dirty = GX_TRUE;
25     }
26 
27     hour_angle = system_time.hour * 30 + system_time.minute / 2;
28 
29     if (hour_angle != hour_needle_angle)
30     {
31         hour_needle_angle = hour_angle;
32         mark_dirty = GX_TRUE;
33     }
34 
35     gx_circular_gauge_angle_set(&template->clock_screen_template_gauge, system_time.second * 6);
36 
37     if (mark_dirty)
38     {
39         gx_system_dirty_mark(&template->clock_screen_template_gauge);
40     }
41 }
42 
43 /******************************************************************************************/
44 /* Draw a needle in specified position.                                                   */
45 /******************************************************************************************/
draw_needle(GX_PIXELMAP * map,INT angle,INT xcenter,INT ycenter)46 static VOID draw_needle(GX_PIXELMAP *map, INT angle, INT xcenter, INT ycenter)
47 {
48     GX_PIXELMAP needle_rotated;
49     INT xcor;
50     INT ycor;
51 
52     xcor = (map->gx_pixelmap_width >> 1);
53     ycor = map->gx_pixelmap_height - xcor;
54 
55     /* Rotate the second needle pixelmap. */
56     if (gx_utility_pixelmap_rotate(map, angle, &needle_rotated, &xcor, &ycor) == GX_SUCCESS)
57     {
58         /* Draw needle .  */
59         gx_canvas_pixelmap_draw((GX_VALUE)(xcenter - xcor), (GX_VALUE)(ycenter - ycor), &needle_rotated);
60 
61         /* Free rotate needle pixelmap memory.  */
62         if (memory_free)
63         {
64             if (needle_rotated.gx_pixelmap_aux_data)
65             {
66                 memory_free((VOID*)needle_rotated.gx_pixelmap_aux_data);
67             }
68             memory_free((VOID*)needle_rotated.gx_pixelmap_data);
69         }
70     }
71     else
72     {
73         /* Draw needle .  */
74         gx_canvas_pixelmap_draw((GX_VALUE)(xcenter - xcor), (GX_VALUE)(ycenter - ycor), map);
75     }
76 }
77 
78 /******************************************************************************************/
79 /* Draw specified gauge with extra needles.                                               */
80 /******************************************************************************************/
clock_gauge_draw(GX_CIRCULAR_GAUGE * gauge,GX_RESOURCE_ID hands_color_id,GX_RESOURCE_ID hands_center_map_id)81 static VOID clock_gauge_draw(GX_CIRCULAR_GAUGE *gauge, GX_RESOURCE_ID hands_color_id, GX_RESOURCE_ID hands_center_map_id)
82 {
83     GX_CIRCULAR_GAUGE_INFO *info;
84     INT xcenter;
85     INT ycenter;
86     GX_PIXELMAP *map;
87 
88     /* Call default circular draw. */
89     gx_circular_gauge_background_draw(gauge);
90 
91     /* Pick up pointer to the gauge information structure.  */
92     info = &gauge->gx_circular_gauge_info;
93 
94     xcenter = gauge->gx_widget_size.gx_rectangle_left + info->gx_circular_gauge_info_needle_xpos;
95     ycenter = gauge->gx_widget_size.gx_rectangle_top + info->gx_circular_gauge_info_needle_ypos;
96 
97     gx_context_fill_color_set(hands_color_id);
98 
99     /* Retrieve the map for the minute needle. */
100     gx_context_pixelmap_get(GX_PIXELMAP_ID_WATCH_HAND_HOUR, &map);
101 
102     if (map)
103     {
104         draw_needle(map, hour_needle_angle, xcenter, ycenter);
105     }
106 
107     /* Retrieve the map for the second needle. */
108     gx_context_pixelmap_get(GX_PIXELMAP_ID_WATCH_HAND_MINUTE, &map);
109 
110     if (map)
111     {
112         draw_needle(map, minute_needle_angle, xcenter, ycenter);
113     }
114 
115     /* Draw watch hands center. */
116     gx_context_pixelmap_get(hands_center_map_id, &map);
117     if (map)
118     {
119         gx_canvas_pixelmap_draw((GX_VALUE)(xcenter - (map->gx_pixelmap_width >> 1)),
120             (GX_VALUE)(ycenter - (map->gx_pixelmap_height >> 1)), map);
121     }
122 }
123 
124 /******************************************************************************************/
125 /* Define custom drawing function for the circular gauge in clock 1 screen.               */
126 /******************************************************************************************/
clock_1_gauge_draw(GX_CIRCULAR_GAUGE * gauge)127 static VOID clock_1_gauge_draw(GX_CIRCULAR_GAUGE *gauge)
128 {
129     /* Draw the gauge with black watch hands.  */
130     clock_gauge_draw(gauge, GX_COLOR_ID_CANVAS, GX_PIXELMAP_ID_WATCH_HANDS_CENTER);
131 }
132 
133 /******************************************************************************************/
134 /* Define custom drawing function for the circular gauge in clock 2 screen.               */
135 /******************************************************************************************/
clock_2_gauge_draw(GX_CIRCULAR_GAUGE * gauge)136 static VOID clock_2_gauge_draw(GX_CIRCULAR_GAUGE *gauge)
137 {
138     /* Draw the gauge with white watch hands.  */
139     clock_gauge_draw(gauge, GX_COLOR_ID_WHITE, GX_PIXELMAP_ID_WATCH_HANDS_CENTER_WHITE);
140 }
141 
142 /******************************************************************************************/
143 /* Initialize watch screen.                                                               */
144 /******************************************************************************************/
watch_screen_initialize()145 VOID watch_screen_initialize()
146 {
147     gx_widget_fill_color_set(&clock_1_screen.base, GX_COLOR_ID_WHITE, GX_COLOR_ID_WHITE, GX_COLOR_ID_WHITE);
148     gx_widget_fill_color_set(&clock_2_screen.base, GX_COLOR_ID_CANVAS, GX_COLOR_ID_CANVAS, GX_COLOR_ID_CANVAS);
149 
150     gx_icon_pixelmap_set((GX_ICON*)&clock_1_screen.base.clock_screen_template_gauge, GX_PIXELMAP_ID_W_DIAL_BLACK, GX_PIXELMAP_ID_W_DIAL_BLACK);
151     gx_icon_pixelmap_set((GX_ICON*)&clock_2_screen.base.clock_screen_template_gauge, GX_PIXELMAP_ID_W_DIAL_WHITE, GX_PIXELMAP_ID_W_DIAL_WHITE);
152 
153     gx_widget_draw_set((GX_ICON*)&clock_1_screen.base.clock_screen_template_gauge, clock_1_gauge_draw);
154     gx_widget_draw_set((GX_ICON*)&clock_2_screen.base.clock_screen_template_gauge, clock_2_gauge_draw);
155 }
156 
157 /******************************************************************************************/
158 /* Override the default event processing of "clock_screen_template" to handle signals     */
159 /* from my child widgets.                                                                 */
160 /******************************************************************************************/
clock_screen_template_event_process(GX_WINDOW * window,GX_EVENT * event_ptr)161 UINT clock_screen_template_event_process(GX_WINDOW* window, GX_EVENT* event_ptr)
162 {
163     switch (event_ptr->gx_event_type)
164     {
165     case GX_EVENT_SHOW:
166         clock_gauge_update((CLOCK_SCREEN_TEMPLATE_CONTROL_BLOCK*)window);
167         gx_system_timer_start(window, SCREEN_CLOCK_TIMER_ID, GX_TICKS_SECOND, GX_TICKS_SECOND);
168         return gx_window_event_process(window, event_ptr);
169 
170     case GX_EVENT_HIDE:
171         gx_system_timer_stop(window, SCREEN_CLOCK_TIMER_ID);
172         return gx_window_event_process(window, event_ptr);
173 
174     case GX_EVENT_TIMER:
175         if (event_ptr->gx_event_payload.gx_event_timer_id == SCREEN_CLOCK_TIMER_ID)
176         {
177             clock_gauge_update((CLOCK_SCREEN_TEMPLATE_CONTROL_BLOCK*)window);
178         }
179         break;
180 
181     default:
182         return gx_window_event_process(window, event_ptr);
183     }
184 
185     return 0;
186 }
187