add existing code (build system, libs, initial mizucp code)
[mizunara.git] / ui / motif / list.c
1 /*
2  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
3  *
4  * Copyright 2014 Olaf Wintermann. All rights reserved.
5  *
6  * Redistribution and use in source and binary forms, with or without
7  * modification, are permitted provided that the following conditions are met:
8  *
9  *   1. Redistributions of source code must retain the above copyright
10  *      notice, this list of conditions and the following disclaimer.
11  *
12  *   2. Redistributions in binary form must reproduce the above copyright
13  *      notice, this list of conditions and the following disclaimer in the
14  *      documentation and/or other materials provided with the distribution.
15  *
16  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
17  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
19  * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
20  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
21  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
22  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
23  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
24  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
25  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
26  * POSSIBILITY OF SUCH DAMAGE.
27  */
28
29 #include <stdio.h>
30 #include <stdlib.h>
31
32 #include "container.h"
33
34 #include "list.h"
35 #include "../common/object.h"
36
37
38 void* ui_strmodel_getvalue(void *elm, int column) {
39     return column == 0 ? elm : NULL;
40 }
41
42
43 UIWIDGET ui_listview_str(UiObject *obj, UiList *list, ui_callback f, void *udata) {
44     return ui_listview(obj, list, ui_strmodel_getvalue, f, udata);
45 }
46
47 UIWIDGET ui_listview_var(UiObject *obj, UiVar *var, ui_getvaluefunc getvalue, ui_callback f, void *udata) {
48     int count;
49     XmStringTable items = ui_create_stringlist(var->value, getvalue, &count);
50     
51     Arg args[8];
52     int n = 0;
53     XtSetArg(args[n], XmNitemCount, count);
54     n++;
55     XtSetArg(args[n], XmNitems, count == 0 ? NULL : items);
56     n++;
57     
58     UiContainer *ct = uic_get_current_container(obj);
59     Widget parent = ct->prepare(ct, args, &n, TRUE);
60     Widget widget = XmCreateScrolledList(parent, "listview", args, n);
61     ct->add(ct, XtParent(widget));
62     XtManageChild(widget);
63     
64     UiListView *listview = ucx_mempool_malloc(obj->ctx->mempool, sizeof(UiListView));
65     listview->widget = widget;
66     listview->list = var;
67     listview->getvalue = getvalue;
68     
69     for (int i=0;i<count;i++) {
70         XmStringFree(items[i]);
71     }
72     XtFree((char *)items);
73     
74     if(f) {
75         UiListViewEventData *event = ucx_mempool_malloc(
76                 obj->ctx->mempool,
77                 sizeof(UiListViewEventData));
78         event->event.obj = obj;
79         event->event.userdata = udata;
80         event->event.callback = f;
81         event->event.value = 0;
82         event->var = var;
83         XtAddCallback(
84                 widget,
85                 XmNdefaultActionCallback,
86                 (XtCallbackProc)ui_list_selection_callback,
87                 event);
88     }
89     
90     return widget;
91 }
92
93 UIWIDGET ui_listview(UiObject *obj, UiList *list, ui_getvaluefunc getvalue, ui_callback f, void *udata) {
94     UiVar *var = malloc(sizeof(UiVar));
95     var->value = list;
96     var->type = UI_VAR_SPECIAL;
97     return ui_listview_var(obj, var, getvalue, f, udata);
98 }
99
100 UIWIDGET ui_listview_nv(UiObject *obj, char *varname, ui_getvaluefunc getvalue, ui_callback f, void *udata) {
101     UiVar *var = uic_create_var(obj->ctx, varname, UI_VAR_LIST);
102     if(var) {
103         UiListVar *value = var->value;
104         return ui_listview_var(obj, var, getvalue, f, udata);
105     } else {
106         // TODO: error
107     }
108     return NULL;
109 }
110
111
112 XmStringTable ui_create_stringlist(UiList *list, ui_getvaluefunc getvalue, int *count) { 
113     int num = list->count(list);
114     XmStringTable items = (XmStringTable)XtMalloc(num * sizeof(XmString));
115     void *data = list->first(list);
116     for(int i=0;i<num;i++) {
117         items[i] = XmStringCreateLocalized(getvalue(data, 0));
118         data = list->next(list);
119     }
120     
121     *count = num;
122     return items;
123 }
124
125
126 void ui_listview_update(UiEvent *event, UiListView *view) {
127     int count;
128     XmStringTable items = ui_create_stringlist(
129             view->list->value,
130             view->getvalue,
131             &count);
132     
133     XtVaSetValues(
134             view->widget,
135             XmNitems, count == 0 ? NULL : items,
136             XmNitemCount,
137             count,
138             NULL);
139     
140     for (int i=0;i<count;i++) {
141         XmStringFree(items[i]);
142     }
143     XtFree((char *)items);
144 }
145
146 void ui_list_selection_callback (Widget widget, UiListViewEventData *event, XtPointer data) {
147     XmListCallbackStruct *cbs = (XmListCallbackStruct *)data;
148     
149     UiEvent e;
150     e.obj = event->event.obj;
151     e.window = event->event.obj->window;
152     e.document = event->event.obj->ctx->document;
153     UiList *list = event->var->value;
154     e.eventdata = list->get(list, cbs->item_position - 1);
155     e.intval = cbs->item_position - 1;
156     event->event.callback(&e, event->event.userdata);
157 }
158
159
160 /* --------------------------- ComboBox ---------------------------  */
161
162 UIWIDGET ui_combobox_str(UiObject *obj, UiList *list, ui_callback f, void *udata) {
163     return ui_combobox(obj, list, ui_strmodel_getvalue, f, udata);
164 }
165
166 UIWIDGET ui_combobox(UiObject *obj, UiList *list, ui_getvaluefunc getvalue, ui_callback f, void *udata) {
167     UiVar *var = malloc(sizeof(UiVar));
168     var->value = list;
169     var->type = UI_VAR_SPECIAL;
170     return ui_combobox_var(obj, var, getvalue, f, udata);
171 }
172
173 UIWIDGET ui_combobox_nv(UiObject *obj, char *varname, ui_getvaluefunc getvalue, ui_callback f, void *udata) {
174     UiVar *var = uic_create_var(obj->ctx, varname, UI_VAR_LIST);
175     if(var) {
176         UiListVar *value = var->value;
177         return ui_combobox_var(obj, var, getvalue, f, udata);
178     } else {
179         // TODO: error
180     }
181     return NULL;
182 }
183
184 UIWIDGET ui_combobox_var(UiObject *obj, UiVar *var, ui_getvaluefunc getvalue, ui_callback f, void *udata) {
185     UiListView *listview = ucx_mempool_malloc(
186                 obj->ctx->mempool,
187                 sizeof(UiListView));
188     
189     UiContainer *ct = uic_get_current_container(obj);
190     Arg args[16];
191     int n = 0;
192     XtSetArg(args[n], XmNindicatorOn, XmINDICATOR_NONE);
193     n++;
194     XtSetArg(args[n], XmNtraversalOn, FALSE);
195     n++;
196     XtSetArg(args[n], XmNwidth, 160);
197     n++;
198     Widget parent = ct->prepare(ct, args, &n, FALSE);
199     Widget combobox = XmCreateDropDownList(parent, "combobox", args, n);
200     XtManageChild(combobox);
201     listview->widget = combobox;
202     listview->list = var;
203     listview->getvalue = getvalue;
204     
205     ui_listview_update(NULL, listview);
206     
207 }