1 /* This is a small demo of the high-performance GUIX graphics framework. */
2 
3 #include "demo_guix_industrial.h"
4 
5 /* Define this to improve animation performance when running on target board with two layers enabled. */
6 /* #define USE_CANVAS_FOR_ANIMATION */
7 
8 #define MEMORY_POOL_BUFFER_SIZE (MAIN_DISPLAY_X_RESOLUTION * MAIN_DISPLAY_Y_RESOLUTION * 8)
9 
10 /* Define memory for memory pool. */
11 GX_UBYTE        memory_pool_buffer[MEMORY_POOL_BUFFER_SIZE];
12 TX_BYTE_POOL    memory_pool;
13 GX_WINDOW_ROOT *root;
14 
15 USHORT toggle_animation_flag = ANIMATION_NONE;
16 GX_WINDOW *current_screen = (GX_WINDOW *)&main_screen;
17 
18 #ifdef USE_CANVAS_FOR_ANIMATION
19 #define ANIMATION_WINDOW_WIDTH  640
20 #define ANIMATION_WINDOW_HEIGHT 327
21 #define ANIMATION_CANVAS_MEMORY_SIZE (ANIMATION_WINDOW_WIDTH * ANIMATION_WINDOW_HEIGHT * 4)
22 
23 GX_UBYTE animation_canvas_memory[ANIMATION_CANVAS_MEMORY_SIZE];
24 GX_CANVAS animation_canvas;
25 GX_WINDOW_ROOT animation_root;
26 #endif
27 
28 /* Define prototypes.   */
29 VOID  guix_setup(void);
30 extern UINT win32_graphics_driver_setup_24xrgb(GX_DISPLAY *display);
31 UINT root_win_event_process(GX_WINDOW *root, GX_EVENT *event_ptr);
32 
33 /* Define GX_PIXELMAP type variable to receive pixelmap data decoded from background jpeg. */
34 GX_PIXELMAP main_screen_bg;
35 
36 /******************************************************************************************/
37 /* Application entry.                                                                     */
38 /******************************************************************************************/
main(int argc,char ** argv)39 int main(int argc, char ** argv)
40 {
41     tx_kernel_enter();
42     return(0);
43 }
44 
45 /******************************************************************************************/
46 /* Define memory allocator function.                                                      */
47 /******************************************************************************************/
memory_allocate(ULONG size)48 VOID *memory_allocate(ULONG size)
49 {
50     VOID *memptr;
51 
52     if (tx_byte_allocate(&memory_pool, &memptr, size, TX_NO_WAIT) == TX_SUCCESS)
53     {
54         return memptr;
55     }
56     return NULL;
57 }
58 
59 /******************************************************************************************/
60 /* Define memory de-allocator function.                                                   */
61 /******************************************************************************************/
memory_free(VOID * mem)62 VOID memory_free(VOID *mem)
63 {
64     tx_byte_release(mem);
65 }
66 
67 /******************************************************************************************/
68 /* Define tx_application_define function.                                                 */
69 /******************************************************************************************/
tx_application_define(void * first_unused_memory)70 VOID tx_application_define(void *first_unused_memory)
71 {
72     guix_setup();
73 }
74 
75 /******************************************************************************************/
76 /* Initiate and run GUIX.                                                                 */
77 /******************************************************************************************/
guix_setup()78 VOID  guix_setup()
79 {
80 #ifdef USE_CANVAS_FOR_ANIMATION
81     GX_RECTANGLE size;
82 #endif
83 
84     /* Create byte pool. */
85     tx_byte_pool_create(&memory_pool, "memory_pool_buffer", memory_pool_buffer, MEMORY_POOL_BUFFER_SIZE);
86 
87     /* Initialize GUIX.  */
88     gx_system_initialize();
89 
90     /* install our memory allocator and de-allocator */
91     gx_system_memory_allocator_set(memory_allocate, memory_free);
92 
93     gx_studio_display_configure(MAIN_DISPLAY, win32_graphics_driver_setup_24xrgb,
94         LANGUAGE_ENGLISH, MAIN_DISPLAY_THEME_1, &root);
95 
96     gx_widget_event_process_set(root, root_win_event_process);
97 
98     /* Create the main screen */
99     gx_studio_named_widget_create("main_screen", (GX_WIDGET *)root, GX_NULL);
100 
101     /* Create sequence window. */
102     gx_studio_named_widget_create("sequence_window", GX_NULL, GX_NULL);
103 
104     /* Create sequence number window. */
105     gx_studio_named_widget_create("sequence_number", GX_NULL, GX_NULL);
106 
107     /* Create complete window. */
108     gx_studio_named_widget_create("complete_window", GX_NULL, GX_NULL);
109 
110 #ifdef USE_CANVAS_FOR_ANIMATION
111     /* Define animation root window size.  */
112     gx_utility_rectangle_define(&size, 0, 0, ANIMATION_WINDOW_WIDTH - 1, ANIMATION_WINDOW_HEIGHT - 1);
113 
114     /* create the root window used for window blend animation */
115     gx_window_root_create(&animation_root, "animation root", &animation_canvas, GX_STYLE_ENABLED, GX_NULL, &size);
116 
117     /* Create new canvas for sequence screen fade in/out animation. */
118     gx_canvas_create(&animation_canvas, GX_NULL,
119                      root->gx_window_root_canvas->gx_canvas_display,
120                      GX_CANVAS_SIMPLE,
121                      ANIMATION_WINDOW_WIDTH, ANIMATION_WINDOW_HEIGHT,
122                      (GX_COLOR *)animation_canvas_memory, ANIMATION_CANVAS_MEMORY_SIZE);
123     gx_canvas_hardware_layer_bind(&animation_canvas, 2);
124 #endif
125 
126     /* Initialize "main_screen_by" varaible. */
127     memset(&main_screen_bg, 0, sizeof(GX_PIXELMAP));
128 
129     /* Show the root window to make it and patients screen visible.  */
130     gx_widget_show(root);
131 
132     /* Let GUIX run */
133     gx_system_start();
134 }
135 
136 /******************************************************************************************/
137 /* Decode "main_screen" background image.                                                 */
138 /******************************************************************************************/
decode_main_screen_jpeg()139 static VOID decode_main_screen_jpeg()
140 {
141     GX_IMAGE_READER reader;
142     GX_PIXELMAP *map;
143 
144     /* get a pointer to the raw jpeg data */
145     gx_context_pixelmap_get(GX_PIXELMAP_ID_BG_METAL_DARK, &map);
146 
147     /* create an image reader object */
148     gx_image_reader_create(&reader, map->gx_pixelmap_data, map->gx_pixelmap_data_size, GX_COLOR_FORMAT_24XRGB, 0);
149 
150     /* decode and color space convert the jpeg to produce a GUIX compatible pixelmap image */
151     gx_image_reader_start(&reader, &main_screen_bg);
152 }
153 
154 /******************************************************************************************/
155 /* Override the default draw function of "main_screen".                                   */
156 /******************************************************************************************/
main_screen_draw(GX_WINDOW * window)157 VOID main_screen_draw(GX_WINDOW *window)
158 {
159     gx_window_background_draw(window);
160 
161     /* If this is the first time drawing, then we need to decompress the raw jpeg
162        image we use to paint the screen background.  */
163     if (!main_screen_bg.gx_pixelmap_data)
164     {
165         decode_main_screen_jpeg();
166     }
167 
168     /* Unless something went wrong, the pixelmap data should now be populated in
169        GUIX pixelmap format.  */
170     if (main_screen_bg.gx_pixelmap_data)
171     {
172         /* Draw background map. */
173         gx_canvas_pixelmap_draw(window->gx_widget_size.gx_rectangle_left,
174             window->gx_widget_size.gx_rectangle_top, &main_screen_bg);
175     }
176 
177     gx_widget_children_draw(window);
178 }
179 
180 /******************************************************************************************/
181 /* Override default event processing of root window to handle screen animation            */
182 /* complete events.                                                                       */
183 /******************************************************************************************/
root_win_event_process(GX_WINDOW * root,GX_EVENT * event_ptr)184 UINT root_win_event_process(GX_WINDOW *root, GX_EVENT *event_ptr)
185 {
186     switch(event_ptr->gx_event_type)
187     {
188     case GX_EVENT_ANIMATION_COMPLETE:
189         switch (event_ptr->gx_event_sender)
190         {
191         case ANI_ID_SEQ_WIN_FADE_IN:
192             current_screen = (GX_WINDOW *)&sequence_window;
193             sequence_animation_start();
194             toggle_animation_flag = ANIMATION_NONE;
195             break;
196 
197         case ANI_ID_START_BTN_SLIDE_IN:
198             current_screen = (GX_WINDOW *)&main_screen;
199             toggle_animation_flag = ANIMATION_NONE;
200             break;
201 
202         case ANI_ID_COMPLETE_WIN_FADE_IN:
203             current_screen = (GX_WINDOW *)&complete_window;
204             toggle_animation_flag = ANIMATION_NONE;
205             complete_window_timer_start();
206             break;
207         }
208         break;
209 
210     default:
211         gx_window_event_process(root, event_ptr);
212         break;
213     }
214     return GX_SUCCESS;
215 }
216 
217 /******************************************************************************************/
218 /* Override default event processing of "main_screen" to handle signals from my child     */
219 /* widgets.                                                                               */
220 /******************************************************************************************/
main_screen_event_process(GX_WINDOW * window,GX_EVENT * event_ptr)221 UINT main_screen_event_process(GX_WINDOW *window, GX_EVENT *event_ptr)
222 {
223     switch (event_ptr->gx_event_type)
224     {
225     case GX_SIGNAL(ID_START, GX_EVENT_CLICKED):
226 
227         /* Toggle to sequence screen.  */
228         screen_toggle_animation_start((GX_WINDOW *)&sequence_window, current_screen);
229         break;
230 
231     case GX_SIGNAL(ID_ON_OFF, GX_EVENT_CLICKED):
232         if (main_screen.main_screen_prompt_on_off.gx_prompt_text_id == GX_STRING_ID_TURN_ON)
233         {
234             /* Toggle to sequence screen.  */
235             screen_toggle_animation_start((GX_WINDOW *)&sequence_window, current_screen);
236         }
237         else
238         {
239             /* Toggle to main screen.  */
240             screen_toggle_animation_start((GX_WINDOW *)&main_screen, current_screen);
241         }
242         break;
243 
244     case GX_SIGNAL(ID_INSPECTING, GX_EVENT_CLICKED):
245     case GX_SIGNAL(ID_ASSEMBLING, GX_EVENT_CLICKED):
246     case GX_SIGNAL(ID_WELDING, GX_EVENT_CLICKED):
247     case GX_SIGNAL(ID_PALLETIZING, GX_EVENT_CLICKED):
248         if (current_screen->gx_widget_id == ID_SEQUENCE_WINDOW)
249         {
250             /* Pass event to sequence window.  */
251             sequence_window.gx_widget_event_process_function((GX_WIDGET *)window, event_ptr);
252         }
253         else
254         {
255             GX_WIDGET *find;
256             gx_widget_find(&main_screen, event_ptr->gx_event_sender, GX_SEARCH_DEPTH_INFINITE, &find);
257             if (find)
258             {
259                 button_indicator_attach((GX_PIXELMAP_BUTTON*)find);
260             }
261         }
262         break;
263 
264     default:
265         return gx_window_event_process(window, event_ptr);
266     }
267 
268     return 0;
269 }
270 
271 /******************************************************************************************/
272 /* Attach the indicator icon to the specified button.                                     */
273 /******************************************************************************************/
button_indicator_attach(GX_PIXELMAP_BUTTON * button)274 VOID button_indicator_attach(GX_PIXELMAP_BUTTON *button)
275 {
276     GX_WIDGET *indicator = (GX_WIDGET *)&main_screen.main_screen_button_indicator_dot;
277     INT x_shift;
278     INT y_shift;
279 
280     if ((GX_WIDGET *)button != indicator->gx_widget_parent)
281     {
282         gx_widget_attach((GX_WIDGET *)button, indicator);
283     }
284 
285     x_shift = button->gx_widget_size.gx_rectangle_right - 18 - indicator->gx_widget_size.gx_rectangle_right;
286     y_shift = button->gx_widget_size.gx_rectangle_top + 16 - indicator->gx_widget_size.gx_rectangle_top;
287     gx_widget_shift(indicator, x_shift, y_shift, GX_TRUE);
288 }
289 
290 /******************************************************************************************/
291 /* Start an animation to toggle between screens.                                          */
292 /******************************************************************************************/
screen_toggle_animation_start(GX_WINDOW * show,GX_WINDOW * hide)293 VOID screen_toggle_animation_start(GX_WINDOW *show, GX_WINDOW *hide)
294 {
295     GX_EVENT  my_event;
296 #ifdef USE_CANVAS_FOR_ANIMATION
297     GX_ANIMATION *animation;
298     GX_ANIMATION_INFO info;
299 #endif
300 
301     if (toggle_animation_flag != ANIMATION_NONE)
302     {
303         return;
304     }
305 
306     toggle_animation_flag = ANIMATION_ACTIVE;
307 
308     memset(&my_event, 0, sizeof(GX_EVENT));
309     my_event.gx_event_target = (GX_WIDGET *)show;
310 
311     switch (show->gx_widget_id)
312     {
313     case ID_MAIN_SCREEN:
314 
315         /* Set button status to "Turn On". */
316         gx_prompt_text_id_set(&main_screen.main_screen_prompt_on_off, GX_STRING_ID_TURN_ON);
317 
318         /* Detach sequence number prompt. */
319         gx_widget_detach(&sequence_number);
320 
321         /* Fade in start window. */
322         my_event.gx_event_type = USER_EVENT_START_WIN_FADE_IN;
323         gx_system_event_send(&my_event);
324         break;
325 
326     case ID_SEQUENCE_WINDOW:
327 
328         /* Attach sequence number prompt.  */
329         gx_widget_attach((GX_WIDGET*)&main_screen, &sequence_number);
330 
331         /* Initialize sequence window.  */
332         sequence_window_init();
333 
334         /* Fade in sequence window. */
335 #ifdef USE_CANVAS_FOR_ANIMATION
336         gx_system_animation_get(&animation);
337         gx_animation_canvas_define(animation, &animation_canvas);
338         memset(&info, 0, sizeof(GX_ANIMATION_INFO));
339         info.gx_animation_end_alpha = 255;
340         info.gx_animation_start_alpha = 0;
341         info.gx_animation_frame_interval = 1;
342         info.gx_animation_steps = 20;
343         info.gx_animation_parent = (GX_WIDGET*)&main_screen;
344         info.gx_animation_target = (GX_WIDGET*)&sequence_window;
345         info.gx_animation_start_position.gx_point_x = 0;
346         info.gx_animation_start_position.gx_point_y = 70;
347         info.gx_animation_end_position.gx_point_x = info.gx_animation_start_position.gx_point_x;
348         info.gx_animation_end_position.gx_point_y = info.gx_animation_start_position.gx_point_y;
349         info.gx_animation_id = ANI_ID_SEQ_WIN_FADE_IN;
350 
351         gx_animation_start(animation, &info);
352 #else
353         my_event.gx_event_type = USER_EVENT_SEQ_WIN_FADE_IN;
354         gx_system_event_send(&my_event);
355 #endif
356         break;
357 
358     case ID_COMPLETE_WINDOW:
359 
360         /* Detach button window. */
361         gx_widget_detach((GX_WIDGET*)&main_screen.main_screen_button_window);
362 
363         /* Initialize complete window.  */
364         complete_window_init();
365 
366         /* Fade in complete window. */
367         my_event.gx_event_type = USER_EVENT_COMPLETE_WIN_FADE_IN;
368         gx_system_event_send(&my_event);
369         break;
370 
371     default:
372         toggle_animation_flag = ANIMATION_NONE;
373         return;
374     }
375 
376     my_event.gx_event_target = (GX_WIDGET*)hide;
377 
378     switch(hide->gx_widget_id)
379     {
380     case ID_MAIN_SCREEN:
381 
382         /* Set button status to "Shut Off". */
383         gx_prompt_text_id_set(&main_screen.main_screen_prompt_on_off, GX_STRING_ID_TURN_OFF);
384 
385         /* Fade out main screen. */
386         my_event.gx_event_type = USER_EVENT_START_WIN_FADE_OUT;
387         gx_system_event_send(&my_event);
388         break;
389 
390     case ID_SEQUENCE_WINDOW:
391 
392         /* Stop animations in sequence window. */
393         sequence_animation_stop();
394 
395         /* Fade out sequence screen. */
396 #ifdef USE_CANVAS_FOR_ANIMATION
397         gx_system_animation_get(&animation);
398         gx_animation_canvas_define(animation, &animation_canvas);
399         memset(&info, 0, sizeof(GX_ANIMATION_INFO));
400         info.gx_animation_end_alpha = 0;
401         info.gx_animation_start_alpha = 255;
402         info.gx_animation_frame_interval = 1;
403         info.gx_animation_steps = 20;
404         info.gx_animation_parent = (GX_WIDGET *)&main_screen;
405         info.gx_animation_target = (GX_WIDGET*)&sequence_window;
406         info.gx_animation_start_position.gx_point_x = 0;
407         info.gx_animation_start_position.gx_point_y = 70;
408         info.gx_animation_end_position.gx_point_x = info.gx_animation_start_position.gx_point_x;
409         info.gx_animation_end_position.gx_point_y = info.gx_animation_start_position.gx_point_y;
410         info.gx_animation_id = ANI_ID_SEQ_WIN_FADE_OUT;
411         info.gx_animation_style = GX_ANIMATION_DETACH;
412 
413         gx_animation_start(animation, &info);
414 #else
415         my_event.gx_event_type = USER_EVENT_SEQ_WIN_FADE_OUT;
416         gx_system_event_send(&my_event);
417 #endif
418         break;
419 
420     case ID_COMPLETE_WINDOW:
421 
422         /* Attach button window. */
423         gx_widget_attach((GX_WIDGET *)&main_screen, (GX_WIDGET *)&main_screen.main_screen_button_window);
424 
425         /* Stop complete window timer.  */
426         complete_window_timer_stop();
427 
428         /* Fade out complete screen. */
429         my_event.gx_event_type = USER_EVENT_COMPLETE_WIN_FADE_OUT;
430         gx_system_event_send(&my_event);
431         break;
432 
433     default:
434         return;
435     }
436 }
437 
438 /******************************************************************************************/
439 /* Define custom mode button draw function.                                               */
440 /******************************************************************************************/
mode_button_draw(GX_PIXELMAP_BUTTON * button)441 VOID mode_button_draw(GX_PIXELMAP_BUTTON *button)
442 {
443     if (button->gx_widget_style & GX_STYLE_BUTTON_PUSHED)
444     {
445         gx_widget_style_add(button->gx_widget_first_child, GX_STYLE_DRAW_SELECTED);
446     }
447     else
448     {
449         gx_widget_style_remove(button->gx_widget_first_child, GX_STYLE_DRAW_SELECTED);
450     }
451 
452     gx_pixelmap_button_draw(button);
453 }
454 
455 /******************************************************************************************/
456 /* Calculate string length.                                                               */
457 /******************************************************************************************/
string_length_get(GX_CONST GX_CHAR * input_string,UINT max_string_length)458 UINT string_length_get(GX_CONST GX_CHAR* input_string, UINT max_string_length)
459 {
460     UINT length = 0;
461 
462     if (input_string)
463     {
464         /* Traverse the string.  */
465         for (length = 0; input_string[length]; length++)
466         {
467             /* Check if the string length is bigger than the max string length.  */
468             if (length >= max_string_length)
469             {
470                 break;
471             }
472         }
473     }
474 
475     return length;
476 }
477