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