| 59 |
60 |
| 60 if(args->multiselection) { |
61 if(args->multiselection) { |
| 61 XtSetArg(xargs[n], XmNselectionPolicy, XmEXTENDED_SELECT); n++; |
62 XtSetArg(xargs[n], XmNselectionPolicy, XmEXTENDED_SELECT); n++; |
| 62 } else { |
63 } else { |
| 63 XtSetArg(xargs[n], XmNselectionPolicy, XmSINGLE_SELECT); n++; |
64 XtSetArg(xargs[n], XmNselectionPolicy, XmSINGLE_SELECT); n++; |
| |
65 } |
| |
66 if(args->height > 0) { |
| |
67 XtSetArg(xargs[n], XmNheight, args->height); n++; |
| 64 } |
68 } |
| 65 |
69 |
| 66 char *name = args->name ? (char*)args->name : "listview"; |
70 char *name = args->name ? (char*)args->name : "listview"; |
| 67 Widget parent = ui_container_prepare(ctn, &layout, xargs, &n); |
71 Widget parent = ui_container_prepare(ctn, &layout, xargs, &n); |
| 68 Widget widget = XmCreateScrolledList(parent, name, xargs, n); |
72 Widget widget = XmCreateScrolledList(parent, name, xargs, n); |
| 89 listview->onactivate = args->onactivate; |
93 listview->onactivate = args->onactivate; |
| 90 listview->onactivatedata = args->onactivatedata; |
94 listview->onactivatedata = args->onactivatedata; |
| 91 listview->onselection = args->onselection; |
95 listview->onselection = args->onselection; |
| 92 listview->onselectiondata = args->onselectiondata; |
96 listview->onselectiondata = args->onselectiondata; |
| 93 |
97 |
| |
98 char **static_elements = args->static_elements; |
| |
99 size_t static_nelm = args->static_nelm; |
| 94 if(var) { |
100 if(var) { |
| 95 UiList *list = var->value; |
101 UiList *list = var->value; |
| 96 list->obj = listview; |
102 list->obj = listview; |
| 97 list->update = ui_listview_update; |
103 list->update = ui_listview_update; |
| 98 list->getselection = ui_listview_getselection; |
104 list->getselection = ui_listview_getselection; |
| 99 list->setselection = ui_listview_setselection; |
105 list->setselection = ui_listview_setselection; |
| 100 ui_listview_update(list, 0); |
106 ui_listview_update(list, 0); |
| |
107 } else if(static_elements && static_nelm > 0) { |
| |
108 XmStringTable items = calloc(static_nelm, sizeof(XmString)); |
| |
109 for(int i=0;i<static_nelm;i++) { |
| |
110 items[i] = XmStringCreateLocalized(static_elements[i]); |
| |
111 } |
| |
112 XtVaSetValues( |
| |
113 listview->widget, |
| |
114 XmNitems, items, |
| |
115 XmNitemCount, |
| |
116 static_nelm, |
| |
117 NULL); |
| |
118 for (int i=0;i<static_nelm;i++) { |
| |
119 XmStringFree(items[i]); |
| |
120 } |
| |
121 free(items); |
| |
122 listview->getvalue = getvalue_wrapper; |
| |
123 listview->getvaluedata = ui_strmodel_getvalue; |
| 101 } |
124 } |
| 102 |
125 |
| 103 XtAddCallback( |
126 XtAddCallback( |
| 104 widget, |
127 widget, |
| 105 XmNdestroyCallback, |
128 XmNdestroyCallback, |
| 112 (XtCallbackProc)ui_listview_activate, |
135 (XtCallbackProc)ui_listview_activate, |
| 113 listview); |
136 listview); |
| 114 XtAddCallback( |
137 XtAddCallback( |
| 115 widget, |
138 widget, |
| 116 XmNextendedSelectionCallback, |
139 XmNextendedSelectionCallback, |
| 117 (XtCallbackProc)ui_listview_selection, |
140 (XtCallbackProc)ui_listview_selection_changed, |
| 118 listview); |
141 listview); |
| 119 XtAddCallback( |
142 XtAddCallback( |
| 120 widget, |
143 widget, |
| 121 XmNsingleSelectionCallback, |
144 XmNsingleSelectionCallback, |
| 122 (XtCallbackProc)ui_listview_selection, |
145 (XtCallbackProc)ui_listview_selection_changed, |
| 123 listview); |
146 listview); |
| 124 |
147 |
| 125 return widget; |
148 return widget; |
| 126 } |
149 } |
| 127 |
150 |
| |
151 void ui_listview_select(UIWIDGET listview, int index) { |
| |
152 XmListDeselectAllItems(listview); |
| |
153 XmListSelectPos(listview, index+1, False); |
| |
154 } |
| |
155 |
| |
156 int ui_listview_selection(UIWIDGET listview) { |
| |
157 int *selpositions = NULL; |
| |
158 int numpos = 0; |
| |
159 XtVaGetValues(listview, XmNselectedPositions, &selpositions, XmNselectedPositionCount, &numpos, NULL); |
| |
160 return numpos > 0 ? selpositions[0] : -1; |
| |
161 } |
| |
162 |
| 128 void ui_listview_destroy(Widget w, UiListView *listview, XtPointer d) { |
163 void ui_listview_destroy(Widget w, UiListView *listview, XtPointer d) { |
| 129 // TODO |
164 ui_listselection_free(listview->current_selection); |
| |
165 if(listview->model) { |
| |
166 ui_model_remove_observer(listview->model, listview); |
| |
167 ui_model_unref(listview->model); |
| |
168 } |
| |
169 free(listview); |
| 130 } |
170 } |
| 131 |
171 |
| 132 static void list_callback(UiObject *obj, UiListSelection sel, ui_callback callback, void *userdata) { |
172 static void list_callback(UiObject *obj, UiListSelection sel, ui_callback callback, void *userdata) { |
| 133 UiEvent event; |
173 UiEvent event; |
| 134 event.obj = obj; |
174 event.obj = obj; |
| 142 |
182 |
| 143 static void listview_save_selection(UiListView *listview, XmListCallbackStruct *cb) { |
183 static void listview_save_selection(UiListView *listview, XmListCallbackStruct *cb) { |
| 144 UiListSelection sel = { cb->selected_item_count, NULL }; |
184 UiListSelection sel = { cb->selected_item_count, NULL }; |
| 145 if(sel.count > 0) { |
185 if(sel.count > 0) { |
| 146 sel.rows = calloc(sel.count, sizeof(int)); |
186 sel.rows = calloc(sel.count, sizeof(int)); |
| 147 for(int i=0;i<sel.count;i++) { |
187 if(sel.count == 1) { |
| 148 sel.rows[i] = cb->selected_item_positions[i]-1; |
188 sel.rows[0] = cb->item_position-1; |
| |
189 } else if(cb->selected_item_positions) { |
| |
190 for(int i=0;i<sel.count;i++) { |
| |
191 sel.rows[i] = cb->selected_item_positions[i]-1; |
| |
192 } |
| 149 } |
193 } |
| 150 } |
194 } |
| 151 free(listview->current_selection.rows); |
195 free(listview->current_selection.rows); |
| 152 listview->current_selection = sel; |
196 listview->current_selection = sel; |
| 153 } |
197 } |
| 157 if(listview->onactivate) { |
201 if(listview->onactivate) { |
| 158 list_callback(listview->obj, listview->current_selection, listview->onactivate, listview->onactivatedata); |
202 list_callback(listview->obj, listview->current_selection, listview->onactivate, listview->onactivatedata); |
| 159 } |
203 } |
| 160 } |
204 } |
| 161 |
205 |
| 162 void ui_listview_selection(Widget w, UiListView *listview, XmListCallbackStruct *cb) { |
206 void ui_listview_selection_changed(Widget w, UiListView *listview, XmListCallbackStruct *cb) { |
| 163 listview_save_selection(listview, cb); |
207 listview_save_selection(listview, cb); |
| 164 if(listview->onselection) { |
208 if(listview->onselection) { |
| 165 list_callback(listview->obj, listview->current_selection, listview->onselection, listview->onselectiondata); |
209 list_callback(listview->obj, listview->current_selection, listview->onselection, listview->onselectiondata); |
| 166 } |
210 } |
| 167 } |
211 } |
| 207 XtFree((char *)items); |
251 XtFree((char *)items); |
| 208 } |
252 } |
| 209 |
253 |
| 210 UiListSelection ui_listview_getselection(UiList *list) { |
254 UiListSelection ui_listview_getselection(UiList *list) { |
| 211 UiListView *listview = list->obj; |
255 UiListView *listview = list->obj; |
| 212 UiListSelection sel = { listview->current_selection.count, NULL }; |
256 UiListSelection sel = { 0, NULL }; |
| 213 if(sel.count > 0) { |
257 int *selpositions = NULL; |
| 214 sel.rows = calloc(sel.count, sizeof(int)); |
258 int numpos = 0; |
| 215 memcpy(sel.rows, listview->current_selection.rows, sel.count*sizeof(int)); |
259 XtVaGetValues(listview->widget, XmNselectedPositions, &selpositions, XmNselectedPositionCount, &numpos, NULL); |
| |
260 if(numpos > 0) { |
| |
261 sel.rows = calloc(numpos, sizeof(int)); |
| |
262 sel.count = numpos; |
| |
263 memcpy(sel.rows, selpositions, numpos*sizeof(int)); |
| |
264 // motif selected positions start at index 1 -> translate positions |
| |
265 for(int i=0;i<numpos;i++) { |
| |
266 sel.rows[i]--; |
| |
267 } |
| 216 } |
268 } |
| 217 return sel; |
269 return sel; |
| 218 } |
270 } |
| 219 |
271 |
| 220 void ui_listview_setselection(UiList *list, UiListSelection selection) { |
272 void ui_listview_setselection(UiList *list, UiListSelection selection) { |
| 231 return column == 0 ? elm : NULL; |
283 return column == 0 ? elm : NULL; |
| 232 } |
284 } |
| 233 |
285 |
| 234 /* ------------------------------- Drop Down ------------------------------- */ |
286 /* ------------------------------- Drop Down ------------------------------- */ |
| 235 |
287 |
| 236 static void ui_dropdown_selection( |
288 static void ui_dropdown_selection_changed( |
| 237 Widget w, |
289 Widget w, |
| 238 UiListView *listview, |
290 UiListView *listview, |
| 239 XmComboBoxCallbackStruct *cb) |
291 XmComboBoxCallbackStruct *cb) |
| 240 { |
292 { |
| 241 int index = cb->item_position; |
293 int index = cb->item_position; |
| 293 listview->onactivate = args->onactivate; |
345 listview->onactivate = args->onactivate; |
| 294 listview->onactivatedata = args->onactivatedata; |
346 listview->onactivatedata = args->onactivatedata; |
| 295 listview->onselection = args->onselection; |
347 listview->onselection = args->onselection; |
| 296 listview->onselectiondata = args->onselectiondata; |
348 listview->onselectiondata = args->onselectiondata; |
| 297 |
349 |
| |
350 char **static_elements = args->static_elements; |
| |
351 size_t static_nelm = args->static_nelm; |
| 298 if(var) { |
352 if(var) { |
| 299 UiList *list = var->value; |
353 UiList *list = var->value; |
| 300 list->obj = listview; |
354 list->obj = listview; |
| 301 list->update = ui_listview_update; |
355 list->update = ui_listview_update; |
| 302 list->getselection = ui_listview_getselection; |
356 list->getselection = ui_dropdown_getselection; |
| 303 list->setselection = ui_listview_setselection; |
357 list->setselection = ui_dropdown_setselection; |
| 304 ui_listview_update(list, 0); |
358 ui_listview_update(list, 0); |
| |
359 } else if(static_elements && static_nelm > 0) { |
| |
360 XmStringTable items = calloc(static_nelm, sizeof(XmString)); |
| |
361 for(int i=0;i<static_nelm;i++) { |
| |
362 items[i] = XmStringCreateLocalized(static_elements[i]); |
| |
363 } |
| |
364 XtVaSetValues( |
| |
365 listview->widget, |
| |
366 XmNitems, items, |
| |
367 XmNitemCount, |
| |
368 static_nelm, |
| |
369 NULL); |
| |
370 for (int i=0;i<static_nelm;i++) { |
| |
371 XmStringFree(items[i]); |
| |
372 } |
| |
373 free(items); |
| |
374 listview->getvalue = getvalue_wrapper; |
| |
375 listview->getvaluedata = ui_strmodel_getvalue; |
| 305 } |
376 } |
| 306 |
377 |
| 307 XtAddCallback( |
378 XtAddCallback( |
| 308 widget, |
379 widget, |
| 309 XmNdestroyCallback, |
380 XmNdestroyCallback, |
| 310 (XtCallbackProc)ui_listview_destroy, |
381 (XtCallbackProc)ui_listview_destroy, |
| 311 listview); |
382 listview); |
| 312 XtAddCallback( |
383 XtAddCallback( |
| 313 widget, |
384 widget, |
| 314 XmNselectionCallback, |
385 XmNselectionCallback, |
| 315 (XtCallbackProc)ui_dropdown_selection, |
386 (XtCallbackProc)ui_dropdown_selection_changed, |
| 316 listview); |
387 listview); |
| 317 |
388 |
| 318 return widget; |
389 return widget; |
| 319 } |
390 } |
| |
391 |
| |
392 void ui_dropdown_setselection(UiList *list, UiListSelection selection) { |
| |
393 UiListView *listview = list->obj; |
| |
394 if(selection.count > 0) { |
| |
395 XtVaSetValues(listview->widget, XmNselectedPosition, selection.rows[0], NULL); |
| |
396 } else { |
| |
397 XtVaSetValues(listview->widget, XmNselectedPosition, 0, NULL); |
| |
398 } |
| |
399 } |
| |
400 |
| |
401 UiListSelection ui_dropdown_getselection(UiList *list) { |
| |
402 UiListView *listview = list->obj; |
| |
403 int pos = -1; |
| |
404 XtVaGetValues(listview->widget, XmNselectedPosition, &pos, NULL); |
| |
405 UiListSelection sel = { 0, NULL }; |
| |
406 if(pos >= 0) { |
| |
407 sel.rows = malloc(sizeof(int)); |
| |
408 sel.rows[0] = pos; |
| |
409 sel.count = 1; |
| |
410 } |
| |
411 return sel; |
| |
412 } |
| |
413 |
| |
414 void ui_dropdown_select(UIWIDGET dropdown, int index) { |
| |
415 XtVaSetValues(dropdown, XmNselectedPosition, index, NULL); |
| |
416 } |
| |
417 |
| |
418 int ui_dropdown_selection(UIWIDGET dropdown) { |
| |
419 int pos = -1; |
| |
420 XtVaGetValues(dropdown, XmNselectedPosition, &pos, NULL); |
| |
421 } |