GCC Code Coverage Report
Directory: ./ Exec Total Coverage
File: gx_widget_resize.c Lines: 43 43 100.0 %
Date: 2024-12-05 08:52:37 Branches: 26 26 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
31
32
/**************************************************************************/
33
/*                                                                        */
34
/*  FUNCTION                                               RELEASE        */
35
/*                                                                        */
36
/*    _gx_widget_resize                                   PORTABLE C      */
37
/*                                                           6.1          */
38
/*  AUTHOR                                                                */
39
/*                                                                        */
40
/*    Kenneth Maxwell, Microsoft Corporation                              */
41
/*                                                                        */
42
/*  DESCRIPTION                                                           */
43
/*                                                                        */
44
/*    This function  resizes the widget.                                  */
45
/*                                                                        */
46
/*  INPUT                                                                 */
47
/*                                                                        */
48
/*    widget                                Pointer to widget             */
49
/*    new_size                              New widget size               */
50
/*                                                                        */
51
/*  OUTPUT                                                                */
52
/*                                                                        */
53
/*    status                                Completion status             */
54
/*                                                                        */
55
/*  CALLS                                                                 */
56
/*                                                                        */
57
/*    _gx_utility_rectangle_compare          Compares two rectangles      */
58
/*    _gx_utility_rectangle_inside_detect    Detect if a second rectangle */
59
/*                                             is completely within the   */
60
/*                                             first one                  */
61
/*    _gx_system_dirty_partial_add           Add dirty area               */
62
/*    _gx_utility_rectangle_combine          Combines two rectangles      */
63
/*    _gx_widget_client_get                  Retrieves client area        */
64
/*    _gx_widget_shift                       Changes the position of      */
65
/*                                             a widget                   */
66
/*    _gx_widget_clipping_update             Update the clipping members  */
67
/*                                             of each child widget       */
68
/*    _gx_widget_event_process_function      Indirect call to widget      */
69
/*                                             event processing function  */
70
/*                                                                        */
71
/*  CALLED BY                                                             */
72
/*                                                                        */
73
/*    Application Code                                                    */
74
/*    GUIX Internal Code                                                  */
75
/*                                                                        */
76
/*  RELEASE HISTORY                                                       */
77
/*                                                                        */
78
/*    DATE              NAME                      DESCRIPTION             */
79
/*                                                                        */
80
/*  05-19-2020     Kenneth Maxwell          Initial Version 6.0           */
81
/*  09-30-2020     Kenneth Maxwell          Modified comment(s),          */
82
/*                                            resulting in version 6.1    */
83
/*                                                                        */
84
/**************************************************************************/
85
47828
UINT  _gx_widget_resize(GX_WIDGET *widget, GX_RECTANGLE *new_size)
86
{
87
GX_WIDGET      *child;
88
GX_WINDOW      *win;
89
GX_WINDOW_ROOT *root;
90
GX_RECTANGLE    area_sum;
91
GX_VALUE        LeftShift;
92
GX_VALUE        TopShift;
93
GX_VALUE        RightShift;
94
GX_VALUE        BottomShift;
95
GX_EVENT        new_event;
96
97
    /* first, check to see if the old and new size are the same */
98
99
47828
    if (_gx_utility_rectangle_compare(&widget -> gx_widget_size, new_size))
100
    {
101
25888
        return GX_SUCCESS;
102
    }
103
104
21940
    if (widget -> gx_widget_status & GX_STATUS_VISIBLE)
105
    {
106
        /* If my new size encompasses my old size, then I just need to
107
           mark myself as dirty
108
         */
109
10539
        if (_gx_utility_rectangle_inside_detect(new_size, &widget -> gx_widget_size))
110
        {
111
1592
            _gx_system_dirty_partial_add(widget, new_size);
112
        }
113
        else
114
        {
115
            /* here if my new size is smaller or in a different position,
116
               I need to mark my parent as dirty
117
             */
118
8947
            area_sum = *new_size;
119
8947
            _gx_utility_rectangle_combine(&area_sum, &widget -> gx_widget_size);
120
8947
            _gx_system_dirty_partial_add(widget -> gx_widget_parent, &area_sum);
121
        }
122
    }
123
124
    /* keep track of how far I am shifting */
125
21940
    LeftShift = (GX_VALUE)(new_size -> gx_rectangle_left - widget -> gx_widget_size.gx_rectangle_left);
126
21940
    TopShift = (GX_VALUE)(new_size -> gx_rectangle_top - widget -> gx_widget_size.gx_rectangle_top);
127
21940
    RightShift = (GX_VALUE)(new_size -> gx_rectangle_right - widget -> gx_widget_size.gx_rectangle_right);
128
21940
    BottomShift = (GX_VALUE)(new_size -> gx_rectangle_bottom - widget -> gx_widget_size.gx_rectangle_bottom);
129
130
    /* reset my size */
131
21940
    widget -> gx_widget_size = *new_size;
132
133
    /* if I am a window, update my client area */
134
135
21940
    if (widget -> gx_widget_type >= GX_TYPE_WINDOW)
136
    {
137
432
        win = (GX_WINDOW *)widget;
138
432
        win -> gx_window_client.gx_rectangle_left   = (GX_VALUE)(win -> gx_window_client.gx_rectangle_left + LeftShift);
139
432
        win -> gx_window_client.gx_rectangle_top    = (GX_VALUE)(win -> gx_window_client.gx_rectangle_top + TopShift);
140
432
        win -> gx_window_client.gx_rectangle_right  = (GX_VALUE)(win -> gx_window_client.gx_rectangle_right + RightShift);
141
432
        win -> gx_window_client.gx_rectangle_bottom = (GX_VALUE)(win -> gx_window_client.gx_rectangle_bottom + BottomShift);
142
143
        /* if parent is root window, then viewports need to be updated */
144
432
        if (widget -> gx_widget_parent)
145
        {
146
289
            if (widget -> gx_widget_parent -> gx_widget_type == GX_TYPE_ROOT_WINDOW)
147
            {
148
18
                root = (GX_WINDOW_ROOT *)widget -> gx_widget_parent;
149
18
                root -> gx_window_root_views_changed = GX_TRUE;
150
            }
151
        }
152
    }
153
154
    /* if my top-left shifted, I need to move my child widgets */
155
156

21940
    if (LeftShift || TopShift)
157
    {
158
        /* pick up pointer to first child widget */
159
12810
        child = widget -> gx_widget_first_child;
160
161
        /* loop through and shift all my child widgets */
162
163
16710
        while (child)
164
        {
165
3900
            _gx_widget_shift(child, LeftShift, TopShift, GX_FALSE);
166
3900
            child = child -> gx_widget_next;
167
        }
168
    }
169
170
21940
    if (widget -> gx_widget_type >= GX_TYPE_WINDOW)
171
    {
172
        /* tell all my child widgets that I have been re-sized */
173
432
        new_event.gx_event_type = GX_EVENT_PARENT_SIZED;
174
432
        child = widget -> gx_widget_first_child;
175
176
1494
        while (child)
177
        {
178
1062
            child -> gx_widget_event_process_function(child, &new_event);
179
1062
            child = child -> gx_widget_next;
180
        }
181
    }
182
183
21940
    if (widget -> gx_widget_status & GX_STATUS_VISIBLE)
184
    {
185
186
        /* update this widget clip rectangle */
187
10539
        _gx_widget_clipping_update(widget);
188
189
10539
        if (widget -> gx_widget_status & GX_STATUS_RESIZE_NOTIFY)
190
        {
191
            /* Notify widget of size change.  */
192
624
            memset(&new_event, 0, sizeof(GX_EVENT));
193
624
            new_event.gx_event_target = widget;
194
624
            new_event.gx_event_type = GX_EVENT_RESIZED;
195
624
            _gx_system_event_fold(&new_event);
196
        }
197
    }
198
21940
    return(GX_SUCCESS);
199
}
200