Sat, 10 May 2014 15:43:22 +0200
added listview, sidebar and toolbar image button (GTK)
--- a/application/main.c Sat Apr 12 13:44:53 2014 +0200 +++ b/application/main.c Sat May 10 15:43:22 2014 +0200 @@ -47,6 +47,8 @@ UiList *list; +/* + void action_new(UiEvent *event, void *data) { UiObject *window = ui_window("Mod1", NULL); //ui_window_addint(window, "check1"); @@ -152,14 +154,15 @@ printf("delete\n"); } +//*/ int main(int argc, char** argv) { ui_init("app1", argc, argv); ui_locales_dir("/opt/app1/locales"); ui_load_lang_def(NULL, "en_EN"); - ui_openfilefunc(action_new, NULL); + //ui_openfilefunc(action_new, NULL); - + /* list = ui_list_new(); ui_list_append(list, "file1.txt"); ui_list_append(list, "hello.txt"); @@ -204,10 +207,16 @@ ui_toolbar_add_default("close"); ui_toolbar_add_default("undo"); ui_toolbar_add_default("redo"); + //*/ + ui_menu("File"); + ui_menuitem("New", NULL, NULL); + ui_menuitem("Close", NULL, NULL); + ui_menu("Edit"); + ui_menuitem("Preferences", NULL, NULL); printf("create window\n"); - UiObject *window = ui_window("Mod0", NULL); + UiObject *window = ui_window("Mod0", NULL); TestWindowData *wdata = calloc(1, sizeof(TestWindowData)); window->window = wdata; @@ -221,7 +230,7 @@ ui_set_document(window, doc1); //ui_button(window, "OK", action_open, NULL); - ui_textarea(window, &wdata->text); + //ui_textarea(window, &wdata->text); //ui_window_addint(window, "check1"); ui_show(window);
--- a/make/gcc.mk Sat Apr 12 13:44:53 2014 +0200 +++ b/make/gcc.mk Sat May 10 15:43:22 2014 +0200 @@ -26,12 +26,14 @@ # POSSIBILITY OF SUCH DAMAGE. # -CC = gcc -LD = gcc -AR = ar -RM = rm +CC = gcc +CXX = g++ +LD = gcc +AR = ar +RM = rm CFLAGS += -std=gnu99 -g +CXXFLAGS += -g LDFLAGS += ARFLAGS = -r RMFLAGS = -f
--- a/ui/common/context.c Sat Apr 12 13:44:53 2014 +0200 +++ b/ui/common/context.c Sat May 10 15:43:22 2014 +0200 @@ -119,6 +119,21 @@ sizeof(UiInteger)); return s; } + case UI_VAR_TEXT: { + UiText *t = a->calloc( + a->pool, + 1, + sizeof(UiText)); + return t; + } + case UI_VAR_LIST: { + UiListVar *l = a->malloc(a->pool, sizeof(UiListVar)); + UiListPtr *lp = a->malloc(a->pool, sizeof(UiListPtr)); + l->listptr = lp; + lp->list = NULL; + // TODO: create empty list + return l; + } } return NULL; } @@ -181,7 +196,7 @@ int i = 0; UCX_FOREACH(elm, ctx->groups) { - groups[i++] = (int)elm->data; + groups[i++] = (intptr_t)elm->data; } *ngroups = nelm;
--- a/ui/common/context.h Sat Apr 12 13:44:53 2014 +0200 +++ b/ui/common/context.h Sat May 10 15:43:22 2014 +0200 @@ -39,6 +39,8 @@ #endif typedef struct UiVar UiVar; +typedef struct UiListPtr UiListPtr; +typedef struct UiListVar UiListVar; typedef struct UiGroupWidget UiGroupWidget; struct UiContext { @@ -60,6 +62,14 @@ UcxMap *from; }; +struct UiListPtr { + UiList *list; +}; + +struct UiListVar { + UiListPtr *listptr; +}; + struct UiGroupWidget { UIWIDGET widget; int *groups; @@ -68,7 +78,9 @@ enum UiVarType { UI_VAR_INTEGER = 0, - UI_VAR_STRING + UI_VAR_STRING, + UI_VAR_TEXT, + UI_VAR_LIST }; UiContext* uic_context(UiObject *toplevel, UcxMempool *mp);
--- a/ui/common/document.c Sat Apr 12 13:44:53 2014 +0200 +++ b/ui/common/document.c Sat May 10 15:43:22 2014 +0200 @@ -248,6 +248,32 @@ break; } case UI_VAR_STRING: { + // TODO + break; + } + case UI_VAR_TEXT: { + UiText *f = from->value; + UiText *t = to->value; + char *tvalue = t->value; + memcpy(t, f, sizeof(UiText)); + if(set) { + t->set(t, tvalue); + } else { + f->value = f->get(f); + } + break; + } + case UI_VAR_LIST: { + UiListVar *f = from->value; + UiListVar *t = to->value; + UiList *list = t->listptr->list; + UiObserver *observers = f->listptr->list->observers; + t->listptr = f->listptr; + if(set) { + t->listptr->list = list; + list->observers = observers; + ui_notify(observers, list); + } break; } } @@ -261,3 +287,14 @@ uic_document_regvar(doc, name, UI_VAR_INTEGER, sizeof(UiInteger), i); } +void ui_document_regtext(void *doc, char *name, UiText *text) { + uic_document_regvar(doc, name, UI_VAR_TEXT, sizeof(UiText), text); +} + +void ui_document_reglist(void *doc, char *name, UiList *list) { + UiListVar *lv = ui_document_malloc(doc, sizeof(UiListVar)); + UiListPtr *lp = ui_document_malloc(doc, sizeof(UiListPtr)); + lv->listptr = lp; + lp->list = list; + uic_document_regvar(doc, name, UI_VAR_LIST, sizeof(UiListPtr), lv); +}
--- a/ui/common/object.c Sat Apr 12 13:44:53 2014 +0200 +++ b/ui/common/object.c Sat May 10 15:43:22 2014 +0200 @@ -30,8 +30,49 @@ #include <stdlib.h> #include "object.h" +#include "context.h" + +void ui_end(UiObject *obj) { + if(!obj->next) { + return; + } + + UiObject *prev = NULL; + while(obj->next) { + prev = obj; + obj = obj->next; + } + + if(prev) { + // TODO: free last obj + prev->next = NULL; + } +} + + +UiObject* uic_object_new(UiObject *toplevel, UIWIDGET widget) { + UiContext *ctx = toplevel->ctx; + + UiObject *newobj = ucx_mempool_calloc(ctx->mempool, 1, sizeof(UiObject)); + newobj->ctx = ctx; + newobj->widget = widget; + + return newobj; +} + +void uic_obj_add(UiObject *toplevel, UiObject *ctobj) { + UiObject *current = uic_current_obj(toplevel); + current->next = ctobj; +} + +UiObject* uic_current_obj(UiObject *toplevel) { + UiObject *obj = toplevel; + while(obj->next) { + obj = obj->next; + } + return obj; +} UiContainer* uic_get_current_container(UiObject *obj) { - // TODO - return obj->container; + return uic_current_obj(obj)->container; }
--- a/ui/common/object.h Sat Apr 12 13:44:53 2014 +0200 +++ b/ui/common/object.h Sat May 10 15:43:22 2014 +0200 @@ -35,6 +35,10 @@ extern "C" { #endif +UiObject* uic_object_new(UiObject *toplevel, UIWIDGET widget); +void uic_obj_add(UiObject *toplevel, UiObject *ctobj); +UiObject* uic_current_obj(UiObject *toplevel); + UiContainer* uic_get_current_container(UiObject *obj);
--- a/ui/common/properties.c Sat Apr 12 13:44:53 2014 +0200 +++ b/ui/common/properties.c Sat May 10 15:43:22 2014 +0200 @@ -286,3 +286,12 @@ } return ucx_map_cstr_get(language, name); } + + +char* uic_get_image_path(char *imgfilename) { + if(pixmaps_dir) { + return uic_concat_path(pixmaps_dir, imgfilename, NULL); + } else { + return NULL; + } +}
--- a/ui/common/properties.h Sat Apr 12 13:44:53 2014 +0200 +++ b/ui/common/properties.h Sat May 10 15:43:22 2014 +0200 @@ -47,6 +47,7 @@ void uic_store_app_properties(); int uic_load_language_file(char *path); +char* uic_get_image_path(char *imgfilename); #ifdef __cplusplus }
--- a/ui/gtk/button.c Sat Apr 12 13:44:53 2014 +0200 +++ b/ui/gtk/button.c Sat May 10 15:43:22 2014 +0200 @@ -33,6 +33,7 @@ #include "container.h" #include "../../ucx/mempool.h" #include "../common/context.h" +#include "../common/object.h" UIWIDGET ui_button(UiObject *obj, char *label, ui_callback f, void *data) { GtkWidget *button = gtk_button_new_with_label(label); @@ -74,3 +75,13 @@ e.intval = event->value; event->callback(&e, event->user_data); } + +void ui_button_toggled(GtkToggleToolButton *widget, UiEventData *event) { + UiEvent e; + e.obj = event->obj; + e.window = event->obj->window; + e.document = event->obj->document; + e.eventdata = NULL; + e.intval = gtk_toggle_tool_button_get_active(widget); + event->callback(&e, event->user_data); +}
--- a/ui/gtk/button.h Sat Apr 12 13:44:53 2014 +0200 +++ b/ui/gtk/button.h Sat May 10 15:43:22 2014 +0200 @@ -38,6 +38,7 @@ // event wrapper void ui_button_clicked(GtkWidget *widget, UiEventData *event); +void ui_button_toggled(GtkToggleToolButton *widget, UiEventData *event); #ifdef __cplusplus
--- a/ui/gtk/container.c Sat Apr 12 13:44:53 2014 +0200 +++ b/ui/gtk/container.c Sat May 10 15:43:22 2014 +0200 @@ -31,6 +31,8 @@ #include "container.h" #include "../common/context.h" +#include "../common/object.h" + UiContainer* ui_frame_container(UiObject *obj, GtkWidget *frame) { UiContainer *ct = ucx_mempool_malloc( @@ -44,3 +46,58 @@ void ui_frame_container_add(UiContainer *ct, GtkWidget *widget) { gtk_container_add(GTK_CONTAINER(ct->widget), widget); } + + +UIWIDGET ui_sidebar(UiObject *obj) { +#ifdef UI_GTK3 + GtkWidget *paned = gtk_paned_new(GTK_ORIENTATION_HORIZONTAL); +#else + GtkWidget *paned = gtk_hpaned_new(); +#endif + gtk_paned_set_position(GTK_PANED(paned), 200); + + GtkWidget *sidebar; +#ifdef UI_GTK3 + sidebar = gtk_box_new(GTK_ORIENTATION_VERTICAL, 0); +#else + sidebar = gtk_vbox_new(FALSE, 0); +#endif + gtk_paned_pack1(GTK_PANED(paned), sidebar, TRUE, FALSE); + + UiObject *left = uic_object_new(obj, sidebar); + UiContainer *ct1 = ucx_mempool_malloc( + obj->ctx->mempool, + sizeof(UiContainer)); + ct1->widget = sidebar; + ct1->add = ui_box_add; + left->container = ct1; + + UiObject *right = uic_object_new(obj, sidebar); + UiContainer *ct2 = ucx_mempool_malloc( + obj->ctx->mempool, + sizeof(UiContainer)); + ct2->widget = paned; + ct2->add = ui_split_container_add2; + right->container = ct2; + + UiContainer *ct = uic_get_current_container(obj); + ct->add(ct, paned); + + uic_obj_add(obj, right); + uic_obj_add(obj, left); + + return sidebar; +} + +void ui_split_container_add1(UiContainer *ct, GtkWidget *widget) { + gtk_paned_pack1(GTK_PANED(ct->widget), widget, TRUE, FALSE); +} + +void ui_split_container_add2(UiContainer *ct, GtkWidget *widget) { + gtk_paned_pack2(GTK_PANED(ct->widget), widget, TRUE, FALSE); +} + + +void ui_box_add(UiContainer *ct, GtkWidget *widget) { + gtk_box_pack_start(GTK_BOX(ct->widget), widget, TRUE, TRUE, 0); +}
--- a/ui/gtk/container.h Sat Apr 12 13:44:53 2014 +0200 +++ b/ui/gtk/container.h Sat May 10 15:43:22 2014 +0200 @@ -45,6 +45,11 @@ UiContainer* ui_frame_container(UiObject *obj, GtkWidget *frame); void ui_frame_container_add(UiContainer *ct, GtkWidget *widget); +void ui_split_container_add1(UiContainer *ct, GtkWidget *widget); +void ui_split_container_add2(UiContainer *ct, GtkWidget *widget); + +void ui_box_add(UiContainer *ct, GtkWidget *widget); + #ifdef __cplusplus } #endif
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/ui/gtk/image.c Sat May 10 15:43:22 2014 +0200 @@ -0,0 +1,73 @@ +/* + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. + * + * Copyright 2014 Olaf Wintermann. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include "../../ucx/map.h" + +#include "image.h" +#include "../common/properties.h" + + +static UcxMap *image_map; + +void ui_image_init() { + image_map = ucx_map_new(8); +} + +void ui_add_image(char *imgname, char *filename) { + // create file path + char *path = uic_get_image_path(filename); + if(!path) { + // TODO: error + fprintf(stderr, "UiError: pixmaps directory not set\n"); + return; + } + + GError *error = NULL; + GdkPixbuf *image = gdk_pixbuf_new_from_file(path, &error); + if(!image) { + // TODO: error + fprintf(stderr, "UiError: Cannot load image: %s\n", path); + } else { + ucx_map_cstr_put(image_map, imgname, image); + } + + free(path); +} + +GdkPixbuf* ui_get_image(char *name) { + GdkPixbuf *pixbuf = ucx_map_cstr_get(image_map, name); + if(pixbuf) { + return pixbuf; + } else { + ui_add_image(name, name); + return ucx_map_cstr_get(image_map, name); + } +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/ui/gtk/image.h Sat May 10 15:43:22 2014 +0200 @@ -0,0 +1,48 @@ +/* + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. + * + * Copyright 2014 Olaf Wintermann. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef IMAGE_H +#define IMAGE_H + +#include "../ui/toolkit.h" + +#ifdef __cplusplus +extern "C" { +#endif + +void ui_image_init(); + +GdkPixbuf* ui_get_image(char *name); + + +#ifdef __cplusplus +} +#endif + +#endif /* IMAGE_H */ +
--- a/ui/gtk/objs.mk Sat Apr 12 13:44:53 2014 +0200 +++ b/ui/gtk/objs.mk Sat May 10 15:43:22 2014 +0200 @@ -37,6 +37,9 @@ GTKOBJ += toolbar.o GTKOBJ += button.o GTKOBJ += text.o +GTKOBJ += model.o +GTKOBJ += tree.o +GTKOBJ += image.o TOOLKITOBJS = $(GTKOBJ:%=$(GTK_OBJPRE)%) TOOLKITSOURCE = $(GTKOBJ:%.o=gtk/%.c)
--- a/ui/gtk/text.c Sat Apr 12 13:44:53 2014 +0200 +++ b/ui/gtk/text.c Sat May 10 15:43:22 2014 +0200 @@ -32,6 +32,8 @@ #include "text.h" #include "container.h" +#include "../common/context.h" +#include "../common/document.h" static void selection_handler( GtkTextBuffer *buf, @@ -97,6 +99,12 @@ // bind value if(value) { + GtkTextBuffer *buf = gtk_text_view_get_buffer(GTK_TEXT_VIEW(text_area)); + + if(value->value) { + gtk_text_buffer_set_text(buf, value->value, -1); + } + value->get = ui_textarea_get; value->set = ui_textarea_set; value->getsubstr = ui_textarea_getsubstr; @@ -104,8 +112,8 @@ value->position = ui_textarea_position; value->selection = ui_textarea_selection; value->length = ui_textarea_length; + value->remove = ui_textarea_remove; value->value = NULL; - GtkTextBuffer *buf = gtk_text_view_get_buffer(GTK_TEXT_VIEW(text_area)); value->obj = buf; if(!value->undomgr) { value->undomgr = ui_create_undomgr(); @@ -133,6 +141,17 @@ return scroll_area; } +UIWIDGET ui_textarea_nv(UiObject *obj, char *varname) { + UiVar *var = uic_connect_var(obj->ctx, varname, UI_VAR_TEXT); + if(var) { + UiText *value = var->value; + return ui_textarea(obj, value); + } else { + // TODO: error + } + return NULL; +} + char* ui_textarea_get(UiText *text) { if(text->value) { g_free(text->value); @@ -201,6 +220,15 @@ return gtk_text_iter_get_offset(&end); } +void ui_textarea_remove(UiText *text, int begin, int end) { + GtkTextBuffer *buf = text->obj; + GtkTextIter ib; + GtkTextIter ie; + gtk_text_buffer_get_iter_at_offset(buf, &ib, begin); + gtk_text_buffer_get_iter_at_offset(buf, &ie, end); + gtk_text_buffer_delete(buf, &ib, &ie); +} + void ui_textarea_realize_event(GtkWidget *widget, gpointer data) { gtk_widget_grab_focus(widget); }
--- a/ui/gtk/text.h Sat Apr 12 13:44:53 2014 +0200 +++ b/ui/gtk/text.h Sat May 10 15:43:22 2014 +0200 @@ -66,6 +66,7 @@ int ui_textarea_position(UiText *text); void ui_textarea_selection(UiText *text, int *begin, int *end); int ui_textarea_length(UiText *text); +void ui_textarea_remove(UiText *text, int begin, int end); void ui_textarea_realize_event(GtkWidget *widget, gpointer data); void ui_textbuf_insert(
--- a/ui/gtk/toolbar.c Sat Apr 12 13:44:53 2014 +0200 +++ b/ui/gtk/toolbar.c Sat May 10 15:43:22 2014 +0200 @@ -32,6 +32,7 @@ #include "toolbar.h" #include "button.h" +#include "image.h" #include "../../ucx/mempool.h" #include "../common/context.h" @@ -43,29 +44,85 @@ } void ui_toolitem(char *name, char *label, ui_callback f, void *udata) { - UiToolItem *item = malloc(sizeof(UiToolItem)); - item->item.add_to = (ui_toolbar_add_f)add_toolitem_widget; - item->label = label; - item->callback = f; - item->userdata = udata; - - ucx_map_cstr_put(toolbar_items, name, item); + ui_toolitem_img(name, label, NULL, f, udata); } void ui_toolitem_st(char *name, char *stockid, ui_callback f, void *userdata) { ui_toolitem_stgr(name, stockid, f, userdata, -1); } +void ui_toolitem_sti(char *name, char *stockid, ui_callback f, void *userdata) { + ui_toolitem_stgri(name, stockid, f, userdata, -1); +} + void ui_toolitem_stgr(char *name, char *stockid, ui_callback f, void *userdata, ...) { + va_list ap; + va_start(ap, userdata); + ui_toolitem_vstgr(name, stockid, 0, f, userdata, ap); + va_end(ap); +} + +void ui_toolitem_stgri(char *name, char *stockid, ui_callback f, void *userdata, ...) { + va_list ap; + va_start(ap, userdata); + ui_toolitem_vstgr(name, stockid, 1, f, userdata, ap); + va_end(ap); +} + +void ui_toolitem_img(char *name, char *label, char *img, ui_callback f, void *udata) { + UiToolItem *item = malloc(sizeof(UiToolItem)); + item->item.add_to = (ui_toolbar_add_f)add_toolitem_widget; + item->label = label; + item->image = img; + item->callback = f; + item->userdata = udata; + item->isimportant = 0; + item->groups = NULL; + + ucx_map_cstr_put(toolbar_items, name, item); +} + +void ui_toolitem_vstgr( + char *name, + char *stockid, + int isimportant, + ui_callback f, + void *userdata, + va_list ap) +{ UiStToolItem *item = malloc(sizeof(UiStToolItem)); item->item.add_to = (ui_toolbar_add_f)add_toolitem_st_widget; item->stockid = stockid; item->callback = f; item->userdata = userdata; + item->groups = NULL; + item->isimportant = isimportant; + + // add groups + int group; + while((group = va_arg(ap, int)) != -1) { + item->groups = ucx_list_append(item->groups, (void*)(intptr_t)group); + } + + ucx_map_cstr_put(toolbar_items, name, item); +} + +void ui_toolitem_toggle_st(char *name, char *stockid, ui_callback f, void *udata, ...) { + ui_toolitem_toggle_stgr(name, stockid, f, udata, -1); +} + +void ui_toolitem_toggle_stgr(char *name, char *stockid, ui_callback f, void *udata, ...) { + UiStToolItem *item = malloc(sizeof(UiStToolItem)); + item->item.add_to = (ui_toolbar_add_f)add_toolitem_toggle_st_widget; + item->stockid = stockid; + item->callback = f; + item->userdata = udata; + item->groups = NULL; + item->isimportant = 0; // add groups va_list ap; - va_start(ap, userdata); + va_start(ap, udata); int group; while((group = va_arg(ap, int)) != -1) { item->groups = ucx_list_append(item->groups, (void*)(intptr_t)group); @@ -75,6 +132,29 @@ ucx_map_cstr_put(toolbar_items, name, item); } +void ui_toolitem_toggle_imggr(char *name, char *label, char *img, ui_callback f, void *udata, ...) { + UiToolItem *item = malloc(sizeof(UiToolItem)); + item->item.add_to = (ui_toolbar_add_f)add_toolitem_toggle_widget; + item->label = label; + item->image = img; + item->callback = f; + item->userdata = udata; + item->groups = NULL; + item->isimportant = 0; + + // add groups + va_list ap; + va_start(ap, udata); + int group; + while((group = va_arg(ap, int)) != -1) { + item->groups = ucx_list_append(item->groups, (void*)(intptr_t)group); + } + va_end(ap); + + ucx_map_cstr_put(toolbar_items, name, item); +} + + void ui_toolbar_add_default(char *name) { char *s = strdup(name); defaults = ucx_list_append(defaults, s); @@ -110,6 +190,11 @@ void add_toolitem_widget(GtkToolbar *tb, UiToolItem *item, UiObject *obj) { GtkToolItem *button = gtk_tool_button_new(NULL, item->label); gtk_tool_item_set_homogeneous(button, FALSE); + if(item->image) { + GdkPixbuf *pixbuf = ui_get_image(item->image); + GtkWidget *image = gtk_image_new_from_pixbuf(pixbuf); + gtk_tool_button_set_icon_widget(GTK_TOOL_BUTTON(button), image); + } if(item->callback) { UiEventData *event = ucx_mempool_malloc( @@ -136,6 +221,9 @@ void add_toolitem_st_widget(GtkToolbar *tb, UiStToolItem *item, UiObject *obj) { GtkToolItem *button = gtk_tool_button_new_from_stock(item->stockid); gtk_tool_item_set_homogeneous(button, FALSE); + if(item->isimportant) { + gtk_tool_item_set_is_important(button, TRUE); + } if(item->callback) { UiEventData *event = ucx_mempool_malloc( @@ -158,3 +246,63 @@ uic_add_group_widget(obj->ctx, button, item->groups); } } + +void add_toolitem_toggle_widget(GtkToolbar *tb, UiToolItem *item, UiObject *obj) { + GtkToolItem *button = gtk_toggle_tool_button_new(); + gtk_tool_item_set_homogeneous(button, FALSE); + if(item->label) { + gtk_tool_button_set_label(GTK_TOOL_BUTTON(button), item->label); + } + if(item->image) { + GdkPixbuf *pixbuf = ui_get_image(item->image); + GtkWidget *image = gtk_image_new_from_pixbuf(pixbuf); + gtk_tool_button_set_icon_widget(GTK_TOOL_BUTTON(button), image); + } + + if(item->callback) { + UiEventData *event = ucx_mempool_malloc( + obj->ctx->mempool, + sizeof(UiEventData)); + event->obj = obj; + event->user_data = item->userdata; + event->callback = item->callback; + + g_signal_connect( + button, + "toggled", + G_CALLBACK(ui_button_toggled), + event); + } + + gtk_toolbar_insert(tb, button, -1); + + if(item->groups) { + uic_add_group_widget(obj->ctx, button, item->groups); + } +} + +void add_toolitem_toggle_st_widget(GtkToolbar *tb, UiStToolItem *item, UiObject *obj) { + GtkToolItem *button = gtk_toggle_tool_button_new_from_stock(item->stockid); + gtk_tool_item_set_homogeneous(button, FALSE); + + if(item->callback) { + UiEventData *event = ucx_mempool_malloc( + obj->ctx->mempool, + sizeof(UiEventData)); + event->obj = obj; + event->user_data = item->userdata; + event->callback = item->callback; + + g_signal_connect( + button, + "toggled", + G_CALLBACK(ui_button_toggled), + event); + } + + gtk_toolbar_insert(tb, button, -1); + + if(item->groups) { + uic_add_group_widget(obj->ctx, button, item->groups); + } +}
--- a/ui/gtk/toolbar.h Sat Apr 12 13:44:53 2014 +0200 +++ b/ui/gtk/toolbar.h Sat May 10 15:43:22 2014 +0200 @@ -48,11 +48,13 @@ }; struct UiToolItem { - UiToolItemI item; + UiToolItemI item; char *label; + char *image; ui_callback callback; void *userdata; UcxList *groups; + int isimportant; }; struct UiStToolItem { @@ -61,14 +63,25 @@ ui_callback callback; void *userdata; UcxList *groups; + int isimportant; }; void ui_toolbar_init(); +void ui_toolitem_vstgr( + char *name, + char *stockid, + int isimportant, + ui_callback f, + void *userdata, + va_list ap); + GtkWidget* ui_create_toolbar(UiObject *obj); void add_toolitem_widget(GtkToolbar *tb, UiToolItem *item, UiObject *obj); void add_toolitem_st_widget(GtkToolbar *tb, UiStToolItem *item, UiObject *obj); +void add_toolitem_toggle_widget(GtkToolbar *tb, UiToolItem *item, UiObject *obj); +void add_toolitem_toggle_st_widget(GtkToolbar *tb, UiStToolItem *item, UiObject *obj); #ifdef __cplusplus
--- a/ui/gtk/toolkit.c Sat Apr 12 13:44:53 2014 +0200 +++ b/ui/gtk/toolkit.c Sat May 10 15:43:22 2014 +0200 @@ -32,14 +32,20 @@ #include "toolkit.h" #include "toolbar.h" +#include "model.h" +#include "image.h" #include "../common/document.h" #include "../common/properties.h" +#include <pthread.h> + static char *application_name; static ui_callback appclose_fnc; static void *appclose_udata; +static UiObject *active_window; + void ui_init(char *appname, int argc, char **argv) { gtk_init(&argc, &argv); application_name = appname; @@ -48,7 +54,9 @@ ui_toolbar_init(); // init custom types - //ui_list_init(); + ui_list_init(); + + ui_image_init(); uic_load_app_properties(); } @@ -57,9 +65,9 @@ return application_name; } -void ui_exitfunc(ui_callback f, void *udata) { +void ui_exitfunc(ui_callback f, void *userdata) { appclose_fnc = f; - appclose_udata = udata; + appclose_udata = userdata; } void ui_openfilefunc(ui_callback f, void *userdata) { @@ -79,10 +87,62 @@ gtk_widget_show_all(obj->widget); } +void ui_close(UiObject *obj) { + gtk_widget_destroy(obj->widget); +} + + +static gboolean ui_job_finished(void *data) { + UiJob *job = data; + + UiEvent event; + event.obj = job->obj; + event.window = job->obj->window; + event.document = job->obj->document; + event.intval = 0; + event.eventdata = NULL; + + job->finish_callback(&event, job->finish_data); + free(job); + return FALSE; +} + +static void* ui_jobthread(void *data) { + UiJob *job = data; + int result = job->job_func(job->job_data); + if(!result) { + g_idle_add(ui_job_finished, job); + } +} + +void ui_job(UiObject *obj, ui_threadfunc tf, void *td, ui_callback f, void *fd) { + UiJob *job = malloc(sizeof(UiJob)); + job->obj = obj; + job->job_func = tf; + job->job_data = td; + job->finish_callback = f; + job->finish_data = fd; + pthread_t pid; + pthread_create(&pid, NULL, ui_jobthread, job); +} + void ui_set_enabled(UIWIDGET widget, int enabled) { gtk_widget_set_sensitive(widget, enabled); } +void ui_set_show_all(UIWIDGET widget, int value) { + gtk_widget_set_no_show_all(widget, !value); +} + +void ui_set_visible(UIWIDGET widget, int visible) { + if(visible) { + gtk_widget_set_no_show_all(widget, FALSE); + gtk_widget_show_all(widget); + } else { + gtk_widget_hide(widget); + } +} + void ui_clipboard_set(char *str) { GtkClipboard *cb = gtk_clipboard_get(GDK_SELECTION_CLIPBOARD); gtk_clipboard_set_text(cb, str, strlen(str)); @@ -103,3 +163,11 @@ void ui_destroy_userdata(GtkWidget *object, void *userdata) { free(userdata); } + +void ui_set_active_window(UiObject *obj) { + active_window = obj; +} + +UiObject *ui_get_active_window() { + return active_window; +}
--- a/ui/gtk/toolkit.h Sat Apr 12 13:44:53 2014 +0200 +++ b/ui/gtk/toolkit.h Sat May 10 15:43:22 2014 +0200 @@ -44,8 +44,19 @@ int value; } UiEventData; +typedef struct UiJob { + UiObject *obj; + ui_threadfunc job_func; + void *job_data; + ui_callback finish_callback; + void *finish_data; +} UiJob; + void ui_destroy_userdata(GtkWidget *object, void *userdata); +void ui_set_active_window(UiObject *obj); +UiObject *ui_get_active_window(); + #ifdef __cplusplus } #endif
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/ui/gtk/tree.c Sat May 10 15:43:22 2014 +0200 @@ -0,0 +1,158 @@ +/* + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. + * + * Copyright 2014 Olaf Wintermann. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#include <stdio.h> +#include <stdlib.h> +#include <string.h> + +#include "../common/context.h" +#include "../common/object.h" +#include "container.h" + +#include "tree.h" + + +void* ui_strmodel_getvalue(void *elm, int column) { + return column == 0 ? elm : NULL; +} + + +UIWIDGET ui_listview_str(UiObject *obj, UiList *list, ui_callback f, void *udata) { + return ui_listview(obj, list, ui_strmodel_getvalue, f, udata); +} + +UIWIDGET ui_listview_var(UiObject *obj, UiListPtr *list, ui_model_getvalue_f getvalue, ui_callback f, void *udata) { + // create treeview + GtkWidget *view = gtk_tree_view_new(); + GtkCellRenderer *renderer = gtk_cell_renderer_text_new(); + GtkTreeViewColumn *column = gtk_tree_view_column_new_with_attributes(NULL, renderer, "text", 0, NULL); + gtk_tree_view_append_column(GTK_TREE_VIEW(view), column); + + gtk_tree_view_set_headers_visible(GTK_TREE_VIEW(view), FALSE); +#ifdef UI_GTK3 + gtk_tree_view_set_activate_on_single_click(GTK_TREE_VIEW(view), TRUE); +#else + +#endif + + UiListModel *model = ui_list_model_new(list, getvalue); + gtk_tree_view_set_model(GTK_TREE_VIEW(view), GTK_TREE_MODEL(model)); + + // add TreeView as observer to the UiList to update the TreeView if the + // data changes + UiListView *listview = ucx_mempool_malloc(obj->ctx->mempool, sizeof(UiListView)); + listview->widget = view; + listview->list = list; + listview->getvalue = getvalue; + list->list->observers = ui_add_observer( + list->list->observers, + (ui_callback)ui_listview_update, + listview); + + // add callback + if(f) { + UiEventData *event = ucx_mempool_malloc( + obj->ctx->mempool, + sizeof(UiEventData)); + event->obj = obj; + event->user_data = udata; + event->callback = f; + event->value = 0; + + g_signal_connect( + view, + "row-activated", + G_CALLBACK(ui_listview_selected), + event); + } + + // add widget to the current container + GtkWidget *scroll_area = gtk_scrolled_window_new(NULL, NULL); + gtk_scrolled_window_set_policy( + GTK_SCROLLED_WINDOW(scroll_area), + GTK_POLICY_AUTOMATIC, + GTK_POLICY_AUTOMATIC); // GTK_POLICY_ALWAYS + gtk_container_add(GTK_CONTAINER(scroll_area), view); + + UiContainer *ct = uic_get_current_container(obj); + ct->add(ct, scroll_area); + + return scroll_area; +} + +UIWIDGET ui_listview(UiObject *obj, UiList *list, ui_model_getvalue_f getvalue, ui_callback f, void *udata) { + UiListPtr *listptr = ucx_mempool_malloc(obj->ctx->mempool, sizeof(UiListPtr)); + listptr->list = list; + return ui_listview_var(obj, listptr, getvalue, f, udata); +} + +UIWIDGET ui_listview_nv(UiObject *obj, char *varname, ui_model_getvalue_f getvalue, ui_callback f, void *udata) { + UiVar *var = uic_connect_var(obj->ctx, varname, UI_VAR_LIST); + if(var) { + UiListVar *value = var->value; + return ui_listview_var(obj, value->listptr, getvalue, f, udata); + } else { + // TODO: error + } + return NULL; +} + + +void ui_listview_update(UiEvent *event, UiListView *view) { + UiList *list = view->list->list; + + UiListModel *model = ui_list_model_new(view->list, view->getvalue); + gtk_tree_view_set_model(GTK_TREE_VIEW(view->widget), GTK_TREE_MODEL(model)); +} + +void ui_listview_selected( + GtkTreeView *treeview, + GtkTreePath *path, + GtkTreeViewColumn *column, + UiEventData *event) +{ + int *indices = gtk_tree_path_get_indices(path); + int depth = gtk_tree_path_get_depth(path); + if(depth == 0) { + fprintf(stderr, "UiError: ui_treeview_selected: depth == 0\n"); + return; + } + GtkTreeModel *model = gtk_tree_view_get_model(treeview); + GtkTreeIter iter; + gtk_tree_model_get_iter (model, &iter, path); + void *value = NULL; + gtk_tree_model_get(model, &iter, 0, &value, -1); + + UiEvent e; + e.obj = event->obj; + e.window = event->obj->window; + e.document = event->obj->document; + e.eventdata = value; + e.intval = indices[depth-1]; + event->callback(&e, event->user_data); +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/ui/gtk/tree.h Sat May 10 15:43:22 2014 +0200 @@ -0,0 +1,62 @@ +/* + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. + * + * Copyright 2014 Olaf Wintermann. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef TREE_H +#define TREE_H + +#include "../ui/tree.h" +#include "toolkit.h" +#include "model.h" + +#ifdef __cplusplus +extern "C" { +#endif + +typedef struct UiListView { + GtkWidget *widget; + UiListPtr *list; + ui_model_getvalue_f getvalue; +} UiListView; + +void* ui_strmodel_getvalue(void *elm, int column); + +UIWIDGET ui_listview_var(UiObject *obj, UiListPtr *list, ui_model_getvalue_f getvalue, ui_callback f, void *udata); + +void ui_listview_update(UiEvent *event, UiListView *view); +void ui_listview_selected( + GtkTreeView *tree_view, + GtkTreePath *path, + GtkTreeViewColumn *column, + UiEventData *event); + +#ifdef __cplusplus +} +#endif + +#endif /* TREE_H */ +
--- a/ui/ui/text.h Sat Apr 12 13:44:53 2014 +0200 +++ b/ui/ui/text.h Sat May 10 15:43:22 2014 +0200 @@ -36,6 +36,7 @@ #endif UIWIDGET ui_textarea(UiObject *obj, UiText *value); +UIWIDGET ui_textarea_nv(UiObject *obj, char *varname); void ui_text_undo(UiText *value); void ui_text_redo(UiText *value);
--- a/ui/ui/toolbar.h Sat Apr 12 13:44:53 2014 +0200 +++ b/ui/ui/toolbar.h Sat May 10 15:43:22 2014 +0200 @@ -30,6 +30,7 @@ #define UI_TOOLBAR_H #include "toolkit.h" +#include <stdarg.h> #ifdef __cplusplus extern "C" { @@ -37,7 +38,13 @@ void ui_toolitem(char *name, char *label, ui_callback f, void *udata); void ui_toolitem_st(char *name, char *stockid, ui_callback f, void *udata); +void ui_toolitem_sti(char *name, char *stockid, ui_callback f, void *udata); void ui_toolitem_stgr(char *name, char *stockid, ui_callback f, void *udata, ...); +void ui_toolitem_stgri(char *name, char *stockid, ui_callback f, void *userdata, ...); +void ui_toolitem_img(char *name, char *label, char *img, ui_callback f, void *udata); +void ui_toolitem_toggle_st(char *name, char *stockid, ui_callback f, void *udata, ...); +void ui_toolitem_toggle_stgr(char *name, char *stockid, ui_callback f, void *udata, ...); +void ui_toolitem_toggle_imggr(char *name, char *label, char *img, ui_callback f, void *udata, ...); void ui_toolbar_add_default(char *name);
--- a/ui/ui/toolkit.h Sat Apr 12 13:44:53 2014 +0200 +++ b/ui/ui/toolkit.h Sat May 10 15:43:22 2014 +0200 @@ -49,6 +49,15 @@ #include <Xm/XmAll.h> #define UIWIDGET Widget +#elif defined(UI_QT4) || defined(UI_QT5) +#ifdef __cplusplus +#include <QApplication> +#include <QWidget> +#define UIWIDGET QWidget* +#else /* __cplusplus */ +#define UIWIDGET void* +#endif + #endif #ifdef __cplusplus @@ -58,14 +67,14 @@ #define UI_GROUP_SELECTION 20000 /* public types */ -typedef struct UiObject UiObject; -typedef struct UiEvent UiEvent; -typedef struct UiObserver UiObserver; +typedef struct UiObject UiObject; +typedef struct UiEvent UiEvent; +typedef struct UiObserver UiObserver; -typedef struct UiInteger UiInteger; -typedef struct UiString UiString; -typedef struct UiText UiText; -typedef struct UiList UiList; +typedef struct UiInteger UiInteger; +typedef struct UiString UiString; +typedef struct UiText UiText; +typedef struct UiList UiList; /* private types */ typedef struct UiContext UiContext; @@ -74,37 +83,49 @@ #define ui_getval(val) (val).get(&(val)) #define ui_setval(val, v) (val).set(&(val), v) -#define ui_getsubstr(text, begin, end) (text).getsubstr(&(val), begin, end) +#define ui_getsubstr(text, begin, end) (text).getsubstr(&(text), begin, end) #define ui_insert(text, begin, str) (text).insert(&(text), begin, str) +#define ui_length(text) (text).length(&(text)) +#define ui_selection(text, begin, end) (text).selection(&(text), begin, end) +#define ui_position(text) (text).position(&(text)) +#define ui_remove(text, begin, end) (text).remove(&(text), begin, end) + +typedef void(*ui_callback)(UiEvent*, void*); /* event, user data */ - -typedef void(*ui_callback)(UiEvent*, void*); /* event, user data */ +typedef void*(*ui_model_getvalue_f)(void*, int); + +typedef int(*ui_threadfunc)(void*); struct UiObject { /* * native widget */ - UIWIDGET widget; + UIWIDGET widget; /* * user window data */ - void *window; + void *window; /* * current document */ - void *document; + void *document; /* * window context (private) */ - UiContext *ctx; + UiContext *ctx; /* * container interface (private) */ UiContainer *container; + + /* + * next container object + */ + UiObject *next; }; struct UiEvent { @@ -143,10 +164,11 @@ int (*position)(UiText*); void (*selection)(UiText*, int*, int*); // text, begin, end int (*length)(UiText*); + void (*remove)(UiText*, int, int); // text, begin, end char *value; void *obj; void *undomgr; - // TODO: selection, undo, replace, ... + // TODO: replace, ... }; /* @@ -170,6 +192,7 @@ }; + void ui_init(char *appname, int argc, char **argv); char* ui_appname(); @@ -178,7 +201,16 @@ void ui_main(); void ui_show(UiObject *obj); +void ui_close(UiObject *obj); + +void ui_job(ui_threadfunc tf, void *td, ui_callback f, void *fd); + void ui_set_enabled(UIWIDGET widget, int enabled); +void ui_set_show_all(UIWIDGET widget, int value); +void ui_set_visible(UIWIDGET widget, int visible); + +UIWIDGET ui_sidebar(UiObject *obj); +void ui_end(UiObject *obj); void ui_set_document(UiObject *obj, void *document); void ui_detach_document(UiObject *obj, void *document); @@ -197,6 +229,9 @@ void ui_document_setint(void *doc, char *name, int val); int ui_document_getint(void *doc, char *name); +void ui_document_regtext(void *doc, char *name, UiText *text); +void ui_document_reglist(void *doc, char *name, UiList *list); + // new: int ui_getint(UiObject *obj, char *name); @@ -226,6 +261,8 @@ void ui_clipboard_set(char *str); char* ui_clipboard_get(); +void ui_add_image(char *imgname, char *filename); + #ifdef __cplusplus } #endif
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/ui/ui/tree.h Sat May 10 15:43:22 2014 +0200 @@ -0,0 +1,47 @@ +/* + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. + * + * Copyright 2014 Olaf Wintermann. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef UI_TREE_H +#define UI_TREE_H + +#include "toolkit.h" + +#ifdef __cplusplus +extern "C" { +#endif + +UIWIDGET ui_listview(UiObject *obj, UiList *list, ui_model_getvalue_f getvalue, ui_callback f, void *udata); +UIWIDGET ui_listview_str(UiObject *obj, UiList *list, ui_callback f, void *udata); +UIWIDGET ui_listview_nv(UiObject *obj, char *listname, ui_model_getvalue_f getvalue, ui_callback f, void *udata); + +#ifdef __cplusplus +} +#endif + +#endif /* UI_TREE_H */ +