GCC Code Coverage Report
Directory: ./ Exec Total Coverage
File: gx_tree_view_event_process.c Lines: 109 109 100.0 %
Date: 2026-03-06 19:21:09 Branches: 69 69 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
/**   Tree View Management (View)                                         */
19
/**                                                                       */
20
/**************************************************************************/
21
22
#define GX_SOURCE_CODE
23
24
25
/* Include necessary system files.  */
26
27
#include "gx_api.h"
28
#include "gx_tree_view.h"
29
#include "gx_widget.h"
30
#include "gx_window.h"
31
#include "gx_system.h"
32
#include "gx_utility.h"
33
34
/**************************************************************************/
35
/*                                                                        */
36
/*  FUNCTION                                               RELEASE        */
37
/*                                                                        */
38
/*    _tree_view_selected_detect                          PORTABLE C      */
39
/*                                                           6.1          */
40
/*  AUTHOR                                                                */
41
/*                                                                        */
42
/*    Kenneth Maxwell, Microsoft Corporation                              */
43
/*                                                                        */
44
/*  DESCRIPTION                                                           */
45
/*                                                                        */
46
/*    Internal helper function to test if a menu contain selected item.   */
47
/*                                                                        */
48
/*  INPUT                                                                 */
49
/*                                                                        */
50
/*    tree                                  Pointer to the tree view      */
51
/*                                            control block               */
52
/*    test_menu                             Menu for test                 */
53
/*                                                                        */
54
/*  OUTPUT                                                                */
55
/*                                                                        */
56
/*    status                                Completion status             */
57
/*                                                                        */
58
/*  CALLS                                                                 */
59
/*                                                                        */
60
/*    _tree_view_selected_detect            Detect if a menu contain      */
61
/*                                             selected item              */
62
/*                                                                        */
63
/*  CALLED BY                                                             */
64
/*                                                                        */
65
/*    _gx_tree_menu_pen_down_event_process                                */
66
/*                                                                        */
67
/**************************************************************************/
68
8
static GX_BOOL _tree_view_selected_detect(GX_TREE_VIEW *tree, GX_MENU *test_menu)
69
{
70
8
GX_MENU_LIST *list = &test_menu -> gx_menu_list;
71
GX_WIDGET    *child;
72
8
GX_BOOL       found = GX_FALSE;
73
74
8
    if (!tree -> gx_tree_view_selected)
75
    {
76
1
        return found;
77
    }
78
7
    child = list -> gx_widget_first_child;
79
80
13
    while (child)
81
    {
82
9
        if (child == tree -> gx_tree_view_selected)
83
        {
84
2
            found = GX_TRUE;
85
2
            break;
86
        }
87
88
7
        if (child -> gx_widget_type == GX_TYPE_MENU)
89
        {
90
2
            found = _tree_view_selected_detect(tree, (GX_MENU *)child);
91
92
2
            if (found)
93
            {
94
1
                break;
95
            }
96
        }
97
6
        child = child -> gx_widget_next;
98
    }
99
100
7
    return found;
101
}
102
103
/**************************************************************************/
104
/*                                                                        */
105
/*  FUNCTION                                               RELEASE        */
106
/*                                                                        */
107
/*    _gx_tree_view_item_find                             PORTABLE C      */
108
/*                                                           6.1          */
109
/*  AUTHOR                                                                */
110
/*                                                                        */
111
/*    Kenneth Maxwell, Microsoft Corporation                              */
112
/*                                                                        */
113
/*  DESCRIPTION                                                           */
114
/*                                                                        */
115
/*    Internal helper function to find a tree view item that is           */
116
/*    intersecting the specified horizontal line.                         */
117
/*                                                                        */
118
/*  INPUT                                                                 */
119
/*                                                                        */
120
/*    start                                  Widget to start searching    */
121
/*    line_y                                 Y coordinate of the          */
122
/*                                             horizontal line            */
123
/*    returned_item                          Pointer to retrieved item    */
124
/*                                                                        */
125
/*  OUTPUT                                                                */
126
/*                                                                        */
127
/*    status                                Completion status             */
128
/*                                                                        */
129
/*  CALLS                                                                 */
130
/*                                                                        */
131
/*    _gx_widget_first_client_child_get     Get the first client child    */
132
/*    _gx_widget_next_client_child_get      Get the next client child     */
133
/*    _gx_tree_view_item_find               Find tree view item with test */
134
/*                                            point                       */
135
/*                                                                        */
136
/*  CALLED BY                                                             */
137
/*                                                                        */
138
/*    _gx_tree_menu_pen_down_event_process                                */
139
/*                                                                        */
140
/**************************************************************************/
141
21
static UINT _gx_tree_view_item_find(GX_WIDGET *start, GX_VALUE line_y, GX_WIDGET **returned_item)
142
{
143
21
UINT          status = GX_SUCCESS;
144
GX_WIDGET    *child;
145
GX_WIDGET    *next;
146
21
GX_WIDGET    *found = NULL;
147
GX_MENU_LIST *list;
148
GX_BOOL       search_child;
149
150
21
    child = _gx_widget_first_client_child_get((GX_WIDGET *)start);
151
152

22
    while (child && child -> gx_widget_type == GX_TYPE_MENU_LIST)
153
    {
154
1
        child = _gx_widget_next_client_child_get(child);
155
    }
156
157
59
    while (child)
158
    {
159
        /* Pick up next client child. */
160
58
        next = _gx_widget_next_client_child_get(child);
161
162

64
        while (next && next -> gx_widget_type == GX_TYPE_MENU_LIST)
163
        {
164
6
            next = _gx_widget_next_client_child_get(next);
165
        }
166
167
        /* Check if the widget if intersecting the specified horizontal line. */
168
58
        if ((line_y >= child -> gx_widget_size.gx_rectangle_top) &&
169
54
            (line_y <= child -> gx_widget_size.gx_rectangle_bottom))
170
        {
171
            /* Line y is in current item. */
172
5
            found = child;
173
5
            break;
174
        }
175
176
53
        search_child = GX_FALSE;
177
178
53
        if (next)
179
        {
180
51
            if (line_y < next -> gx_widget_size.gx_rectangle_top)
181
            {
182
10
                search_child = GX_TRUE;
183
            }
184
41
            else if (line_y <= next -> gx_widget_size.gx_rectangle_bottom)
185
            {
186
                /* Line y is inside next item. */
187
14
                found = next;
188
14
                break;
189
            }
190
        }
191
        else
192
        {
193
2
            search_child = GX_TRUE;
194
        }
195
196
39
        if (search_child)
197
        {
198
            /* Line y is before next item. */
199
12
            if (child -> gx_widget_type == GX_TYPE_MENU)
200
            {
201
11
                list = &((GX_MENU *)child) -> gx_menu_list;
202
203
11
                if (list -> gx_widget_status & GX_STATUS_VISIBLE)
204
                {
205
8
                    child = list -> gx_widget_first_child;
206
8
                    continue;
207
                }
208
            }
209
            else
210
            {
211
                /* Not found. */
212
1
                break;
213
            }
214
        }
215
216
30
        child = next;
217
    }
218
219
21
    *returned_item = found;
220
221
21
    return status;
222
}
223
224
/**************************************************************************/
225
/*                                                                        */
226
/*  FUNCTION                                               RELEASE        */
227
/*                                                                        */
228
/*    _gx_tree_view_root_icon_rect_get                    PORTABLE C      */
229
/*                                                           6.1          */
230
/*  AUTHOR                                                                */
231
/*                                                                        */
232
/*    Kenneth Maxwell, Microsoft Corporation                              */
233
/*                                                                        */
234
/*  DESCRIPTION                                                           */
235
/*                                                                        */
236
/*    Internal helper function to get the root icon draw area of a tree   */
237
/*    view item.                                                          */
238
/*                                                                        */
239
/*  INPUT                                                                 */
240
/*                                                                        */
241
/*    tree                                  Pointer to the tree view      */
242
/*                                            control block               */
243
/*    item                                  Pointer to the tree view item */
244
/*                                            whose root icon draw area is*/
245
/*                                            retrieved                   */
246
/*    root_rect                             Retrieved root icon draw area */
247
/*                                                                        */
248
/*  OUTPUT                                                                */
249
/*                                                                        */
250
/*    status                                Completion status             */
251
/*                                                                        */
252
/*  CALLS                                                                 */
253
/*                                                                        */
254
/*    _gx_widget_pixelmap_get               Get pixelmap by supplied ID   */
255
/*                                                                        */
256
/*  CALLED BY                                                             */
257
/*                                                                        */
258
/*    _gx_tree_menu_pen_down_event_process                                */
259
/*                                                                        */
260
/**************************************************************************/
261
15
static UINT _gx_tree_view_root_icon_rect_get(GX_TREE_VIEW *tree, GX_WIDGET *item, GX_RECTANGLE *root_rect)
262
{
263
GX_PIXELMAP *map;
264
265
15
    _gx_widget_pixelmap_get((GX_WIDGET *)tree, tree -> gx_tree_view_expand_pixelmap_id, &map);
266
267
15
    if (map)
268
    {
269
13
        root_rect -> gx_rectangle_left = (GX_VALUE)(item -> gx_widget_size.gx_rectangle_left - (tree -> gx_tree_view_indentation >> 1));
270
13
        root_rect -> gx_rectangle_left = (GX_VALUE)(root_rect -> gx_rectangle_left - (map -> gx_pixelmap_width >> 1));
271
13
        root_rect -> gx_rectangle_top = (GX_VALUE)(item -> gx_widget_size.gx_rectangle_top + item -> gx_widget_size.gx_rectangle_bottom - 1);
272
13
        root_rect -> gx_rectangle_top = (GX_VALUE)(root_rect -> gx_rectangle_top >> 1);
273
13
        root_rect -> gx_rectangle_top = (GX_VALUE)(root_rect -> gx_rectangle_top - (map -> gx_pixelmap_height >> 1));
274
13
        root_rect -> gx_rectangle_right = (GX_VALUE)((root_rect -> gx_rectangle_left + map -> gx_pixelmap_width - 1));
275
13
        root_rect -> gx_rectangle_bottom = (GX_VALUE)((root_rect -> gx_rectangle_top + map -> gx_pixelmap_height - 1));
276
    }
277
    else
278
    {
279
2
        memset(root_rect, 0, sizeof(GX_RECTANGLE));
280
    }
281
282
15
    return GX_SUCCESS;
283
}
284
285
/**************************************************************************/
286
/*                                                                        */
287
/*  FUNCTION                                               RELEASE        */
288
/*                                                                        */
289
/*    _gx_tree_menu_pen_down_event_process                PORTABLE C      */
290
/*                                                           6.1          */
291
/*  AUTHOR                                                                */
292
/*                                                                        */
293
/*    Kenneth Maxwell, Microsoft Corporation                              */
294
/*                                                                        */
295
/*  DESCRIPTION                                                           */
296
/*                                                                        */
297
/*    Internal helper function to process pen down event for the tree     */
298
/*    view.                                                               */
299
/*                                                                        */
300
/*  INPUT                                                                 */
301
/*                                                                        */
302
/*    tree                                  Pointer to tree view control  */
303
/*                                            block                       */
304
/*    event_ptr                             Pointer to event to process   */
305
/*                                                                        */
306
/*  OUTPUT                                                                */
307
/*                                                                        */
308
/*    status                                Completion status             */
309
/*                                                                        */
310
/*  CALLS                                                                 */
311
/*                                                                        */
312
/*    _gx_tree_view_item_find               Find tree view item with test */
313
/*                                            point                       */
314
/*    _gx_tree_view_root_icon_rect_get      Retrieve root icon rectangle  */
315
/*                                            of specified tree view item */
316
/*    _tree_view_selected_detect            Detect if a menu contain      */
317
/*                                            selected item               */
318
/*    _gx_tree_view_selected_set            Set new selected item         */
319
/*    _gx_tree_view_position                Position a tree view          */
320
/*    _gx_system_dirty_partial_add          Mark partial area of a widget */
321
/*                                            as dirty                    */
322
/*    _gx_system_top_widget_find            Find top widget that contain  */
323
/*                                            test point                  */
324
/*    _gx_utility_rectangle_point_detect    Test if the point is resides  */
325
/*                                            in the rectangle.           */
326
/*    _gx_window_event_process              Default window event process  */
327
/*                                                                        */
328
/*  CALLED BY                                                             */
329
/*                                                                        */
330
/*    _gx_tree_view_event_process                                         */
331
/*                                                                        */
332
/**************************************************************************/
333
21
static VOID _gx_tree_menu_pen_down_event_process(GX_TREE_VIEW *tree, GX_EVENT *event_ptr)
334
{
335
21
GX_WIDGET   *widget = (GX_WIDGET *)tree;
336
21
GX_WIDGET   *child = GX_NULL;
337
GX_RECTANGLE root_rect;
338
GX_POINT    *point;
339
21
GX_BOOL      check_selection = GX_FALSE;
340
341
21
    point = &event_ptr -> gx_event_payload.gx_event_pointdata;
342
343
    /* Find tree view item that is intersecting the horizontal line of the click point. */
344
21
    _gx_tree_view_item_find((GX_WIDGET *)tree, point -> gx_point_y, &child);
345
346

21
    if (child && (child -> gx_widget_type == GX_TYPE_MENU) &&
347
16
        ((GX_MENU *)child) -> gx_menu_list.gx_widget_first_child)
348
    {
349
15
        _gx_tree_view_root_icon_rect_get(tree, child, &root_rect);
350
351
30
        if (_gx_utility_rectangle_point_detect(&root_rect, *point))
352
        {
353
12
            if (child -> gx_widget_style & GX_STYLE_MENU_EXPANDED)
354
            {
355
6
                child -> gx_widget_style &= (ULONG)(~GX_STYLE_MENU_EXPANDED);
356
357
6
                if (_tree_view_selected_detect(tree, (GX_MENU *)child))
358
                {
359
2
                    _gx_tree_view_selected_set(tree, child);
360
                }
361
            }
362
            else
363
            {
364
6
                child -> gx_widget_style |= GX_STYLE_MENU_EXPANDED;
365
            }
366
367
12
            _gx_tree_view_position(tree);
368
369
12
            root_rect = tree -> gx_window_client;
370
12
            if (!(tree -> gx_widget_style & GX_STYLE_TREE_VIEW_SHOW_ROOT_LINES))
371
            {
372
2
                root_rect.gx_rectangle_top = child -> gx_widget_size.gx_rectangle_top;
373
            }
374
375
12
            _gx_system_dirty_partial_add((GX_WIDGET *)tree, &root_rect);
376
        }
377
        else
378
        {
379
3
            check_selection = GX_TRUE;
380
        }
381
    }
382
    else
383
    {
384
6
        check_selection = GX_TRUE;
385
6
        _gx_window_event_process((GX_WINDOW *)widget, event_ptr);
386
    }
387
388
21
    if (check_selection)
389
    {
390
9
        child = _gx_system_top_widget_find((GX_WIDGET *)tree, *point, GX_STATUS_SELECTABLE);
391
392
9
        if (child)
393
        {
394
5
            if ((child -> gx_widget_type == GX_TYPE_MENU) ||
395
3
                (child -> gx_widget_parent -> gx_widget_type == GX_TYPE_MENU_LIST))
396
            {
397
3
                _gx_tree_view_selected_set(tree, child);
398
            }
399
        }
400
    }
401
21
}
402
403
/**************************************************************************/
404
/*                                                                        */
405
/*  FUNCTION                                               RELEASE        */
406
/*                                                                        */
407
/*    _gx_tree_view_event_process                         PORTABLE C      */
408
/*                                                           6.1          */
409
/*  AUTHOR                                                                */
410
/*                                                                        */
411
/*    Kenneth Maxwell, Microsoft Corporation                              */
412
/*                                                                        */
413
/*  DESCRIPTION                                                           */
414
/*                                                                        */
415
/*    This function processes an event for the tree menu.                 */
416
/*                                                                        */
417
/*  INPUT                                                                 */
418
/*                                                                        */
419
/*    tree                                  Pointer to tree menu control  */
420
/*                                            block                       */
421
/*    event_ptr                             Pointer to event to process   */
422
/*                                                                        */
423
/*  OUTPUT                                                                */
424
/*                                                                        */
425
/*    status                                Completion status             */
426
/*                                                                        */
427
/*  CALLS                                                                 */
428
/*                                                                        */
429
/*    _gx_window_event_process              Default window event process  */
430
/*    _gx_tree_view_position                Position the children of the  */
431
/*                                            tree view                   */
432
/*    _gx_tree_menu_pen_down_event_process  Handle pen down event         */
433
/*    _gx_tree_view_scroll                  Scroll tree view client area  */
434
/*                                                                        */
435
/*  CALLED BY                                                             */
436
/*                                                                        */
437
/*    Application Code                                                    */
438
/*    GUIX Internal Code                                                  */
439
/*                                                                        */
440
/**************************************************************************/
441
283
UINT _gx_tree_view_event_process(GX_TREE_VIEW *tree, GX_EVENT *event_ptr)
442
{
443

283
    switch (event_ptr -> gx_event_type)
444
    {
445
47
    case GX_EVENT_SHOW:
446
47
        _gx_window_event_process((GX_WINDOW *)tree, event_ptr);
447

47
        if (tree -> gx_widget_parent && (tree -> gx_widget_parent -> gx_widget_type != GX_TYPE_MENU_LIST))
448
        {
449
45
            _gx_tree_view_position(tree);
450
        }
451
47
        break;
452
453
21
    case GX_EVENT_PEN_DOWN:
454
21
        _gx_tree_menu_pen_down_event_process(tree, event_ptr);
455
21
        break;
456
457
3
    case GX_EVENT_VERTICAL_SCROLL:
458
3
        _gx_tree_view_scroll(tree, 0, (GX_VALUE)(event_ptr -> gx_event_payload.gx_event_intdata[1] - event_ptr -> gx_event_payload.gx_event_intdata[0]));
459
3
        break;
460
461
3
    case GX_EVENT_HORIZONTAL_SCROLL:
462
3
        _gx_tree_view_scroll(tree, (GX_VALUE)(event_ptr -> gx_event_payload.gx_event_intdata[1] - event_ptr -> gx_event_payload.gx_event_intdata[0]), 0);
463
3
        break;
464
465
209
    default:
466
209
        return _gx_window_event_process((GX_WINDOW *)tree, event_ptr);
467
    }
468
469
74
    return(GX_SUCCESS);
470
}
471