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_widget.h"
30 
31 
32 /**************************************************************************/
33 /*                                                                        */
34 /*  FUNCTION                                               RELEASE        */
35 /*                                                                        */
36 /*    _gx_widget_nav_order_initialize                     PORTABLE C      */
37 /*                                                           6.1          */
38 /*  AUTHOR                                                                */
39 /*                                                                        */
40 /*    Kenneth Maxwell, Microsoft Corporation                              */
41 /*                                                                        */
42 /*  DESCRIPTION                                                           */
43 /*                                                                        */
44 /*    This function configures next/previous navigation order.            */
45 /*                                                                        */
46 /*  INPUT                                                                 */
47 /*                                                                        */
48 /*    widget                                Widget control block          */
49 /*                                                                        */
50 /*  OUTPUT                                                                */
51 /*                                                                        */
52 /*    status                                Completion status             */
53 /*                                                                        */
54 /*  CALLS                                                                 */
55 /*                                                                        */
56 /*                                                                        */
57 /*  CALLED BY                                                             */
58 /*                                                                        */
59 /*    GUIX Internal Code                                                  */
60 /*                                                                        */
61 /*  RELEASE HISTORY                                                       */
62 /*                                                                        */
63 /*    DATE              NAME                      DESCRIPTION             */
64 /*                                                                        */
65 /*  05-19-2020     Kenneth Maxwell          Initial Version 6.0           */
66 /*  09-30-2020     Kenneth Maxwell          Modified comment(s),          */
67 /*                                            resulting in version 6.1    */
68 /*                                                                        */
69 /**************************************************************************/
_gx_widget_nav_order_initialize(GX_WIDGET * widget)70 VOID _gx_widget_nav_order_initialize(GX_WIDGET *widget)
71 {
72 GX_WIDGET *winner;
73 GX_WIDGET *child;
74 GX_WIDGET *first_stop = NULL;
75 GX_WIDGET *last_stop = NULL;
76 GX_BOOL    assign_default_focus = GX_TRUE;
77 
78     child = widget -> gx_widget_first_child;
79 
80     /* test to see if any child already has default focus status flag */
81     while (child)
82     {
83         if (assign_default_focus)
84         {
85             if (child -> gx_widget_status & GX_STATUS_DEFAULT_FOCUS)
86             {
87                 assign_default_focus = GX_FALSE;
88             }
89         }
90         else
91         {
92             /* make sure only one child has default focus flag */
93             child -> gx_widget_status &= ~GX_STATUS_DEFAULT_FOCUS;
94         }
95 
96         child -> gx_widget_nav_next = GX_NULL;
97         child -> gx_widget_nav_previous = GX_NULL;
98         child = child -> gx_widget_next;
99     }
100 
101     /* loop through child widgets looking for
102        the top-left child and assigning the navigation order
103        in left-to-right top-to-bottom order.
104      */
105 
106     do
107     {
108         child = widget -> gx_widget_first_child;
109         winner = GX_NULL;
110 
111         while (child)
112         {
113             if (child == last_stop || (child -> gx_widget_status & GX_STATUS_VISIBLE) == 0)
114             {
115                 child = child -> gx_widget_next;
116                 continue;
117             }
118 
119             if (!child -> gx_widget_nav_next)
120             {
121                 if ((child -> gx_widget_status & GX_STATUS_ACCEPTS_FOCUS) &&
122                     !(child -> gx_widget_status & GX_STATUS_NONCLIENT))
123                 {
124                     if (winner)
125                     {
126                         if (child -> gx_widget_size.gx_rectangle_top < winner -> gx_widget_size.gx_rectangle_top)
127                         {
128                             winner = child;
129                         }
130                         else
131                         {
132                             if (child -> gx_widget_size.gx_rectangle_top == winner -> gx_widget_size.gx_rectangle_top &&
133                                 child -> gx_widget_size.gx_rectangle_left < winner -> gx_widget_size.gx_rectangle_left)
134                             {
135                                 winner = child;
136                             }
137                         }
138                     }
139                     else
140                     {
141                         winner = child;
142                     }
143                 }
144             }
145 
146             child = child -> gx_widget_next;
147         }
148 
149         if (winner)
150         {
151             if (!first_stop)
152             {
153                 first_stop = winner;
154 
155                 if (assign_default_focus)
156                 {
157                     first_stop -> gx_widget_status |= GX_STATUS_DEFAULT_FOCUS;
158                 }
159             }
160 
161             if (last_stop)
162             {
163                 winner -> gx_widget_nav_previous = last_stop;
164                 last_stop -> gx_widget_nav_next = winner;
165             }
166             last_stop = winner;
167         }
168     } while (winner);
169 
170     /* loop the last in the order back to the first */
171     if (last_stop)
172     {
173         last_stop -> gx_widget_nav_next = first_stop;
174         first_stop -> gx_widget_nav_previous = last_stop;
175     }
176 }
177 
178