| 511 GTK_SCROLLED_WINDOW(scroll_area), |
519 GTK_SCROLLED_WINDOW(scroll_area), |
| 512 GTK_POLICY_AUTOMATIC, |
520 GTK_POLICY_AUTOMATIC, |
| 513 GTK_POLICY_AUTOMATIC); // GTK_POLICY_ALWAYS |
521 GTK_POLICY_AUTOMATIC); // GTK_POLICY_ALWAYS |
| 514 SCROLLEDWINDOW_SET_CHILD(scroll_area, view); |
522 SCROLLEDWINDOW_SET_CHILD(scroll_area, view); |
| 515 |
523 |
| 516 UI_APPLY_LAYOUT2(current, args); |
524 if(args->width > 0 || args->height > 0) { |
| 517 current->container->add(current->container, scroll_area); |
525 int width = args->width; |
| 518 |
526 int height = args->height; |
| 519 // ct->current should point to view, not scroll_area, to make it possible |
527 if(width == 0) { |
| 520 // to add a context menu |
528 width = -1; |
| 521 current->container->current = view; |
529 } |
| |
530 if(height == 0) { |
| |
531 height = -1; |
| |
532 } |
| |
533 gtk_widget_set_size_request(scroll_area, width, height); |
| |
534 } |
| |
535 |
| |
536 UiContainerPrivate *ct = (UiContainerPrivate*)obj->container_end; |
| |
537 UiLayout layout = UI_ARGS2LAYOUT(args); |
| |
538 ct->add(ct, scroll_area, &layout); |
| 522 |
539 |
| 523 return scroll_area; |
540 return scroll_area; |
| 524 } |
541 } |
| 525 |
542 |
| 526 UIWIDGET ui_combobox_create(UiObject *obj, UiListArgs *args) { |
543 UIWIDGET ui_combobox_create(UiObject *obj, UiListArgs *args) { |
| 527 UiObject* current = uic_current_obj(obj); |
|
| 528 |
|
| 529 // to simplify things and share code with ui_tableview_create, we also |
544 // to simplify things and share code with ui_tableview_create, we also |
| 530 // use a UiModel for the listview |
545 // use a UiModel for the listview |
| 531 UiModel *model = ui_model(obj->ctx, UI_STRING, "", -1); |
546 UiModel *model = ui_model(obj->ctx, UI_STRING, "", -1); |
| 532 args->model = model; |
547 args->model = model; |
| 533 |
548 |
| 551 g_signal_connect(factory, "setup", G_CALLBACK(column_factory_setup), listview->columns); |
566 g_signal_connect(factory, "setup", G_CALLBACK(column_factory_setup), listview->columns); |
| 552 g_signal_connect(factory, "bind", G_CALLBACK(column_factory_bind), listview->columns); |
567 g_signal_connect(factory, "bind", G_CALLBACK(column_factory_bind), listview->columns); |
| 553 |
568 |
| 554 GtkWidget *view = gtk_drop_down_new(G_LIST_MODEL(ls), NULL); |
569 GtkWidget *view = gtk_drop_down_new(G_LIST_MODEL(ls), NULL); |
| 555 gtk_drop_down_set_factory(GTK_DROP_DOWN(view), factory); |
570 gtk_drop_down_set_factory(GTK_DROP_DOWN(view), factory); |
| 556 |
571 if(args->width > 0) { |
| 557 UiVar* var = uic_widget_var(obj->ctx, current->ctx, args->list, args->varname, UI_VAR_LIST); |
572 gtk_widget_set_size_request(view, args->width, -1); |
| |
573 } |
| |
574 |
| |
575 UiVar* var = uic_widget_var(obj->ctx, obj->ctx, args->list, args->varname, UI_VAR_LIST); |
| 558 |
576 |
| 559 // init listview |
577 // init listview |
| 560 listview->widget = view; |
578 listview->widget = view; |
| 561 listview->var = var; |
579 listview->var = var; |
| 562 listview->liststore = ls; |
580 listview->liststore = ls; |
| 602 void ui_combobox_select(UIWIDGET dropdown, int index) { |
622 void ui_combobox_select(UIWIDGET dropdown, int index) { |
| 603 gtk_drop_down_set_selected(GTK_DROP_DOWN(dropdown), index); |
623 gtk_drop_down_set_selected(GTK_DROP_DOWN(dropdown), index); |
| 604 } |
624 } |
| 605 |
625 |
| 606 UIWIDGET ui_table_create(UiObject *obj, UiListArgs *args) { |
626 UIWIDGET ui_table_create(UiObject *obj, UiListArgs *args) { |
| 607 UiObject* current = uic_current_obj(obj); |
|
| 608 |
|
| 609 GListStore *ls = g_list_store_new(G_TYPE_OBJECT); |
627 GListStore *ls = g_list_store_new(G_TYPE_OBJECT); |
| 610 //g_list_store_append(ls, v1); |
628 //g_list_store_append(ls, v1); |
| 611 |
629 |
| 612 // create obj to store all relevant data we need for handling events |
630 // create obj to store all relevant data we need for handling events |
| 613 // and list updates |
631 // and list updates |
| 614 UiListView *tableview = create_listview(obj, args); |
632 UiListView *tableview = create_listview(obj, args); |
| 615 |
633 |
| 616 GtkSelectionModel *selection_model = create_selection_model(tableview, ls, args->multiselection); |
634 GtkSelectionModel *selection_model = create_selection_model(tableview, ls, args->multiselection); |
| 617 GtkWidget *view = gtk_column_view_new(GTK_SELECTION_MODEL(selection_model)); |
635 GtkWidget *view = gtk_column_view_new(GTK_SELECTION_MODEL(selection_model)); |
| 618 |
636 |
| 619 UiVar* var = uic_widget_var(obj->ctx, current->ctx, args->list, args->varname, UI_VAR_LIST); |
637 UiVar* var = uic_widget_var(obj->ctx, obj->ctx, args->list, args->varname, UI_VAR_LIST); |
| 620 |
638 |
| 621 // init tableview |
639 // init tableview |
| 622 tableview->widget = view; |
640 tableview->widget = view; |
| 623 tableview->var = var; |
641 tableview->var = var; |
| 624 tableview->liststore = ls; |
642 tableview->liststore = ls; |
| 695 GTK_SCROLLED_WINDOW(scroll_area), |
713 GTK_SCROLLED_WINDOW(scroll_area), |
| 696 GTK_POLICY_AUTOMATIC, |
714 GTK_POLICY_AUTOMATIC, |
| 697 GTK_POLICY_AUTOMATIC); // GTK_POLICY_ALWAYS |
715 GTK_POLICY_AUTOMATIC); // GTK_POLICY_ALWAYS |
| 698 SCROLLEDWINDOW_SET_CHILD(scroll_area, view); |
716 SCROLLEDWINDOW_SET_CHILD(scroll_area, view); |
| 699 |
717 |
| 700 UI_APPLY_LAYOUT2(current, args); |
718 if(args->width > 0 || args->height > 0) { |
| 701 current->container->add(current->container, scroll_area); |
719 int width = args->width; |
| 702 |
720 int height = args->height; |
| 703 // ct->current should point to view, not scroll_area, to make it possible |
721 if(width == 0) { |
| 704 // to add a context menu |
722 width = -1; |
| 705 current->container->current = view; |
723 } |
| |
724 if(height == 0) { |
| |
725 height = -1; |
| |
726 } |
| |
727 gtk_widget_set_size_request(scroll_area, width, height); |
| |
728 } |
| |
729 |
| |
730 UiContainerPrivate *ct = (UiContainerPrivate*)obj->container_end; |
| |
731 UiLayout layout = UI_ARGS2LAYOUT(args); |
| |
732 ct->add(ct, scroll_area, &layout); |
| 706 |
733 |
| 707 return scroll_area; |
734 return scroll_area; |
| 708 } |
735 } |
| 709 |
736 |
| 710 static UiListSelection selectionmodel_get_selection(GtkSelectionModel *model) { |
737 static UiListSelection selectionmodel_get_selection(GtkSelectionModel *model) { |
| 1219 GTK_SCROLLED_WINDOW(scroll_area), |
1244 GTK_SCROLLED_WINDOW(scroll_area), |
| 1220 GTK_POLICY_AUTOMATIC, |
1245 GTK_POLICY_AUTOMATIC, |
| 1221 GTK_POLICY_AUTOMATIC); // GTK_POLICY_ALWAYS |
1246 GTK_POLICY_AUTOMATIC); // GTK_POLICY_ALWAYS |
| 1222 SCROLLEDWINDOW_SET_CHILD(scroll_area, view); |
1247 SCROLLEDWINDOW_SET_CHILD(scroll_area, view); |
| 1223 |
1248 |
| 1224 UI_APPLY_LAYOUT2(current, args); |
1249 if(args->width > 0 || args->height > 0) { |
| 1225 current->container->add(current->container, scroll_area); |
1250 int width = args->width; |
| 1226 |
1251 int height = args->height; |
| 1227 // ct->current should point to view, not scroll_area, to make it possible |
1252 if(width == 0) { |
| 1228 // to add a context menu |
1253 width = -1; |
| 1229 current->container->current = view; |
1254 } |
| |
1255 if(height == 0) { |
| |
1256 height = -1; |
| |
1257 } |
| |
1258 gtk_widget_set_size_request(scroll_area, width, height); |
| |
1259 } |
| |
1260 |
| |
1261 UiContainerPrivate *ct = (UiContainerPrivate*)obj->container_end; |
| |
1262 UiLayout layout = UI_ARGS2LAYOUT(args); |
| |
1263 ct->add(ct, scroll_area, &layout); |
| 1230 |
1264 |
| 1231 return scroll_area; |
1265 return scroll_area; |
| 1232 } |
1266 } |
| 1233 |
1267 |
| 1234 void ui_listview_select(UIWIDGET listview, int index) { |
1268 void ui_listview_select(UIWIDGET listview, int index) { |
| 1414 GTK_SCROLLED_WINDOW(scroll_area), |
1446 GTK_SCROLLED_WINDOW(scroll_area), |
| 1415 GTK_POLICY_AUTOMATIC, |
1447 GTK_POLICY_AUTOMATIC, |
| 1416 GTK_POLICY_AUTOMATIC); // GTK_POLICY_ALWAYS |
1448 GTK_POLICY_AUTOMATIC); // GTK_POLICY_ALWAYS |
| 1417 SCROLLEDWINDOW_SET_CHILD(scroll_area, view); |
1449 SCROLLEDWINDOW_SET_CHILD(scroll_area, view); |
| 1418 |
1450 |
| |
1451 if(args->width > 0 || args->height > 0) { |
| |
1452 int width = args->width; |
| |
1453 int height = args->height; |
| |
1454 if(width == 0) { |
| |
1455 width = -1; |
| |
1456 } |
| |
1457 if(height == 0) { |
| |
1458 height = -1; |
| |
1459 } |
| |
1460 gtk_widget_set_size_request(scroll_area, width, height); |
| |
1461 } |
| |
1462 |
| 1419 if(args->contextmenu) { |
1463 if(args->contextmenu) { |
| 1420 UIMENU menu = ui_contextmenu_create(args->contextmenu, obj, scroll_area); |
1464 UIMENU menu = ui_contextmenu_create(args->contextmenu, obj, scroll_area); |
| 1421 #if GTK_MAJOR_VERSION >= 4 |
1465 #if GTK_MAJOR_VERSION >= 4 |
| 1422 ui_widget_set_contextmenu(scroll_area, menu); |
1466 ui_widget_set_contextmenu(scroll_area, menu); |
| 1423 #else |
1467 #else |
| 1424 ui_widget_set_contextmenu(view, menu); |
1468 ui_widget_set_contextmenu(view, menu); |
| 1425 #endif |
1469 #endif |
| 1426 } |
1470 } |
| 1427 |
1471 |
| 1428 UI_APPLY_LAYOUT2(current, args); |
1472 UiContainerPrivate *ct = (UiContainerPrivate*)obj->container_end; |
| 1429 current->container->add(current->container, scroll_area); |
1473 UiLayout layout = UI_ARGS2LAYOUT(args); |
| 1430 |
1474 ct->add(ct, scroll_area, &layout); |
| 1431 // ct->current should point to view, not scroll_area, to make it possible |
|
| 1432 // to add a context menu |
|
| 1433 current->container->current = view; |
|
| 1434 |
1475 |
| 1435 return scroll_area; |
1476 return scroll_area; |
| 1436 } |
1477 } |
| 1437 |
1478 |
| 1438 |
1479 |
| 1474 |
1515 |
| 1475 |
1516 |
| 1476 /* --------------------------- ComboBox --------------------------- */ |
1517 /* --------------------------- ComboBox --------------------------- */ |
| 1477 |
1518 |
| 1478 UIWIDGET ui_combobox_create(UiObject *obj, UiListArgs *args) { |
1519 UIWIDGET ui_combobox_create(UiObject *obj, UiListArgs *args) { |
| 1479 UiObject* current = uic_current_obj(obj); |
|
| 1480 |
|
| 1481 GtkWidget *combobox = gtk_combo_box_new(); |
1520 GtkWidget *combobox = gtk_combo_box_new(); |
| |
1521 if(args->width > 0) { |
| |
1522 gtk_widget_set_size_request(combobox, args->width, -1); |
| |
1523 } |
| 1482 |
1524 |
| 1483 ui_set_name_and_style(combobox, args->name, args->style_class); |
1525 ui_set_name_and_style(combobox, args->name, args->style_class); |
| 1484 ui_set_widget_groups(obj->ctx, combobox, args->groups); |
1526 ui_set_widget_groups(obj->ctx, combobox, args->groups); |
| 1485 UI_APPLY_LAYOUT2(current, args); |
1527 UiContainerPrivate *ct = (UiContainerPrivate*)obj->container_end; |
| 1486 current->container->add(current->container, combobox); |
1528 UiLayout layout = UI_ARGS2LAYOUT(args); |
| 1487 current->container->current = combobox; |
1529 ct->add(ct, combobox, &layout); |
| 1488 |
1530 |
| 1489 UiListView *listview = create_listview(obj, args); |
1531 UiListView *listview = create_listview(obj, args); |
| 1490 listview->widget = combobox; |
1532 listview->widget = combobox; |
| 1491 listview->style_offset = 1; |
1533 listview->style_offset = 1; |
| 1492 listview->model = ui_model(obj->ctx, UI_STRING, "", -1); |
1534 listview->model = ui_model(obj->ctx, UI_STRING, "", -1); |
| 2128 GtkWidget *scroll_area = SCROLLEDWINDOW_NEW(); |
2180 GtkWidget *scroll_area = SCROLLEDWINDOW_NEW(); |
| 2129 SCROLLEDWINDOW_SET_CHILD(scroll_area, listbox); |
2181 SCROLLEDWINDOW_SET_CHILD(scroll_area, listbox); |
| 2130 |
2182 |
| 2131 ui_set_name_and_style(listbox, args->name, args->style_class); |
2183 ui_set_name_and_style(listbox, args->name, args->style_class); |
| 2132 ui_set_widget_groups(obj->ctx, listbox, args->groups); |
2184 ui_set_widget_groups(obj->ctx, listbox, args->groups); |
| 2133 UI_APPLY_LAYOUT2(current, args); |
2185 UiContainerPrivate *ct = (UiContainerPrivate*)obj->container_end; |
| 2134 current->container->add(current->container, scroll_area); |
2186 UiLayout layout = UI_ARGS2LAYOUT(args); |
| |
2187 ct->add(ct, scroll_area, &layout); |
| 2135 |
2188 |
| 2136 UiListBox *uilistbox = malloc(sizeof(UiListBox)); |
2189 UiListBox *uilistbox = malloc(sizeof(UiListBox)); |
| 2137 uilistbox->obj = obj; |
2190 uilistbox->obj = obj; |
| 2138 uilistbox->listbox = GTK_LIST_BOX(listbox); |
2191 uilistbox->listbox = GTK_LIST_BOX(listbox); |
| |
2192 uilistbox->header_is_item = args->header_is_item; |
| 2139 uilistbox->getvalue = args->getvalue; |
2193 uilistbox->getvalue = args->getvalue; |
| 2140 uilistbox->getvaluedata = args->getvaluedata; |
2194 uilistbox->getvaluedata = args->getvaluedata; |
| 2141 uilistbox->onactivate = args->onactivate; |
2195 uilistbox->onactivate = args->onactivate; |
| 2142 uilistbox->onactivatedata = args->onactivatedata; |
2196 uilistbox->onactivatedata = args->onactivatedata; |
| 2143 uilistbox->onbuttonclick = args->onbuttonclick; |
2197 uilistbox->onbuttonclick = args->onbuttonclick; |
| 2280 event.set = ui_get_setop(); |
2336 event.set = ui_get_setop(); |
| 2281 |
2337 |
| 2282 if(data->callback2) { |
2338 if(data->callback2) { |
| 2283 data->callback2(&event, data->userdata2); |
2339 data->callback2(&event, data->userdata2); |
| 2284 } |
2340 } |
| 2285 } |
2341 |
| |
2342 if(data->customdata3) { |
| |
2343 UIMENU menu = data->customdata3; |
| |
2344 g_object_set_data(G_OBJECT(button), "ui-button-popup", menu); |
| |
2345 gtk_popover_popup(GTK_POPOVER(menu)); |
| |
2346 } |
| |
2347 } |
| |
2348 |
| |
2349 #if GTK_CHECK_VERSION(3, 0, 0) |
| |
2350 static void button_popover_closed(GtkPopover *popover, GtkWidget *button) { |
| |
2351 g_object_set_data(G_OBJECT(button), "ui-button-popup", NULL); |
| |
2352 if(g_object_get_data(G_OBJECT(button), "ui-button-invisible")) { |
| |
2353 g_object_set_data(G_OBJECT(button), "ui-button-invisible", NULL); |
| |
2354 gtk_widget_set_visible(button, FALSE); |
| |
2355 } |
| |
2356 } |
| |
2357 #endif |
| 2286 |
2358 |
| 2287 static void listbox_fill_row(UiListBox *listbox, GtkWidget *row, UiListBoxSubList *sublist, UiSubListItem *item, int index) { |
2359 static void listbox_fill_row(UiListBox *listbox, GtkWidget *row, UiListBoxSubList *sublist, UiSubListItem *item, int index) { |
| |
2360 UiBool is_header = index < 0; |
| |
2361 |
| 2288 GtkWidget *hbox = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 10); |
2362 GtkWidget *hbox = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 10); |
| 2289 if(item->icon) { |
2363 if(item->icon) { |
| 2290 GtkWidget *icon = ICON_IMAGE(item->icon); |
2364 GtkWidget *icon = ICON_IMAGE(item->icon); |
| 2291 BOX_ADD(hbox, icon); |
2365 BOX_ADD(hbox, icon); |
| 2292 } |
2366 } |
| 2293 GtkWidget *label = gtk_label_new(item->label); |
2367 GtkWidget *label = gtk_label_new(item->label); |
| |
2368 if(is_header) { |
| |
2369 WIDGET_ADD_CSS_CLASS(label, "ui-listbox-header-row"); |
| |
2370 } |
| 2294 gtk_widget_set_halign(label, GTK_ALIGN_START); |
2371 gtk_widget_set_halign(label, GTK_ALIGN_START); |
| 2295 BOX_ADD_EXPAND(hbox, label); |
2372 BOX_ADD_EXPAND(hbox, label); |
| 2296 if(item->badge) { |
2373 if(item->badge) { |
| 2297 |
2374 |
| 2298 } |
2375 } |
| 2376 free(item.button_label); |
2468 free(item.button_label); |
| 2377 free(item.button_icon); |
2469 free(item.button_icon); |
| 2378 free(item.badge); |
2470 free(item.badge); |
| 2379 } |
2471 } |
| 2380 |
2472 |
| |
2473 static void listbox_row_on_enter(GtkWidget *row) { |
| |
2474 GtkWidget *button = g_object_get_data(G_OBJECT(row), "ui-listbox-row-button"); |
| |
2475 if(button) { |
| |
2476 gtk_widget_set_visible(button, TRUE); |
| |
2477 } |
| |
2478 } |
| |
2479 |
| |
2480 static void listbox_row_on_leave(GtkWidget *row) { |
| |
2481 GtkWidget *button = g_object_get_data(G_OBJECT(row), "ui-listbox-row-button"); |
| |
2482 if(button) { |
| |
2483 if(!g_object_get_data(G_OBJECT(button), "ui-button-popup")) { |
| |
2484 gtk_widget_set_visible(button, FALSE); |
| |
2485 } else { |
| |
2486 g_object_set_data(G_OBJECT(button), "ui-button-invisible", (void*)1); |
| |
2487 } |
| |
2488 } |
| |
2489 } |
| |
2490 |
| |
2491 #if GTK_CHECK_VERSION(4, 0, 0) |
| |
2492 static void listbox_row_enter( |
| |
2493 GtkEventControllerMotion* self, |
| |
2494 gdouble x, |
| |
2495 gdouble y, |
| |
2496 GtkWidget *row) |
| |
2497 { |
| |
2498 listbox_row_on_enter(row); |
| |
2499 } |
| |
2500 |
| |
2501 static void listbox_row_leave( |
| |
2502 GtkEventControllerMotion* self, |
| |
2503 GtkWidget *row) |
| |
2504 { |
| |
2505 listbox_row_on_leave(row); |
| |
2506 } |
| |
2507 #else |
| |
2508 static gboolean listbox_row_enter( |
| |
2509 GtkWidget *row, |
| |
2510 GdkEventCrossing event, |
| |
2511 gpointer user_data) |
| |
2512 { |
| |
2513 listbox_row_on_enter(row); |
| |
2514 return FALSE; |
| |
2515 } |
| |
2516 |
| |
2517 |
| |
2518 static gboolean listbox_row_leave( |
| |
2519 GtkWidget *row, |
| |
2520 GdkEventCrossing *event, |
| |
2521 gpointer user_data) |
| |
2522 { |
| |
2523 listbox_row_on_leave(row); |
| |
2524 return FALSE; |
| |
2525 } |
| |
2526 |
| |
2527 #endif |
| |
2528 |
| 2381 void ui_listbox_update_sublist(UiListBox *listbox, UiListBoxSubList *sublist, size_t listbox_insert_index) { |
2529 void ui_listbox_update_sublist(UiListBox *listbox, UiListBoxSubList *sublist, size_t listbox_insert_index) { |
| 2382 // clear sublist |
2530 // clear sublist |
| 2383 CxIterator r = cxListIterator(sublist->widgets); |
2531 CxIterator r = cxListIterator(sublist->widgets); |
| 2384 cx_foreach(GtkWidget*, widget, r) { |
2532 cx_foreach(GtkWidget*, widget, r) { |
| 2385 LISTBOX_REMOVE(listbox->listbox, widget); |
2533 LISTBOX_REMOVE(listbox->listbox, widget); |
| 2395 UiList *list = sublist->var->value; |
2543 UiList *list = sublist->var->value; |
| 2396 if(!list) { |
2544 if(!list) { |
| 2397 return; |
2545 return; |
| 2398 } |
2546 } |
| 2399 |
2547 |
| 2400 size_t index = 0; |
2548 int index = 0; |
| 2401 void *elm = list->first(list); |
2549 void *elm = list->first(list); |
| 2402 |
2550 void *first = elm; |
| 2403 if(!elm && sublist->header) { |
2551 |
| |
2552 if(sublist->header && !listbox->header_is_item && !elm) { |
| 2404 // empty row for header |
2553 // empty row for header |
| 2405 GtkWidget *row = gtk_list_box_row_new(); |
2554 GtkWidget *row = gtk_list_box_row_new(); |
| 2406 cxListAdd(sublist->widgets, row); |
2555 cxListAdd(sublist->widgets, row); |
| 2407 g_object_set_data(G_OBJECT(row), "ui_listbox", listbox); |
2556 g_object_set_data(G_OBJECT(row), "ui_listbox", listbox); |
| 2408 g_object_set_data(G_OBJECT(row), "ui_listbox_sublist", sublist); |
2557 g_object_set_data(G_OBJECT(row), "ui_listbox_sublist", sublist); |
| 2409 intptr_t rowindex = listbox_insert_index + index; |
2558 //intptr_t rowindex = listbox_insert_index + index; |
| 2410 g_object_set_data(G_OBJECT(row), "ui_listbox_row_index", (gpointer)rowindex); |
2559 //g_object_set_data(G_OBJECT(row), "ui_listbox_row_index", (gpointer)rowindex); |
| 2411 gtk_list_box_insert(listbox->listbox, row, listbox_insert_index + index); |
2560 gtk_list_box_insert(listbox->listbox, row, listbox_insert_index + index); |
| 2412 sublist->numitems = 1; |
2561 sublist->numitems = 1; |
| 2413 return; |
2562 return; |
| |
2563 } |
| |
2564 |
| |
2565 int first_index = 0; |
| |
2566 int header_row = 0; |
| |
2567 if(listbox->header_is_item && sublist->header) { |
| |
2568 index = -1; |
| |
2569 first_index = -1; |
| |
2570 header_row = 1; |
| |
2571 elm = sublist->header; |
| 2414 } |
2572 } |
| 2415 |
2573 |
| 2416 while(elm) { |
2574 while(elm) { |
| 2417 UiSubListItem item = { NULL, NULL, NULL, NULL, NULL, NULL }; |
2575 UiSubListItem item = { NULL, NULL, NULL, NULL, NULL, NULL }; |
| 2418 if(listbox->getvalue) { |
2576 if(listbox->getvalue) { |
| 2419 listbox->getvalue(list, sublist->userdata, elm, index, &item, listbox->getvaluedata); |
2577 listbox->getvalue(list, sublist->userdata, elm, index, &item, listbox->getvaluedata); |
| 2420 } else { |
2578 } else { |
| 2421 item.label = strdup(elm); |
2579 item.label = strdup(elm); |
| 2422 } |
2580 } |
| 2423 |
2581 |
| |
2582 if(item.label == NULL && index == -1 && sublist->header) { |
| |
2583 item.label = strdup(sublist->header); |
| |
2584 } |
| |
2585 |
| 2424 // create listbox item |
2586 // create listbox item |
| 2425 GtkWidget *row = gtk_list_box_row_new(); |
2587 GtkWidget *row = gtk_list_box_row_new(); |
| 2426 listbox_fill_row(listbox, row, sublist, &item, (int)index); |
2588 #if GTK_CHECK_VERSION(4, 0, 0) |
| 2427 if(index == 0) { |
2589 GtkEventController *motion_controller = gtk_event_controller_motion_new(); |
| |
2590 gtk_widget_add_controller(GTK_WIDGET(row), motion_controller); |
| |
2591 g_signal_connect(motion_controller, "enter", G_CALLBACK(listbox_row_enter), row); |
| |
2592 g_signal_connect(motion_controller, "leave", G_CALLBACK(listbox_row_leave), row); |
| |
2593 #else |
| |
2594 gtk_widget_set_events(GTK_WIDGET(row), GDK_POINTER_MOTION_MASK | GDK_ENTER_NOTIFY_MASK | GDK_LEAVE_NOTIFY_MASK); |
| |
2595 g_signal_connect(row, "enter-notify-event", G_CALLBACK(listbox_row_enter), NULL); |
| |
2596 g_signal_connect(row, "leave-notify-event", G_CALLBACK(listbox_row_leave), NULL); |
| |
2597 #endif |
| |
2598 |
| |
2599 listbox_fill_row(listbox, row, sublist, &item, index); |
| |
2600 if(index == first_index) { |
| 2428 // first row in the sublist, set ui_listbox data to the row |
2601 // first row in the sublist, set ui_listbox data to the row |
| 2429 // which is then used by the headerfunc |
2602 // which is then used by the headerfunc |
| 2430 g_object_set_data(G_OBJECT(row), "ui_listbox", listbox); |
2603 g_object_set_data(G_OBJECT(row), "ui_listbox", listbox); |
| 2431 g_object_set_data(G_OBJECT(row), "ui_listbox_sublist", sublist); |
2604 g_object_set_data(G_OBJECT(row), "ui_listbox_sublist", sublist); |
| 2432 |
2605 |
| 2433 if(listbox_insert_index == 0) { |
2606 if(listbox_insert_index == 0) { |
| 2434 // first row in the GtkListBox |
2607 // first row in the GtkListBox |
| 2435 listbox->first_row = GTK_LIST_BOX_ROW(row); |
2608 listbox->first_row = GTK_LIST_BOX_ROW(row); |
| 2436 } |
2609 } |
| 2437 } |
2610 } |
| 2438 intptr_t rowindex = listbox_insert_index + index; |
2611 //intptr_t rowindex = listbox_insert_index + index; |
| 2439 g_object_set_data(G_OBJECT(row), "ui_listbox_row_index", (gpointer)rowindex); |
2612 //g_object_set_data(G_OBJECT(row), "ui_listbox_row_index", (gpointer)rowindex); |
| 2440 gtk_list_box_insert(listbox->listbox, row, listbox_insert_index + index); |
2613 gtk_list_box_insert(listbox->listbox, row, listbox_insert_index + index + header_row); |
| 2441 cxListAdd(sublist->widgets, row); |
2614 cxListAdd(sublist->widgets, row); |
| 2442 |
2615 |
| 2443 // cleanup |
2616 // cleanup |
| 2444 free(item.label); |
2617 free(item.label); |
| 2445 free(item.icon); |
2618 free(item.icon); |
| 2446 free(item.button_label); |
2619 free(item.button_label); |
| 2447 free(item.button_icon); |
2620 free(item.button_icon); |
| 2448 free(item.badge); |
2621 free(item.badge); |
| 2449 |
2622 |
| 2450 // next row |
2623 // next row |
| 2451 elm = list->next(list); |
2624 elm = index >= 0 ? list->next(list) : first; |
| 2452 index++; |
2625 index++; |
| 2453 } |
2626 } |
| 2454 |
2627 |
| 2455 sublist->numitems = cxListSize(sublist->widgets); |
2628 sublist->numitems = cxListSize(sublist->widgets); |
| 2456 } |
2629 } |