Mon, 21 Apr 2025 11:03:17 +0200
implement listview (QT)
| application/main.c | file | annotate | diff | comparison | revisions | |
| ui/qt/list.cpp | file | annotate | diff | comparison | revisions | |
| ui/qt/model.cpp | file | annotate | diff | comparison | revisions | |
| ui/qt/model.h | file | annotate | diff | comparison | revisions |
--- a/application/main.c Sun Apr 20 10:56:50 2025 +0200 +++ b/application/main.c Mon Apr 21 11:03:17 2025 +0200 @@ -915,8 +915,21 @@ #ifdef UI_QT +static void list_activate(UiEvent *event, void *userdata) { + UiListSelection *sel = event->eventdata; + printf("selection [%d]\n", sel->rows[0]); +} + void application_startup(UiEvent *event, void *data) { UiObject *obj = ui_window("My Window", NULL); + + UiList *list = ui_list_new(obj->ctx, "mylist"); + ui_list_append(list, "Entry 1"); + ui_list_append(list, "Entry 2"); + ui_list_append(list, "Entry 3"); + ui_list_append(list, "Entry 4"); + ui_list_append(list, "Entry 5"); + ui_grid(obj, .margin = 10, .columnspacing = 10, .rowspacing = 10) { ui_button(obj, .label = "Button 1"); ui_button(obj, .label = "Button 2", .hexpand = TRUE, .hfill = TRUE); @@ -924,6 +937,7 @@ ui_newline(obj); ui_textarea(obj, .vexpand = TRUE, .vfill = TRUE); + ui_listview(obj, .varname = "mylist", .colspan = 2, .fill = TRUE, .onactivate = list_activate); ui_newline(obj); ui_button(obj, .label = "Button Y");
--- a/ui/qt/list.cpp Sun Apr 20 10:56:50 2025 +0200 +++ b/ui/qt/list.cpp Mon Apr 21 11:03:17 2025 +0200 @@ -33,4 +33,43 @@ #include <QTreeWidgetItem> #include <QListView> +extern "C" void* ui_strmodel_getvalue(void *elm, int column) { + return column == 0 ? elm : NULL; +} + +UIWIDGET ui_listview_create(UiObject* obj, UiListArgs args) { + UiContainerPrivate *ctn = ui_obj_container(obj); + UI_APPLY_LAYOUT(ctn->layout, args); + + QListView *view = new QListView(); + + ui_getvaluefunc getvalue = args.getvalue ? args.getvalue : ui_strmodel_getvalue; + UiVar* var = uic_widget_var(obj->ctx, obj->ctx, args.list, args.varname, UI_VAR_LIST); + + ListModel *model = new ListModel(obj, view, var, getvalue); + view->setModel(model); + + if(var) { + UiList *list = (UiList*)var->value; + list->update = ui_listmodel_update; + list->getselection = ui_listmodel_getselection; + list->setselection = ui_listmodel_setselection; + list->obj = model; + } + + model->setActivationCallback(args.onactivate, args.onactivatedata); + model->setSelectionCallback(args.onselection, args.onselectiondata); + + QItemSelectionModel *s = view->selectionModel(); + QObject::connect( + s, + SIGNAL(selectionChanged(const QItemSelection &, const QItemSelection &)), + model, + SLOT(selectionChanged(const QItemSelection &, const QItemSelection &))); + + + ctn->add(view, false); + + return view; +}
--- a/ui/qt/model.cpp Sun Apr 20 10:56:50 2025 +0200 +++ b/ui/qt/model.cpp Mon Apr 21 11:03:17 2025 +0200 @@ -29,13 +29,34 @@ #include "model.h" -ListModel::ListModel(UiObject *obj, QListView *view, UiVar *var, ui_getvaluefunc getvalue, ui_callback f, void *userdata){ +ListModel::ListModel(UiObject *obj, QListView *view, UiVar *var, ui_getvaluefunc getvalue){ this->obj = obj; this->view = view; this->var = var; this->getvalue = getvalue; - this->callback = f; - this->userdata = userdata; + this->onactivate = nullptr; + this->onactivatedata = nullptr; + this->onselection = nullptr; + this->onselectiondata = nullptr; +} + +void ListModel::setActivationCallback(ui_callback f, void *userdata) { + onactivate = f; + onactivatedata = userdata; +} + +void ListModel::setSelectionCallback(ui_callback f, void *userdata) { + onselection = f; + onselectiondata = userdata; +} + +void ListModel::update(int row) { + if(row >= 0) { + this->update(row); + } else { + this->beginResetModel(); + this->endResetModel(); + } } int ListModel::rowCount(const QModelIndex& parent) const { @@ -56,7 +77,66 @@ } void ListModel::selectionChanged(const QItemSelection& selected, const QItemSelection& deselected) { + UiListSelection sel = ui_selection_model_to_selection(view->selectionModel()); + UiEvent event; + event.obj = obj; + event.window = obj->window; + event.document = obj->ctx->document; + event.eventdata = &sel; + event.intval = sel.count; + event.set = ui_get_setop(); + + if(onactivate) { + onactivate(&event, onactivatedata); + } + if(onselection) { + onselection(&event, onselectiondata); + } + + free(sel.rows); } + + +UiListSelection ui_selection_model_to_selection(QItemSelectionModel *model) { + UiListSelection sel; + sel.rows = NULL; + sel.count = 0; + + if(model->hasSelection()) { + QModelIndexList indices = model->selectedIndexes(); + sel.count = indices.count(); + sel.rows = (int*)calloc(sel.count, sizeof(int)); + + int i = 0; + for (const QModelIndex &index : indices) { + sel.rows[i++] = index.row(); + } + } + + return sel; +} + +/* ---------------------- UiList implementation -----------------------------*/ + +void ui_listmodel_update(UiList *list, int row) { + ListModel *model = (ListModel*)list->obj; + model->update(row); +} + +void ui_listmodel_setselection(UiList *list, UiListSelection sel) { + ListModel *model = (ListModel*)list->obj; + QItemSelection selection; + for (int i=0;i<sel.count;i++) { + QModelIndex index = model->index(sel.rows[i]); + selection.select(index, index); + } + model->view->selectionModel()->select(selection, QItemSelectionModel::ClearAndSelect); +} + +UiListSelection ui_listmodel_getselection(UiList *list) { + ListModel *model = (ListModel*)list->obj; + return ui_selection_model_to_selection(model->view->selectionModel()); +}
--- a/ui/qt/model.h Sun Apr 20 10:56:50 2025 +0200 +++ b/ui/qt/model.h Mon Apr 21 11:03:17 2025 +0200 @@ -44,15 +44,23 @@ class ListModel : public QAbstractListModel { Q_OBJECT + ui_getvaluefunc getvalue; + ui_callback onactivate; + void *onactivatedata; + ui_callback onselection; + void *onselectiondata; + +public: UiObject *obj; UiVar *var; - ui_getvaluefunc getvalue; - ui_callback callback; - void *userdata; QListView *view; -public: - ListModel(UiObject *obj, QListView *view, UiVar *var, ui_getvaluefunc getvalue, ui_callback f, void *userdata); + ListModel(UiObject *obj, QListView *view, UiVar *var, ui_getvaluefunc getvalue); + + void setActivationCallback(ui_callback f, void *userdata); + void setSelectionCallback(ui_callback f, void *userdata); + + void update(int row); int rowCount(const QModelIndex &parent = QModelIndex()) const; QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const; @@ -64,6 +72,15 @@ }; +UiListSelection ui_selection_model_to_selection(QItemSelectionModel *model); + +extern "C" { + + void ui_listmodel_update(UiList *list, int row); + void ui_listmodel_setselection(UiList *list, UiListSelection sel); + UiListSelection ui_listmodel_getselection(UiList *list); + +} #endif /* MODEL_H */