1 /* This is a small demo of the high-performance GUIX graphics framework. */
2 
3 #include <stdio.h>
4 #include <string.h>
5 #include "gx_api.h"
6 
7 /* The GUIX line chart widget has not yet been introduced into GUIX library, so temporarily need
8    to include this header file seperately
9 */
10 #include <time.h>
11 
12 #include "line_chart_resources.h"
13 #include "line_chart_specifications.h"
14 
15 GX_WINDOW_ROOT    *root;
16 void start_guix(VOID);
17 extern UINT win32_graphics_driver_setup_565rgb(GX_DISPLAY *display);
18 VOID generate_chart_data(VOID);
19 
20 #define ID_PRESSURE_CHART     200
21 #define ID_CHART_TIMER          1
22 #define CHART_UPDATE_PERIOD   100
23 #define MAX_DATA_COUNT        60
24 #define DATA_MAX_VAL          24
25 #define DATA_MIN_VAL           0
26 #define NUM_VERTICAL_GRID_LINES 24
27 
28 #define AXIS_LINE_WIDTH  3
29 #define DATA_LINE_WIDTH  2
30 #define GRID_LINE_WIDTH  1
31 
32 INT chart_data[MAX_DATA_COUNT];
33 int num_data_vals;
34 
35 
36 ///////////////////////////////////////////////////////////////////////////////
37 // TEST line chart appearance- additional setting specific to the appearance
38 //      of the pressure chart.
39 typedef struct TEST_LINE_CHART_INFO_STRUCT
40 {
41     GX_RESOURCE_ID high_line_color;
42     GX_RESOURCE_ID med_line_color;
43     GX_RESOURCE_ID low_line_color;
44     GX_RESOURCE_ID grid_color;
45     GX_RESOURCE_ID axis_label_color;
46     GX_RESOURCE_ID axis_label_font;
47     INT            high_line_value;
48     INT            med_line_value;
49     INT            low_line_value;
50     ULONG          dash_line_pattern;
51     GX_BOOL        draw_grid;
52 } TEST_LINE_CHART_INFO;
53 
54 TEST_LINE_CHART_INFO pressure_chart_info;
55 
56 ///////////////////////////////////////////////////////////////////////////////
57 // program entry point
main(int argc,char ** argv)58 int main(int argc, char ** argv)
59 {
60     /* Enter the ThreadX kernel.  */
61     tx_kernel_enter();
62 
63     return(0);
64 }
65 
66 ///////////////////////////////////////////////////////////////////////////////
67 // Standard ThreadX startup function
tx_application_define(void * first_unused_memory)68 VOID tx_application_define(void *first_unused_memory)
69 {
70     start_guix();
71 }
72 
73 
74 ///////////////////////////////////////////////////////////////////////////////
75 // GUIX startup function
start_guix(VOID)76 VOID  start_guix(VOID)
77 {
78     /* Initialize GUIX.  */
79     gx_system_initialize();
80 
81     /* create display driver instance */
82     gx_studio_display_configure(MAIN_DISPLAY, win32_graphics_driver_setup_565rgb,
83 		LANGUAGE_ENGLISH, MAIN_DISPLAY_DEFAULT_THEME, &root);
84 
85     /* create the thermometer screen */
86     gx_studio_named_widget_create("pressure_trend_frame", (GX_WIDGET *) root, GX_NULL);
87 
88     /* Show the root window to make it and patients screen visible.  */
89     gx_widget_show(root);
90 
91     /* let GUIX run */
92     gx_system_start();
93 }
94 
95 
96 ///////////////////////////////////////////////////////////////////////////////
97 // TEST line chart drawing of scale along X axis
test_line_chart_scale_draw(GX_LINE_CHART * chart)98 VOID test_line_chart_scale_draw(GX_LINE_CHART *chart)
99 {
100     INT scale_count;
101     INT scale_val;
102     INT pos;
103     INT step;
104     INT offset;
105     INT line_start;
106     char ScaleString[10];
107     GX_RECTANGLE chart_bound;
108     GX_LINE_CHART_INFO *gx_info;
109     GX_STRING str;
110 
111     gx_info = &chart->gx_line_chart_info;
112     chart_bound = chart->gx_widget_size;
113     chart_bound.gx_rectangle_right -= gx_info->gx_line_chart_right_margin;
114     chart_bound.gx_rectangle_bottom -= gx_info->gx_line_chart_bottom_margin;
115 
116     // draw the vertical tick markss first
117     step = chart_bound.gx_rectangle_right - chart_bound.gx_rectangle_left + 1;
118     step = GX_FIXED_VAL_MAKE(step);
119 
120     /* make each grid value == 2.5, so 24 gridlines? */
121     step /= NUM_VERTICAL_GRID_LINES;
122     offset = GX_FIXED_VAL_MAKE(chart_bound.gx_rectangle_left);
123     gx_context_line_color_set(pressure_chart_info.grid_color);
124 
125     pos = GX_FIXED_VAL_TO_INT(offset);
126     gx_context_brush_width_set(1);
127     line_start = chart_bound.gx_rectangle_bottom + 1;
128     scale_count = 0;
129     scale_val = 0;
130 
131     do {
132         if ((scale_count % 4)  == 0)
133         {
134             gx_utility_ltoa(scale_val, ScaleString, 10);
135             gx_canvas_line_draw(pos, line_start, pos, line_start + 14);
136 
137             gx_context_line_color_set(pressure_chart_info.axis_label_color);
138             str.gx_string_ptr = ScaleString;
139             str.gx_string_length = strnlen(ScaleString, sizeof(ScaleString));
140             gx_canvas_text_draw_ext(pos + 3, line_start + 6, &str);
141             gx_context_line_color_set(pressure_chart_info.grid_color);
142             scale_val += 10;
143         }
144         else
145         {
146             gx_canvas_line_draw(pos, line_start, pos, line_start + 8);
147         }
148         scale_count++;
149         offset += step;
150         pos = GX_FIXED_VAL_TO_INT(offset);
151 
152     } while (pos < chart_bound.gx_rectangle_right);
153 }
154 
155 
156 
157 ///////////////////////////////////////////////////////////////////////////////
158 // test line chart draw sub function, draw the reference grid.
test_line_chart_grid_draw(GX_LINE_CHART * chart)159 VOID test_line_chart_grid_draw(GX_LINE_CHART *chart)
160 {
161     INT pos;
162     INT step;
163     INT offset;
164     INT line_start;
165     INT line_end;
166     GX_RECTANGLE chart_bound;
167 
168     GX_LINE_CHART_INFO *gx_info;
169 
170     gx_info = &chart->gx_line_chart_info;
171     chart_bound = chart->gx_widget_size;
172     chart_bound.gx_rectangle_right -= gx_info->gx_line_chart_right_margin;
173     chart_bound.gx_rectangle_bottom -= gx_info->gx_line_chart_bottom_margin;
174 
175     // draw the vertial gridlines first
176 
177     step = chart_bound.gx_rectangle_right - chart_bound.gx_rectangle_left + 1;
178     step = GX_FIXED_VAL_MAKE(step);
179 
180     /* make each grid value == 2.5, so 24 gridlines? */
181 
182     step /= NUM_VERTICAL_GRID_LINES;
183     offset = GX_FIXED_VAL_MAKE(chart_bound.gx_rectangle_left) + step;
184 
185     pos = GX_FIXED_VAL_TO_INT(offset);
186     gx_context_brush_width_set(1);
187     gx_context_line_color_set(pressure_chart_info.grid_color);
188     line_start = chart_bound.gx_rectangle_top;
189     line_end = chart_bound.gx_rectangle_bottom - gx_info->gx_line_chart_axis_line_width;
190 
191     do {
192         gx_canvas_line_draw(pos, line_start, pos, line_end);
193         offset += step;
194         pos = GX_FIXED_VAL_TO_INT(offset);
195     } while (pos < chart_bound.gx_rectangle_right);
196 
197     // now draw the horizontal gridlines
198     step = chart_bound.gx_rectangle_bottom - chart_bound.gx_rectangle_top + 1;
199     step = GX_FIXED_VAL_MAKE(step);
200 
201     /* 7 gridlines? */
202     step /= 7;
203     offset = GX_FIXED_VAL_MAKE(chart_bound.gx_rectangle_bottom) - step;
204     pos = GX_FIXED_VAL_TO_INT(offset);
205 
206     line_start = chart_bound.gx_rectangle_left + gx_info->gx_line_chart_axis_line_width;
207     line_end = chart_bound.gx_rectangle_right;
208 
209     do {
210         gx_canvas_line_draw(line_start, pos, line_end, pos);
211         offset -= step;
212         pos = GX_FIXED_VAL_TO_INT(offset);
213     } while (pos > chart_bound.gx_rectangle_top);
214 }
215 
216 ///////////////////////////////////////////////////////////////////////////////
217 // test line chart draw sub function, draw the hi-med-low lines.
test_line_chart_reference_lines_draw(GX_LINE_CHART * chart)218 VOID test_line_chart_reference_lines_draw(GX_LINE_CHART *chart)
219 {
220     INT y_scale;
221     INT y_pos;
222     INT bottom_pos;
223     INT line_start;
224     INT line_end;
225     GX_BRUSH *brush;
226     GX_FONT  *label_font;
227     GX_RECTANGLE chart_bound;
228     GX_STRING str;
229 
230     GX_LINE_CHART_INFO *gx_info = &chart->gx_line_chart_info;
231     chart_bound = chart->gx_widget_size;
232     chart_bound.gx_rectangle_right -= gx_info->gx_line_chart_right_margin;
233     chart_bound.gx_rectangle_bottom -= gx_info->gx_line_chart_bottom_margin;
234 
235     gx_line_chart_y_scale_calculate(chart, &y_scale);
236     line_start = chart_bound.gx_rectangle_left + gx_info->gx_line_chart_axis_line_width;
237     line_end = chart->gx_widget_size.gx_rectangle_right;
238     bottom_pos = chart_bound.gx_rectangle_bottom;
239     gx_context_brush_width_set(1);
240     gx_context_brush_get(&brush);
241     brush->gx_brush_line_pattern = pressure_chart_info.dash_line_pattern;
242     brush->gx_brush_pattern_mask = 0x80000000;
243 
244     // draw the high line
245     y_pos = pressure_chart_info.high_line_value - chart->gx_line_chart_info.gx_line_chart_min_val;
246     y_pos *= y_scale;
247     y_pos = bottom_pos - GX_FIXED_VAL_TO_INT(y_pos);
248     gx_context_line_color_set(pressure_chart_info.high_line_color);
249     gx_context_fill_color_set(GX_COLOR_ID_BLACK);
250     gx_canvas_line_draw(line_start, y_pos, line_end, y_pos);
251 
252     // label the high line:
253     gx_context_font_get(pressure_chart_info.axis_label_font, &label_font);
254     gx_context_font_set(pressure_chart_info.axis_label_font);
255     y_pos -= label_font->gx_font_line_height + 4;
256     gx_context_line_color_set(pressure_chart_info.axis_label_color);
257     str.gx_string_ptr = "HIGH";
258     str.gx_string_length = 4;
259     gx_canvas_text_draw_ext(chart_bound.gx_rectangle_right, y_pos, &str);
260 
261     // draw the med line
262     y_pos = pressure_chart_info.med_line_value - chart->gx_line_chart_info.gx_line_chart_min_val;
263     y_pos *= y_scale;
264     y_pos = bottom_pos - GX_FIXED_VAL_TO_INT(y_pos);
265     gx_context_line_color_set(pressure_chart_info.med_line_color);
266     gx_context_fill_color_set(GX_COLOR_ID_BLACK);
267     brush->gx_brush_pattern_mask = 0x80000000;
268     gx_canvas_line_draw(line_start, y_pos, line_end, y_pos);
269 
270     // label the MED line:
271     y_pos -= label_font->gx_font_line_height + 4;
272     gx_context_line_color_set(pressure_chart_info.axis_label_color);
273     str.gx_string_ptr = "MED";
274     str.gx_string_length = 3;
275     gx_canvas_text_draw_ext(chart_bound.gx_rectangle_right, y_pos, &str);
276 
277     // draw the low line
278     y_pos = pressure_chart_info.low_line_value - chart->gx_line_chart_info.gx_line_chart_min_val;
279     y_pos *= y_scale;
280     y_pos = bottom_pos - GX_FIXED_VAL_TO_INT(y_pos);
281     gx_context_line_color_set(pressure_chart_info.low_line_color);
282     gx_context_fill_color_set(GX_COLOR_ID_BLACK);
283     brush->gx_brush_pattern_mask = 0x80000000;
284     gx_canvas_line_draw(line_start, y_pos, line_end, y_pos);
285 
286     // label the LOW line:
287     y_pos -= label_font->gx_font_line_height + 4;
288     gx_context_line_color_set(pressure_chart_info.axis_label_color);
289     str.gx_string_ptr = "LOW";
290     str.gx_string_length = 3;
291     gx_canvas_text_draw_ext(chart_bound.gx_rectangle_right, y_pos, &str);
292 }
293 
294 ///////////////////////////////////////////////////////////////////////////////
295 // test line chart draw- customize drawing to draw special features of Moog chart.
test_line_chart_draw(GX_LINE_CHART * chart)296 VOID test_line_chart_draw(GX_LINE_CHART *chart)
297 {
298     gx_window_draw((GX_WINDOW *) chart);
299 
300     // draw the axis (done by base chart)
301     gx_line_chart_axis_draw(chart);
302 
303     // draw the grid if it is enabled:
304 
305     if (pressure_chart_info.draw_grid)
306     {
307         test_line_chart_grid_draw(chart);
308     }
309 
310     // draw the high, mid, low reference lines
311     test_line_chart_reference_lines_draw(chart);
312 
313     // draw the scale along x axis
314     test_line_chart_scale_draw(chart);
315 
316     // draw the chart data line (done by base chart)
317     gx_line_chart_data_draw(chart);
318 
319     // draw any child widgets
320     gx_widget_children_draw(chart);
321 }
322 
323 ///////////////////////////////////////////////////////////////////////////////
324 // Create test chart with params specific to the pressure chart.
325 // We might use different params for other chart types.
create_test_pressure_chart(GX_WINDOW * parent)326 void create_test_pressure_chart(GX_WINDOW *parent)
327 {
328     // Initialize params for the Moog specific line chart
329     pressure_chart_info.high_line_color   =        GX_COLOR_ID_HIGH_COLOR;
330     pressure_chart_info.med_line_color    =        GX_COLOR_ID_MED_COLOR;
331     pressure_chart_info.low_line_color    =        GX_COLOR_ID_LOW_COLOR;
332     pressure_chart_info.grid_color        =        GX_COLOR_ID_GRID_COLOR;
333     pressure_chart_info.axis_label_color  =        GX_COLOR_ID_LABEL_TEXT;
334     pressure_chart_info.axis_label_font   =        GX_FONT_ID_SMALL;
335     pressure_chart_info.high_line_value = 20;
336     pressure_chart_info.med_line_value  = 12;
337     pressure_chart_info.low_line_value  =  5;
338     pressure_chart_info.dash_line_pattern =        0xffffff00;
339     pressure_chart_info.draw_grid         =        GX_TRUE;
340 }
341 
342 ///////////////////////////////////////////////////////////////////////////////
343 // Generate psuedo-random data for the chart to draw
generate_chart_data(VOID)344 VOID generate_chart_data(VOID)
345 {
346 INT index;
347 INT base_val;
348 
349     // generate some random chart data:
350     memset(chart_data, 0, MAX_DATA_COUNT * sizeof(INT));
351 
352     num_data_vals = 40 +  (rand() * 20 / RAND_MAX) + 1;
353     if (num_data_vals > MAX_DATA_COUNT)
354     {
355         num_data_vals = MAX_DATA_COUNT;
356     }
357 
358     base_val = DATA_MAX_VAL / 3;
359     for (index = 0; index < num_data_vals; index++)
360     {
361         chart_data[index] = base_val + (rand() * base_val / RAND_MAX);
362     }
363     gx_line_chart_update((GX_LINE_CHART *) &pressure_trend_frame.pressure_trend_frame_line_chart, chart_data, num_data_vals);
364 }
365 
366 ///////////////////////////////////////////////////////////////////////////////
367 // Event processing for the background frame window
trend_frame_event_process(GX_WINDOW * win,GX_EVENT * event_ptr)368 UINT trend_frame_event_process(GX_WINDOW *win, GX_EVENT *event_ptr)
369 {
370     switch(event_ptr->gx_event_type)
371     {
372     case GX_EVENT_SHOW:
373         srand((unsigned) time(NULL));
374         gx_window_event_process(win, event_ptr);
375         create_test_pressure_chart(win);
376         gx_system_timer_start(win, ID_CHART_TIMER, CHART_UPDATE_PERIOD, CHART_UPDATE_PERIOD);
377         break;
378 
379     case GX_EVENT_TIMER:
380         generate_chart_data();
381         break;
382 
383     default:
384         return gx_window_event_process(win, event_ptr);
385     }
386     return 0;
387 }
388 
389