1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29 #include "pch.h"
30
31 #include "list.h"
32 #include "container.h"
33 #include "util.h"
34
35 #include "../common/context.h"
36 #include "../common/object.h"
37
38
39 using namespace winrt;
40 using namespace Microsoft::
UI::Xaml;
41 using namespace Microsoft::
UI::Xaml::Controls;
42 using namespace Windows::
UI::Xaml::Interop;
43 using namespace winrt::Windows::Foundation;
44 using namespace Microsoft::
UI::Xaml::Markup;
45 using namespace Microsoft::
UI::Xaml::Media;
46 using namespace winrt::Microsoft::
UI::Xaml::Controls::Primitives;
47
48
49 UIWIDGET ui_listview_create(UiObject* obj, UiListArgs args) {
50 UiObject* current = uic_current_obj(obj);
51
52
53 ListView listview = ListView();
54 if (args.multiselection) {
55 listview.SelectionMode(ListViewSelectionMode::Extended);
56 }
57
58 bool clickEnabled = listview.IsItemClickEnabled();
59 listview.IsItemClickEnabled(true);
60
61
62 UIElement elm = listview;
63 UiWidget* widget = new UiWidget(elm);
64 widget->data1 = args.model;
65 widget->data2 = args.getvalue;
66 ui_context_add_widget_destructor(current->ctx, widget);
67 ui_set_widget_groups(current->ctx, widget, args.groups);
68
69
70 UiVar* var = uic_widget_var(obj->ctx, current->ctx, args.list, args.varname,
UI_VAR_LIST);
71 if (var) {
72 UiList* list = (UiList*)var->value;
73 list->update = ui_simple_list_update;
74 list->getselection = ui_listview_getselection;
75 list->setselection = ui_listview_setselection;
76 list->obj = widget;
77
78 ui_simple_list_update(list,
0);
79 }
80
81 if (args.onselection) {
82 ui_callback onselection = args.onselection;
83 void* cbdata = args.onselectiondata;
84 listview.SelectionChanged([onselection, cbdata, obj](IInspectable
const& sender, RoutedEventArgs evtargs) {
85 std::vector<
int> selectedRows = ui_create_listview_selection(sender.as<ListView>());
86
87 UiListSelection selection;
88 selection.rows = selectedRows.data();
89 selection.count = selectedRows.size();
90
91 UiEvent evt;
92 evt.obj = obj;
93 evt.window = obj->window;
94 evt.document = obj->ctx->document;
95 evt.eventdata = &selection;
96 evt.intval =
0;
97 onselection(&evt, cbdata);
98 });
99 }
100 if (args.onactivate) {
101 ui_callback cb = args.onactivate;
102 void* cbdata = args.onactivatedata;
103 listview.ItemClick([cb, cbdata, obj](IInspectable
const& sender, RoutedEventArgs evtargs) {
104 std::vector<
int> selectedRows = ui_create_listview_selection(sender.as<ListView>());
105 UiListSelection selection;
106 selection.rows = selectedRows.data();
107 selection.count = selectedRows.size();
108
109 UiEvent evt;
110 evt.obj = obj;
111 evt.window = obj->window;
112 evt.document = obj->ctx->document;
113 evt.eventdata = &selection;
114 evt.intval =
0;
115 cb(&evt, cbdata);
116 });
117 }
118
119
120 UI_APPLY_LAYOUT1(current, args);
121
122 current->container->Add(listview, false);
123
124 return widget;
125 }
126
127
128 UIWIDGET ui_combobox_create(UiObject* obj, UiListArgs args) {
129 UiObject* current = uic_current_obj(obj);
130
131
132 ComboBox combobox = ComboBox();
133
134 UIElement elm = combobox;
135 UiWidget* widget = new UiWidget(elm);
136 widget->data1 = args.model;
137 widget->data2 = args.getvalue;
138 ui_context_add_widget_destructor(current->ctx, widget);
139 ui_set_widget_groups(current->ctx, widget, args.groups);
140
141
142 UiVar* var = uic_widget_var(obj->ctx, current->ctx, args.list, args.varname,
UI_VAR_LIST);
143 if (var) {
144 UiList* list = (UiList*)var->value;
145 list->update = ui_simple_list_update;
146 list->getselection = ui_dropdown_getselection;
147 list->setselection = ui_dropdown_setselection;
148 list->obj = widget;
149 ui_simple_list_update(list,
0);
150 }
151
152 if (args.onactivate) {
153 ui_callback cb = args.onactivate;
154 void* cbdata = args.onactivatedata;
155 combobox.SelectionChanged([cb, cbdata, obj](IInspectable
const& sender, RoutedEventArgs evtargs) {
156 int selectedrow = sender.as<ComboBox>().SelectedIndex();
157 UiListSelection selection;
158 selection.count =
1;
159 selection.rows = &selectedrow;
160
161 UiEvent evt;
162 evt.obj = obj;
163 evt.window = obj->window;
164 evt.document = obj->ctx->document;
165 evt.eventdata = &selection;
166 evt.intval = selectedrow;
167 cb(&evt, cbdata);
168 });
169 }
170
171
172 UI_APPLY_LAYOUT1(current, args);
173
174 current->container->Add(combobox, false);
175
176 return widget;
177 }
178
179 UiListSelection ui_listview_getselection(UiList *list) {
180 UiWidget *widget = (UiWidget*)list->obj;
181 ListView listview = widget->uielement.as<ListView>();
182 std::vector<
int> selectedRows = ui_create_listview_selection(listview);
183
184 UiListSelection selection = {
NULL,
0 };
185 if (selectedRows.size() >
0) {
186 selection.count = selectedRows.size();
187 int *data = selectedRows.data();
188 selection.rows = (
int*)calloc(selection.count,
sizeof(
int));
189 memcpy(selection.rows, data, selection.count);
190 }
191
192 return selection;
193 }
194
195 void ui_listview_setselection(UiList *list, UiListSelection selection) {
196 UiWidget* widget = (UiWidget*)list->obj;
197 if (selection.count >
0) {
198 ListView listview = widget->uielement.as<ListView>();
199 listview.SelectedIndex(selection.rows[
0]);
200 }
201 }
202
203 UiListSelection ui_dropdown_getselection(UiList *list) {
204 UiWidget* widget = (UiWidget*)list->obj;
205 ComboBox cb = widget->uielement.as<ComboBox>();
206 int index = cb.SelectedIndex();
207 UiListSelection selection = {
NULL,
0 };
208 if (index >=
0) {
209 selection.rows = (
int*)calloc(
1,
sizeof(
int));
210 selection.count =
1;
211 selection.rows[
0] = index;
212 }
213 return selection;
214 }
215
216 void ui_dropdown_setselection(UiList *list, UiListSelection selection) {
217 UiWidget* widget = (UiWidget*)list->obj;
218 if (selection.count >
0) {
219 ComboBox cb = widget->uielement.as<ComboBox>();
220 cb.SelectedIndex(selection.rows[
0]);
221 }
222 }
223
224 UIEXPORT UIWIDGET ui_breadcrumbbar_create(UiObject* obj, UiListArgs args) {
225 UiObject* current = uic_current_obj(obj);
226
227
228 BreadcrumbBar bcbar = BreadcrumbBar();
229
230 UIElement elm = bcbar;
231 UiWidget* widget = new UiWidget(elm);
232 widget->data1 = args.model;
233 widget->data2 = args.getvalue;
234 ui_context_add_widget_destructor(current->ctx, widget);
235 ui_set_widget_groups(current->ctx, widget, args.groups);
236
237
238 UiVar* var = uic_widget_var(obj->ctx, current->ctx, args.list, args.varname,
UI_VAR_LIST);
239 if (var) {
240 UiList* list = (UiList*)var->value;
241 list->update = ui_breadcrumbbar_update;
242 list->obj = widget;
243 ui_breadcrumbbar_update(list,
0);
244 }
245
246 if (args.onactivate) {
247 ui_callback cb = args.onactivate;
248 void* cbdata = args.onactivatedata;
249 bcbar.ItemClicked([cb, cbdata, obj](IInspectable
const& sender, BreadcrumbBarItemClickedEventArgs evtargs) {
250 UiEvent evt;
251 evt.obj = obj;
252 evt.window = obj->window;
253 evt.document = obj->ctx->document;
254 evt.eventdata = nullptr;
255 evt.intval = evtargs.Index();
256 cb(&evt, cbdata);
257 });
258 }
259
260
261 UI_APPLY_LAYOUT1(current, args);
262
263 current->container->Add(bcbar, false);
264
265 return widget;
266 }
267
268 static void* getstrvalue(
void* elm,
int ignore) {
269 return elm;
270 }
271
272 void ui_simple_list_update(UiList* list,
int i) {
273 UiWidget* widget = (UiWidget*)list->obj;
274 UiModel* model = (UiModel*)widget->data1;
275 ui_getvaluefunc getvalue = (ui_getvaluefunc)widget->data2;
276 ItemsControl listview = widget->uielement.as<ItemsControl>();
277 auto items = listview.Items();
278
279
280 if (getvalue == nullptr) {
281 if (model && model->getvalue) {
282 getvalue = model->getvalue;
283 }
else {
284 getvalue = getstrvalue;
285 }
286 }
287
288
289 items.Clear();
290 void* elm = list->first(list);
291 while (elm) {
292 char* value = (
char*)getvalue(elm,
0);
293 wchar_t* wstr = str2wstr(value, nullptr);
294 items.Append(box_value(wstr));
295 free(wstr);
296
297 elm = list->next(list);
298 }
299 }
300
301 extern "C" void ui_breadcrumbbar_update(UiList * list,
int i) {
302 UiWidget* widget = (UiWidget*)list->obj;
303 UiModel* model = (UiModel*)widget->data1;
304 ui_getvaluefunc getvalue = (ui_getvaluefunc)widget->data2;
305
306
307 if (getvalue == nullptr) {
308 if (model && model->getvalue) {
309 getvalue = model->getvalue;
310 }
311 else {
312 getvalue = getstrvalue;
313 }
314 }
315
316 BreadcrumbBar bar = widget->uielement.as<BreadcrumbBar>();
317
318 Windows::Foundation::Collections::IVector<Windows::Foundation::IInspectable> items { winrt::single_threaded_vector<Windows::Foundation::IInspectable>() };
319 void* elm = list->first(list);
320 while (elm) {
321 char* value = (
char*)getvalue(elm,
0);
322 wchar_t* wstr = str2wstr(value, nullptr);
323 items.Append(box_value(wstr));
324 free(wstr);
325
326 elm = list->next(list);
327 }
328
329 bar.ItemsSource(items);
330 }
331
332
333 std::vector<
int> ui_create_listview_selection(ListView listview) {
334 std::vector<
int> selection;
335 int p =
0;
336 auto ranges = listview.SelectedRanges();
337 for (
auto range : ranges) {
338 int begin = range.FirstIndex();
339 int end = range.LastIndex();
340 for (
int i = begin; i <= end; i++) {
341 selection.push_back(i);
342 }
343 }
344 return selection;
345 }
346
347