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