GCC Code Coverage Report
Directory: ./ Exec Total Coverage
File: gx_widget_front_move.c Lines: 35 35 100.0 %
Date: 2024-12-05 08:52:37 Branches: 24 24 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
/**   Widget Management (Widget)                                          */
18
/**                                                                       */
19
/**************************************************************************/
20
21
#define GX_SOURCE_CODE
22
23
24
/* Include necessary system files.  */
25
26
#include "gx_api.h"
27
#include "gx_system.h"
28
#include "gx_utility.h"
29
#include "gx_widget.h"
30
#include "gx_window.h"
31
32
33
/**************************************************************************/
34
/*                                                                        */
35
/*  FUNCTION                                               RELEASE        */
36
/*                                                                        */
37
/*    _gx_widget_front_move                               PORTABLE C      */
38
/*                                                           6.1          */
39
/*  AUTHOR                                                                */
40
/*                                                                        */
41
/*    Kenneth Maxwell, Microsoft Corporation                              */
42
/*                                                                        */
43
/*  DESCRIPTION                                                           */
44
/*                                                                        */
45
/*    This function moves the widget to the front.                        */
46
/*                                                                        */
47
/*  INPUT                                                                 */
48
/*                                                                        */
49
/*    widget                                Pointer to widget to move     */
50
/*    return_moved                          Pointer to destination for    */
51
/*                                            indication widget was moved */
52
/*                                                                        */
53
/*  OUTPUT                                                                */
54
/*                                                                        */
55
/*    status                                Completion status             */
56
/*                                                                        */
57
/*  CALLS                                                                 */
58
/*                                                                        */
59
/*    _gx_system_dirty_partial_add          Add dirty area                */
60
/*    _gx_utility_rectangle_combine         Combine rectangles            */
61
/*    _gx_utility_rectangle_define          Define rectangle              */
62
/*    _gx_utility_rectangle_overlap_detect  Check for overlap             */
63
/*                                                                        */
64
/*  CALLED BY                                                             */
65
/*                                                                        */
66
/*    Application Code                                                    */
67
/*    GUIX Internal Code                                                  */
68
/*                                                                        */
69
/*  RELEASE HISTORY                                                       */
70
/*                                                                        */
71
/*    DATE              NAME                      DESCRIPTION             */
72
/*                                                                        */
73
/*  05-19-2020     Kenneth Maxwell          Initial Version 6.0           */
74
/*  09-30-2020     Kenneth Maxwell          Modified comment(s),          */
75
/*                                            resulting in version 6.1    */
76
/*                                                                        */
77
/**************************************************************************/
78
4705
UINT  _gx_widget_front_move(GX_WIDGET *widget, GX_BOOL *return_moved)
79
{
80
GX_WIDGET   *parent;
81
GX_WIDGET   *sibling;
82
GX_RECTANGLE dirty_area;
83
GX_RECTANGLE overlap;
84
85
    /* Pickup parent widget.  */
86
4705
    parent =  widget -> gx_widget_parent;
87
88
    /* Is parent valid?  */
89
4705
    if (!parent)
90
    {
91
92
        /* Return error.  */
93
1
        return(GX_PTR_ERROR);
94
    }
95
96
    /* First check to see if the widget is already in front.  */
97
4704
    if (parent -> gx_widget_last_child == widget)
98
    {
99
100
        /* Yes, widget is already in front, so nothing to do.  */
101
102
        /* Return no change.  */
103
3716
        return(GX_NO_CHANGE);
104
    }
105
106
    /* Relink widget to the end
107
        1) Determine what to dirty, all or partial
108
        2) unlink and stitch linked list
109
        3) relink to the end
110
        4) call dirty so that I will get redraw
111
     */
112
988
    _gx_utility_rectangle_define(&dirty_area, GX_VALUE_MAX, GX_VALUE_MAX, -1, -1);
113
114
    /* Pickup sibling widget.  */
115
988
    sibling =  widget -> gx_widget_next;
116
117
    /* Traverse the sibling list.  */
118
5683
    while (sibling)
119
    {
120
        /* Check for an overlap of siblings.  */
121
4695
        if (_gx_utility_rectangle_overlap_detect(&widget -> gx_widget_size, &sibling -> gx_widget_size, &overlap))
122
        {
123
            /* Yes, calculate the dirty area.  */
124
425
            if (dirty_area.gx_rectangle_left > dirty_area.gx_rectangle_right)
125
            {
126
226
                dirty_area = overlap;
127
            }
128
            else
129
            {
130
199
                _gx_utility_rectangle_combine(&dirty_area, &overlap);
131
            }
132
        }
133
134
        /* Move to next sibling.  */
135
4695
        sibling =  sibling -> gx_widget_next;
136
    }
137
138
139
988
    if (dirty_area.gx_rectangle_left <= dirty_area.gx_rectangle_right)
140
    {
141
142
        /* Add dirty area.  */
143
226
        _gx_system_dirty_partial_add(widget, &dirty_area);
144
    }
145
146
    /* Is widget the first child of it's parent?  */
147
988
    if (parent -> gx_widget_first_child == widget)
148
    {
149
        /* Yes, the first child, easy remove the first child.  */
150
433
        parent -> gx_widget_first_child =  widget -> gx_widget_next;
151
433
        widget -> gx_widget_next -> gx_widget_previous =  NULL;
152
    }
153
    else
154
    {
155
        /* No, not the first child. Remove from the middle.  */
156
555
        widget -> gx_widget_previous -> gx_widget_next =  widget -> gx_widget_next;
157
555
        widget -> gx_widget_next -> gx_widget_previous =  widget -> gx_widget_previous;
158
    }
159
160
    /* Link the widget to the end of the list.  */
161
162
988
    sibling  =  parent -> gx_widget_last_child;
163
988
    sibling -> gx_widget_next =  widget;
164
988
    widget  -> gx_widget_previous =  sibling;
165
988
    widget  -> gx_widget_next =  NULL;
166
988
    parent  -> gx_widget_last_child =  widget;
167
168
988
    if (widget -> gx_widget_type >= GX_TYPE_WINDOW)
169
    {
170
        /* if parent is root window, then viewports need to be updated */
171
869
        _gx_window_view_update_detect((GX_WINDOW *)widget);
172
173
        /* if window accepts focus and parent has focus, focus should be moved */
174
869
        if (parent -> gx_widget_status & GX_STATUS_HAS_FOCUS &&
175
868
            (widget -> gx_widget_status & GX_STATUS_ACCEPTS_FOCUS) &&
176
867
            !(widget -> gx_widget_status & GX_STATUS_HAS_FOCUS))
177
        {
178
2
            _gx_system_focus_claim(widget);
179
        }
180
    }
181
182
183
    /* Indicate the widget was moved.  */
184
185
988
    if (return_moved)
186
    {
187
7
        *return_moved =  GX_TRUE;
188
    }
189
190
    /* Return successful completion.  */
191
988
    return(GX_SUCCESS);
192
}
193