GCC Code Coverage Report
Directory: ./ Exec Total Coverage
File: gx_menu_position.c Lines: 69 69 100.0 %
Date: 2024-12-05 08:52:37 Branches: 34 34 100.0 %

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
/**   Menu Management (Menu)                                              */
18
/**                                                                       */
19
/**************************************************************************/
20
21
#define GX_SOURCE_CODE
22
23
24
/* Include necessary system files.  */
25
26
#include "gx_api.h"
27
#include "gx_menu.h"
28
#include "gx_widget.h"
29
#include "gx_system.h"
30
31
/**************************************************************************/
32
/*                                                                        */
33
/*  FUNCTION                                               RELEASE        */
34
/*                                                                        */
35
/*    _gx_menu_one_level_position                         PORTABLE C      */
36
/*                                                           6.1          */
37
/*  AUTHOR                                                                */
38
/*                                                                        */
39
/*    Kenneth Maxwell, Microsoft Corporation                              */
40
/*                                                                        */
41
/*  DESCRIPTION                                                           */
42
/*                                                                        */
43
/*    This function positions first level items for a menu widget.        */
44
/*                                                                        */
45
/*  INPUT                                                                 */
46
/*                                                                        */
47
/*    menu                                  Pointer to menu control block */
48
/*    indentation                           Menu indentations             */
49
/*                                                                        */
50
/*  OUTPUT                                                                */
51
/*                                                                        */
52
/*    status                                Completion status             */
53
/*                                                                        */
54
/*  CALLS                                                                 */
55
/*                                                                        */
56
/*    _gx_widget_resize                     Resize a widget               */
57
/*    _gx_widget_detach                     Detach a widget from its      */
58
/*                                            parent                      */
59
/*                                                                        */
60
/*  CALLED BY                                                             */
61
/*                                                                        */
62
/*    GUIX Internal Code                                                  */
63
/*                                                                        */
64
/*  RELEASE HISTORY                                                       */
65
/*                                                                        */
66
/*    DATE              NAME                      DESCRIPTION             */
67
/*                                                                        */
68
/*  05-19-2020     Kenneth Maxwell          Initial Version 6.0           */
69
/*  09-30-2020     Kenneth Maxwell          Modified comment(s),          */
70
/*                                            resulting in version 6.1    */
71
/*                                                                        */
72
/**************************************************************************/
73
981
UINT  _gx_menu_one_level_position(GX_MENU *menu, GX_VALUE indentation)
74
{
75
981
GX_RECTANGLE *menu_size = &menu -> gx_widget_size;
76
981
GX_WIDGET    *list = (GX_WIDGET *)&menu -> gx_menu_list;
77
GX_WIDGET    *item;
78
GX_RECTANGLE  size;
79
GX_VALUE      height;
80
GX_VALUE      width;
81
981
INT           max_width = 0;
82
GX_MENU_LIST *item_list;
83
84
981
    size.gx_rectangle_left = (GX_VALUE)(menu_size -> gx_rectangle_left + indentation);
85
981
    size.gx_rectangle_right = (GX_VALUE)(menu_size -> gx_rectangle_right);
86
981
    size.gx_rectangle_top = (GX_VALUE)(menu_size -> gx_rectangle_bottom + 1);
87
981
    size.gx_rectangle_bottom = (GX_VALUE)(size.gx_rectangle_top - 1);
88
89
    /* Reposition menu list. */
90
981
    _gx_widget_resize(list, &size);
91
92
981
    if (menu -> gx_widget_style & GX_STYLE_MENU_EXPANDED)
93
    {
94
59
        if (!list -> gx_widget_parent)
95
        {
96
22
            _gx_widget_link(menu -> gx_widget_parent, (GX_WIDGET *)list);
97
        }
98
    }
99
    else
100
    {
101
922
        if (list -> gx_widget_parent)
102
        {
103
8
            _gx_widget_detach((GX_WIDGET *)list);
104
        }
105
    }
106
107
981
    item = list -> gx_widget_first_child;
108
981
    size.gx_rectangle_bottom = menu_size -> gx_rectangle_bottom;
109
110
    /* Reposition items of menu list. */
111
2357
    while (item)
112
    {
113
1376
        if (item -> gx_widget_type == GX_TYPE_MENU_LIST)
114
        {
115
21
            item = item -> gx_widget_next;
116
21
            continue;
117
        }
118
119
1355
        height = (GX_VALUE)(item -> gx_widget_size.gx_rectangle_bottom - item -> gx_widget_size.gx_rectangle_top + 1);
120
1355
        width = (GX_VALUE)(item -> gx_widget_size.gx_rectangle_right - item -> gx_widget_size.gx_rectangle_left + 1);
121
122
1355
        if (width > max_width)
123
        {
124
1038
            max_width = width;
125
        }
126
127
1355
        size.gx_rectangle_top = (GX_VALUE)(size.gx_rectangle_bottom + 1);
128
1355
        size.gx_rectangle_bottom = (GX_VALUE)(size.gx_rectangle_top + height - 1);
129
1355
        size.gx_rectangle_right = (GX_VALUE)(size.gx_rectangle_left + width - 1);
130
131
1355
        _gx_widget_resize(item, &size);
132
133
1355
        switch (item -> gx_widget_type)
134
        {
135
296
        case GX_TYPE_MENU:
136
296
            item_list = &((GX_MENU *)item) -> gx_menu_list;
137
296
            if (item_list -> gx_widget_parent)
138
            {
139
21
                _gx_widget_shift((GX_WIDGET *)item_list,
140
21
                                 (GX_VALUE)(size.gx_rectangle_left + indentation - item_list -> gx_widget_size.gx_rectangle_left),
141
21
                                 (GX_VALUE)(size.gx_rectangle_bottom + 1 - item_list -> gx_widget_size.gx_rectangle_top), GX_FALSE);
142
143
21
                height = (GX_VALUE)(item_list -> gx_widget_size.gx_rectangle_bottom - size.gx_rectangle_top + 1);
144
21
                width = (GX_VALUE)(item_list -> gx_widget_size.gx_rectangle_right - size.gx_rectangle_left + 1);
145
146
21
                if (width > max_width)
147
                {
148
20
                    max_width = width;
149
                }
150
            }
151
296
            break;
152
153
1059
        default:
154
1059
            break;
155
        }
156
157
1355
        size.gx_rectangle_bottom = (GX_VALUE)(size.gx_rectangle_top + height - 1);
158
159
1355
        item = item -> gx_widget_next;
160
    }
161
162
981
    if (menu -> gx_widget_style & GX_STYLE_MENU_EXPANDED)
163
    {
164
59
        size.gx_rectangle_top = (GX_VALUE)(menu_size -> gx_rectangle_bottom + 1);
165
59
        size.gx_rectangle_right = (GX_VALUE)(size.gx_rectangle_left + max_width - 1);
166
59
        _gx_widget_resize(list, &size);
167
    }
168
169
    /* Return completion status code. */
170
981
    return(GX_SUCCESS);
171
}
172
173
/**************************************************************************/
174
/*                                                                        */
175
/*  FUNCTION                                               RELEASE        */
176
/*                                                                        */
177
/*    _gx_menu_position                                   PORTABLE C      */
178
/*                                                           6.1          */
179
/*  AUTHOR                                                                */
180
/*                                                                        */
181
/*    Kenneth Maxwell, Microsoft Corporation                              */
182
/*                                                                        */
183
/*  DESCRIPTION                                                           */
184
/*                                                                        */
185
/*    This function positions a menu and its menu list.                   */
186
/*                                                                        */
187
/*  INPUT                                                                 */
188
/*                                                                        */
189
/*    menu                                  Pointer to menu control block */
190
/*                                                                        */
191
/*  OUTPUT                                                                */
192
/*                                                                        */
193
/*    status                                Completion status             */
194
/*                                                                        */
195
/*  CALLS                                                                 */
196
/*                                                                        */
197
/*    _gx_menu_one_level_position           Position a menu widget        */
198
/*                                                                        */
199
/*  CALLED BY                                                             */
200
/*                                                                        */
201
/*    GUIX Internal Code                                                  */
202
/*                                                                        */
203
/*  RELEASE HISTORY                                                       */
204
/*                                                                        */
205
/*    DATE              NAME                      DESCRIPTION             */
206
/*                                                                        */
207
/*  05-19-2020     Kenneth Maxwell          Initial Version 6.0           */
208
/*  09-30-2020     Kenneth Maxwell          Modified comment(s),          */
209
/*                                            resulting in version 6.1    */
210
/*                                                                        */
211
/**************************************************************************/
212
271
UINT  _gx_menu_position(GX_MENU *menu, GX_VALUE indentation)
213
{
214
271
UINT          status = GX_SUCCESS;
215
271
GX_WIDGET    *parent = (GX_WIDGET *)menu;
216
GX_WIDGET    *child;
217
GX_MENU_LIST *child_list;
218
219
271
    child = menu -> gx_menu_list.gx_widget_first_child;
220
221
    /* Reposition items of menu list. */
222
746
    while (child)
223
    {
224
735
        if (child -> gx_widget_type == GX_TYPE_MENU)
225
        {
226
198
            child_list = &((GX_MENU *)child) -> gx_menu_list;
227
228
198
            if (child_list -> gx_widget_first_child)
229
            {
230
196
                child = child_list -> gx_widget_first_child;
231
196
                continue;
232
            }
233
2
            else if (child_list -> gx_widget_parent)
234
            {
235
1
                _gx_widget_detach((GX_WIDGET *)child_list);
236
            }
237
        }
238
239

995
        while ((child -> gx_widget_next == GX_NULL) && (child != parent))
240
        {
241
            /* Child parent is menu list. */
242
456
            child_list = (GX_MENU_LIST *)child -> gx_widget_parent;
243
456
            child = child_list -> gx_menu_list_owner;
244
245
456
            _gx_menu_one_level_position((GX_MENU *)child, indentation);
246
        }
247
248
539
        if (child == parent)
249
        {
250
260
            break;
251
        }
252
253
279
        child = child -> gx_widget_next;
254
    }
255
256
    /* Return completion status code. */
257
271
    return(status);
258
}
259