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 /** Window Management (Window) */
18 /** */
19 /**************************************************************************/
20
21 #define GX_SOURCE_CODE
22
23
24 /* Include necessary system files. */
25
26 #include "gx_api.h"
27 #include "gx_widget.h"
28 #include "gx_window.h"
29 #include "gx_system.h"
30 #include "gx_utility.h"
31 #include "gx_scrollbar.h"
32
33 /**************************************************************************/
34 /* */
35 /* FUNCTION RELEASE */
36 /* */
37 /* _gx_horizontal_list_total_columns_set PORTABLE C */
38 /* 6.1.10 */
39 /* AUTHOR */
40 /* */
41 /* Kenneth Maxwell, Microsoft Corporation */
42 /* */
43 /* DESCRIPTION */
44 /* */
45 /* This function assigns the number of list columns */
46 /* */
47 /* INPUT */
48 /* */
49 /* vertical_list Vertical list widget control */
50 /* block */
51 /* */
52 /* OUTPUT */
53 /* */
54 /* None */
55 /* */
56 /* CALLS */
57 /* */
58 /* _gx_system_lock Obtain GUIX system lock */
59 /* _gx_system_unlock Release GUIX system lock */
60 /* _gx_first_client_child_get Get the first client child */
61 /* _gx_window_scrollbar_find Find the scrollbar */
62 /* _gx_scrollbar_reset Reset the schollbar */
63 /* _gx_system_dirty_mark Mark the widget dirty */
64 /* */
65 /* CALLED BY */
66 /* */
67 /* GUIX Internal Code */
68 /* */
69 /* RELEASE HISTORY */
70 /* */
71 /* DATE NAME DESCRIPTION */
72 /* */
73 /* 05-19-2020 Kenneth Maxwell Initial Version 6.0 */
74 /* 09-30-2020 Kenneth Maxwell Modified comment(s), */
75 /* resulting in version 6.1 */
76 /* 01-31-2022 Ting Zhu Modified comment(s), */
77 /* improved logic, */
78 /* resulting in version 6.1.10 */
79 /* */
80 /**************************************************************************/
_gx_horizontal_list_total_columns_set(GX_HORIZONTAL_LIST * list,INT count)81 UINT _gx_horizontal_list_total_columns_set(GX_HORIZONTAL_LIST *list, INT count)
82 {
83 INT page_index;
84 INT index;
85 GX_WIDGET *test;
86 GX_SCROLLBAR *pScroll;
87
88 _gx_system_lock();
89
90 /* Update total count of rows. */
91 list -> gx_horizontal_list_total_columns = count;
92
93 /* Update selected index. */
94 if (list -> gx_horizontal_list_selected < 0)
95 {
96 list -> gx_horizontal_list_selected = 0;
97 }
98
99 if (list -> gx_horizontal_list_selected > count - 1)
100 {
101 list -> gx_horizontal_list_selected = count - 1;
102 }
103
104 /* Calculate current page index. */
105 page_index = list -> gx_horizontal_list_top_index;
106
107 test = _gx_widget_first_client_child_get((GX_WIDGET *)list);
108
109 while (test && (test -> gx_widget_size.gx_rectangle_right <= list -> gx_widget_size.gx_rectangle_left))
110 {
111 page_index++;
112 test = _gx_widget_next_client_child_get(test);
113 }
114
115 /* Calculate new page index */
116 if (page_index + list -> gx_horizontal_list_visible_columns > count)
117 {
118 if (count > list -> gx_horizontal_list_visible_columns)
119 {
120 page_index = count - list -> gx_horizontal_list_visible_columns;
121 }
122 else
123 {
124 page_index = 0;
125 }
126 }
127
128 /* Add idle children back to horizontal list. */
129 if (list -> gx_horizontal_list_idle_child_list)
130 {
131 while (list -> gx_horizontal_list_idle_child_list)
132 {
133 test = list -> gx_horizontal_list_idle_child_list;
134 list -> gx_horizontal_list_idle_child_list = list -> gx_horizontal_list_idle_child_list -> gx_widget_next;
135
136 _gx_widget_attach((GX_WIDGET *)list, test);
137 list -> gx_horizontal_list_child_count++;
138 }
139 }
140
141 /* Check whether list child count is larger than count. */
142 while (list -> gx_horizontal_list_child_count > count)
143 {
144 test = _gx_widget_last_client_child_get((GX_WIDGET *)list);
145
146 if (test)
147 {
148 _gx_widget_detach(test);
149
150 /* Put detached widget to idle list. */
151 test -> gx_widget_next = list -> gx_horizontal_list_idle_child_list;
152 list -> gx_horizontal_list_idle_child_list = test;
153 list -> gx_horizontal_list_child_count--;
154 }
155 else
156 {
157 return GX_FAILURE;
158 }
159 }
160
161 list -> gx_horizontal_list_top_index = 0;
162 index = 0;
163 test = _gx_widget_first_client_child_get((GX_WIDGET *)list);
164
165 while (test)
166 {
167 list -> gx_horizontal_list_callback(list, test, index++);
168
169 test = _gx_widget_next_client_child_get(test);
170 }
171
172 /* Reposition child widgets. */
173 _gx_horizontal_list_children_position(list);
174
175
176 /* Make new page index visible */
177 _gx_horizontal_list_page_index_set(list, page_index);
178
179 _gx_window_scrollbar_find((GX_WINDOW *)list, GX_TYPE_HORIZONTAL_SCROLL, &pScroll);
180
181 if (pScroll)
182 {
183 _gx_scrollbar_reset(pScroll, GX_NULL);
184 }
185
186 _gx_system_unlock();
187
188 /* Refresh screen. */
189 if (list -> gx_widget_status & GX_STATUS_VISIBLE)
190 {
191 _gx_system_dirty_mark((GX_WIDGET *)list);
192 }
193 return GX_SUCCESS;
194 }
195
196