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