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