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_utility.h"
32 #include "gx_scrollbar.h"
33
34 /**************************************************************************/
35 /* */
36 /* FUNCTION RELEASE */
37 /* */
38 /* _gx_vertical_list_total_rows_set PORTABLE C */
39 /* 6.1.10 */
40 /* AUTHOR */
41 /* */
42 /* Kenneth Maxwell, Microsoft Corporation */
43 /* */
44 /* DESCRIPTION */
45 /* */
46 /* This function assigns total number of list rows. */
47 /* */
48 /* INPUT */
49 /* */
50 /* vertical_list Vertical list control block */
51 /* count Number of rows */
52 /* */
53 /* OUTPUT */
54 /* */
55 /* status Completion status */
56 /* */
57 /* CALLS */
58 /* */
59 /* _gx_system_lock Obtain GUIX system lock */
60 /* _gx_system_unlock Release GUIX system lock */
61 /* _gx_first_client_child_get Get the first client child */
62 /* [gx_vertical_list_callback] Vertical list callback */
63 /* _gx_window_scrollbar_find Find the scrollbar */
64 /* _gx_scrollbar_reset Reset the schollbar */
65 /* _gx_system_dirty_mark Mark the widget dirty */
66 /* */
67 /* CALLED BY */
68 /* */
69 /* GUIX Internal Code */
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 /* 01-31-2022 Ting Zhu Modified comment(s), */
79 /* improved logic, */
80 /* resulting in version 6.1.10 */
81 /* */
82 /**************************************************************************/
_gx_vertical_list_total_rows_set(GX_VERTICAL_LIST * list,INT count)83 UINT _gx_vertical_list_total_rows_set(GX_VERTICAL_LIST *list, INT count)
84 {
85 INT page_index;
86 INT index;
87 GX_WIDGET *test;
88 GX_SCROLLBAR *pScroll;
89
90 _gx_system_lock();
91
92 /* Update total count of rows. */
93 list -> gx_vertical_list_total_rows = count;
94
95 /* Update selected index. */
96 if (list -> gx_vertical_list_selected < 0)
97 {
98 list -> gx_vertical_list_selected = 0;
99 }
100
101 if (list -> gx_vertical_list_selected > count - 1)
102 {
103 list -> gx_vertical_list_selected = count - 1;
104 }
105
106 /* Calculate current page index. */
107 page_index = list -> gx_vertical_list_top_index;
108
109 test = _gx_widget_first_client_child_get((GX_WIDGET *)list);
110
111 while (test && (test -> gx_widget_size.gx_rectangle_bottom <= list -> gx_widget_size.gx_rectangle_top))
112 {
113 page_index++;
114 test = _gx_widget_next_client_child_get(test);
115 }
116
117 /* Calculate new page index */
118 if (page_index + list -> gx_vertical_list_visible_rows > count)
119 {
120 if (count > list -> gx_vertical_list_visible_rows)
121 {
122 page_index = count - list -> gx_vertical_list_visible_rows;
123 }
124 else
125 {
126 page_index = 0;
127 }
128 }
129
130 /* Add idle children back to vertical list. */
131 if (list -> gx_vertical_list_idle_child_list)
132 {
133 while (list -> gx_vertical_list_idle_child_list)
134 {
135 test = list -> gx_vertical_list_idle_child_list;
136 list -> gx_vertical_list_idle_child_list = list -> gx_vertical_list_idle_child_list -> gx_widget_next;
137
138 _gx_widget_attach((GX_WIDGET *)list, test);
139 list -> gx_vertical_list_child_count++;
140 }
141 }
142
143 /* Check whether list child count is larger than count. */
144 while (list -> gx_vertical_list_child_count > count)
145 {
146 test = _gx_widget_last_client_child_get((GX_WIDGET *)list);
147
148 if (test)
149 {
150 _gx_widget_detach(test);
151
152 /* Put detached widget to idle list. */
153 test -> gx_widget_next = list -> gx_vertical_list_idle_child_list;
154 list -> gx_vertical_list_idle_child_list = test;
155 list -> gx_vertical_list_child_count--;
156 }
157 else
158 {
159 return GX_FAILURE;
160 }
161 }
162
163 list -> gx_vertical_list_top_index = 0;
164 index = 0;
165 test = _gx_widget_first_client_child_get((GX_WIDGET *)list);
166
167 while (test)
168 {
169 list -> gx_vertical_list_callback(list, test, index++);
170
171 test = _gx_widget_next_client_child_get(test);
172 }
173
174 /* Reposition child widgets. */
175 _gx_vertical_list_children_position(list);
176
177 /* Make new page index visible */
178 _gx_vertical_list_page_index_set(list, page_index);
179
180 _gx_window_scrollbar_find((GX_WINDOW *)list, GX_TYPE_VERTICAL_SCROLL, &pScroll);
181
182 if (pScroll)
183 {
184 _gx_scrollbar_reset(pScroll, GX_NULL);
185 }
186
187 _gx_system_unlock();
188
189 /* Refresh screen. */
190 if (list -> gx_widget_status & GX_STATUS_VISIBLE)
191 {
192 _gx_system_dirty_mark((GX_WIDGET *)list);
193 }
194 return GX_SUCCESS;
195 }
196
197