added listview, sidebar and toolbar image button (GTK)

Sat, 10 May 2014 15:43:22 +0200

author
Olaf Wintermann <olaf.wintermann@gmail.com>
date
Sat, 10 May 2014 15:43:22 +0200
changeset 33
458831c574f4
parent 32
9a5f47fbc5c3
child 34
0ec8a5f17782

added listview, sidebar and toolbar image button (GTK)

application/main.c file | annotate | diff | comparison | revisions
make/gcc.mk file | annotate | diff | comparison | revisions
ui/common/context.c file | annotate | diff | comparison | revisions
ui/common/context.h file | annotate | diff | comparison | revisions
ui/common/document.c file | annotate | diff | comparison | revisions
ui/common/object.c file | annotate | diff | comparison | revisions
ui/common/object.h file | annotate | diff | comparison | revisions
ui/common/properties.c file | annotate | diff | comparison | revisions
ui/common/properties.h file | annotate | diff | comparison | revisions
ui/gtk/button.c file | annotate | diff | comparison | revisions
ui/gtk/button.h file | annotate | diff | comparison | revisions
ui/gtk/container.c file | annotate | diff | comparison | revisions
ui/gtk/container.h file | annotate | diff | comparison | revisions
ui/gtk/image.c file | annotate | diff | comparison | revisions
ui/gtk/image.h file | annotate | diff | comparison | revisions
ui/gtk/objs.mk file | annotate | diff | comparison | revisions
ui/gtk/text.c file | annotate | diff | comparison | revisions
ui/gtk/text.h file | annotate | diff | comparison | revisions
ui/gtk/toolbar.c file | annotate | diff | comparison | revisions
ui/gtk/toolbar.h file | annotate | diff | comparison | revisions
ui/gtk/toolkit.c file | annotate | diff | comparison | revisions
ui/gtk/toolkit.h file | annotate | diff | comparison | revisions
ui/gtk/tree.c file | annotate | diff | comparison | revisions
ui/gtk/tree.h file | annotate | diff | comparison | revisions
ui/ui/text.h file | annotate | diff | comparison | revisions
ui/ui/toolbar.h file | annotate | diff | comparison | revisions
ui/ui/toolkit.h file | annotate | diff | comparison | revisions
ui/ui/tree.h file | annotate | diff | comparison | revisions
ui/ui/ui.h file | annotate | diff | comparison | revisions
--- 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 */
+
--- a/ui/ui/ui.h	Sat Apr 12 13:44:53 2014 +0200
+++ b/ui/ui/ui.h	Sat May 10 15:43:22 2014 +0200
@@ -37,6 +37,7 @@
 #include "button.h"
 #include "text.h"
 #include "properties.h"
+#include "tree.h"
 
 #endif	/* UI_H */
 

mercurial