GCC Code Coverage Report
Directory: ./ Exec Total Coverage
File: gx_drop_list_draw.c Lines: 57 60 95.0 %
Date: 2024-12-05 08:52:37 Branches: 21 24 87.5 %

Line Branch Exec Source
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
/**   Drop List Management (List)                                         */
18
/**                                                                       */
19
/**************************************************************************/
20
21
#define GX_SOURCE_CODE
22
23
24
/* Include necessary system files.  */
25
26
#include "gx_api.h"
27
#include "gx_system.h"
28
#include "gx_display.h"
29
#include "gx_context.h"
30
#include "gx_widget.h"
31
#include "gx_window.h"
32
#include "gx_utility.h"
33
#include "gx_drop_list.h"
34
35
/**************************************************************************/
36
/*                                                                        */
37
/*  FUNCTION                                               RELEASE        */
38
/*                                                                        */
39
/*    _gx_drop_list_selected_children_draw                PORTABLE C      */
40
/*                                                           6.3.0        */
41
/*  AUTHOR                                                                */
42
/*                                                                        */
43
/*    Ting Zhu, Microsoft Corporation                                     */
44
/*                                                                        */
45
/*  DESCRIPTION                                                           */
46
/*                                                                        */
47
/*    This function draws the children of the selected item to the drop   */
48
/*    list client area with the specified shift values.                   */
49
/*                                                                        */
50
/*  INPUT                                                                 */
51
/*                                                                        */
52
/*    drop_list                             Pointer to drop list widget   */
53
/*    widget                                Widget to be drawn            */
54
/*    xshift                                Shift value in x coordinate   */
55
/*    yshift                                Shift value in y coordinate   */
56
/*                                                                        */
57
/*  OUTPUT                                                                */
58
/*                                                                        */
59
/*    None                                                                */
60
/*                                                                        */
61
/*  CALLS                                                                 */
62
/*                                                                        */
63
/*    _gx_utility_rectangle_shift           Shift rectangle               */
64
/*                                                                        */
65
/*  CALLED BY                                                             */
66
/*                                                                        */
67
/*    _gx_drop_list_draw                                                  */
68
/*                                                                        */
69
/*  RELEASE HISTORY                                                       */
70
/*                                                                        */
71
/*    DATE              NAME                      DESCRIPTION             */
72
/*                                                                        */
73
/*  10-31-2023     Ting Zhu                 Initial Version 6.3.0         */
74
/*                                                                        */
75
/**************************************************************************/
76
2
static VOID _gx_drop_list_selected_children_draw(GX_DROP_LIST *drop_list, GX_WIDGET *widget, GX_VALUE xshift, GX_VALUE yshift)
77
{
78
GX_WIDGET   *child;
79
GX_WIDGET   *child_child;
80
GX_RECTANGLE old_size;
81
GX_RECTANGLE old_clip;
82
ULONG        old_style;
83
84
    /* Save the first child.  */
85
2
    child = widget -> gx_widget_first_child;
86
87
    /* Draw the children.  */
88
6
    while (child)
89
    {
90
        /* Save the widget size.  */
91
4
        old_size = child -> gx_widget_size;
92
93
        /* Save the widget clip size.  */
94
4
        old_clip = child -> gx_widget_clip;
95
96
        /* Save the widget style.  */
97
4
        old_style = child -> gx_widget_style;
98
99
        /* Update the widget style temporarily.  */
100
4
        if (drop_list -> gx_widget_status & GX_STATUS_HAS_FOCUS)
101
        {
102
            child -> gx_widget_style |= ~GX_STYLE_DRAW_SELECTED;
103
        }
104
        else
105
        {
106
4
            child -> gx_widget_style &= ~GX_STYLE_DRAW_SELECTED;
107
        }
108
109
        /* Shift the widget size and clip with the specified shift values temporarily.  */
110
4
        _gx_utility_rectangle_shift(&child -> gx_widget_size, xshift, yshift);
111
4
        _gx_utility_rectangle_shift(&child -> gx_widget_clip, xshift, yshift);
112
113
4
        child_child = child -> gx_widget_first_child;
114
115
        /* Set the first child to NULL temporarily.  */
116
4
        child -> gx_widget_first_child = GX_NULL;
117
118
        /* Draw the widget.  */
119
4
        child -> gx_widget_draw_function(child);
120
121
4
        if (child_child)
122
        {
123
            child -> gx_widget_first_child = child_child;
124
125
            _gx_drop_list_selected_children_draw(drop_list, child, xshift, yshift);
126
        }
127
128
        /* Recover the widget properties.  */
129
4
        child -> gx_widget_size = old_size;
130
4
        child -> gx_widget_clip = old_clip;
131
4
        child -> gx_widget_style = old_style;
132
133
4
        child = child -> gx_widget_next;
134
    }
135
2
}
136
137
/**************************************************************************/
138
/*                                                                        */
139
/*  FUNCTION                                               RELEASE        */
140
/*                                                                        */
141
/*    _gx_drop_list_draw                                  PORTABLE C      */
142
/*                                                           6.3.0        */
143
/*  AUTHOR                                                                */
144
/*                                                                        */
145
/*    Kenneth Maxwell, Microsoft Corporation                              */
146
/*                                                                        */
147
/*  DESCRIPTION                                                           */
148
/*                                                                        */
149
/*    This function draws the specified widget.                           */
150
/*                                                                        */
151
/*  INPUT                                                                 */
152
/*                                                                        */
153
/*    drop_list                             Pointer to drop list widget   */
154
/*                                                                        */
155
/*  OUTPUT                                                                */
156
/*                                                                        */
157
/*    None                                                                */
158
/*                                                                        */
159
/*  CALLS                                                                 */
160
/*                                                                        */
161
/*    _gx_drop_list_background_draw         Draw the widget background    */
162
/*    _gx_widget_children_draw              Draw children widgets         */
163
/*    _gx_vertical_list_selected_widget_get Get selected child item of    */
164
/*                                            popup list                  */
165
/*    _gx_widget_client_get                 Find the client area of a     */
166
/*                                            widget                      */
167
/*                                                                        */
168
/*  CALLED BY                                                             */
169
/*                                                                        */
170
/*    Application Code                                                    */
171
/*    GUIX Internal Code                                                  */
172
/*                                                                        */
173
/*  RELEASE HISTORY                                                       */
174
/*                                                                        */
175
/*    DATE              NAME                      DESCRIPTION             */
176
/*                                                                        */
177
/*  05-19-2020     Kenneth Maxwell          Initial Version 6.0           */
178
/*  09-30-2020     Kenneth Maxwell          Modified comment(s),          */
179
/*                                            resulting in version 6.1    */
180
/*  10-31-2023     Ting Zhu                 Modified comment(s),          */
181
/*                                            improved drawing of the     */
182
/*                                            selected item,              */
183
/*                                            resulting in version 6.3.0  */
184
/*                                                                        */
185
/**************************************************************************/
186
6398
VOID _gx_drop_list_draw(GX_DROP_LIST *drop_list)
187
{
188
GX_RECTANGLE      client;
189
GX_WIDGET        *selected;
190
GX_VALUE          xshift;
191
GX_VALUE          yshift;
192
INT               selected_index;
193
6398
GX_VERTICAL_LIST *list = &drop_list -> gx_drop_list_popup.gx_popup_list_list;
194
GX_RECTANGLE      size;
195
GX_RECTANGLE      clip;
196
ULONG             style;
197
6398
GX_WIDGET        *child = GX_NULL;
198
6398
GX_BOOL           reuse_list_item = GX_FALSE;
199
200
    /* Draw the background.  */
201
6398
    _gx_drop_list_background_draw(drop_list);
202
203
    /* Pick the selected item.  */
204
6398
    _gx_vertical_list_selected_widget_get(list, &selected);
205
206

6398
    if (!selected && list -> gx_vertical_list_callback)
207
    {
208
        /* If not be able to retrieve the selected widget, its possible that the selcted item
209
           has been reused for displaying the other list items during the scrolling.
210
           In this case, try to get the selected index first, then reuse the list child to draw the selected item. */
211
212
        /* Get the selected index.  */
213
3
        _gx_vertical_list_selected_index_get(list, &selected_index);
214
215

3
        if((selected_index >= 0) && (selected_index < list -> gx_vertical_list_total_rows))
216
        {
217
            /* Make the first list child as the selected widget temporarily.  */
218
1
            selected = _gx_widget_first_client_child_get((GX_WIDGET *)list);
219
220
            /* Call the list callback function to create the selected widget.  */
221
1
            list -> gx_vertical_list_callback(list, selected, selected_index);
222
223
1
            reuse_list_item = GX_TRUE;
224
        }
225
    }
226
227
6398
    if (selected)
228
    {
229
230
6380
        _gx_widget_client_get((GX_WIDGET *)drop_list, -1, &client);
231
232
6380
        size = selected -> gx_widget_size;
233
6380
        clip = selected -> gx_widget_clip;
234
235
6380
        if (selected -> gx_widget_first_child)
236
        {
237
2
            child = selected -> gx_widget_first_child;
238
2
            selected -> gx_widget_first_child = GX_NULL;
239
240
            /* Calculate the distance from the selected widget to the client area.  */
241
2
            xshift = (GX_VALUE)(client.gx_rectangle_left - size.gx_rectangle_left);
242
2
            yshift = (GX_VALUE)((client.gx_rectangle_bottom + client.gx_rectangle_top - size.gx_rectangle_bottom - size.gx_rectangle_top) >> 1);
243
        }
244
245
6380
        selected -> gx_widget_size = client;
246
6380
        selected -> gx_widget_clip = client;
247
248
249
        /* Save the widget style.  */
250
6380
        style = selected -> gx_widget_style;
251
252
        /* Update the widget style temporarily.  */
253
6380
        if (drop_list -> gx_widget_status & GX_STATUS_HAS_FOCUS)
254
        {
255
1
            selected -> gx_widget_style |= ~GX_STYLE_DRAW_SELECTED;
256
        }
257
        else
258
        {
259
6379
            selected -> gx_widget_style &= ~GX_STYLE_DRAW_SELECTED;
260
        }
261
262
6380
        selected -> gx_widget_draw_function(selected);
263
264
6380
        if (child)
265
        {
266
2
            selected -> gx_widget_first_child = child;
267
268
            /* Draw the selected widget into my client area: */
269
2
            _gx_drop_list_selected_children_draw(drop_list, selected, xshift, yshift);
270
        }
271
272
6380
        selected -> gx_widget_size = size;
273
6380
        selected -> gx_widget_clip = clip;
274
6380
        selected -> gx_widget_style = style;
275
    }
276
277
6398
    if (reuse_list_item)
278
    {
279
        /* Call the list callback funtion to create the widget with its original index. */
280
1
        list -> gx_vertical_list_callback(list, selected, list -> gx_vertical_list_top_index);
281
    }
282
283
    /* Draw the children.  */
284
6398
    _gx_widget_children_draw((GX_WIDGET *)drop_list);
285
6398
}
286