1 /***************************************************************************
2 * Copyright (c) 2024 Microsoft Corporation
3 *
4 * This program and the accompanying materials are made available under the
5 * terms of the MIT License which is available at
6 * https://opensource.org/licenses/MIT.
7 *
8 * SPDX-License-Identifier: MIT
9 **************************************************************************/
10
11
12 /**************************************************************************/
13 /**************************************************************************/
14 /** */
15 /** GUIX Component */
16 /** */
17 /** Progress Bar Management (Progress Bar) */
18 /** */
19 /**************************************************************************/
20
21 #define GX_SOURCE_CODE
22
23 /* Include necessary system files. */
24
25 #include "gx_api.h"
26 #include "gx_context.h"
27 #include "gx_widget.h"
28 #include "gx_canvas.h"
29 #include "gx_utility.h"
30 #include "gx_progress_bar.h"
31
32 /**************************************************************************/
33 /* */
34 /* FUNCTION RELEASE */
35 /* */
36 /* _gx_progress_bar_background_draw PORTABLE C */
37 /* 6.1 */
38 /* AUTHOR */
39 /* */
40 /* Kenneth Maxwell, Microsoft Corporation */
41 /* */
42 /* DESCRIPTION */
43 /* */
44 /* This service draws the background of the specified progress bar. */
45 /* */
46 /* INPUT */
47 /* */
48 /* progress_bar Progress Bar control block */
49 /* */
50 /* OUTPUT */
51 /* */
52 /* None */
53 /* */
54 /* CALLS */
55 /* */
56 /* _gx_widget_border_draw Draw the widget border */
57 /* _gx_context_fill_color_set Set fill color */
58 /* _gx_context_pixelmap_get Retrieve pixelmap by ID */
59 /* _gx_widget_client_get Get widget client area */
60 /* _gx_widget_width_get Get widget width */
61 /* _gx_widget_height_get Get widget height */
62 /* _gx_canvas_rectangle_draw Draw a rectangle on canvas */
63 /* _gx_canvas_pixelmap_tile Tile a pixelmap on cavnas */
64 /* _gx_utility_rectangle_shift Shift a rectangle by specified*/
65 /* x,y values */
66 /* */
67 /* CALLED BY */
68 /* */
69 /* Application Code */
70 /* GUIX Internal Code */
71 /* */
72 /* RELEASE HISTORY */
73 /* */
74 /* DATE NAME DESCRIPTION */
75 /* */
76 /* 05-19-2020 Kenneth Maxwell Initial Version 6.0 */
77 /* 09-30-2020 Kenneth Maxwell Modified comment(s), */
78 /* resulting in version 6.1 */
79 /* */
80 /**************************************************************************/
_gx_progress_bar_background_draw(GX_PROGRESS_BAR * progress_bar)81 VOID _gx_progress_bar_background_draw(GX_PROGRESS_BAR *progress_bar)
82 {
83 GX_PIXELMAP *fill_map;
84 GX_RECTANGLE fill_rect;
85 INT fill_width;
86 INT fill_height;
87 GX_VALUE segment_width;
88 GX_VALUE segment_height;
89 INT range;
90 INT i;
91 INT min_value;
92 INT max_value;
93 INT cur_value;
94 GX_VALUE widget_width;
95 GX_VALUE widget_height;
96 INT segment_number;
97 INT total_segment;
98 GX_RESOURCE_ID fill_color;
99
100 if (progress_bar -> gx_widget_style & GX_STYLE_ENABLED)
101 {
102 fill_color = progress_bar -> gx_widget_normal_fill_color;
103 }
104 else
105 {
106 fill_color = progress_bar -> gx_widget_disabled_fill_color;
107 }
108
109 /* Draw progress bar background and border. */
110 _gx_widget_border_draw((GX_WIDGET *)progress_bar, GX_COLOR_ID_DEFAULT_BORDER,
111 fill_color, fill_color, GX_TRUE);
112
113 min_value = progress_bar -> gx_progress_bar_info.gx_progress_bar_info_min_val;
114 max_value = progress_bar -> gx_progress_bar_info.gx_progress_bar_info_max_val;
115 range = max_value - min_value;
116
117 if (range <= 0)
118 {
119 return;
120 }
121
122 _gx_widget_client_get((GX_WIDGET *)progress_bar, -1, &fill_rect);
123 fill_width = fill_rect.gx_rectangle_right - fill_rect.gx_rectangle_left + 1;
124 fill_height = fill_rect.gx_rectangle_bottom - fill_rect.gx_rectangle_top + 1;
125
126 cur_value = progress_bar -> gx_progress_bar_info.gx_progress_bar_info_current_val;
127
128 if (progress_bar -> gx_progress_bar_info.gx_progress_bar_fill_pixelmap)
129 {
130 _gx_context_pixelmap_get(progress_bar -> gx_progress_bar_info.gx_progress_bar_fill_pixelmap, &fill_map);
131
132 if (fill_map)
133 {
134 if (progress_bar -> gx_widget_style & GX_STYLE_PROGRESS_VERTICAL)
135 {
136 fill_rect.gx_rectangle_top = (GX_VALUE)(fill_rect.gx_rectangle_bottom -
137 ((cur_value - min_value) * fill_height / range) + 1);
138 }
139 else
140 {
141 fill_rect.gx_rectangle_right = (GX_VALUE)(fill_rect.gx_rectangle_left +
142 ((cur_value - min_value) * fill_width / range) - 1);
143 }
144 _gx_canvas_pixelmap_tile(&fill_rect, fill_map);
145 }
146 }
147 else
148 {
149 /* Pickup color to use */
150 _gx_context_fill_color_set(progress_bar -> gx_widget_selected_fill_color);
151
152 if (progress_bar -> gx_widget_style & GX_STYLE_PROGRESS_SEGMENTED_FILL)
153 {
154 if (progress_bar -> gx_widget_style & GX_STYLE_PROGRESS_VERTICAL)
155 {
156 _gx_widget_width_get((GX_WIDGET *)progress_bar, &widget_width);
157 segment_height = widget_width >> 1;
158 total_segment = (fill_height - GX_SEGMENT_INTERVAL) / (segment_height + GX_SEGMENT_INTERVAL);
159 segment_number = (cur_value - min_value) * total_segment / range;
160 fill_rect.gx_rectangle_left = (GX_VALUE)(fill_rect.gx_rectangle_left + GX_SEGMENT_BORDER_INTERVAL);
161 fill_rect.gx_rectangle_right = (GX_VALUE)(fill_rect.gx_rectangle_right - GX_SEGMENT_BORDER_INTERVAL);
162 fill_rect.gx_rectangle_top = (GX_VALUE)(fill_rect.gx_rectangle_bottom - segment_height + 1);
163
164 for (i = 1; i <= segment_number; i++)
165 {
166 _gx_canvas_rectangle_draw(&fill_rect);
167 _gx_utility_rectangle_shift(&fill_rect, 0, (GX_VALUE)(-(segment_height + GX_SEGMENT_INTERVAL)));
168 }
169 }
170 else
171 {
172 _gx_widget_height_get((GX_WIDGET *)progress_bar, &widget_height);
173 segment_width = widget_height >> 1;
174 total_segment = (fill_width - GX_SEGMENT_INTERVAL) / (segment_width + GX_SEGMENT_INTERVAL);
175 segment_number = (cur_value - min_value) * total_segment / range;
176
177 fill_rect.gx_rectangle_top = (GX_VALUE)(fill_rect.gx_rectangle_top + GX_SEGMENT_BORDER_INTERVAL);
178 fill_rect.gx_rectangle_bottom = (GX_VALUE)(fill_rect.gx_rectangle_bottom - GX_SEGMENT_BORDER_INTERVAL);
179 fill_rect.gx_rectangle_right = (GX_VALUE)(fill_rect.gx_rectangle_left + segment_width - 1);
180
181 for (i = 1; i <= segment_number; i++)
182 {
183 _gx_canvas_rectangle_draw(&fill_rect);
184 _gx_utility_rectangle_shift(&fill_rect, (GX_VALUE)(segment_width + GX_SEGMENT_INTERVAL), 0);
185 }
186 }
187 }
188 else
189 {
190 if (progress_bar -> gx_widget_style & GX_STYLE_PROGRESS_VERTICAL)
191 {
192 fill_rect.gx_rectangle_top = (GX_VALUE)(fill_rect.gx_rectangle_bottom -
193 ((cur_value - min_value) * fill_height / range) + 1);
194 }
195 else
196 {
197 fill_rect.gx_rectangle_right = (GX_VALUE)(fill_rect.gx_rectangle_left +
198 ((cur_value - min_value) * fill_width / range) - 1);
199 }
200 _gx_canvas_rectangle_draw(&fill_rect);
201 }
202 }
203 }
204
205