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 /* FUNCTION RELEASE */
35 /* */
36 /* _gx_widget_shift_helper PORTABLE C */
37 /* 6.1 */
38 /* AUTHOR */
39 /* */
40 /* Kenneth Maxwell, Microsoft Corporation */
41 /* */
42 /* DESCRIPTION */
43 /* */
44 /* Internal helper function to shift one widget and optionally marks */
45 /* it as dirty. */
46 /* */
47 /* INPUT */
48 /* */
49 /* widget Pointer to widget */
50 /* x_shift Number of pixels to shift on */
51 /* the x-axis */
52 /* y_shift Number of pixels to shift on */
53 /* the y-axis */
54 /* mark_dirty GX_TRUE to indicate dirty, */
55 /* otherwise GX_FALSE */
56 /* */
57 /* OUTPUT */
58 /* */
59 /* status Completion status */
60 /* */
61 /* CALLS */
62 /* */
63 /* _gx_utility_rectangle_shift Adjust a rectangle */
64 /* _gx_utility_rectangle_combine Combine rectangles */
65 /* _gx_system_dirty_partial_add Add area to the dirty list */
66 /* _gx_widget_shift Shift a widget */
67 /* */
68 /* CALLED BY */
69 /* */
70 /* _gx_widget_shift */
71 /* */
72 /* RELEASE HISTORY */
73 /* */
74 /* DATE NAME DESCRIPTION */
75 /* */
76 /* 05-19-2020 Kenneth Maxwell Initial Version 6.0 */
77 /* 09-30-2020 Kenneth Maxwell Modified comment(s), */
78 /* resulting in version 6.1 */
79 /* */
80 /**************************************************************************/
_gx_widget_shift_helper(GX_WIDGET * widget,GX_VALUE x_shift,GX_VALUE y_shift,GX_BOOL mark_dirty)81 static VOID _gx_widget_shift_helper(GX_WIDGET *widget, GX_VALUE x_shift, GX_VALUE y_shift, GX_BOOL mark_dirty)
82 {
83 GX_WINDOW *win;
84 GX_RECTANGLE area_sum;
85 GX_RECTANGLE newsize;
86 GX_EVENT new_event;
87
88 newsize = widget -> gx_widget_size;
89 _gx_utility_rectangle_shift(&newsize, x_shift, y_shift);
90
91 if (mark_dirty && (widget -> gx_widget_status & GX_STATUS_VISIBLE))
92 {
93 /* here if my new size is smaller or in a different position,
94 I need to mark my parent as dirty
95 */
96 area_sum = newsize;
97 _gx_utility_rectangle_combine(&area_sum, &widget -> gx_widget_size);
98 _gx_system_dirty_partial_add(widget -> gx_widget_parent, &area_sum);
99 }
100
101 widget -> gx_widget_size = newsize;
102
103 if (widget -> gx_widget_type >= GX_TYPE_WINDOW)
104 {
105 win = (GX_WINDOW *)widget;
106 _gx_utility_rectangle_shift(&win -> gx_window_client, x_shift, y_shift);
107
108 if (win -> gx_widget_status & GX_STATUS_VISIBLE)
109 {
110 /* check to see if viewports need to be updated */
111 _gx_window_view_update_detect(win);
112 }
113 }
114
115 if ((widget -> gx_widget_status & GX_STATUS_VISIBLE) &&
116 (widget -> gx_widget_status & GX_STATUS_RESIZE_NOTIFY))
117 {
118 /* Notify widget of size change. */
119 memset(&new_event, 0, sizeof(GX_EVENT));
120 new_event.gx_event_target = widget;
121 new_event.gx_event_type = GX_EVENT_RESIZED;
122 _gx_system_event_fold(&new_event);
123 }
124 }
125
126 /**************************************************************************/
127 /* */
128 /* FUNCTION RELEASE */
129 /* */
130 /* _gx_widget_shift PORTABLE C */
131 /* 6.1 */
132 /* AUTHOR */
133 /* */
134 /* Kenneth Maxwell, Microsoft Corporation */
135 /* */
136 /* DESCRIPTION */
137 /* */
138 /* This service shifts the widget and optionally marks it as dirty. */
139 /* */
140 /* INPUT */
141 /* */
142 /* widget Pointer to widget */
143 /* x_shift Number of pixels to shift on */
144 /* the x-axis */
145 /* y_shift Number of pixels to shift on */
146 /* the y-axis */
147 /* mark_dirty GX_TRUE to indicate dirty, */
148 /* otherwise GX_FALSE */
149 /* */
150 /* OUTPUT */
151 /* */
152 /* status Completion status */
153 /* */
154 /* CALLS */
155 /* */
156 /* _gx_widget_shift_helper Shift a widget */
157 /* _gx_widget_clipping_update Update widget clipping area */
158 /* */
159 /* CALLED BY */
160 /* */
161 /* Application Code */
162 /* GUIX Internal Code */
163 /* */
164 /* RELEASE HISTORY */
165 /* */
166 /* DATE NAME DESCRIPTION */
167 /* */
168 /* 05-19-2020 Kenneth Maxwell Initial Version 6.0 */
169 /* 09-30-2020 Kenneth Maxwell Modified comment(s), */
170 /* resulting in version 6.1 */
171 /* */
172 /**************************************************************************/
_gx_widget_shift(GX_WIDGET * widget,GX_VALUE x_shift,GX_VALUE y_shift,GX_BOOL mark_dirty)173 UINT _gx_widget_shift(GX_WIDGET *widget, GX_VALUE x_shift, GX_VALUE y_shift, GX_BOOL mark_dirty)
174 {
175 GX_WIDGET *child;
176
177 if (x_shift == 0 && y_shift == 0)
178 {
179 return GX_SUCCESS;
180 }
181
182 _gx_widget_shift_helper(widget, x_shift, y_shift, mark_dirty);
183
184 /* pick up pointer to first child widget */
185 child = widget -> gx_widget_first_child;
186
187 /* loop through and shift all my child widgets */
188
189 while (child)
190 {
191 _gx_widget_shift_helper(child, x_shift, y_shift, GX_FALSE);
192
193 if (child -> gx_widget_first_child)
194 {
195 child = child -> gx_widget_first_child;
196 continue;
197 }
198
199 while ((child -> gx_widget_next == GX_NULL) && (child != widget))
200 {
201 child = child -> gx_widget_parent;
202 }
203
204 if (child == widget)
205 {
206 break;
207 }
208
209 child = child -> gx_widget_next;
210 }
211
212 if (mark_dirty && (widget -> gx_widget_status & GX_STATUS_VISIBLE))
213 {
214 _gx_widget_clipping_update(widget);
215 }
216
217 return(GX_SUCCESS);
218 }
219
220