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 /** Vertical List (List) */
19 /** */
20 /**************************************************************************/
21
22 #define GX_SOURCE_CODE
23
24
25 /* Include necessary system files. */
26
27 #include "gx_api.h"
28 #include "gx_widget.h"
29 #include "gx_window.h"
30 #include "gx_system.h"
31 #include "gx_scrollbar.h"
32
33 /**************************************************************************/
34 /* */
35 /* FUNCTION RELEASE */
36 /* */
37 /* _gx_vertical_list_selected_set PORTABLE C */
38 /* 6.1.12 */
39 /* AUTHOR */
40 /* */
41 /* Kenneth Maxwell, Microsoft Corporation */
42 /* */
43 /* DESCRIPTION */
44 /* */
45 /* This service sets the list entry at the current list index. */
46 /* */
47 /* INPUT */
48 /* */
49 /* vertical_list Vertical list widget control */
50 /* block */
51 /* index Index based position of new */
52 /* list entry */
53 /* */
54 /* OUTPUT */
55 /* */
56 /* status Completion status */
57 /* */
58 /* CALLS */
59 /* */
60 /* _gx_widget_first_client_child_get */
61 /* _gx_widget_next_client_child_get */
62 /* _gx_vertical_list_page_index_set */
63 /* _gx_widget_event_generate */
64 /* _gx_system_dirty_mark */
65 /* */
66 /* CALLED BY */
67 /* */
68 /* Application Code */
69 /* _gx_drop_list_event_process Process drop list event */
70 /* */
71 /* RELEASE HISTORY */
72 /* */
73 /* DATE NAME DESCRIPTION */
74 /* */
75 /* 05-19-2020 Kenneth Maxwell Initial Version 6.0 */
76 /* 09-30-2020 Kenneth Maxwell Modified comment(s), */
77 /* resulting in version 6.1 */
78 /* 07-29-2022 Kenneth Maxwell Added support for GX_STYLE_ */
79 /* REPEAT_SELECT, */
80 /* resulting in version 6.1.12 */
81 /* */
82 /**************************************************************************/
_gx_vertical_list_selected_set(GX_VERTICAL_LIST * vertical_list,INT index)83 UINT _gx_vertical_list_selected_set(GX_VERTICAL_LIST *vertical_list, INT index)
84 {
85 GX_WIDGET *child;
86 GX_WIDGET *found = GX_NULL;
87 INT page_index = vertical_list -> gx_vertical_list_top_index;
88 INT top_index;
89 INT bottom_index;
90
91 if (vertical_list -> gx_vertical_list_selected == index)
92 {
93 if ((vertical_list -> gx_widget_style & GX_STYLE_REPEAT_SELECT) == 0)
94 {
95 return GX_SUCCESS;
96 }
97 }
98
99 if (index < 0)
100 {
101 _gx_vertical_list_selected_widget_get(vertical_list, &child);
102
103 if (child)
104 {
105 child -> gx_widget_style &= ~GX_STYLE_DRAW_SELECTED;
106 _gx_system_dirty_mark(child);
107 }
108 vertical_list -> gx_vertical_list_selected = index;
109 return GX_SUCCESS;
110 }
111
112 child = _gx_widget_first_client_child_get((GX_WIDGET *)vertical_list);
113
114 while (child && (child -> gx_widget_size.gx_rectangle_bottom <= vertical_list -> gx_widget_size.gx_rectangle_top))
115 {
116 page_index++;
117 child = _gx_widget_next_client_child_get(child);
118 }
119
120 top_index = vertical_list -> gx_vertical_list_top_index;
121 bottom_index = top_index + vertical_list -> gx_vertical_list_child_count - 1;
122
123 /* Reset page index when needed and calculate the child count from the top index to new index. */
124 if (bottom_index >= vertical_list -> gx_vertical_list_total_rows)
125 {
126 bottom_index -= vertical_list -> gx_vertical_list_total_rows;
127
128 if (index >= top_index)
129 {
130 page_index = index - vertical_list -> gx_vertical_list_top_index;
131 }
132 else if (index <= bottom_index)
133 {
134 page_index = vertical_list -> gx_vertical_list_total_rows + index - vertical_list -> gx_vertical_list_top_index;
135 }
136 else
137 {
138 _gx_vertical_list_page_index_set(vertical_list, index);
139 page_index = index - vertical_list -> gx_vertical_list_top_index;
140 }
141 }
142 else
143 {
144 if (index < top_index)
145 {
146 _gx_vertical_list_page_index_set(vertical_list, index);
147 }
148 else if (index > bottom_index)
149 {
150 _gx_vertical_list_page_index_set(vertical_list, index - vertical_list -> gx_vertical_list_visible_rows + 1);
151 }
152
153 page_index = index - vertical_list -> gx_vertical_list_top_index;
154 }
155
156 if (page_index < 0)
157 {
158 /* consider the situation that top index is bigger than current select index. */
159 page_index += vertical_list -> gx_vertical_list_total_rows;
160 }
161
162 child = _gx_widget_first_client_child_get((GX_WIDGET *)vertical_list);
163
164 /* Select new index and update widget draw style. */
165 while (child)
166 {
167 if (page_index == 0)
168 {
169 found = child;
170 vertical_list -> gx_vertical_list_selected = index;
171 _gx_vertical_list_selected_visible(vertical_list, found);
172 found -> gx_widget_style |= GX_STYLE_DRAW_SELECTED;
173 _gx_system_dirty_mark(found);
174
175 if (vertical_list -> gx_widget_id)
176 {
177 _gx_widget_event_generate((GX_WIDGET *)vertical_list, GX_EVENT_LIST_SELECT, vertical_list -> gx_vertical_list_selected);
178 }
179 }
180 else
181 {
182 if (child -> gx_widget_style & GX_STYLE_DRAW_SELECTED)
183 {
184 child -> gx_widget_style &= ~GX_STYLE_DRAW_SELECTED;
185 _gx_system_dirty_mark(child);
186 }
187 }
188 child = _gx_widget_next_client_child_get(child);
189 page_index--;
190 }
191
192 if (found)
193 {
194 return GX_SUCCESS;
195 }
196 return GX_FAILURE;
197 }
198
199