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