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