| 50 |
55 |
| 51 static void* null_getvalue(UiList *list, void *elm, int row, int col, void *userdata, UiBool *freeResult) { |
56 static void* null_getvalue(UiList *list, void *elm, int row, int col, void *userdata, UiBool *freeResult) { |
| 52 return NULL; |
57 return NULL; |
| 53 } |
58 } |
| 54 |
59 |
| 55 |
60 /* |
| |
61 * Creates an UiListView widget object and initializes it from the UiListArgs |
| |
62 */ |
| 56 static UiListView* create_listview_widget(UiObject *obj, HWND hwnd, UiListArgs *args, UiBool table) { |
63 static UiListView* create_listview_widget(UiObject *obj, HWND hwnd, UiListArgs *args, UiBool table) { |
| 57 UiListView *listview = w32_widget_create(&listview_widget_class, hwnd, sizeof(UiListView)); |
64 UiListView *listview = w32_widget_create(&listview_widget_class, hwnd, sizeof(UiListView)); |
| 58 listview->widget.hwnd = hwnd; |
65 listview->widget.hwnd = hwnd; |
| 59 listview->preferred_width = args->width ? args->width : 300; |
66 listview->obj = obj; |
| |
67 listview->preferred_width = args->width ? args->width : 300; // 300: default width/height |
| 60 listview->preferred_height = args->height ? args->height : 300; |
68 listview->preferred_height = args->height ? args->height : 300; |
| 61 listview->onactivate = args->onactivate; |
69 listview->onactivate = args->onactivate; |
| 62 listview->onactivatedata = args->onactivatedata; |
70 listview->onactivatedata = args->onactivatedata; |
| 63 listview->onselection = args->onselection; |
71 listview->onselection = args->onselection; |
| 64 listview->onselectiondata = args->onselectiondata; |
72 listview->onselectiondata = args->onselectiondata; |
| 68 listview->ondragcompletedata = args->ondragcompletedata; |
76 listview->ondragcompletedata = args->ondragcompletedata; |
| 69 listview->ondrop = args->ondrop; |
77 listview->ondrop = args->ondrop; |
| 70 listview->ondropdata = args->ondropdata; |
78 listview->ondropdata = args->ondropdata; |
| 71 listview->istable = table; |
79 listview->istable = table; |
| 72 |
80 |
| |
81 // convert ui_getvaluefunc into ui_getvaluefunc2 if necessary |
| 73 ui_getvaluefunc2 getvalue = args->getvalue2; |
82 ui_getvaluefunc2 getvalue = args->getvalue2; |
| 74 void *getvaluedata = args->getvalue2data; |
83 void *getvaluedata = args->getvalue2data; |
| 75 if(!getvalue) { |
84 if(!getvalue) { |
| 76 if(args->getvalue) { |
85 if(args->getvalue) { |
| 77 getvalue = getvalue_wrapper; |
86 getvalue = getvalue_wrapper; |
| 103 parent, |
112 parent, |
| 104 (HMENU)1337, |
113 (HMENU)1337, |
| 105 hInstance, |
114 hInstance, |
| 106 NULL); |
115 NULL); |
| 107 ui_win32_set_ui_font(hwnd); |
116 ui_win32_set_ui_font(hwnd); |
| 108 |
|
| 109 ListView_SetExtendedListViewStyle( |
117 ListView_SetExtendedListViewStyle( |
| 110 hwnd, |
118 hwnd, |
| 111 LVS_EX_FULLROWSELECT //| LVS_EX_GRIDLINES |
119 LVS_EX_FULLROWSELECT //| LVS_EX_GRIDLINES |
| 112 ); |
120 ); |
| 113 |
121 |
| 114 UiListView *listview = create_listview_widget(obj, hwnd, args, table); |
122 UiListView *listview = create_listview_widget(obj, hwnd, args, table); |
| 115 ui_container_add(container, (W32Widget*)listview, &layout); |
123 ui_container_add(container, (W32Widget*)listview, &layout); |
| 116 |
124 |
| 117 // model |
125 // init list model |
| |
126 // always initialize listview->model |
| 118 int numcolumns = 0; |
127 int numcolumns = 0; |
| 119 if (table) { |
128 if (table) { |
| 120 if (args->model) { |
129 if (args->model) { |
| 121 listview->model = ui_model_copy(obj->ctx, args->model); |
130 listview->model = ui_model_copy(obj->ctx, args->model); |
| 122 numcolumns = listview->model->columns; |
131 numcolumns = listview->model->columns; |
| 128 ui_model_add_column(obj->ctx, model, UI_STRING, "Test", -1); |
137 ui_model_add_column(obj->ctx, model, UI_STRING, "Test", -1); |
| 129 listview->model = model; |
138 listview->model = model; |
| 130 numcolumns = 1; |
139 numcolumns = 1; |
| 131 } |
140 } |
| 132 |
141 |
| |
142 // create columns |
| 133 UiModel *model = listview->model; |
143 UiModel *model = listview->model; |
| 134 for (int i=0;i<numcolumns;i++) { |
144 for (int i=0;i<numcolumns;i++) { |
| 135 LVCOLUMN col; |
145 LVCOLUMN col; |
| 136 UiModelType type = model->types[i]; |
146 UiModelType type = model->types[i]; |
| 137 char *title = model->titles[i]; |
147 char *title = model->titles[i]; |
| 162 } |
173 } |
| 163 |
174 |
| 164 return (W32Widget*)listview; |
175 return (W32Widget*)listview; |
| 165 } |
176 } |
| 166 |
177 |
| |
178 static UiListSelection listview_get_selection(UiListView *listview) { |
| |
179 UiListSelection sel = { 0, NULL }; |
| |
180 HWND hwnd = listview->widget.hwnd; |
| |
181 |
| |
182 CX_ARRAY_DECLARE(int, indices); |
| |
183 cx_array_initialize(indices, 8); |
| |
184 |
| |
185 int index = -1; |
| |
186 while ((index = ListView_GetNextItem(hwnd, index, LVNI_SELECTED)) != -1) { |
| |
187 cx_array_simple_add(indices, index); |
| |
188 } |
| |
189 |
| |
190 if (indices_size > 0) { |
| |
191 sel.rows = indices; |
| |
192 sel.count = indices_size; |
| |
193 } |
| |
194 |
| |
195 return sel; |
| |
196 } |
| |
197 |
| |
198 // listview class event proc |
| 167 void ui_listview_eventproc(W32Widget *widget, HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) { |
199 void ui_listview_eventproc(W32Widget *widget, HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) { |
| 168 |
200 UiListView *listview = (UiListView*)widget; |
| |
201 switch (uMsg) { |
| |
202 case WM_NOTIFY: { |
| |
203 LPNMHDR hdr = (LPNMHDR)lParam; |
| |
204 switch (hdr->code) { |
| |
205 case LVN_ITEMCHANGED: { |
| |
206 LPNMLISTVIEW lv = (LPNMLISTVIEW)lParam; |
| |
207 int row = lv->iItem; |
| |
208 if ((lv->uChanged & LVIF_STATE) && (lv->uNewState & LVIS_SELECTED) && listview->onselection) { |
| |
209 UiListSelection sel = listview_get_selection(listview); |
| |
210 |
| |
211 UiEvent event; |
| |
212 event.obj = listview->obj; |
| |
213 event.window = listview->obj->window; |
| |
214 event.document = listview->obj->ctx->document; |
| |
215 event.eventdata = &sel; |
| |
216 event.eventdatatype = UI_EVENT_DATA_LIST_SELECTION; |
| |
217 event.intval = row; |
| |
218 event.set = ui_get_setop(); |
| |
219 listview->onselection(&event, listview->onselectiondata); |
| |
220 |
| |
221 ui_listselection_free(sel); |
| |
222 } |
| |
223 break; |
| |
224 } |
| |
225 case LVN_ITEMACTIVATE: { |
| |
226 LPNMLISTVIEW lv = (LPNMLISTVIEW)lParam; |
| |
227 int row = lv->iItem; |
| |
228 if (listview->onactivate) { |
| |
229 UiEvent event; |
| |
230 event.obj = listview->obj; |
| |
231 event.window = listview->obj->window; |
| |
232 event.document = listview->obj->ctx->document; |
| |
233 event.eventdata = NULL; |
| |
234 event.eventdatatype = UI_EVENT_DATA_LIST_ELM; |
| |
235 event.intval = row; |
| |
236 event.set = ui_get_setop(); |
| |
237 |
| |
238 if (listview->var) { |
| |
239 UiList *list = listview->var->value; |
| |
240 event.eventdata = list->get(list, row); |
| |
241 event.eventdatatype = UI_EVENT_DATA_LIST_ELM; |
| |
242 } |
| |
243 |
| |
244 listview->onactivate(&event, listview->onactivatedata); |
| |
245 } |
| |
246 break; |
| |
247 } |
| |
248 } |
| |
249 break; |
| |
250 } |
| |
251 } |
| 169 } |
252 } |
| 170 |
253 |
| 171 W32Size ui_listview_get_preferred_size(W32Widget *widget) { |
254 W32Size ui_listview_get_preferred_size(W32Widget *widget) { |
| 172 UiListView *listview = (UiListView*)widget; |
255 UiListView *listview = (UiListView*)widget; |
| 173 W32Size size; |
256 W32Size size; |
| 174 size.width = listview->preferred_width; |
257 size.width = listview->preferred_width; |
| 175 size.height = listview->preferred_height; |
258 size.height = listview->preferred_height; |
| 176 return size; |
259 return size; |
| 177 } |
260 } |
| 178 |
261 |
| |
262 /* |
| |
263 * Creates and inserts an LVITEM |
| |
264 * |
| |
265 * list: An UiList bound to an UiListView |
| |
266 * row: row index |
| |
267 * elm: list element (same as list->get(list, row)) |
| |
268 */ |
| 179 static void insert_item(UiList *list, int row, void *elm) { |
269 static void insert_item(UiList *list, int row, void *elm) { |
| 180 UiListView *listview = (UiListView*)list->obj; |
270 UiListView *listview = (UiListView*)list->obj; |
| 181 HWND hwnd = listview->widget.hwnd; |
271 HWND hwnd = listview->widget.hwnd; |
| 182 UiModel *model = listview->model; |
272 UiModel *model = listview->model; |
| 183 |
273 |
| 186 item.iItem = row; |
276 item.iItem = row; |
| 187 item.iSubItem = 0; |
277 item.iSubItem = 0; |
| 188 int idx = -1; |
278 int idx = -1; |
| 189 for (int col=0;col<model->columns;col++) { |
279 for (int col=0;col<model->columns;col++) { |
| 190 UiBool freeResult = FALSE; |
280 UiBool freeResult = FALSE; |
| |
281 // convert the list element to a value, that can be displayed in the list view |
| |
282 // TODO: handle all model types |
| 191 char *str = listview->getvalue(list, elm, row, col, listview->getvaluedata, &freeResult); |
283 char *str = listview->getvalue(list, elm, row, col, listview->getvaluedata, &freeResult); |
| 192 if (col == 0) { |
284 if (col == 0) { |
| 193 item.pszText = str; |
285 item.pszText = str; |
| 194 idx = ListView_InsertItem(hwnd, &item); |
286 idx = ListView_InsertItem(hwnd, &item); |
| 195 } else { |
287 } else { |
| 219 ListView_DeleteItem(hwnd, row); |
317 ListView_DeleteItem(hwnd, row); |
| 220 void *elm = list->get(list, row); |
318 void *elm = list->get(list, row); |
| 221 insert_item(list, row, elm); |
319 insert_item(list, row, elm); |
| 222 } |
320 } |
| 223 |
321 |
| |
322 // re-adjust all columns |
| 224 for (int i=0;i<model->columns;i++) { |
323 for (int i=0;i<model->columns;i++) { |
| 225 ListView_SetColumnWidth(hwnd, i, LVSCW_AUTOSIZE); |
324 ListView_SetColumnWidth(hwnd, i, LVSCW_AUTOSIZE); |
| 226 } |
325 } |
| 227 } |
326 } |
| 228 |
327 |
| 229 UiListSelection ui_listview_getselection(UiList *list) { |
328 UiListSelection ui_listview_getselection(UiList *list) { |
| 230 UiListSelection sel = { 0, NULL }; |
329 UiListView *listview = (UiListView*)list->obj; |
| 231 return sel; |
330 return listview_get_selection(listview); |
| 232 } |
331 } |
| 233 |
332 |
| 234 void ui_listview_setselection(UiList *list, UiListSelection selection) { |
333 void ui_listview_setselection(UiList *list, UiListSelection selection) { |
| 235 |
334 |
| 236 } |
335 } |
| 237 |
336 |
| |
337 // public API |
| 238 UIWIDGET ui_listview_create(UiObject *obj, UiListArgs *args) { |
338 UIWIDGET ui_listview_create(UiObject *obj, UiListArgs *args) { |
| 239 return listview_create(obj, args, FALSE); |
339 return listview_create(obj, args, FALSE); |
| 240 } |
340 } |
| 241 |
341 |
| |
342 // public API |
| 242 UIWIDGET ui_table_create(UiObject *obj, UiListArgs *args) { |
343 UIWIDGET ui_table_create(UiObject *obj, UiListArgs *args) { |
| 243 return listview_create(obj, args, TRUE); |
344 return listview_create(obj, args, TRUE); |
| 244 } |
345 } |