1 /* This is a small demo of the high-performance GUIX graphics framework. */
2 
3 #include <stdio.h>
4 #include "gx_api.h"
5 #include "guix_widget_types_resources.h"
6 #include "guix_widget_types_specifications.h"
7 
8 
9 #define SCRATCHPAD_PIXELS (PRIMARY_X_RESOLUTION * PRIMARY_Y_RESOLUTION)
10 #define DROP_LIST_VISIBLE_ROWS  4
11 #define NUM_SLIDERS             8
12 
13 #define COUNTER_TIMER  2
14 #define UNIT_TIMER     3
15 #define BLEND_TIMER    4
16 #define SLIDER_ANIMATION_TIMER 5
17 #define PROMPT_VALUE_UPDATE_TIMER 6
18 
19 #define SLIDER_ANIMATION_STEPS 12
20 
21 #define MAX_ROW_TEXT_LENGTH 80
22 #define MAX_SLIDER_VAL_TEXT_LENGTH 10
23 
24 GX_BOOL APP_SHIFT_FLAG = GX_FALSE;
25 GX_BOOL APP_CTRL_FLAG = GX_FALSE;
26 
27 /* allocate memory for composite canvas */
28 GX_COLOR           scratchpad[SCRATCHPAD_PIXELS];
29 
30 extern GX_STUDIO_DISPLAY_INFO guix_widget_types_display_table[];
31 extern UINT win32_graphics_driver_setup_24xrgb(GX_DISPLAY *display);
32 extern GX_SCROLLBAR_APPEARANCE  Window_Screen_Vertical_Scroll_properties;
33 void ToggleScreen(GX_WINDOW *new_win, GX_WINDOW *old_win);
34 UINT string_length_get(GX_CONST GX_CHAR* input_string, UINT max_string_length);
35 
36 TX_BYTE_POOL       rotate_pool;
37 GX_WINDOW_ROOT    *root;
38 GX_SCROLLBAR       list_scroll;
39 
40 INT                blend_alpha;
41 INT                blend_increment;
42 INT                numeric_prompt_value = 10000;
43 
44 /* A structure to hold control block and text for each drop-list item */
45 typedef struct {
46     GX_PROMPT prompt;
47     GX_CHAR   text[MAX_ROW_TEXT_LENGTH + 1];
48 } DROP_LIST_WIDGET;
49 
50 DROP_LIST_WIDGET drop_list_widgets[DROP_LIST_VISIBLE_ROWS + 1];
51 
52 /* A structure to hold values used to animate slider controls */
53 typedef struct {
54     int target_val;
55     int current_val;
56     int increment;
57     GX_SLIDER *slider;
58 } SLIDER_VAL_ENTRY;
59 
60 SLIDER_VAL_ENTRY slider_vals[NUM_SLIDERS];
61 
62 /* Define prototypes.   */
63 VOID PopulateDropList();
64 VOID reset_sliders(GX_WINDOW *parent);
65 GX_BOOL update_sliders();
66 VOID start_guix(void);
67 
68 int glyph_struct_size;
69 
70 static GX_CHAR slider_val_text[MAX_SLIDER_VAL_TEXT_LENGTH + 1];
71 
72 /*****************************************************************************/
73 /* Application entry.                                                        */
74 /*****************************************************************************/
main(int argc,char ** argv)75 int main(int argc, char ** argv)
76 {
77   tx_kernel_enter();
78   return(0);
79 }
80 
81 /*****************************************************************************/
82 /* Function called by GUIX internals to allocate memory block. This is used  */
83 /* to allocate memory for rotated gauge needle image                         */
84 /*****************************************************************************/
rotate_memory_allocate(ULONG size)85 VOID *rotate_memory_allocate(ULONG size)
86 {
87     VOID *memptr;
88 
89     if (tx_byte_allocate(&rotate_pool, &memptr, size, TX_NO_WAIT) == TX_SUCCESS)
90     {
91         return memptr;
92     }
93 
94     return NULL;
95 }
96 
97 /*****************************************************************************/
98 /* Function called by GUIX internals to free memory dynamically allocated    */
99 /*****************************************************************************/
rotate_memory_free(VOID * mem)100 VOID rotate_memory_free(VOID *mem)
101 {
102     tx_byte_release(mem);
103 }
104 
105 /*****************************************************************************/
106 /* Function called by ThreadX startup to define initial system               */
107 /*****************************************************************************/
tx_application_define(void * first_unused_memory)108 VOID tx_application_define(void *first_unused_memory)
109 {
110     /* create byte pool for rotate to use */
111     tx_byte_pool_create(&rotate_pool, "scratchpad", scratchpad,
112                         SCRATCHPAD_PIXELS * sizeof(GX_COLOR));
113 
114     glyph_struct_size = sizeof(GX_GLYPH);
115     start_guix();
116 }
117 
118 /*****************************************************************************/
119 /* Called by tx_application_define (above), configure and start GUIX         */
120 /*****************************************************************************/
start_guix(void)121 VOID start_guix(void)
122 {
123     /* Initialize GUIX.  */
124     gx_system_initialize();
125 
126     /* install our memory allocator and de-allocator */
127     gx_system_memory_allocator_set(rotate_memory_allocate, rotate_memory_free);
128 
129     gx_studio_display_configure(PRIMARY, win32_graphics_driver_setup_24xrgb,
130                                 LANGUAGE_ENGLISH, PRIMARY_THEME_1, &root);
131 
132     /* create the button screen */
133     gx_studio_named_widget_create("Button_Screen", GX_NULL, GX_NULL);
134 
135     /* create the text widget screen */
136     gx_studio_named_widget_create("Text_Screen", GX_NULL, GX_NULL);
137 
138     /* create the slider widget screen */
139     gx_studio_named_widget_create("Slider_Screen", GX_NULL, GX_NULL);
140 
141     /* create circular gauge screen */
142     gx_studio_named_widget_create("Gauge_Screen", GX_NULL, GX_NULL);
143     gx_circular_gauge_angle_set(&Gauge_Screen.Gauge_Screen_Gauge_Animated, -111);
144     gx_circular_gauge_angle_set(&Gauge_Screen.Gauge_Screen_Gauge_Not_Animated, -111);
145 
146     gx_studio_named_widget_create("Window_Screen", GX_NULL, GX_NULL);
147 
148     /* Create scroll wheel screen. */
149     gx_studio_named_widget_create("Scroll_Wheel_Screen", (GX_WIDGET *)root, GX_NULL);
150 
151     /* Create menu screen. */
152     gx_studio_named_widget_create("Menu_Screen", GX_NULL, GX_NULL);
153 
154     /* Add child widgets to the drop-down list */
155     PopulateDropList();
156 
157     /* Show the root window to make it and patients screen visible.  */
158     gx_widget_show(root);
159 
160     /* start the GUIX thread */
161     gx_system_start();
162 }
163 
164 
165 /*****************************************************************************/
166 /* Override event processing of "text screen" to update numeric prompt value.*/
167 /*****************************************************************************/
text_screen_event_handler(GX_WINDOW * window,GX_EVENT * event_ptr)168 UINT text_screen_event_handler(GX_WINDOW *window, GX_EVENT *event_ptr)
169 {
170     switch (event_ptr->gx_event_type)
171     {
172     case GX_EVENT_SHOW:
173         gx_system_timer_start(&Text_Screen, PROMPT_VALUE_UPDATE_TIMER, 20, 20);
174         gx_window_event_process(window, event_ptr);
175         break;
176 
177     case GX_EVENT_TIMER:
178         if (event_ptr->gx_event_payload.gx_event_timer_id == PROMPT_VALUE_UPDATE_TIMER)
179         {
180             numeric_prompt_value++;
181 
182             if (numeric_prompt_value > 19999)
183             {
184                 numeric_prompt_value = 10000;
185             }
186             gx_numeric_prompt_value_set(&Text_Screen.Text_Screen_numeric_prompt, numeric_prompt_value);
187             gx_numeric_pixelmap_prompt_value_set(&Text_Screen.Text_Screen_numeric_pixelmap_prompt, numeric_prompt_value);
188         }
189         break;
190 
191     default:
192         return gx_window_event_process(window, event_ptr);
193     }
194     return 0;
195 }
196 
197 /*****************************************************************************/
198 /* Override event processing of "window screen" to implement canvas blend    */
199 /* animation.                                                                */
200 /*****************************************************************************/
window_screen_event_handler(GX_WINDOW * window,GX_EVENT * event_ptr)201 UINT window_screen_event_handler(GX_WINDOW *window, GX_EVENT *event_ptr)
202 {
203     switch(event_ptr->gx_event_type)
204     {
205     case GX_EVENT_SHOW:
206         gx_window_event_process(window, event_ptr);
207         blend_alpha = 10;
208         blend_increment = 8;
209         gx_system_timer_start(window, BLEND_TIMER, 1, 1);
210         break;
211 
212     case GX_EVENT_HIDE:
213         gx_system_timer_stop(window, BLEND_TIMER);
214         gx_window_event_process(window, event_ptr);
215         break;
216 
217     case GX_EVENT_TIMER:
218         gx_system_dirty_mark(&((WINDOW_SCREEN_CONTROL_BLOCK *)window)->Window_Screen_Nested_Window_BG);
219         break;
220 
221     default:
222         return gx_window_event_process(window, event_ptr);
223     }
224     return 0;
225 }
226 
227 /*****************************************************************************/
228 /* Override drawing of "nested_window" to draw the window with specified     */
229 /* alpha.                                                                    */
230 /*****************************************************************************/
nested_parent_window_draw(GX_WINDOW * window)231 VOID nested_parent_window_draw(GX_WINDOW *window)
232 {
233 GX_BRUSH   *brush;
234 
235     gx_context_brush_get(&brush);
236 
237     blend_alpha += blend_increment;
238     if (blend_alpha > 255)
239     {
240         blend_alpha = 255;
241         blend_increment = -blend_increment;
242     }
243     else
244     {
245         if (blend_alpha < 0)
246         {
247             blend_alpha = 0;
248             blend_increment = -blend_increment;
249         }
250     }
251     brush -> gx_brush_alpha = blend_alpha;
252     gx_window_draw(window);
253 }
254 
255 /*****************************************************************************/
256 /* Update slider value.                                                      */
257 /*****************************************************************************/
slider_value_update(GX_EVENT * event_ptr)258 void slider_value_update(GX_EVENT *event_ptr)
259 {
260     INT pos;
261     GX_STRING string;
262 
263     string.gx_string_ptr = slider_val_text;
264 
265     pos = event_ptr->gx_event_payload.gx_event_longdata;
266     gx_progress_bar_value_set(&Slider_Screen.Slider_Screen_Progress_Bar, pos);
267     gx_utility_ltoa(pos, (GX_CHAR *)string.gx_string_ptr, MAX_SLIDER_VAL_TEXT_LENGTH);
268     strncat((GX_CHAR *)string.gx_string_ptr, "%", 1);
269     string.gx_string_length = string_length_get(string.gx_string_ptr, MAX_SLIDER_VAL_TEXT_LENGTH);
270     gx_prompt_text_set_ext(&Slider_Screen.Slider_Screen_Progress_Bar_Prompt, &string);
271 }
272 
273 /*****************************************************************************/
274 /* Override event processing of "slider screen" to start animation for slider*/
275 /* widgets.                                                                  */
276 /*****************************************************************************/
slider_screen_event_process(GX_WINDOW * window,GX_EVENT * event_ptr)277 UINT slider_screen_event_process(GX_WINDOW *window, GX_EVENT *event_ptr)
278 {
279 
280     switch (event_ptr->gx_event_type)
281     {
282     case GX_EVENT_SHOW:
283         gx_window_event_process(window, event_ptr);
284 
285         /* save slider current value and reset current value to 0 */
286         reset_sliders(window);
287         gx_system_timer_start(window, SLIDER_ANIMATION_TIMER, 1, 1);
288         break;
289 
290     case GX_SIGNAL(ID_PIXELMAP_SLIDER_THIN_H, GX_EVENT_SLIDER_VALUE):
291         /* propogate this slider value to the progress bar */
292         slider_value_update(event_ptr);
293         break;
294 
295     case GX_EVENT_TIMER:
296         if (event_ptr->gx_event_payload.gx_event_timer_id == SLIDER_ANIMATION_TIMER)
297         {
298             /* Animate the sliders, moving them towards target value */
299             if (!update_sliders())
300             {
301                 gx_system_timer_stop(window, SLIDER_ANIMATION_TIMER);
302             }
303         }
304         break;
305 
306     default:
307         return gx_window_event_process(window, event_ptr);
308     }
309 
310     return 0;
311 }
312 
313 
314 /*****************************************************************************/
315 /* Look for each child slider on the slider screen, save its current value,  */
316 /* calculate increment to arrive at final value when animation completes.    */
317 /*****************************************************************************/
reset_sliders(GX_WINDOW * parent)318 VOID reset_sliders(GX_WINDOW *parent)
319 {
320     GX_WIDGET *widget;
321     GX_SLIDER *slider;
322     int slider_index;
323 
324     for (slider_index = 0; slider_index < NUM_SLIDERS; slider_index++)
325     {
326         slider_vals[slider_index].slider = GX_NULL;
327     }
328 
329     slider_index = 0;
330     widget = parent->gx_widget_first_child;
331 
332     while(widget)
333     {
334         if (widget->gx_widget_type == GX_TYPE_SLIDER ||
335             widget->gx_widget_type == GX_TYPE_PIXELMAP_SLIDER)
336         {
337             slider = (GX_SLIDER *) widget;
338             slider_vals[slider_index].slider = slider;
339             slider_vals[slider_index].target_val = slider->gx_slider_info.gx_slider_info_current_val << 4;
340             slider_vals[slider_index].current_val = 0;
341             slider_vals[slider_index].increment = slider_vals[slider_index].target_val / SLIDER_ANIMATION_STEPS;
342             gx_slider_value_set(slider, &slider->gx_slider_info, 0);
343             slider_index++;
344         }
345         widget= widget->gx_widget_next;
346     }
347 }
348 
349 /*****************************************************************************/
350 /* Go through the list of sliders and update each slider value               */
351 /*****************************************************************************/
update_sliders()352 GX_BOOL update_sliders()
353 {
354     SLIDER_VAL_ENTRY *sval = slider_vals;
355     int value;
356     int status = GX_FALSE;
357 
358     while(sval->slider)
359     {
360         if (sval->current_val != sval->target_val)
361         {
362             status = GX_TRUE;
363             value = sval->current_val;
364             value += sval->increment;
365 
366             if (value > sval->target_val)
367             {
368                 value = sval->target_val;
369             }
370             sval -> current_val = value;
371             gx_slider_value_set(sval->slider, &sval->slider->gx_slider_info, value >> 4);
372         }
373         sval++;
374     }
375     return status;
376 }
377 
378 
379 /*****************************************************************************/
380 /* Create child element for the drop list. This function is called during    */
381 /* initial setup to populate children, and also called as the drop-list is   */
382 /* scrolled to update the child elements.                                    */
383 /*****************************************************************************/
drop_list_row_create(GX_VERTICAL_LIST * list,GX_WIDGET * widget,INT index)384 VOID drop_list_row_create(GX_VERTICAL_LIST *list, GX_WIDGET *widget, INT index)
385 {
386     GX_BOOL created;
387     GX_RECTANGLE size;
388     GX_CHAR temp[10];
389     GX_STRING string;
390 
391     DROP_LIST_WIDGET *entry = (DROP_LIST_WIDGET *)widget;
392 
393     strcpy(entry->text, "List Entry #");
394     gx_utility_ltoa(index + 1, temp, 10);
395     strcat(entry->text, (char*)temp);
396 
397     gx_widget_created_test(widget, &created);
398 
399     if (!created)
400     {
401         gx_utility_rectangle_define(&size, 0, 0, 100, 44);
402         gx_prompt_create(&entry->prompt, entry->text, list, 0, GX_STYLE_ENABLED | GX_STYLE_TEXT_LEFT | GX_STYLE_BORDER_NONE, 0, &size);
403         gx_widget_fill_color_set(&entry->prompt, GX_COLOR_ID_TEAL, GX_COLOR_ID_DARK_TEAL, GX_COLOR_ID_TEAL);
404         gx_prompt_text_color_set(&entry->prompt, GX_COLOR_ID_WHITE, GX_COLOR_ID_WHITE, GX_COLOR_ID_WHITE);
405     }
406 
407     string.gx_string_ptr = entry->text;
408     string.gx_string_length = string_length_get(entry->text, MAX_ROW_TEXT_LENGTH);
409     gx_prompt_text_set_ext(&entry->prompt, &string);
410 }
411 
412 /*****************************************************************************/
413 /* Create initial set of child elements for drop list                        */
414 /*****************************************************************************/
PopulateDropList(void)415 VOID PopulateDropList(void)
416 {
417     int index;
418     GX_VERTICAL_LIST *list;
419     GX_SCROLLBAR_APPEARANCE sa;
420 
421     WINDOW_SCREEN_CONTROL_BLOCK *control = &Window_Screen;
422     GX_DROP_LIST *drop = &control->Window_Screen_Drop_List;
423     gx_drop_list_popup_get(drop, &list);
424 
425     for (index = 0; index < DROP_LIST_VISIBLE_ROWS; index++)
426     {
427         drop_list_row_create(list, (GX_WIDGET *)&drop_list_widgets[index], index);
428     }
429 
430     sa.gx_scroll_thumb_pixelmap = GX_PIXELMAP_ID_LIST_SCROLL_THUMB;
431     sa.gx_scroll_thumb_travel_min = 4;
432     sa.gx_scroll_thumb_travel_max = 4;
433     sa.gx_scroll_thumb_width = 8;
434     sa.gx_scroll_width = 10;
435 
436     gx_vertical_scrollbar_create(&list_scroll, "list_scroll", list,
437         &sa, GX_SCROLLBAR_VERTICAL|GX_STYLE_ENABLED);
438 }
439 
440 /*****************************************************************************/
441 /* Draw the custom border for icon button widget                             */
442 /*****************************************************************************/
custom_icon_button_draw(GX_ICON_BUTTON * button)443 VOID custom_icon_button_draw(GX_ICON_BUTTON *button)
444 {
445     GX_PIXELMAP *map;
446     INT icon_offset;
447     INT xpos;
448     INT ypos;
449 
450     // draw the background
451     if (button->gx_widget_style & GX_STYLE_BUTTON_PUSHED)
452     {
453         gx_context_pixelmap_get(GX_PIXELMAP_ID_BUTTON_SM_ACTIVE, &map);
454         icon_offset = 1;
455     }
456     else
457     {
458         gx_context_pixelmap_get(GX_PIXELMAP_ID_BUTTON_SM, &map);
459         icon_offset = 0;
460     }
461     gx_canvas_pixelmap_draw(button->gx_widget_size.gx_rectangle_left,
462                             button->gx_widget_size.gx_rectangle_top,
463                             map);
464 
465     // draw the icon
466     switch (button->gx_widget_id)
467     {
468     case ICON_BUTTON_DISC:
469         gx_context_pixelmap_get(GX_PIXELMAP_ID_ICON_DISC, &map);
470         break;
471 
472     case ICON_BUTTON_USER:
473         gx_context_pixelmap_get(GX_PIXELMAP_ID_ICON_USER, &map);
474         break;
475 
476     case ICON_BUTTON_PEN:
477         gx_context_pixelmap_get(GX_PIXELMAP_ID_ICON_PEN, &map);
478         break;
479 
480     case ICON_BUTTON_TRASH:
481         gx_context_pixelmap_get(GX_PIXELMAP_ID_ICON_TRASH, &map);
482         break;
483 
484     case ICON_BUTTON_COG:
485         gx_context_pixelmap_get(GX_PIXELMAP_ID_ICON_COG, &map);
486         break;
487 
488     default:
489         break;
490     }
491 
492     xpos = button->gx_widget_size.gx_rectangle_right - button->gx_widget_size.gx_rectangle_left + 1;
493     xpos -= map->gx_pixelmap_width;
494     xpos /= 2;
495     xpos += button->gx_widget_size.gx_rectangle_left + icon_offset;
496 
497     ypos = button->gx_widget_size.gx_rectangle_bottom - button->gx_widget_size.gx_rectangle_top + 1;
498     ypos -= map->gx_pixelmap_height;
499     ypos /= 2;
500     ypos += button->gx_widget_size.gx_rectangle_top + icon_offset;
501     gx_canvas_pixelmap_draw(xpos, ypos, map);
502     gx_widget_children_draw(button);
503 }
504 
505 /*****************************************************************************/
506 /* Draw the custom border for text button widget                             */
507 /*****************************************************************************/
custom_text_button_draw(GX_TEXT_BUTTON * button)508 VOID custom_text_button_draw(GX_TEXT_BUTTON *button)
509 {
510     GX_PIXELMAP *map;
511 
512     // draw the background
513     if (button->gx_widget_style & GX_STYLE_BUTTON_PUSHED)
514     {
515         gx_context_pixelmap_get(GX_PIXELMAP_ID_BUTTON_ACTIVE, &map);
516     }
517     else
518     {
519         gx_context_pixelmap_get(GX_PIXELMAP_ID_BUTTON, &map);
520     }
521     gx_canvas_pixelmap_draw(button->gx_widget_size.gx_rectangle_left,
522                             button->gx_widget_size.gx_rectangle_top,
523                             map);
524     gx_text_button_text_draw(button);
525     gx_widget_children_draw(button);
526 }
527 
528 /*****************************************************************************/
529 /* Define a custom button draw function.                                     */
530 /*****************************************************************************/
custom_button_draw(GX_BUTTON * button)531 VOID custom_button_draw(GX_BUTTON *button)
532 {
533     GX_PIXELMAP *map;
534     // draw the background
535     if (button->gx_widget_style & GX_STYLE_BUTTON_PUSHED)
536     {
537         gx_context_pixelmap_get(GX_PIXELMAP_ID_BUTTON_ACTIVE, &map);
538     }
539     else
540     {
541         gx_context_pixelmap_get(GX_PIXELMAP_ID_BUTTON, &map);
542     }
543     gx_canvas_pixelmap_draw(button->gx_widget_size.gx_rectangle_left,
544                             button->gx_widget_size.gx_rectangle_top,
545                             map);
546     gx_widget_children_draw(button);
547 }
548 
549 /*****************************************************************************/
550 /* Define a custom draw function of multi-line text button.                  */
551 /*****************************************************************************/
custom_multi_line_text_button_draw(GX_MULTI_LINE_TEXT_BUTTON * button)552 VOID custom_multi_line_text_button_draw(GX_MULTI_LINE_TEXT_BUTTON *button)
553 {
554     GX_PIXELMAP *map;
555 
556     // draw the background
557     if (button->gx_widget_style & GX_STYLE_BUTTON_PUSHED)
558     {
559         gx_context_pixelmap_get(GX_PIXELMAP_ID_BUTTON_LG_ACTIVE, &map);
560     }
561     else
562     {
563         gx_context_pixelmap_get(GX_PIXELMAP_ID_BUTTON_LG, &map);
564     }
565     gx_canvas_pixelmap_draw(button->gx_widget_size.gx_rectangle_left,
566                             button->gx_widget_size.gx_rectangle_top,
567                             map);
568 
569     gx_multi_line_text_button_text_draw(button);
570     gx_widget_children_draw(button);
571 }
572 
573 /*****************************************************************************/
574 /* Draw custom thick border for transparent prompt                           */
575 /*****************************************************************************/
custom_transparent_prompt_thick_border_draw(GX_PROMPT * prompt)576 VOID custom_transparent_prompt_thick_border_draw(GX_PROMPT *prompt)
577 {
578     GX_PIXELMAP *map;
579 
580     gx_prompt_draw(prompt);
581 
582     gx_context_pixelmap_get(GX_PIXELMAP_ID_PROMPT_BORDER_HEAVY, &map);
583 
584     gx_canvas_pixelmap_draw(prompt->gx_widget_size.gx_rectangle_left,
585         prompt->gx_widget_size.gx_rectangle_top,
586         map);
587 
588     gx_prompt_text_draw(prompt);
589     gx_widget_children_draw(prompt);
590 }
591 
592 /*****************************************************************************/
593 /* Override event processing of "scroll frame".                              */
594 /*****************************************************************************/
scroll_frame_event_handler(GX_WINDOW * frame,GX_EVENT * event_ptr)595 UINT scroll_frame_event_handler(GX_WINDOW *frame, GX_EVENT *event_ptr)
596 {
597     if (event_ptr->gx_event_type == GX_EVENT_SHOW)
598     {
599         gx_window_event_process(frame, event_ptr);
600         /* adjust my client are just enough to show the wide frame */
601         frame->gx_window_client.gx_rectangle_bottom -= 4;
602         return 0;
603     }
604     else
605     {
606         return gx_window_event_process(frame, event_ptr);
607     }
608 }
609 
610 /*****************************************************************************/
611 /* Custom window drawing. Draw the rounded corners of the scroll frame window*/
612 /*****************************************************************************/
scroll_frame_draw(GX_WINDOW * frame)613 VOID scroll_frame_draw(GX_WINDOW *frame)
614 {
615 GX_PIXELMAP *map;
616 
617     gx_window_draw(frame);
618 
619     /* draw the rounded corners */
620     gx_context_pixelmap_get(GX_PIXELMAP_ID_UL_CORNER, &map);
621     gx_canvas_pixelmap_draw(frame->gx_widget_size.gx_rectangle_left,
622                             frame->gx_widget_size.gx_rectangle_top, map);
623 
624     gx_context_pixelmap_get(GX_PIXELMAP_ID_UR_CORNER, &map);
625     gx_canvas_pixelmap_draw(frame->gx_widget_size.gx_rectangle_right - map->gx_pixelmap_width + 1,
626                             frame->gx_widget_size.gx_rectangle_top, map);
627 
628     gx_context_pixelmap_get(GX_PIXELMAP_ID_LL_CORNER, &map);
629     gx_canvas_pixelmap_draw(frame->gx_widget_size.gx_rectangle_left,
630                             frame->gx_widget_size.gx_rectangle_bottom - map->gx_pixelmap_height + 1, map);
631 
632     gx_context_pixelmap_get(GX_PIXELMAP_ID_LR_CORNER, &map);
633     gx_canvas_pixelmap_draw(frame->gx_widget_size.gx_rectangle_right - map->gx_pixelmap_width + 1,
634                             frame->gx_widget_size.gx_rectangle_bottom - map->gx_pixelmap_height + 1, map);
635 
636 }
637 
638 /*****************************************************************************/
639 /* Simple custom drawing for the next button, which is just a pixelmap       */
640 /*****************************************************************************/
custom_next_button_draw(GX_PIXELMAP_BUTTON * pixelmap_button)641 VOID custom_next_button_draw(GX_PIXELMAP_BUTTON *pixelmap_button)
642 {
643     GX_VALUE x_pos, y_pos;
644     GX_PIXELMAP *map = GX_NULL;
645 
646     gx_context_pixelmap_get(GX_PIXELMAP_ID_NEXT_BUTTON_2, &map);
647     x_pos = pixelmap_button->gx_widget_size.gx_rectangle_left;
648     y_pos = pixelmap_button->gx_widget_size.gx_rectangle_top;
649 
650     if (pixelmap_button -> gx_widget_style & GX_STYLE_BUTTON_PUSHED)
651     {
652         x_pos += 2;
653         y_pos += 2;
654     }
655 
656     if (map)
657     {
658         gx_canvas_pixelmap_draw(x_pos, y_pos, map);
659     }
660 }
661 
662 /*****************************************************************************/
663 /* Define a function to format numeric prompt value.                         */
664 /*****************************************************************************/
numeric_prompt_format_func(GX_NUMERIC_PROMPT * prompt,INT value)665 VOID numeric_prompt_format_func(GX_NUMERIC_PROMPT *prompt, INT value)
666 {
667     gx_utility_ltoa(value % 10, prompt->gx_numeric_prompt_buffer, GX_NUMERIC_PROMPT_BUFFER_SIZE);
668 }
669 
670 /*****************************************************************************/
671 /* Define a function to fromat numeric pixelmap prompt value                 */
672 /*****************************************************************************/
numeric_pixelmap_prompt_format_func(GX_NUMERIC_PIXELMAP_PROMPT * prompt,INT value)673 VOID numeric_pixelmap_prompt_format_func(GX_NUMERIC_PIXELMAP_PROMPT *prompt, INT value)
674 {
675     int length;
676     gx_utility_ltoa(value / 100, prompt->gx_numeric_pixelmap_prompt_buffer, GX_NUMERIC_PROMPT_BUFFER_SIZE);
677 
678     length = string_length_get(prompt->gx_numeric_pixelmap_prompt_buffer, GX_NUMERIC_PROMPT_BUFFER_SIZE);
679     prompt->gx_numeric_pixelmap_prompt_buffer[length++] = '.';
680     gx_utility_ltoa(value % 100, prompt->gx_numeric_pixelmap_prompt_buffer + length, GX_NUMERIC_PROMPT_BUFFER_SIZE - length);
681 }
682 
683 /******************************************************************************************/
684 /* Calculate string length.                                                               */
685 /******************************************************************************************/
string_length_get(GX_CONST GX_CHAR * input_string,UINT max_string_length)686 UINT string_length_get(GX_CONST GX_CHAR* input_string, UINT max_string_length)
687 {
688     UINT length = 0;
689 
690     if (input_string)
691     {
692         /* Traverse the string.  */
693         for (length = 0; input_string[length]; length++)
694         {
695             /* Check if the string length is bigger than the max string length.  */
696             if (length >= max_string_length)
697             {
698                 break;
699             }
700         }
701     }
702 
703     return length;
704 }
705