add new toolbar toggle button

Thu, 10 Dec 2020 13:42:25 +0100

author
Olaf Wintermann <olaf.wintermann@gmail.com>
date
Thu, 10 Dec 2020 13:42:25 +0100
changeset 167
161511838ea6
parent 166
6e48030cf2db
child 168
1b99acacc5bb

add new toolbar toggle button

ui/common/context.c file | annotate | diff | comparison | revisions
ui/common/context.h file | annotate | diff | comparison | revisions
ui/common/types.c 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/image.c file | annotate | diff | comparison | revisions
ui/gtk/image.h file | annotate | diff | comparison | revisions
ui/gtk/text.c 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/ui/toolbar.h file | annotate | diff | comparison | revisions
ui/ui/toolkit.h file | annotate | diff | comparison | revisions
--- a/ui/common/context.c	Tue Dec 08 15:19:31 2020 +0100
+++ b/ui/common/context.c	Thu Dec 10 13:42:25 2020 +0100
@@ -36,6 +36,16 @@
 #include "document.h"
 #include "types.h"
 
+static UiContext* global_context;
+
+void uic_init_global_context(void) {
+    UcxMempool *mp = ucx_mempool_new(32);
+    global_context = uic_context(NULL, mp);
+}
+
+UiContext* ui_global_context(void) {
+    return global_context;
+}
 
 UiContext* uic_context(UiObject *toplevel, UcxMempool *mp) {
     UiContext *ctx = ucx_mempool_malloc(mp, sizeof(UiContext));
@@ -48,7 +58,7 @@
     ctx->detach_document2 = uic_context_detach_document2;
     
 #ifdef UI_GTK
-    if(toplevel->widget) {
+    if(toplevel && toplevel->widget) {
         ctx->accel_group = gtk_accel_group_new();
         gtk_window_add_accel_group(GTK_WINDOW(toplevel->widget), ctx->accel_group);
     }
@@ -156,12 +166,12 @@
     return var;
 }
 
-UiVar* uic_get_var(UiContext *ctx, char *name) {
+UiVar* uic_get_var(UiContext *ctx, const char *name) {
     UcxKey key = ucx_key(name, strlen(name));
     return ctx_getvar(ctx, key);
 }
 
-UiVar* uic_create_var(UiContext *ctx, char *name, UiVarType type) {
+UiVar* uic_create_var(UiContext *ctx, const char *name, UiVarType type) {
     UiVar *var = uic_get_var(ctx, name);
     if(var) {
         if(var->type == type) {
--- a/ui/common/context.h	Tue Dec 08 15:19:31 2020 +0100
+++ b/ui/common/context.h	Thu Dec 10 13:42:25 2020 +0100
@@ -97,6 +97,8 @@
 };
 
 
+void uic_init_global_context(void);
+
 UiContext* uic_context(UiObject *toplevel, UcxMempool *mp);
 UiContext* uic_root_context(UiContext *ctx);
 void uic_context_set_document(UiContext *ctx, void *document); // deprecated
@@ -106,8 +108,8 @@
 void uic_context_detach_document2(UiContext *ctx, void *document);
 void uic_context_detach_all(UiContext *ctx);
 
-UiVar* uic_get_var(UiContext *ctx, char *name);
-UiVar* uic_create_var(UiContext *ctx, char *name, UiVarType type);
+UiVar* uic_get_var(UiContext *ctx, const char *name);
+UiVar* uic_create_var(UiContext *ctx, const char *name, UiVarType type);
 void* uic_create_value(UiContext *ctx, UiVarType type);
 
 void uic_copy_binding(UiVar *from, UiVar *to, UiBool copytodoc);
--- a/ui/common/types.c	Tue Dec 08 15:19:31 2020 +0100
+++ b/ui/common/types.c	Thu Dec 10 13:42:25 2020 +0100
@@ -67,14 +67,15 @@
 }
 
 void ui_notify_except(UiObserver *observer, UiObserver *exc, void *data) {
+    UiEvent evt;
+    evt.obj = NULL;
+    evt.window = NULL;
+    evt.document = NULL;
+    evt.eventdata = data;
+    evt.intval = 0;
+    
     while(observer) {
-        if(observer != exc) {
-            UiEvent evt;
-            evt.obj = NULL;
-            evt.window = NULL;
-            evt.document = NULL;
-            evt.eventdata = data;
-            evt.intval = 0;
+        if(observer != exc) { 
             observer->callback(&evt, observer->data);
         }
         observer = observer->next;
--- a/ui/gtk/button.c	Tue Dec 08 15:19:31 2020 +0100
+++ b/ui/gtk/button.c	Thu Dec 10 13:42:25 2020 +0100
@@ -74,16 +74,6 @@
     event->callback(&e, event->userdata);
 }
 
-void ui_button_toggled(GtkToggleToolButton *widget, UiEventData *event) {
-    UiEvent e;
-    e.obj = event->obj;
-    e.window = event->obj->window;
-    e.document = event->obj->ctx->document;
-    e.eventdata = NULL;
-    e.intval = gtk_toggle_tool_button_get_active(widget);
-    event->callback(&e, event->userdata);
-}
-
 int64_t ui_toggle_button_get(UiInteger *integer) {
     GtkToggleButton *button = integer->obj;
     integer->value = (int)gtk_toggle_button_get_active(button);
--- a/ui/gtk/button.h	Tue Dec 08 15:19:31 2020 +0100
+++ b/ui/gtk/button.h	Thu Dec 10 13:42:25 2020 +0100
@@ -39,7 +39,6 @@
 
 // event wrapper
 void ui_button_clicked(GtkWidget *widget, UiEventData *event);
-void ui_button_toggled(GtkToggleToolButton *widget, UiEventData *event);
 
 
 void ui_toggled_obs(GtkToggleToolButton *widget, UiVarEventData *event);
--- a/ui/gtk/image.c	Tue Dec 08 15:19:31 2020 +0100
+++ b/ui/gtk/image.c	Thu Dec 10 13:42:25 2020 +0100
@@ -47,7 +47,7 @@
 
 // **** deprecated functions ****
 
-GdkPixbuf* ui_get_image(char *name) {
+GdkPixbuf* ui_get_image(const char *name) {
     UiImage *img = ucx_map_cstr_get(image_map, name);
     if(img) {
         return img->pixbuf;
--- a/ui/gtk/image.h	Tue Dec 08 15:19:31 2020 +0100
+++ b/ui/gtk/image.h	Thu Dec 10 13:42:25 2020 +0100
@@ -50,7 +50,7 @@
 
 void ui_image_init(void);
 
-GdkPixbuf* ui_get_image(char *name);
+GdkPixbuf* ui_get_image(const char *name);
 
 
 #ifdef	__cplusplus
--- a/ui/gtk/text.c	Tue Dec 08 15:19:31 2020 +0100
+++ b/ui/gtk/text.c	Thu Dec 10 13:42:25 2020 +0100
@@ -568,6 +568,8 @@
         var = malloc(sizeof(UiVar));
         var->value = value;
         var->type = UI_VAR_SPECIAL;
+        var->from = NULL;
+        var->from_ctx = NULL;
     }
     return create_textfield_var(obj, width, frameless, password, var);
 }
--- a/ui/gtk/toolbar.c	Tue Dec 08 15:19:31 2020 +0100
+++ b/ui/gtk/toolbar.c	Thu Dec 10 13:42:25 2020 +0100
@@ -108,49 +108,58 @@
     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;
+void ui_toolitem_toggle(const char *name, const char *label, const char *img, UiInteger *i) {
+    UiToggleToolItem *item = malloc(sizeof(UiToggleToolItem));
+    item->item.add_to = (ui_toolbar_add_f)add_toolitem_toggle_widget;
+    item->label = label;
+    item->image = img;
+    item->stockid = NULL;
     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);
+    item->value = i;
+    item->var = NULL;
     
     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));
+void ui_toolitem_toggle_st(const char *name, const char *stockid, UiInteger *i) {
+    UiToggleToolItem *item = malloc(sizeof(UiToggleToolItem));
+    item->item.add_to = (ui_toolbar_add_f)add_toolitem_toggle_widget;
+    item->label = NULL;
+    item->image = NULL;
+    item->stockid = stockid;
+    item->groups = NULL;
+    item->isimportant = 0;
+    item->value = i;
+    item->var = NULL;
+    
+    ucx_map_cstr_put(toolbar_items, name, item);
+}
+
+void ui_toolitem_toggle_nv(const char *name, const char *label, const char *img, const char *intvar) {
+    UiToggleToolItem *item = malloc(sizeof(UiToggleToolItem));
     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->stockid = NULL;
     item->groups = NULL;
     item->isimportant = 0;
+    item->value = NULL;
+    item->var = intvar;
     
-    // 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_toolitem_toggle_stnv(const char *name, const char *stockid, const char *intvar) {
+    UiToggleToolItem *item = malloc(sizeof(UiToggleToolItem));
+    item->item.add_to = (ui_toolbar_add_f)add_toolitem_toggle_widget;
+    item->label = NULL;
+    item->image = NULL;
+    item->stockid = stockid;
+    item->groups = NULL;
+    item->isimportant = 0;
+    item->value = NULL;
+    item->var = intvar;
     
     ucx_map_cstr_put(toolbar_items, name, item);
 }
@@ -299,33 +308,61 @@
     }
 }
 
-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);
+void add_toolitem_toggle_widget(GtkToolbar *tb, UiToggleToolItem *item, UiObject *obj) {
+    GtkToolItem *button;
+    if(item->stockid) {
+        button = gtk_toggle_tool_button_new_from_stock(item->stockid);
+    } else {
+        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->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->userdata = item->userdata;
-        event->callback = item->callback;
-        
-        g_signal_connect(
-                button,
-                "toggled",
-                G_CALLBACK(ui_button_toggled),
-                event);
+    UiVar *var;
+    if(item->value) {
+        var = malloc(sizeof(UiVar));
+        var->value = item->value;
+        var->type = UI_VAR_SPECIAL;
+        var->from = NULL;
+        var->from_ctx = NULL;
+    } else {
+        var = uic_create_var(obj->ctx, item->var, UI_VAR_INTEGER);
     }
     
+    if(var->value) {
+        UiInteger *i = var->value;
+        i->get = ui_tool_toggle_button_get;
+        i->set = ui_tool_toggle_button_set;
+        i->obj = button;
+        
+        if(i->value != 0) {
+            gtk_toggle_tool_button_set_active(GTK_TOGGLE_TOOL_BUTTON(button), TRUE);
+        }
+    }
+    
+    // register event
+    // the event func will call the UiInteger observer callbacks
+    UiEventData *event = ucx_mempool_malloc(
+            obj->ctx->mempool,
+            sizeof(UiEventData));
+    event->obj = obj;
+    event->userdata = var;
+    event->callback = NULL;
+
+    g_signal_connect(
+            button,
+            "toggled",
+            G_CALLBACK(ui_tool_button_toggled),
+            event);
+    
+    // add item to toolbar
     gtk_toolbar_insert(tb, button, -1);
     
     if(item->groups) {
@@ -333,30 +370,29 @@
     }
 }
 
-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);
+void ui_tool_button_toggled(GtkToggleToolButton *widget, UiEventData *event) {
+    UiEvent e;
+    e.obj = event->obj;
+    e.window = event->obj->window;
+    e.document = event->obj->ctx->document;
+    e.eventdata = NULL;
+    e.intval = gtk_toggle_tool_button_get_active(widget);
+    
+    UiVar *var = event->userdata;
+    UiInteger *i = var->value;
     
-    if(item->callback) {
-        UiEventData *event = ucx_mempool_malloc(
-                obj->ctx->mempool,
-                sizeof(UiEventData));
-        event->obj = obj;
-        event->userdata = 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);
-    }
+    ui_notify_evt(i->observers, &e);
+}
+
+int64_t ui_tool_toggle_button_get(UiInteger *integer) {
+    integer->value = gtk_toggle_tool_button_get_active(GTK_TOGGLE_TOOL_BUTTON(integer->obj));
+    return integer->value;
+}
+
+void ui_tool_toggle_button_set(UiInteger *integer, int64_t value) {
+    gboolean s = integer->value != 0 ? TRUE : FALSE;
+    gtk_toggle_tool_button_set_active(GTK_TOGGLE_TOOL_BUTTON(integer->obj), s);
+    integer->value = s;
 }
 
 void add_toolbar_combobox(GtkToolbar *tb, UiToolbarComboBox *cb, UiObject *obj) {
--- a/ui/gtk/toolbar.h	Tue Dec 08 15:19:31 2020 +0100
+++ b/ui/gtk/toolbar.h	Thu Dec 10 13:42:25 2020 +0100
@@ -40,9 +40,10 @@
 extern "C" {
 #endif
 
-typedef struct UiToolItemI    UiToolItemI;
-typedef struct UiToolItem     UiToolItem;
-typedef struct UiStToolItem   UiStToolItem;
+typedef struct UiToolItemI      UiToolItemI;
+typedef struct UiToolItem       UiToolItem;
+typedef struct UiStToolItem     UiStToolItem;
+typedef struct UiToggleToolItem UiToggleToolItem;
 
 typedef struct UiToolbarComboBox   UiToolbarComboBox;
 typedef struct UiToolbarComboBoxNV UiToolbarComboBoxNV;
@@ -55,19 +56,32 @@
 
 struct UiToolItem {
     UiToolItemI    item;
-    char           *label;
-    char           *image;
+    const char     *label;
+    const char     *image;
     ui_callback    callback;
     void           *userdata;
+    const char     *varname;
     UcxList        *groups;
     int            isimportant;
 };
 
 struct UiStToolItem {
     UiToolItemI    item;
-    char           *stockid;
+    const char     *stockid;
     ui_callback    callback;
     void           *userdata;
+    const char     *varname;
+    UcxList        *groups;
+    int            isimportant;
+};
+
+struct UiToggleToolItem {
+    UiToolItemI    item;
+    const char     *label;
+    const char     *image;
+    const char     *stockid;
+    UiInteger      *value;
+    const char     *var;
     UcxList        *groups;
     int            isimportant;
 };
@@ -102,14 +116,17 @@
 
 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);
+void add_toolitem_toggle_widget(GtkToolbar *tb, UiToggleToolItem *item, UiObject *obj);
 
 void add_toolbar_combobox(GtkToolbar *tb, UiToolbarComboBox *cb, UiObject *obj);
 void add_toolbar_combobox_nv(GtkToolbar *tb, UiToolbarComboBoxNV *cb, UiObject *obj);
 void ui_combobox_change_event(GtkComboBox *widget, UiEventData *e);
 void ui_combobox_update(UiEvent *event, void *combobox);
 
+void ui_tool_button_toggled(GtkToggleToolButton *widget, UiEventData *event);
+int64_t ui_tool_toggle_button_get(UiInteger *integer);
+void ui_tool_toggle_button_set(UiInteger *integer, int64_t value);
+
 #ifdef	__cplusplus
 }
 #endif
--- a/ui/gtk/toolkit.c	Tue Dec 08 15:19:31 2020 +0100
+++ b/ui/gtk/toolkit.c	Thu Dec 10 13:42:25 2020 +0100
@@ -63,6 +63,8 @@
 static int scale_factor = 1;
 
 void ui_init(char *appname, int argc, char **argv) {
+    uic_init_global_context();
+    
     gtk_init(&argc, &argv);
     application_name = appname;
     
--- a/ui/ui/toolbar.h	Tue Dec 08 15:19:31 2020 +0100
+++ b/ui/ui/toolbar.h	Thu Dec 10 13:42:25 2020 +0100
@@ -42,9 +42,11 @@
 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_toolitem_toggle(const char *name, const char *label, const char *img, UiInteger *i);
+void ui_toolitem_toggle_st(const char *name, const char *stockid, UiInteger *i);
+void ui_toolitem_toggle_nv(const char *name, const char *label, const char *img, const char *intvar);
+void ui_toolitem_toggle_stnv(const char *name, const char *stockid, const char *intvar);
 
 void ui_toolbar_combobox(char *name, UiList *list, ui_getvaluefunc getvalue, ui_callback f, void *udata);
 void ui_toolbar_combobox_str(char *name, UiList *list, ui_callback f, void *udata);
--- a/ui/ui/toolkit.h	Tue Dec 08 15:19:31 2020 +0100
+++ b/ui/ui/toolkit.h	Thu Dec 10 13:42:25 2020 +0100
@@ -285,6 +285,8 @@
 void ui_init(char *appname, int argc, char **argv);
 char* ui_appname();
 
+UiContext* ui_global_context(void);
+
 void ui_context_closefunc(UiContext *ctx, ui_callback fnc, void *udata);
 
 void ui_onstartup(ui_callback f, void *userdata);

mercurial