GCC Code Coverage Report
Directory: ./ Exec Total Coverage
File: gx_accordion_menu_position.c Lines: 73 73 100.0 %
Date: 2026-03-06 19:21:09 Branches: 35 35 100.0 %

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
/**   Accordion Menu Management (Menu)                                    */
19
/**                                                                       */
20
/**************************************************************************/
21
22
#define GX_SOURCE_CODE
23
24
25
/* Include necessary system files.  */
26
27
#include "gx_api.h"
28
#include "gx_menu.h"
29
#include "gx_widget.h"
30
#include "gx_system.h"
31
32
/**************************************************************************/
33
/*                                                                        */
34
/*  FUNCTION                                               RELEASE        */
35
/*                                                                        */
36
/*    _gx_accordion_menu_one_level_position               PORTABLE C      */
37
/*                                                           6.1          */
38
/*  AUTHOR                                                                */
39
/*                                                                        */
40
/*    Kenneth Maxwell, Microsoft Corporation                              */
41
/*                                                                        */
42
/*  DESCRIPTION                                                           */
43
/*                                                                        */
44
/*    This function positions first level items for an accordion menu.    */
45
/*                                                                        */
46
/*  INPUT                                                                 */
47
/*                                                                        */
48
/*    accordion                             Accordion menu control block  */
49
/*                                                                        */
50
/*  OUTPUT                                                                */
51
/*                                                                        */
52
/*    status                                Completion status             */
53
/*                                                                        */
54
/*  CALLS                                                                 */
55
/*                                                                        */
56
/*    _gx_widget_border_width_get           Get widget border width       */
57
/*    _gx_widget_client_get                 Get widget client rectangle   */
58
/*    _gx_widget_height_get                 Get widget height             */
59
/*    _gx_widget_shift                      Shift a widget                */
60
/*    _gx_widget_resize                     Resize a widget               */
61
/*                                                                        */
62
/*  CALLED BY                                                             */
63
/*                                                                        */
64
/*    _gx_accordion_menu_position                                         */
65
/*                                                                        */
66
/**************************************************************************/
67
229
static UINT  _gx_accordion_menu_one_level_position(GX_ACCORDION_MENU *accordion)
68
{
69
229
GX_WIDGET    *child = accordion -> gx_widget_first_child;
70
GX_RECTANGLE  size;
71
GX_RECTANGLE  client;
72
GX_VALUE      height;
73
GX_VALUE      bottom;
74
GX_VALUE      border_width;
75
GX_MENU_LIST *list;
76
77
229
    _gx_widget_border_width_get((GX_WIDGET *)accordion, &border_width);
78
229
    _gx_widget_client_get((GX_WIDGET *)accordion, border_width, &client);
79
80
229
    size.gx_rectangle_left = client.gx_rectangle_left;
81
229
    size.gx_rectangle_right = client.gx_rectangle_right;
82
229
    size.gx_rectangle_top = client.gx_rectangle_top;
83
229
    size.gx_rectangle_bottom = (GX_VALUE)(size.gx_rectangle_top - 1);
84
85
229
    bottom = size.gx_rectangle_bottom;
86
229
    accordion -> gx_accordion_menu_expand_item = GX_NULL;
87
88
    /* Reposition accordion menu items. */
89
841
    while (child)
90
    {
91
612
        switch (child -> gx_widget_type)
92
        {
93
529
        case GX_TYPE_MENU:
94
529
            list = &((GX_MENU *)child) -> gx_menu_list;
95
96
529
            if (child -> gx_widget_style & GX_STYLE_MENU_EXPANDED)
97
            {
98

11
                if (!accordion -> gx_accordion_menu_expand_item && list -> gx_widget_first_child)
99
                {
100
9
                    accordion -> gx_accordion_menu_expand_item = child;
101
                }
102
                else
103
                {
104
2
                    child -> gx_widget_style &= (ULONG)(~GX_STYLE_MENU_EXPANDED);
105
2
                    _gx_widget_detach((GX_WIDGET *)list);
106
107
2
                    list -> gx_widget_size.gx_rectangle_bottom = (GX_VALUE)(list -> gx_widget_size.gx_rectangle_top - 1);
108
                }
109
            }
110
111
529
            _gx_widget_height_get(child, &height);
112
113
529
            size.gx_rectangle_top = (GX_VALUE)(bottom + 1);
114
529
            size.gx_rectangle_bottom = (GX_VALUE)(size.gx_rectangle_top + height - 1);
115
116
529
            _gx_widget_resize(child, &size);
117
118
529
            if (list -> gx_widget_parent)
119
            {
120
9
                _gx_widget_shift((GX_WIDGET *)list,
121
9
                                 (GX_VALUE)(size.gx_rectangle_left - list -> gx_widget_size.gx_rectangle_left),
122
9
                                 (GX_VALUE)(size.gx_rectangle_bottom + 1 - list -> gx_widget_size.gx_rectangle_top), GX_FALSE);
123
124
9
                bottom = list -> gx_widget_size.gx_rectangle_bottom;
125
            }
126
            else
127
            {
128
520
                bottom = size.gx_rectangle_bottom;
129
            }
130
529
            break;
131
132
9
        case GX_TYPE_MENU_LIST:
133
9
            break;
134
135
74
        default:
136
74
            _gx_widget_height_get(child, &height);
137
74
            size.gx_rectangle_top = (GX_VALUE)(bottom + 1);
138
74
            size.gx_rectangle_bottom = (GX_VALUE)(size.gx_rectangle_top + height - 1);
139
140
74
            _gx_widget_resize(child, &size);
141
74
            bottom = size.gx_rectangle_bottom;
142
74
            break;
143
        }
144
145
612
        child -> gx_widget_status &= ~GX_STATUS_ACCEPTS_FOCUS;
146
612
        child = child -> gx_widget_next;
147
    }
148
149
229
    size = accordion -> gx_widget_size;
150
229
    size.gx_rectangle_bottom = (GX_VALUE)(bottom + border_width);
151
152
    /* Resize accordion menu. */
153
229
    _gx_widget_resize((GX_WIDGET *)accordion, &size);
154
155
    /* Return completion status code. */
156
229
    return GX_SUCCESS;
157
}
158
159
/**************************************************************************/
160
/*                                                                        */
161
/*  FUNCTION                                               RELEASE        */
162
/*                                                                        */
163
/*    _gx_accordion_menu_position                         PORTABLE C      */
164
/*                                                           6.1          */
165
/*  AUTHOR                                                                */
166
/*                                                                        */
167
/*    Kenneth Maxwell, Microsoft Corporation                              */
168
/*                                                                        */
169
/*  DESCRIPTION                                                           */
170
/*                                                                        */
171
/*    This function positions an accordion menu and its items.            */
172
/*                                                                        */
173
/*  INPUT                                                                 */
174
/*                                                                        */
175
/*    accordion                             Accordion menu control block  */
176
/*                                                                        */
177
/*  OUTPUT                                                                */
178
/*                                                                        */
179
/*    status                                Completion status             */
180
/*                                                                        */
181
/*  CALLS                                                                 */
182
/*                                                                        */
183
/*    _gx_menu_one_level_position           Position a menu widget        */
184
/*    _gx_accordion_one_levelmenu_position  Position an accordion menu    */
185
/*                                                                        */
186
/*  CALLED BY                                                             */
187
/*                                                                        */
188
/*    Application Code                                                    */
189
/*                                                                        */
190
/**************************************************************************/
191
118
UINT  _gx_accordion_menu_position(GX_ACCORDION_MENU *accordion)
192
{
193
118
GX_WIDGET    *parent = (GX_WIDGET *)accordion;
194
GX_WIDGET    *child;
195
GX_MENU_LIST *child_list;
196
197
118
    child = accordion -> gx_widget_first_child;
198
199
    /* Reposition items of menu list. */
200
1255
    while (child)
201
    {
202
1254
        if (child -> gx_widget_type == GX_TYPE_MENU)
203
        {
204
627
            child_list = &((GX_MENU *)child) -> gx_menu_list;
205
206
627
            if (child_list -> gx_widget_first_child)
207
            {
208
525
                child = child_list -> gx_widget_first_child;
209
525
                continue;
210
            }
211
102
            else if (child_list -> gx_widget_parent)
212
            {
213
1
                _gx_widget_detach((GX_WIDGET *)child_list);
214
            }
215
        }
216
627
        else if (child -> gx_widget_type == GX_TYPE_ACCORDION_MENU)
217
        {
218
113
            if (child -> gx_widget_first_child)
219
            {
220
112
                child = child -> gx_widget_first_child;
221
112
                continue;
222
            }
223
        }
224
225

1371
        while ((child -> gx_widget_next == GX_NULL) && (child != parent))
226
        {
227
754
            child = child -> gx_widget_parent;
228
229
754
            if (child -> gx_widget_type == GX_TYPE_MENU_LIST)
230
            {
231
525
                child_list = (GX_MENU_LIST *)child;
232
525
                child = child_list -> gx_menu_list_owner;
233
            }
234
235
754
            if ((child -> gx_widget_type == GX_TYPE_MENU))
236
            {
237
525
                _gx_menu_one_level_position((GX_MENU *)child, 0);
238
            }
239
            else
240
            {
241
229
                _gx_accordion_menu_one_level_position((GX_ACCORDION_MENU *)child);
242
            }
243
        }
244
245
617
        if (child == parent)
246
        {
247
117
            break;
248
        }
249
250
500
        child = child -> gx_widget_next;
251
    }
252
253
    /* Return completion status code. */
254
118
    return(GX_SUCCESS);
255
}
256