GCC Code Coverage Report
Directory: ./ Exec Total Coverage
File: gx_drop_list_draw.c Lines: 57 60 95.0 %
Date: 2026-03-06 19:21:09 Branches: 21 24 87.5 %

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

6398
    if (!selected && list -> gx_vertical_list_callback)
190
    {
191
        /* If not be able to retrieve the selected widget, its possible that the selcted item
192
           has been reused for displaying the other list items during the scrolling.
193
           In this case, try to get the selected index first, then reuse the list child to draw the selected item. */
194
195
        /* Get the selected index.  */
196
3
        _gx_vertical_list_selected_index_get(list, &selected_index);
197
198

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