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

22
    while (child && child -> gx_widget_type == GX_TYPE_MENU_LIST)
168
    {
169
1
        child = _gx_widget_next_client_child_get(child);
170
    }
171
172
59
    while (child)
173
    {
174
        /* Pick up next client child. */
175
58
        next = _gx_widget_next_client_child_get(child);
176
177

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

21
    if (child && (child -> gx_widget_type == GX_TYPE_MENU) &&
378
16
        ((GX_MENU *)child) -> gx_menu_list.gx_widget_first_child)
379
    {
380
15
        _gx_tree_view_root_icon_rect_get(tree, child, &root_rect);
381
382
15
        if (_gx_utility_rectangle_point_detect(&root_rect, *point))
383
        {
384
12
            if (child -> gx_widget_style & GX_STYLE_MENU_EXPANDED)
385
            {
386
6
                child -> gx_widget_style &= (ULONG)(~GX_STYLE_MENU_EXPANDED);
387
388
6
                if (_tree_view_selected_detect(tree, (GX_MENU *)child))
389
                {
390
2
                    _gx_tree_view_selected_set(tree, child);
391
                }
392
            }
393
            else
394
            {
395
6
                child -> gx_widget_style |= GX_STYLE_MENU_EXPANDED;
396
            }
397
398
12
            _gx_tree_view_position(tree);
399
400
12
            root_rect = tree -> gx_window_client;
401
12
            if (!(tree -> gx_widget_style & GX_STYLE_TREE_VIEW_SHOW_ROOT_LINES))
402
            {
403
2
                root_rect.gx_rectangle_top = child -> gx_widget_size.gx_rectangle_top;
404
            }
405
406
12
            _gx_system_dirty_partial_add((GX_WIDGET *)tree, &root_rect);
407
        }
408
        else
409
        {
410
3
            check_selection = GX_TRUE;
411
        }
412
    }
413
    else
414
    {
415
6
        check_selection = GX_TRUE;
416
6
        _gx_window_event_process((GX_WINDOW *)widget, event_ptr);
417
    }
418
419
21
    if (check_selection)
420
    {
421
9
        child = _gx_system_top_widget_find((GX_WIDGET *)tree, *point, GX_STATUS_SELECTABLE);
422
423
9
        if (child)
424
        {
425
5
            if ((child -> gx_widget_type == GX_TYPE_MENU) ||
426
3
                (child -> gx_widget_parent -> gx_widget_type == GX_TYPE_MENU_LIST))
427
            {
428
3
                _gx_tree_view_selected_set(tree, child);
429
            }
430
        }
431
    }
432
21
}
433
434
/**************************************************************************/
435
/*                                                                        */
436
/*  FUNCTION                                               RELEASE        */
437
/*                                                                        */
438
/*    _gx_tree_view_event_process                         PORTABLE C      */
439
/*                                                           6.1          */
440
/*  AUTHOR                                                                */
441
/*                                                                        */
442
/*    Kenneth Maxwell, Microsoft Corporation                              */
443
/*                                                                        */
444
/*  DESCRIPTION                                                           */
445
/*                                                                        */
446
/*    This function processes an event for the tree menu.                 */
447
/*                                                                        */
448
/*  INPUT                                                                 */
449
/*                                                                        */
450
/*    tree                                  Pointer to tree menu control  */
451
/*                                            block                       */
452
/*    event_ptr                             Pointer to event to process   */
453
/*                                                                        */
454
/*  OUTPUT                                                                */
455
/*                                                                        */
456
/*    status                                Completion status             */
457
/*                                                                        */
458
/*  CALLS                                                                 */
459
/*                                                                        */
460
/*    _gx_window_event_process              Default window event process  */
461
/*    _gx_tree_view_position                Position the children of the  */
462
/*                                            tree view                   */
463
/*    _gx_tree_menu_pen_down_event_process  Handle pen down event         */
464
/*    _gx_tree_view_scroll                  Scroll tree view client area  */
465
/*                                                                        */
466
/*  CALLED BY                                                             */
467
/*                                                                        */
468
/*    Application Code                                                    */
469
/*    GUIX Internal Code                                                  */
470
/*                                                                        */
471
/*  RELEASE HISTORY                                                       */
472
/*                                                                        */
473
/*    DATE              NAME                      DESCRIPTION             */
474
/*                                                                        */
475
/*  05-19-2020     Kenneth Maxwell          Initial Version 6.0           */
476
/*  09-30-2020     Kenneth Maxwell          Modified comment(s),          */
477
/*                                            resulting in version 6.1    */
478
/*                                                                        */
479
/**************************************************************************/
480
283
UINT _gx_tree_view_event_process(GX_TREE_VIEW *tree, GX_EVENT *event_ptr)
481
{
482

283
    switch (event_ptr -> gx_event_type)
483
    {
484
47
    case GX_EVENT_SHOW:
485
47
        _gx_window_event_process((GX_WINDOW *)tree, event_ptr);
486

47
        if (tree -> gx_widget_parent && (tree -> gx_widget_parent -> gx_widget_type != GX_TYPE_MENU_LIST))
487
        {
488
45
            _gx_tree_view_position(tree);
489
        }
490
47
        break;
491
492
21
    case GX_EVENT_PEN_DOWN:
493
21
        _gx_tree_menu_pen_down_event_process(tree, event_ptr);
494
21
        break;
495
496
3
    case GX_EVENT_VERTICAL_SCROLL:
497
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]));
498
3
        break;
499
500
3
    case GX_EVENT_HORIZONTAL_SCROLL:
501
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);
502
3
        break;
503
504
209
    default:
505
209
        return _gx_window_event_process((GX_WINDOW *)tree, event_ptr);
506
    }
507
508
74
    return(GX_SUCCESS);
509
}
510