#include <stdio.h>
#include <stdlib.h>
#include "container.h"
#include "list.h"
#include "../common/object.h"
UIWIDGET ui_listview_create(UiObject* obj, UiListArgs args) {
Arg xargs[
16];
int n =
0;
UiContainerPrivate *ctn = ui_obj_container(obj);
UI_APPLY_LAYOUT(ctn->layout, args);
if(args.multiselection) {
XtSetArg(xargs[n], XmNselectionPolicy, XmEXTENDED_SELECT); n++;
}
else {
XtSetArg(xargs[n], XmNselectionPolicy, XmSINGLE_SELECT); n++;
}
char *name = args.name ? (
char*)args.name :
"listview";
Widget parent = ctn->prepare(ctn, xargs, &n);
Widget widget = XmCreateScrolledList(parent, name, xargs, n);
XtManageChild(widget);
UiVar* var = uic_widget_var(obj->ctx, obj->ctx, args.list, args.varname,
UI_VAR_LIST);
UiListView *listview = malloc(
sizeof(UiListView));
memset(listview,
0,
sizeof(UiListView));
listview->obj = obj;
listview->widget = widget;
listview->getvalue = args.getvalue ? args.getvalue : ui_strmodel_getvalue;
listview->var = var;
listview->onactivate = args.onactivate;
listview->onactivatedata = args.onactivatedata;
listview->onselection = args.onselection;
listview->onselectiondata = args.onselectiondata;
if(var) {
UiList *list = var->value;
list->obj = listview;
list->update = ui_listview_update;
list->getselection = ui_listview_getselection;
list->setselection = ui_listview_setselection;
ui_listview_update(list,
0);
}
XtAddCallback(
widget,
XmNdestroyCallback,
(XtCallbackProc)ui_listview_destroy,
listview);
XtAddCallback(
widget,
XmNdefaultActionCallback,
(XtCallbackProc)ui_listview_activate,
listview);
XtAddCallback(
widget,
XmNextendedSelectionCallback,
(XtCallbackProc)ui_listview_selection,
listview);
XtAddCallback(
widget,
XmNsingleSelectionCallback,
(XtCallbackProc)ui_listview_selection,
listview);
return widget;
}
void ui_listview_destroy(Widget w, UiListView *listview, XtPointer d) {
}
static void list_callback(UiObject *obj, UiListSelection sel, ui_callback callback,
void *userdata) {
UiEvent event;
event.obj = obj;
event.window = obj->window;
event.document = obj->ctx->document;
event.eventdata = &sel;
event.intval = sel.count >
0 ? sel.rows[
0] : -
1;
callback(&event, userdata);
}
static void listview_save_selection(UiListView *listview, XmListCallbackStruct *cb) {
UiListSelection sel = { cb->selected_item_count,
NULL };
if(sel.count >
0) {
sel.rows = calloc(sel.count,
sizeof(
int));
for(
int i=
0;i<sel.count;i++) {
sel.rows[i] = cb->selected_item_positions[i]-
1;
}
}
free(listview->current_selection.rows);
listview->current_selection = sel;
}
void ui_listview_activate(Widget w, UiListView *listview, XmListCallbackStruct *cb) {
listview_save_selection(listview, cb);
if(listview->onactivate) {
list_callback(listview->obj, listview->current_selection, listview->onactivate, listview->onactivatedata);
}
}
void ui_listview_selection(Widget w, UiListView *listview, XmListCallbackStruct *cb) {
listview_save_selection(listview, cb);
if(listview->onselection) {
list_callback(listview->obj, listview->current_selection, listview->onselection, listview->onselectiondata);
}
}
static XmStringTable create_stringlist(UiList *list, ui_getvaluefunc getvalue,
int *count) {
int num = list->count(list);
XmStringTable items = (XmStringTable)XtMalloc(num *
sizeof(XmString));
void *data = list->first(list);
for(
int i=
0;i<num;i++) {
char *s = getvalue(data,
0);
items[i] = XmStringCreateLocalized(s ? s :
"");
data = list->next(list);
}
*count = num;
return items;
}
void ui_listview_update(UiList *list,
int i) {
UiListView *listview = list->obj;
int count;
XmStringTable items = create_stringlist(
list,
listview->getvalue,
&count);
XtVaSetValues(
listview->widget,
XmNitems, count ==
0 ?
NULL : items,
XmNitemCount,
count,
NULL);
for (
int i=
0;i<count;i++) {
XmStringFree(items[i]);
}
XtFree((
char *)items);
}
UiListSelection ui_listview_getselection(UiList *list) {
UiListView *listview = list->obj;
UiListSelection sel = { listview->current_selection.count,
NULL };
if(sel.count >
0) {
sel.rows = calloc(sel.count,
sizeof(
int));
memcpy(sel.rows, listview->current_selection.rows, sel.count*
sizeof(
int));
}
return sel;
}
void ui_listview_setselection(UiList *list, UiListSelection selection) {
UiListView *listview = list->obj;
XmListDeselectAllItems(listview->widget);
for(
int i=
0;i<selection.count;i++) {
XmListSelectPos(listview->widget, selection.rows[i]+
1, False);
}
}
void* ui_strmodel_getvalue(
void *elm,
int column) {
return column ==
0 ? elm :
NULL;
}