/*
* file listview list
+ * type: FileInfo*
*/
UiList *list_files;
+ char *list_files_parent;
};
/*
}
} else if(view == 1) {
+ free(browser->list_files_parent);
ui_list_clear(browser->list_files);
CxIterator i = cxListIterator(op->result);
cx_foreach(FileInfo *, file, i) {
ui_list_append(browser->list_files, file);
}
+ browser->list_files_parent = op->url;
+ op->url = NULL;
ui_list_update(browser->list_files);
op->result = NULL;
- // TODO: url?
}
} else {
// TODO: error msg
.varname = "list_files",
.getvalue2 = window_filelistview_getvalue,
.getstyle = window_filelistview_getstyle,
+ .onactivate = window_filelistview_onactivate,
.fill = TRUE);
}
}
item->label = strdup(bookmark->name);
}
+void window_filelistview_onactivate(UiEvent *event, void *userdata) {
+ MainWindow *window = event->window;
+ FileBrowser *browser = event->document;
+ if(event->eventdatatype != UI_EVENT_DATA_LIST_SELECTION) {
+ return;
+ }
+
+ UiListSelection *sel = event->eventdata;
+ if(sel->count == 1) {
+ FileInfo *file = ui_list_get(browser->list_files, sel->rows[0]);
+ open_files(&file, 1, window);
+ }
+}
void* window_filelistview_getvalue(UiList *list, void *elm, int row, int col, void *userdata, UiBool *freeResult) {
FileInfo *file = elm;
void window_sidebar_user_dirs_item(UiList *list, void *sublist_userdata, void *rowdata, int index, UiSubListItem *item, void *userdata);
+void window_filelistview_onactivate(UiEvent *event, void *userdata);
+
void* window_filelistview_getvalue(UiList *list, void *elm, int row, int col, void *userdata, UiBool *freeResult);
UiBool window_filelistview_getstyle(UiList *list, void *elm, int row, int col, void *userdata, UiTextStyle *style);
all: $(UI_LIB) $(UI_SHLIB)
+include common/Makefile
include $(TOOLKIT)/Makefile
-
-$(COMMON_OBJPRE)uic_%$(OBJ_EXT): common/%.c
- $(CC) -o $@ -c -I../ucx/ $(CFLAGS) $(SHLIB_CFLAGS) $(TK_CFLAGS) $<
-
--- /dev/null
+#
+# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
+#
+# Copyright 2012 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.
+#
+
+FORCE:
+
+$(COMMON_OBJPRE)uic_action$(OBJ_EXT): common/action.c common/action.h \
+ common/../ui/toolkit.h common/context.h common/object.h
+ $(CC) -o $@ $(CFLAGS) -I../ucx $(SHLIB_CFLAGS) $(TK_CFLAGS) -c $<
+
+$(COMMON_OBJPRE)uic_app$(OBJ_EXT): common/app.c common/app.h \
+ common/../ui/toolkit.h
+ $(CC) -o $@ $(CFLAGS) -I../ucx $(SHLIB_CFLAGS) $(TK_CFLAGS) -c $<
+
+$(COMMON_OBJPRE)uic_args$(OBJ_EXT): common/args.c common/args.h \
+ common/../ui/window.h common/../ui/toolkit.h common/../ui/container.h \
+ common/../ui/display.h common/../ui/button.h common/../ui/entry.h \
+ common/../ui/menu.h common/../ui/toolbar.h common/../ui/list.h \
+ common/../ui/text.h common/../ui/webview.h common/../ui/widget.h
+ $(CC) -o $@ $(CFLAGS) -I../ucx $(SHLIB_CFLAGS) $(TK_CFLAGS) -c $<
+
+$(COMMON_OBJPRE)uic_condvar$(OBJ_EXT): common/condvar.c common/condvar.h \
+ common/../ui/toolkit.h
+ $(CC) -o $@ $(CFLAGS) -I../ucx $(SHLIB_CFLAGS) $(TK_CFLAGS) -c $<
+
+$(COMMON_OBJPRE)uic_container$(OBJ_EXT): common/container.c \
+ common/container.h common/../ui/container.h common/../ui/toolkit.h \
+ common/object.h common/../ui/toolkit.h
+ $(CC) -o $@ $(CFLAGS) -I../ucx $(SHLIB_CFLAGS) $(TK_CFLAGS) -c $<
+
+$(COMMON_OBJPRE)uic_context$(OBJ_EXT): common/context.c common/context.h \
+ common/../ui/toolkit.h common/action.h common/../ui/window.h \
+ common/../ui/toolkit.h common/../ui/widget.h common/document.h \
+ common/types.h
+ $(CC) -o $@ $(CFLAGS) -I../ucx $(SHLIB_CFLAGS) $(TK_CFLAGS) -c $<
+
+$(COMMON_OBJPRE)uic_document$(OBJ_EXT): common/document.c \
+ common/document.h common/../ui/toolkit.h common/context.h \
+ common/action.h
+ $(CC) -o $@ $(CFLAGS) -I../ucx $(SHLIB_CFLAGS) $(TK_CFLAGS) -c $<
+
+$(COMMON_OBJPRE)uic_icons$(OBJ_EXT): common/icons.c common/icons.h \
+ common/../ui/icons.h common/../ui/toolkit.h
+ $(CC) -o $@ $(CFLAGS) -I../ucx $(SHLIB_CFLAGS) $(TK_CFLAGS) -c $<
+
+$(COMMON_OBJPRE)uic_menu$(OBJ_EXT): common/menu.c common/menu.h \
+ common/../ui/menu.h common/../ui/toolkit.h
+ $(CC) -o $@ $(CFLAGS) -I../ucx $(SHLIB_CFLAGS) $(TK_CFLAGS) -c $<
+
+$(COMMON_OBJPRE)uic_message$(OBJ_EXT): common/message.c common/message.h
+ $(CC) -o $@ $(CFLAGS) -I../ucx $(SHLIB_CFLAGS) $(TK_CFLAGS) -c $<
+
+$(COMMON_OBJPRE)uic_object$(OBJ_EXT): common/object.c common/object.h \
+ common/../ui/toolkit.h common/context.h common/action.h \
+ common/../ui/container.h common/../ui/toolkit.h
+ $(CC) -o $@ $(CFLAGS) -I../ucx $(SHLIB_CFLAGS) $(TK_CFLAGS) -c $<
+
+$(COMMON_OBJPRE)uic_properties$(OBJ_EXT): common/properties.c \
+ common/../ui/toolkit.h common/properties.h common/../ui/properties.h \
+ common/../ui/toolkit.h
+ $(CC) -o $@ $(CFLAGS) -I../ucx $(SHLIB_CFLAGS) $(TK_CFLAGS) -c $<
+
+$(COMMON_OBJPRE)uic_threadpool$(OBJ_EXT): common/threadpool.c \
+ common/threadpool.h common/../ui/toolkit.h common/context.h \
+ common/action.h
+ $(CC) -o $@ $(CFLAGS) -I../ucx $(SHLIB_CFLAGS) $(TK_CFLAGS) -c $<
+
+$(COMMON_OBJPRE)uic_toolbar$(OBJ_EXT): common/toolbar.c common/toolbar.h \
+ common/../ui/toolbar.h common/../ui/toolkit.h common/menu.h \
+ common/../ui/menu.h
+ $(CC) -o $@ $(CFLAGS) -I../ucx $(SHLIB_CFLAGS) $(TK_CFLAGS) -c $<
+
+$(COMMON_OBJPRE)uic_types$(OBJ_EXT): common/types.c common/../ui/list.h \
+ common/../ui/toolkit.h common/types.h common/../ui/toolkit.h \
+ common/context.h common/action.h common/../ui/image.h
+ $(CC) -o $@ $(CFLAGS) -I../ucx $(SHLIB_CFLAGS) $(TK_CFLAGS) -c $<
+
+$(COMMON_OBJPRE)uic_utils$(OBJ_EXT): common/utils.c common/utils.h \
+ common/../ui/toolkit.h common/../ui/text.h common/../ui/toolkit.h \
+ common/properties.h common/../ui/properties.h
+ $(CC) -o $@ $(CFLAGS) -I../ucx $(SHLIB_CFLAGS) $(TK_CFLAGS) -c $<
+
+$(COMMON_OBJPRE)uic_wrapper$(OBJ_EXT): common/wrapper.c common/wrapper.h \
+ common/../ui/toolkit.h common/../ui/list.h common/../ui/toolkit.h \
+ common/../ui/text.h common/types.h
+ $(CC) -o $@ $(CFLAGS) -I../ucx $(SHLIB_CFLAGS) $(TK_CFLAGS) -c $<
+
--- /dev/null
+/*
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
+ *
+ * Copyright 2026 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 "action.h"
+#include "context.h"
+#include "object.h"
+
+#include <cx/string.h>
+
+void uic_add_action(
+ UiContext *ctx,
+ const char *name,
+ ui_callback callback,
+ void *userdata,
+ const char *accelerator,
+ const char *accelerator_text)
+{
+ if(!name) {
+ return;
+ }
+
+ UiAction action;
+ action.name = ui_strdup(ctx, name);
+ action.callback = callback;
+ action.userdata = userdata;
+ action.accelerator = accelerator ? ui_strdup(ctx, accelerator) : NULL;
+ action.accelerator_text = accelerator_text ? ui_strdup(ctx, accelerator_text) : NULL;
+ action.ctx = ctx;
+ cxMapPut(ctx->actions, name, &action);
+ cxMapRehash(ctx->actions);
+}
+
+void uic_bind_action(
+ UiContext *ctx,
+ const char *action,
+ void *bind_obj,
+ ui_enablefunc set_enabled)
+{
+ if(!action) {
+ return;
+ }
+
+ UiActionBinding binding;
+ binding.action = ui_strdup(ctx, action);
+ binding.userdata = bind_obj;
+ binding.set_enabled = set_enabled;
+ cxListAdd(ctx->action_bindings, &binding);
+}
+
+UiAction* uic_resolve_action(UiContext *ctx, const char *action) {
+ UiAction *a = NULL;
+ if(ctx->actions) {
+ a = cxMapGet(ctx->actions, action);
+ }
+ // check if any sub-document defines this action
+ // sub-document actions have precedence, the most specific action will
+ // be returned
+ CxIterator i = cxListIterator(ctx->documents);
+ cx_foreach(void *, doc, i) {
+ UiContext *doc_ctx = ui_document_context(doc);
+ UiAction *sub_action = uic_resolve_action(doc_ctx, action);
+ if(sub_action) {
+ a = sub_action;
+ // if one sub-tree has an action, we don't care about other
+ // subtrees
+ break;
+ }
+ }
+
+ if(!a && ctx->parent) {
+ // check parents
+ a = uic_resolve_action_from_parents(ctx, action);
+ }
+
+ return a;
+}
+
+UiAction* uic_resolve_action_from_parents(UiContext *ctx, const char *action) {
+ UiContext *parent = ctx->parent;
+ if(parent == NULL) {
+ return NULL;
+ }
+ if(parent->actions) {
+ UiAction *a = cxMapGet(parent->actions, action);
+ if(a) {
+ return a;
+ }
+ }
+ return uic_resolve_action_from_parents(parent, action);
+}
+
+
+
+void ui_update_action_bindings(UiContext *ctx) {
+ CxIterator i = cxListIterator(ctx->action_bindings);
+ cx_foreach(UiActionBinding*, binding, i) {
+ UiAction *action = uic_resolve_action(ctx, binding->action);
+ if(binding->set_enabled) {
+ binding->set_enabled(binding->userdata, action != NULL);
+ }
+ }
+}
+
+void uic_action_callback(UiEvent *event, const char *action_name) {
+ UiContext *ctx = ui_global_context();
+ if(event->obj) {
+ ctx = event->obj->ctx;
+ }
+
+ UiAction *action = uic_resolve_action(ctx, action_name);
+ if(action) {
+ // override event document: for actions we know that the event is
+ // for a specific document
+ event->document = action->ctx->self_doc;
+ if(action->callback) {
+ action->callback(event, action->userdata);
+ }
+ }
+}
+
+static int call_action(UiContext *ctx, const char *action_name, void *eventdata, UiEventType eventdatatype, int intval) {
+ UiAction *action = uic_resolve_action(ctx, action_name);
+ if(action && action->callback) {
+ UiEvent event;
+ memset(&event, 0, sizeof(UiEvent));
+ event.obj = ctx->obj;
+ event.window = event.obj ? event.obj->window : NULL;
+ event.document = ctx->self_doc ? ctx->self_doc : ctx->document;
+ if(eventdata) {
+ event.eventdata = eventdata;
+ event.eventdatatype = eventdatatype;
+ }
+ event.intval = intval;
+ action->callback(&event, action->userdata);
+ return 1;
+ } else {
+ return 0;
+ }
+}
+
+int ui_call_action(UiContext *ctx, const char *action_name) {
+ return ui_call_action2(ctx, action_name, NULL, 0);
+}
+
+int ui_call_action2(UiContext *ctx, const char *action_name, void *eventdata, int intval) {
+ return call_action(ctx, action_name, eventdata, UI_EVENT_DATA_POINTER, intval);
+}
+
+int ui_call_action3(UiContext *ctx, const char *action_name, void *ptr, uint64_t type_id) {
+ UiTypedObj *obj = malloc(sizeof(UiTypedObj));
+ obj->ptr = ptr;
+ obj->type = type_id;
+ int ret = call_action(ctx, action_name, obj, UI_EVENT_DATA_TYPED_OBJECT, 0);
+ free(obj);
+ return ret;
+}
+
+static void call_action_recursive(const char *action_name, UiContext *ctx, void *eventdata, UiEventType eventdatatype, int intval, UiBool call_children) {
+ UiEvent event;
+ memset(&event, 0, sizeof(UiEvent));
+ event.obj = ctx->obj;
+ event.window = event.obj ? event.obj->window : NULL;
+ event.document = ctx->self_doc ? ctx->self_doc : ctx->document;
+ if(eventdata) {
+ event.eventdata = eventdata;
+ event.eventdatatype = eventdatatype;
+ }
+ event.intval = intval;
+
+ UiAction *a = NULL;
+ if(ctx->actions) {
+ a = cxMapGet(ctx->actions, action_name);
+ }
+ if(a && a->callback) {
+ a->callback(&event, a->userdata);
+ }
+
+ if(call_children) {
+ CxIterator i = cxListIterator(ctx->documents);
+ cx_foreach(void *, doc, i) {
+ UiContext *doc_ctx = ui_document_context(doc);
+ call_action_recursive(action_name, doc_ctx, eventdata, eventdatatype, intval, TRUE);
+ }
+ }
+}
+
+static void broadcast_action(const char *action_name, void *eventdata, UiEventType eventdatatype, int intval) {
+ CxList *objects = uic_object_list();
+ CxIterator i = cxListIterator(objects);
+ cx_foreach(UiObject*, obj, i) {
+ call_action_recursive(action_name, obj->ctx, eventdata, eventdatatype, intval, TRUE);
+ }
+
+ call_action_recursive(action_name, ui_global_context(), eventdata, eventdatatype, intval, FALSE);
+}
+
+void ui_broadcast_action(const char *action_name) {
+ broadcast_action(action_name, NULL, UI_EVENT_DATA_NULL, 0);
+}
+
+void ui_broadcast_action2(const char *action_name, void *eventdata, int intval) {
+ broadcast_action(action_name, eventdata, UI_EVENT_DATA_POINTER, intval);
+}
+
+void ui_call_action_on(UiContext *ctx, const char *action) {
+ UiEvent event;
+ memset(&event, 0, sizeof(UiEvent));
+ event.obj = ctx->obj;
+ event.window = event.obj ? event.obj->window : NULL;
+ event.document = ctx->self_doc ? ctx->self_doc : ctx->document;
+
+ UiAction *a = NULL;
+ if(ctx->actions) {
+ a = cxMapGet(ctx->actions, action);
+ }
+ if(a && a->callback) {
+ a->callback(&event, a->userdata);
+ }
+}
+
+typedef struct UiActionBroadcast {
+ char *action;
+ void *eventdata;
+ UiEventType eventdatataype;
+ int intval;
+} UiActionBroadcast;
+
+void ui_mainthread_broadcast(const char *action_name) {
+ ui_mainthread_broadcast2(action_name, NULL, 0);
+}
+
+static int mainthread_action_broadcast(void *data) {
+ UiActionBroadcast *broadcast = data;
+ broadcast_action(broadcast->action, broadcast->eventdata, broadcast->eventdatataype, broadcast->intval);
+ if(broadcast->eventdatataype == UI_EVENT_DATA_TYPED_OBJECT) {
+ free(broadcast->eventdata);
+ }
+ free(broadcast->action);
+ free(broadcast);
+ return 0;
+}
+
+void ui_mainthread_broadcast2(const char *action_name, void *eventdata, int intval) {
+ UiActionBroadcast *broadcast = malloc(sizeof(UiActionBroadcast));
+ broadcast->action = strdup(action_name);
+ broadcast->eventdata = eventdata;
+ broadcast->eventdatataype = UI_EVENT_DATA_POINTER;
+ broadcast->intval = intval;
+ ui_call_mainthread(mainthread_action_broadcast, broadcast);
+}
+
+void ui_mainthread_broadcast3(const char *action_name, void *ptr, uint64_t type_id) {
+ UiTypedObj *obj = malloc(sizeof(UiTypedObj));
+ obj->ptr = ptr;
+ obj->type = type_id;
+
+ UiActionBroadcast *broadcast = malloc(sizeof(UiActionBroadcast));
+ broadcast->action = strdup(action_name);
+ broadcast->eventdata = obj;
+ broadcast->eventdatataype = UI_EVENT_DATA_TYPED_OBJECT;
+ broadcast->intval = 0;
+ ui_call_mainthread(mainthread_action_broadcast, broadcast);
+}
--- /dev/null
+/*
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
+ *
+ * Copyright 2026 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 UIC_ACTION_H
+#define UIC_ACTION_H
+
+#include "../ui/toolkit.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+typedef struct UiAction UiAction;
+typedef struct UiActionBinding UiActionBinding;
+
+struct UiAction {
+ char *name;
+ char *accelerator;
+ char *accelerator_text;
+ ui_callback callback;
+ void *userdata;
+ UiContext *ctx;
+};
+
+struct UiActionBinding {
+ const char *action;
+ ui_enablefunc set_enabled;
+ void *userdata;
+};
+
+void uic_add_action(
+ UiContext *ctx,
+ const char *name,
+ ui_callback callback,
+ void *userdata,
+ const char *accelerator,
+ const char *accelerator_text);
+
+void uic_bind_action(
+ UiContext *ctx,
+ const char *action,
+ void *bind_obj,
+ ui_enablefunc set_enabled);
+
+UiAction* uic_resolve_action(UiContext *ctx, const char *action);
+UiAction* uic_resolve_action_from_parents(UiContext *ctx, const char *action);
+
+// action event wrapper
+void uic_action_callback(UiEvent *event, const char *action_name);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* UIC_ACTION_H */
+
static ui_callback startup_func;
static void *startup_data;
+static ui_callback newwindow_func;
+static void *newwindow_data;
static ui_callback open_func;
void *open_data;
static ui_callback exit_func;
startup_data = userdata;
}
+void ui_onnewwindow(ui_callback f, void *userdata) {
+ newwindow_func = f;
+ newwindow_data = userdata;
+}
+
void ui_onopen(ui_callback f, void *userdata) {
open_func = f;
open_data = userdata;
exit_data = userdata;
}
-
void uic_application_startup(UiEvent *event) {
if(startup_func) {
startup_func(event, startup_data);
}
}
+void uic_application_newwindow(UiEvent *event) {
+ if(newwindow_func) {
+ newwindow_func(event, newwindow_data);
+ }
+}
+
void uic_application_open(UiEvent *event) {
if(open_func) {
open_func(event, open_data);
exit_func(event, exit_data);
}
}
+
+void ui_newwindow(void) {
+ uic_application_newwindow(NULL);
+}
#endif
void uic_application_startup(UiEvent *event);
+void uic_application_newwindow(UiEvent *event);
void uic_application_open(UiEvent *event);
void uic_application_exit(UiEvent *event);
args->onclickdata = onclickdata;
}
+void ui_menuitem_args_set_action(UiMenuItemArgs *args, const char *action) {
+ args->action = strdup(action);
+}
+
void ui_menuitem_args_free(UiMenuItemArgs *args) {
free((void*)args->label);
free((void*)args->icon);
+ free((void*)args->action);
free(args);
}
args->onchangedata = onclickdata;
}
+void ui_menutoggleitem_args_set_action(UiMenuToggleItemArgs *args, const char *action) {
+ args->action = strdup(action);
+}
+
void ui_menutoggleitem_args_free(UiMenuToggleItemArgs *args) {
free((void*)args->label);
free((void*)args->icon);
free((void*)args->varname);
+ free((void*)args->action);
free(args);
}
args->getvalue = func;
}
+void ui_menuitemlist_args_set_getvalue2(UiMenuItemListArgs *args, ui_getvaluefunc2 func) {
+ args->getvalue2 = func;
+}
+
+void ui_menuitemlist_args_set_getvaluedata(UiMenuItemListArgs *args, void *data) {
+ args->getvaluedata = data;
+}
+
void ui_menuitemlist_args_set_onselect(UiMenuItemListArgs *args, ui_callback callback) {
args->onselect = callback;
}
args->tooltip = strdup(tooltip);
}
+void ui_toolbar_item_args_set_action(UiToolbarItemArgs *args, const char *action) {
+ args->action = strdup(action);
+}
+
void ui_toolbar_item_args_set_onclick(UiToolbarItemArgs *args, ui_callback callback) {
args->onclick = callback;
}
free((void*)args->label);
free((void*)args->icon);
free((void*)args->tooltip);
+ free((void*)args->action);
free((void*)args->states);
free(args);
}
args->varname = strdup(varname);
}
+void ui_toolbar_toggleitem_args_set_action(UiToolbarToggleItemArgs *args, const char *action) {
+ args->action = strdup(action);
+}
+
void ui_toolbar_toggleitem_args_set_onchange(UiToolbarToggleItemArgs *args, ui_callback callback) {
args->onchange = callback;
}
free((void*)args->icon);
free((void*)args->tooltip);
free((void*)args->varname);
+ free((void*)args->action);
+ free((void*)args->states);
+ free(args);
+}
+
+/* ---------------------------- UiToolbarContentToggleItemArgs ---------------------------- */
+
+UiToolbarContentToggleItemArgs* ui_toolbar_content_toggleitem_args_new(void) {
+ UiToolbarContentToggleItemArgs *args = malloc(sizeof(UiToolbarContentToggleItemArgs));
+ memset(args, 0, sizeof(UiToolbarContentToggleItemArgs));
+ return args;
+}
+
+void ui_toolbar_content_toggleitem_args_set_label0(UiToolbarContentToggleItemArgs *args, const char *label) {
+ args->label0 = strdup(label);
+}
+
+void ui_toolbar_content_toggleitem_args_set_icon0(UiToolbarContentToggleItemArgs *args, const char *icon) {
+ args->icon0 = strdup(icon);
+}
+
+void ui_toolbar_content_toggleitem_args_set_tooltip0(UiToolbarContentToggleItemArgs *args, const char *tooltip) {
+ args->tooltip0 = strdup(tooltip);
+}
+
+void ui_toolbar_content_toggleitem_args_set_label1(UiToolbarContentToggleItemArgs *args, const char *label) {
+ args->label1 = strdup(label);
+}
+
+void ui_toolbar_content_toggleitem_args_set_icon1(UiToolbarContentToggleItemArgs *args, const char *icon) {
+ args->icon1 = strdup(icon);
+}
+
+void ui_toolbar_content_toggleitem_args_set_tooltip1(UiToolbarContentToggleItemArgs *args, const char *tooltip) {
+ args->tooltip1 = strdup(tooltip);
+}
+
+void ui_toolbar_content_toggleitem_args_set_varname(UiToolbarContentToggleItemArgs *args, const char *varname) {
+ args->varname = strdup(varname);
+}
+
+void ui_toolbar_content_toggleitem_args_set_action(UiToolbarContentToggleItemArgs *args, const char *action) {
+ args->action = strdup(action);
+}
+
+void ui_toolbar_content_toggleitem_args_set_onchange(UiToolbarContentToggleItemArgs *args, ui_callback callback) {
+ args->onchange = callback;
+}
+
+void ui_toolbar_content_toggleitem_args_set_onchangedata(UiToolbarContentToggleItemArgs *args, void *onchangedata) {
+ args->onchangedata = onchangedata;
+}
+
+void ui_toolbar_content_toggleitem_args_set_istogglebutton(UiToolbarContentToggleItemArgs *args, UiBool value) {
+ args->istogglebutton = value;
+}
+
+void ui_toolbar_content_toggleitem_args_set_toggled_by_state(UiToolbarContentToggleItemArgs *args, int state) {
+ args->toggled_by_state = state;
+}
+
+void ui_toolbar_content_toggleitem_args_set_states(UiToolbarContentToggleItemArgs *args,int *states, int numstates) {
+ args->states = calloc(numstates+1, sizeof(int));
+ memcpy((void*)args->states, states, numstates * sizeof(int));
+ ((int*)args->states)[numstates] = -1;
+}
+
+void ui_toolbar_content_toggleitem_args_free(UiToolbarContentToggleItemArgs *args) {
+ free((void*)args->label0);
+ free((void*)args->icon0);
+ free((void*)args->tooltip0);
+ free((void*)args->label1);
+ free((void*)args->icon1);
+ free((void*)args->tooltip1);
+ free((void*)args->varname);
+ free((void*)args->action);
free((void*)args->states);
free(args);
}
args->onclickdata = onclickdata;
}
+void ui_button_args_set_action(UiButtonArgs *args, const char *action) {
+ args->action = strdup(action);
+}
+
void ui_button_args_set_states(UiButtonArgs *args, int *states, int numstates) {
args->states = calloc(numstates+1, sizeof(int));
memcpy((void*)args->states, states, numstates * sizeof(int));
free((void*)args->label);
free((void*)args->icon);
free((void*)args->tooltip);
+ free((void*)args->action);
free((void*)args->states);
free((void*)args->visibility_states);
free(args);
args->onchangedata = onchangedata;
}
+void ui_toggle_args_set_action(UiToggleArgs *args, const char *action) {
+ args->action = strdup(action);
+}
+
void ui_toggle_args_set_varname(UiToggleArgs *args, const char *varname) {
args->varname = strdup(varname);
}
free((void*)args->icon);
free((void*)args->tooltip);
free((void*)args->varname);
+ free((void*)args->action);
+ free((void*)args->states);
+ free((void*)args->visibility_states);
+ free(args);
+}
+
+/* ------------------------- UiContentToggleArgs ----------------------------*/
+
+
+UiContentToggleArgs* ui_content_toggle_args_new(void) {
+ UiContentToggleArgs *args = malloc(sizeof(UiContentToggleArgs));
+ memset(args, 0, sizeof(UiContentToggleArgs));
+ return args;
+}
+
+void ui_content_toggle_args_set_fill(UiContentToggleArgs *args, UiBool fill) {
+ args->fill = fill;
+}
+
+void ui_content_toggle_args_set_hexpand(UiContentToggleArgs *args, UiBool value) {
+ args->hexpand = value;
+}
+
+void ui_content_toggle_args_set_vexpand(UiContentToggleArgs *args, UiBool value) {
+ args->vexpand = value;
+}
+
+void ui_content_toggle_args_set_hfill(UiContentToggleArgs *args, UiBool value) {
+ args->hfill = value;
+}
+
+void ui_content_toggle_args_set_vfill(UiContentToggleArgs *args, UiBool value) {
+ args->vfill = value;
+}
+
+void ui_content_toggle_args_set_override_defaults(UiContentToggleArgs *args, UiBool value) {
+ args->override_defaults = value;
+}
+
+void ui_content_toggle_args_set_margin(UiContentToggleArgs *args, int value) {
+ args->margin = value;
+}
+
+void ui_content_toggle_args_set_margin_left(UiContentToggleArgs *args, int value) {
+ args->margin_left = value;
+}
+
+void ui_content_toggle_args_set_margin_right(UiContentToggleArgs *args, int value) {
+ args->margin_right = value;
+}
+
+void ui_content_toggle_args_set_margin_top(UiContentToggleArgs *args, int value) {
+ args->margin_top = value;
+}
+
+void ui_content_toggle_args_set_margin_bottom(UiContentToggleArgs *args, int value) {
+ args->margin_bottom = value;
+}
+
+void ui_content_toggle_args_set_colspan(UiContentToggleArgs *args, int colspan) {
+ args->colspan = colspan;
+}
+
+void ui_content_toggle_args_set_rowspan(UiContentToggleArgs *args, int rowspan) {
+ args->rowspan = rowspan;
+}
+
+
+void ui_content_toggle_args_set_name(UiContentToggleArgs *args, const char *name) {
+ args->name = strdup(name);
+}
+
+void ui_content_toggle_args_set_style_class(UiContentToggleArgs *args, const char *classname) {
+ args->style_class = strdup(classname);
+}
+
+void ui_content_toggle_args_set_label0(UiContentToggleArgs *args, const char *label){
+ args->label0 = strdup(label);
+}
+
+void ui_content_toggle_args_set_icon0(UiContentToggleArgs *args, const char *icon){
+ args->icon0 = strdup(icon);
+}
+
+void ui_content_toggle_args_set_tooltip0(UiContentToggleArgs *args, const char *tooltip) {
+ args->tooltip0 = strdup(tooltip);
+}
+
+void ui_content_toggle_args_set_label1(UiContentToggleArgs *args, const char *label){
+ args->label1 = strdup(label);
+}
+
+void ui_content_toggle_args_set_icon1(UiContentToggleArgs *args, const char *icon){
+ args->icon1 = strdup(icon);
+}
+
+void ui_content_toggle_args_set_tooltip1(UiContentToggleArgs *args, const char *tooltip) {
+ args->tooltip1 = strdup(tooltip);
+}
+
+void ui_content_toggle_args_set_labeltype(UiContentToggleArgs *args, int labeltype){
+ args->labeltype = labeltype;
+}
+
+void ui_content_toggle_args_set_onchange(UiContentToggleArgs *args, ui_callback callback){
+ args->onchange = callback;
+}
+
+void ui_content_toggle_args_set_onchangedata(UiContentToggleArgs *args, void *onchangedata){
+ args->onchangedata = onchangedata;
+}
+
+void ui_content_toggle_args_set_action(UiContentToggleArgs *args, const char *action) {
+ args->action = strdup(action);
+}
+
+void ui_content_toggle_args_set_varname(UiContentToggleArgs *args, const char *varname) {
+ args->varname = strdup(varname);
+}
+
+void ui_content_toggle_args_set_value(UiContentToggleArgs *args, UiInteger *value) {
+ args->value = value;
+}
+
+void ui_content_toggle_args_set_toggled_by_state(UiContentToggleArgs *args, int state) {
+ args->toggled_by_state = state;
+}
+
+void ui_content_toggle_args_set_istogglebutton(UiContentToggleArgs *args, UiBool value) {
+ args->istogglebutton = value;
+}
+
+void ui_content_toggle_args_set_enablestate(UiContentToggleArgs *args, int state) {
+ args->enable_state = state;
+}
+
+void ui_content_toggle_args_set_states(UiContentToggleArgs *args, int *states, int numstates) {
+ args->states = calloc(numstates+1, sizeof(int));
+ memcpy((void*)args->states, states, numstates * sizeof(int));
+ ((int*)args->states)[numstates] = -1;
+}
+
+void ui_content_toggle_args_set_visibility_states(UiContentToggleArgs *args, int *states, int numstates) {
+ args->visibility_states = calloc(numstates+1, sizeof(int));
+ memcpy((void*)args->visibility_states, states, numstates * sizeof(int));
+ ((int*)args->visibility_states)[numstates] = -1;
+}
+
+void ui_content_toggle_args_free(UiContentToggleArgs *args) {
+ free((void*)args->name);
+ free((void*)args->style_class);
+ free((void*)args->label0);
+ free((void*)args->icon0);
+ free((void*)args->tooltip0);
+ free((void*)args->label1);
+ free((void*)args->icon1);
+ free((void*)args->tooltip1);
+ free((void*)args->varname);
+ free((void*)args->action);
free((void*)args->states);
free((void*)args->visibility_states);
free(args);
args->onclickdata = userdata;
}
+void ui_linkbutton_args_set_action(UiLinkButtonArgs *args, const char *action) {
+ args->action = strdup(action);
+}
+
void ui_linkbutton_args_set_nofollow(UiLinkButtonArgs *args, UiBool value) {
args->nofollow = value;
}
free((void*)args->style_class);
free((void*)args->label);
free((void*)args->uri);
+ free((void*)args->action);
free((void*)args->varname);
free((void*)args->states);
free(args);
args->onactivatedata = userdata;
}
+void ui_list_args_set_onactivate_action(UiListArgs *args, const char *action) {
+ args->onactivate_action = strdup(action);
+}
+
void ui_list_args_set_onselection(UiListArgs *args, ui_callback callback) {
args->onselection = callback;
}
args->onselectiondata = userdata;
}
+void ui_list_args_set_onselection_action(UiListArgs *args, const char *action) {
+ args->onselection_action = strdup(action);
+}
+
void ui_list_args_set_ondragstart(UiListArgs *args, ui_callback callback) {
args->ondragstart = callback;
}
args->ondragstartdata = userdata;
}
+void ui_list_args_set_ondragstart_action(UiListArgs *args, const char *action) {
+ args->ondragstart_action = strdup(action);
+}
+
void ui_list_args_set_ondragcomplete(UiListArgs *args, ui_callback callback) {
args->ondragcomplete = callback;
}
args->ondragcompletedata = userdata;
}
+void ui_list_args_set_ondragcomplete_action(UiListArgs *args, const char *action) {
+ args->ondragcomplete_action = strdup(action);
+}
+
void ui_list_args_set_ondrop(UiListArgs *args, ui_callback callback) {
args->ondrop = callback;
}
args->ondropdata = userdata;
}
+void ui_list_args_set_ondrop_action(UiListArgs *args, const char *action) {
+ args->ondrop_action = strdup(action);
+}
+
void ui_list_args_set_onsave(UiListArgs *args, ui_list_savefunc onsave) {
args->onsave = onsave;
}
free((void*)args->name);
free((void*)args->style_class);
free((void*)args->varname);
+ free((void*)args->onactivate_action);
+ free((void*)args->onselection_action);
+ free((void*)args->ondragstart_action);
+ free((void*)args->ondragcomplete_action);
+ free((void*)args->ondrop_action);
if(args->static_elements) {
for(int i=0;i<args->static_nelm;i++) {
free(args->static_elements[i]);
args->header_is_item = value;
}
+UIEXPORT void ui_sourcelist_args_set_states(UiSourceListArgs *args, int *states, int numstates) {
+ args->visibility_states = calloc(numstates+1, sizeof(int));
+ memcpy((void*)args->states, states, numstates * sizeof(int));
+ ((int*)args->states)[numstates] = -1;
+}
+
void ui_sourcelist_args_set_visibility_states(UiSourceListArgs *args, int *states, int numstates) {
args->visibility_states = calloc(numstates+1, sizeof(int));
memcpy((void*)args->visibility_states, states, numstates * sizeof(int));
args->onchangedata = onchangedata;
}
+void ui_textarea_args_set_onchange_action(UiTextAreaArgs *args, const char *action) {
+ args->onchange_action = strdup(action);
+}
+
+void ui_textarea_args_set_ontextchanged(UiTextAreaArgs *args, ui_callback callback) {
+ args->ontextchanged = callback;
+}
+
+void ui_textarea_args_set_ontextchangeddata(UiTextAreaArgs *args, void *onchangedata) {
+ args->ontextchangeddata = onchangedata;
+}
+
+void ui_textarea_args_set_ontextchanged_action(UiTextAreaArgs *args, const char *action) {
+ args->ontextchanged_action = strdup(action);
+}
+
void ui_textarea_args_set_varname(UiTextAreaArgs *args, const char *varname) {
args->varname = strdup(varname);
}
free((void*)args->name);
free((void*)args->style_class);
free((void*)args->varname);
+ free((void*)args->onchange_action);
+ free((void*)args->ontextchanged_action);
free((void*)args->states);
free((void*)args->visibility_states);
free(args);
args->onactivatedata = onactivatedata;
}
+void ui_textfield_args_set_onactivate_action(UiTextFieldArgs *args, const char *action) {
+ args->onactivate_action = strdup(action);
+}
+
+void ui_textfield_args_set_onchange_action(UiTextFieldArgs *args, const char *action) {
+ args->onchange_action = action;
+}
+
void ui_textfield_args_set_varname(UiTextFieldArgs *args, const char *varname) {
args->varname = strdup(varname);
}
free((void*)args->name);
free((void*)args->style_class);
free((void*)args->varname);
+ free((void*)args->onactivate_action);
+ free((void*)args->onchange_action);
free((void*)args->states);
free((void*)args->visibility_states);
free(args);
UIEXPORT void ui_menuitem_args_set_icon(UiMenuItemArgs *args, const char *icon);
UIEXPORT void ui_menuitem_args_set_onclick(UiMenuItemArgs *args, ui_callback callback);
UIEXPORT void ui_menuitem_args_set_onclickdata(UiMenuItemArgs *args, void *onclickdata);
+UIEXPORT void ui_menuitem_args_set_action(UiMenuItemArgs *args, const char *action);
UIEXPORT void ui_menuitem_args_free(UiMenuItemArgs *args);
UIEXPORT UiMenuToggleItemArgs* ui_menutoggleitem_args_new(void);
UIEXPORT void ui_menutoggleitem_args_set_varname(UiMenuToggleItemArgs *args, const char *varname);
UIEXPORT void ui_menutoggleitem_args_set_onchange(UiMenuToggleItemArgs *args, ui_callback callback);
UIEXPORT void ui_menutoggleitem_args_set_onchangedata(UiMenuToggleItemArgs *args, void *onchangedata);
+UIEXPORT void ui_menutoggleitem_args_set_action(UiMenuToggleItemArgs *args, const char *action);
UIEXPORT void ui_menutoggleitem_args_free(UiMenuToggleItemArgs *args);
UIEXPORT UiMenuItemListArgs* ui_menuitemlist_args_new(void);
UIEXPORT void ui_menuitemlist_args_set_varname(UiMenuItemListArgs *args, const char *varname);
UIEXPORT void ui_menuitemlist_args_set_getvalue(UiMenuItemListArgs *args, ui_getvaluefunc func);
+UIEXPORT void ui_menuitemlist_args_set_getvalue2(UiMenuItemListArgs *args, ui_getvaluefunc2 func);
+UIEXPORT void ui_menuitemlist_args_set_getvaluedata(UiMenuItemListArgs *args, void *data);
UIEXPORT void ui_menuitemlist_args_set_onselect(UiMenuItemListArgs *args, ui_callback callback);
UIEXPORT void ui_menuitemlist_args_set_onselectdata(UiMenuItemListArgs *args, void *data);
UIEXPORT void ui_menuitemlist_args_set_addseparator(UiMenuItemListArgs *args, UiBool value);
UIEXPORT void ui_toolbar_item_args_set_label(UiToolbarItemArgs *args, const char *label);
UIEXPORT void ui_toolbar_item_args_set_icon(UiToolbarItemArgs *args, const char *icon);
UIEXPORT void ui_toolbar_item_args_set_tooltip(UiToolbarItemArgs *args, const char *tooltip);
+UIEXPORT void ui_toolbar_item_args_set_action(UiToolbarItemArgs *args, const char *action);
UIEXPORT void ui_toolbar_item_args_set_onclick(UiToolbarItemArgs *args, ui_callback callback);
UIEXPORT void ui_toolbar_item_args_set_onclickdata(UiToolbarItemArgs *args, void *onclickdata);
UIEXPORT void ui_toolbar_item_args_set_states(UiToolbarItemArgs *args, int *states, int numstates);
UIEXPORT void ui_toolbar_toggleitem_args_set_icon(UiToolbarToggleItemArgs *args, const char *icon);
UIEXPORT void ui_toolbar_toggleitem_args_set_tooltip(UiToolbarToggleItemArgs *args, const char *tooltip);
UIEXPORT void ui_toolbar_toggleitem_args_set_varname(UiToolbarToggleItemArgs *args, const char *varname);
+UIEXPORT void ui_toolbar_toggleitem_args_set_action(UiToolbarToggleItemArgs *args, const char *action);
UIEXPORT void ui_toolbar_toggleitem_args_set_onchange(UiToolbarToggleItemArgs *args, ui_callback callback);
UIEXPORT void ui_toolbar_toggleitem_args_set_onchangedata(UiToolbarToggleItemArgs *args, void *onchangedata);
UIEXPORT void ui_toolbar_toggleitem_args_set_states(UiToolbarToggleItemArgs *args, int *states, int numstates);
UIEXPORT void ui_toolbar_toggleitem_args_free(UiToolbarToggleItemArgs *args);
+UIEXPORT UiToolbarContentToggleItemArgs* ui_toolbar_content_toggleitem_args_new(void);
+UIEXPORT void ui_toolbar_content_toggleitem_args_set_label0(UiToolbarContentToggleItemArgs *args, const char *label);
+UIEXPORT void ui_toolbar_content_toggleitem_args_set_icon0(UiToolbarContentToggleItemArgs *args, const char *icon);
+UIEXPORT void ui_toolbar_content_toggleitem_args_set_tooltip0(UiToolbarContentToggleItemArgs *args, const char *tooltip);
+UIEXPORT void ui_toolbar_content_toggleitem_args_set_label1(UiToolbarContentToggleItemArgs *args, const char *label);
+UIEXPORT void ui_toolbar_content_toggleitem_args_set_icon1(UiToolbarContentToggleItemArgs *args, const char *icon);
+UIEXPORT void ui_toolbar_content_toggleitem_args_set_tooltip1(UiToolbarContentToggleItemArgs *args, const char *tooltip);
+UIEXPORT void ui_toolbar_content_toggleitem_args_set_varname(UiToolbarContentToggleItemArgs *args, const char *varname);
+UIEXPORT void ui_toolbar_content_toggleitem_args_set_action(UiToolbarContentToggleItemArgs *args, const char *action);
+UIEXPORT void ui_toolbar_content_toggleitem_args_set_onchange(UiToolbarContentToggleItemArgs *args, ui_callback callback);
+UIEXPORT void ui_toolbar_content_toggleitem_args_set_onchangedata(UiToolbarContentToggleItemArgs *args, void *onchangedata);
+UIEXPORT void ui_toolbar_content_toggleitem_args_set_states(UiToolbarContentToggleItemArgs *args, int *states, int numstates);
+UIEXPORT void ui_toolbar_content_toggleitem_args_set_istogglebutton(UiToolbarContentToggleItemArgs *args, UiBool value);
+UIEXPORT void ui_toolbar_content_toggleitem_args_set_toggled_by_state(UiToolbarContentToggleItemArgs *args, int state);
+UIEXPORT void ui_toolbar_content_toggleitem_args_free(UiToolbarContentToggleItemArgs *args);
+
UIEXPORT UiToolbarMenuArgs* ui_toolbar_menu_args_new(void);
UIEXPORT void ui_toolbar_menu_args_set_label(UiToolbarMenuArgs *args, const char *label);
UIEXPORT void ui_toolbar_menu_args_set_icon(UiToolbarMenuArgs *args, const char *icon);
UIEXPORT void ui_button_args_set_labeltype(UiButtonArgs *args, int labeltype);
UIEXPORT void ui_button_args_set_onclick(UiButtonArgs *args, ui_callback callback);
UIEXPORT void ui_button_args_set_onclickdata(UiButtonArgs *args, void *onclickdata);
+UIEXPORT void ui_button_args_set_action(UiButtonArgs *args, const char *action);
UIEXPORT void ui_button_args_set_states(UiButtonArgs *args, int *states, int numstates);
UIEXPORT void ui_button_args_set_visibility_states(UiButtonArgs *args, int *states, int numstates);
UIEXPORT void ui_button_args_free(UiButtonArgs *args);
UIEXPORT void ui_toggle_args_set_labeltype(UiToggleArgs *args, int labeltype);
UIEXPORT void ui_toggle_args_set_onchange(UiToggleArgs *args, ui_callback callback);
UIEXPORT void ui_toggle_args_set_onchangedata(UiToggleArgs *args, void *onchangedata);
+UIEXPORT void ui_toggle_args_set_action(UiToggleArgs *args, const char *action);
UIEXPORT void ui_toggle_args_set_varname(UiToggleArgs *args, const char *varname);
UIEXPORT void ui_toggle_args_set_value(UiToggleArgs *args, UiInteger *value);
UIEXPORT void ui_toggle_args_set_enablestate(UiToggleArgs *args, int state);
UIEXPORT void ui_toggle_args_set_visibility_states(UiToggleArgs *args, int *states, int numstates);
UIEXPORT void ui_toggle_args_free(UiToggleArgs *args);
+UIEXPORT UiContentToggleArgs* ui_content_toggle_args_new(void);
+UIEXPORT void ui_content_toggle_args_set_fill(UiContentToggleArgs *args, UiBool fill);
+UIEXPORT void ui_content_toggle_args_set_hexpand(UiContentToggleArgs *args, UiBool value);
+UIEXPORT void ui_content_toggle_args_set_vexpand(UiContentToggleArgs *args, UiBool value);
+UIEXPORT void ui_content_toggle_args_set_hfill(UiContentToggleArgs *args, UiBool value);
+UIEXPORT void ui_content_toggle_args_set_vfill(UiContentToggleArgs *args, UiBool value);
+UIEXPORT void ui_content_toggle_args_set_override_defaults(UiContentToggleArgs *args, UiBool value);
+UIEXPORT void ui_content_toggle_args_set_margin(UiContentToggleArgs *args, int value);
+UIEXPORT void ui_content_toggle_args_set_margin_left(UiContentToggleArgs *args, int value);
+UIEXPORT void ui_content_toggle_args_set_margin_right(UiContentToggleArgs *args, int value);
+UIEXPORT void ui_content_toggle_args_set_margin_top(UiContentToggleArgs *args, int value);
+UIEXPORT void ui_content_toggle_args_set_margin_bottom(UiContentToggleArgs *args, int value);
+UIEXPORT void ui_content_toggle_args_set_colspan(UiContentToggleArgs *args, int colspan);
+UIEXPORT void ui_content_toggle_args_set_rowspan(UiContentToggleArgs *args, int rowspan);
+UIEXPORT void ui_content_toggle_args_set_name(UiContentToggleArgs *args, const char *name);
+UIEXPORT void ui_content_toggle_args_set_style_class(UiContentToggleArgs *args, const char *classname);
+UIEXPORT void ui_content_toggle_args_set_label0(UiContentToggleArgs *args, const char *label);
+UIEXPORT void ui_content_toggle_args_set_icon0(UiContentToggleArgs *args, const char *icon);
+UIEXPORT void ui_content_toggle_args_set_tooltip0(UiContentToggleArgs *args, const char *tooltip);
+UIEXPORT void ui_content_toggle_args_set_label1(UiContentToggleArgs *args, const char *label);
+UIEXPORT void ui_content_toggle_args_set_icon1(UiContentToggleArgs *args, const char *icon);
+UIEXPORT void ui_content_toggle_args_set_tooltip1(UiContentToggleArgs *args, const char *tooltip);
+UIEXPORT void ui_content_toggle_args_set_labeltype(UiContentToggleArgs *args, int labeltype);
+UIEXPORT void ui_content_toggle_args_set_onchange(UiContentToggleArgs *args, ui_callback callback);
+UIEXPORT void ui_content_toggle_args_set_onchangedata(UiContentToggleArgs *args, void *onchangedata);
+UIEXPORT void ui_content_toggle_args_set_action(UiContentToggleArgs *args, const char *action);
+UIEXPORT void ui_content_toggle_args_set_varname(UiContentToggleArgs *args, const char *varname);
+UIEXPORT void ui_content_toggle_args_set_value(UiContentToggleArgs *args, UiInteger *value);
+UIEXPORT void ui_content_toggle_args_set_toggled_by_state(UiContentToggleArgs *args, int state);
+UIEXPORT void ui_content_toggle_args_set_istogglebutton(UiContentToggleArgs *args, UiBool value);
+UIEXPORT void ui_content_toggle_args_set_enablestate(UiContentToggleArgs *args, int state);
+UIEXPORT void ui_content_toggle_args_set_states(UiContentToggleArgs *args, int *states, int numstates);
+UIEXPORT void ui_content_toggle_args_set_visibility_states(UiContentToggleArgs *args, int *states, int numstates);
+UIEXPORT void ui_content_toggle_args_free(UiContentToggleArgs *args);
+
UIEXPORT UiLinkButtonArgs* ui_linkbutton_args_new(void);
UIEXPORT void ui_linkbutton_args_set_fill(UiLinkButtonArgs *args, UiBool fill);
UIEXPORT void ui_linkbutton_args_set_hexpand(UiLinkButtonArgs *args, UiBool value);
UIEXPORT void ui_linkbutton_args_set_uri(UiLinkButtonArgs *args, const char *uri);
UIEXPORT void ui_linkbutton_args_set_onclick(UiLinkButtonArgs *args, ui_callback callback);
UIEXPORT void ui_linkbutton_args_set_onclickdata(UiLinkButtonArgs *args, void *userdata);
+UIEXPORT void ui_linkbutton_args_set_action(UiLinkButtonArgs *args, const char *action);
UIEXPORT void ui_linkbutton_args_set_nofollow(UiLinkButtonArgs *args, UiBool value);
UIEXPORT void ui_linkbutton_args_set_type(UiLinkButtonArgs *args, UiLinkType type);
UIEXPORT void ui_linkbutton_args_set_states(UiLinkButtonArgs *args, int *states, int numstates);
UIEXPORT void ui_list_args_set_getstyle_data(UiListArgs *args, void *userdata);
UIEXPORT void ui_list_args_set_onactivate(UiListArgs *args, ui_callback callback);
UIEXPORT void ui_list_args_set_onactivatedata(UiListArgs *args, void *userdata);
+UIEXPORT void ui_list_args_set_onactivate_action(UiListArgs *args, const char *action);
UIEXPORT void ui_list_args_set_onselection(UiListArgs *args, ui_callback callback);
UIEXPORT void ui_list_args_set_onselectiondata(UiListArgs *args, void *userdata);
+UIEXPORT void ui_list_args_set_onselection_action(UiListArgs *args, const char *action);
UIEXPORT void ui_list_args_set_ondragstart(UiListArgs *args, ui_callback callback);
UIEXPORT void ui_list_args_set_ondragstartdata(UiListArgs *args, void *userdata);
+UIEXPORT void ui_list_args_set_ondragstart_action(UiListArgs *args, const char *action);
UIEXPORT void ui_list_args_set_ondragcomplete(UiListArgs *args, ui_callback callback);
UIEXPORT void ui_list_args_set_ondragcompletedata(UiListArgs *args, void *userdata);
+UIEXPORT void ui_list_args_set_ondragcomplete_action(UiListArgs *args, const char *action);
UIEXPORT void ui_list_args_set_ondrop(UiListArgs *args, ui_callback callback);
UIEXPORT void ui_list_args_set_ondropdata(UiListArgs *args, void *userdata);
+UIEXPORT void ui_list_args_set_ondrop_action(UiListArgs *args, const char *action);
UIEXPORT void ui_list_args_set_onsave(UiListArgs *args, ui_list_savefunc onsave);
UIEXPORT void ui_list_args_set_onsavedata(UiListArgs *args, void *userdata);
UIEXPORT void ui_list_args_set_multiselection(UiListArgs *args, UiBool multiselection);
UIEXPORT void ui_sourcelist_args_set_onbuttonclickdata(UiSourceListArgs *args, void *userdata);
UIEXPORT void ui_sourcelist_args_set_contextmenu(UiSourceListArgs *args, UiMenuBuilder *menubuilder);
UIEXPORT void ui_sourcelist_args_set_header_is_item(UiSourceListArgs *args, UiBool value);
+UIEXPORT void ui_sourcelist_args_set_states(UiSourceListArgs *args, int *states, int numstates);
UIEXPORT void ui_sourcelist_args_set_visibility_states(UiSourceListArgs *args, int *states, int numstates);
UIEXPORT void ui_sourcelist_args_free(UiSourceListArgs *args);
UIEXPORT void ui_textarea_args_set_style_class(UiTextAreaArgs *args, const char *classname);
UIEXPORT void ui_textarea_args_set_onchange(UiTextAreaArgs *args, ui_callback callback);
UIEXPORT void ui_textarea_args_set_onchangedata(UiTextAreaArgs *args, void *onchangedata);
+UIEXPORT void ui_textarea_args_set_onchange_action(UiTextAreaArgs *args, const char *action);
+UIEXPORT void ui_textarea_args_set_ontextchanged(UiTextAreaArgs *args, ui_callback callback);
+UIEXPORT void ui_textarea_args_set_ontextchangeddata(UiTextAreaArgs *args, void *onchangedata);
+UIEXPORT void ui_textarea_args_set_ontextchanged_action(UiTextAreaArgs *args, const char *action);
UIEXPORT void ui_textarea_args_set_varname(UiTextAreaArgs *args, const char *varname);
UIEXPORT void ui_textarea_args_set_value(UiTextAreaArgs *args, UiText *value);
UIEXPORT void ui_textarea_args_set_states(UiTextAreaArgs *args, int *states, int numstates);
UIEXPORT void ui_textfield_args_set_onchangedata(UiTextFieldArgs *args, void *onchangedata);
UIEXPORT void ui_textfield_args_set_onactivate(UiTextFieldArgs *args, ui_callback callback);
UIEXPORT void ui_textfield_args_set_onactivatedata(UiTextFieldArgs *args, void *onactivatedata);
+UIEXPORT void ui_textfield_args_set_onactivate_action(UiTextFieldArgs *args, const char *action);
+UIEXPORT void ui_textfield_args_set_onchange_action(UiTextFieldArgs *args, const char *action);
UIEXPORT void ui_textfield_args_set_varname(UiTextFieldArgs *args, const char *varname);
UIEXPORT void ui_textfield_args_set_value(UiTextFieldArgs *args, UiString *value);
UIEXPORT void ui_textfield_args_set_states(UiTextFieldArgs *args, int *states, int numstates);
if(!obj->container_end) {
return;
}
- UiContainerX *rm = obj->container_end;
+ UiContainer *rm = obj->container_end;
uic_object_pop_container(obj);
ui_free(obj->ctx, rm);
}
void ui_newline(UiObject *obj) {
- UiContainerX *container = obj->container_end;
+ UiContainer *container = obj->container_end;
if(container) {
container->newline = TRUE;
}
ctx->state_widgets = cxLinkedListCreate(mp->allocator, sizeof(UiStateWidget));
ctx->states = cxArrayListCreate(mp->allocator, sizeof(int), 32);
cxSetCompareFunc(ctx->states, cx_cmp_int);
+ ctx->suppressed_states = cxArrayListCreate(mp->allocator, sizeof(int), 16);
+ cxSetCompareFunc(ctx->suppressed_states, cx_cmp_int);
ctx->actions = cxHashMapCreate(ctx->allocator, sizeof(UiAction), 8);
ctx->action_bindings = cxArrayListCreate(ctx->allocator, sizeof(UiActionBinding), 0);
- ctx->attach_document = uic_context_attach_document;
- ctx->detach_document2 = uic_context_detach_document;
-
#if UI_GTK2 || UI_GTK3
if(toplevel && toplevel->widget) {
ctx->accel_group = gtk_accel_group_new();
}
#endif
+ ctx->ref = 1;
+
return ctx;
}
cxListAdd(ctx->destroy_handler, &handler);
}
+void uic_context_remove_destructor(UiContext *ctx, void *data) {
+ CxIterator i = cxListIterator(ctx->destroy_handler);
+ cx_foreach(UiDestroyHandler *, handler, i) {
+ if(handler->data == data) {
+ cxIteratorFlagRemoval(i);
+ }
+ }
+}
+
void uic_context_prepare_close(UiContext *ctx) {
cxListClear(ctx->states);
cxListClear(ctx->state_widgets);
+ cxListClear(ctx->action_bindings);
+ uic_context_detach_all(ctx);
}
-void uic_context_attach_document(UiContext *ctx, void *document) {
- if(ctx->single_document_mode) {
- if(ctx->document) {
- uic_context_detach_document(ctx, ctx->document);
- }
+void uic_context_destroy(UiContext *ctx, void *document) {
+ if(!ctx) {
+ return;
}
- cxListAdd(ctx->documents, document);
- ctx->document = document;
+ UiEvent ev;
+ ev.obj = ctx->obj;
+ ev.window = ev.obj ? ev.obj->window : NULL;
+ ev.document = document;
+ ev.eventdata = NULL;
+ ev.eventdatatype = 0;
+ ev.intval = 0;
+ ev.set = 0;
+
+ if(ctx->onclose) {
+ ctx->onclose(&ev, ctx->onclosedata);
+ }
- UiContext *doc_ctx = ui_document_context(document);
- doc_ctx->parent = ctx;
+ CxIterator i = cxListIterator(ctx->destroy_handler);
+ cx_foreach(UiDestroyHandler *, h, i) {
+ h->destructor(h->data);
+ }
+ uic_context_detach_all(ctx);
+
+ cxMempoolFree(ctx->mp);
+}
+
+void uic_context_update_bindings(UiContext *ctx) {
+ int onchange_enabled = ui_onchange_events_is_enabled();
+ int onselection_enabled = ui_selection_events_is_enabled();
+ ui_onchange_events_enable(FALSE);
+ ui_selection_events_enable(FALSE);
// if a document variable has the same name as a parent variable,
// move the bindings to the document
- UiContext *var_ctx = ctx;
+ UiContext *var_ctx = ctx->parent;
while(var_ctx) {
CxMapIterator i = cxMapIterator(var_ctx->vars);
cx_foreach(CxMapEntry*, entry, i) {
- printf("attach %.*s\n", (int)entry->key->len, (char*)entry->key->data);
+ // printf("attach %.*s\n", (int)entry->key->len, (char*)entry->key->data);
UiVar *var = entry->value;
- UiVar *docvar = cxMapGet(doc_ctx->vars, *entry->key);
+ UiVar *docvar = cxMapGet(ctx->vars, *entry->key);
if(docvar) {
// bind var to document var
uic_copy_var_binding(var, docvar, TRUE);
var_ctx = var_ctx->parent;
}
+
+ ui_update_action_bindings(ctx);
+
+ if(ctx->documents) {
+ CxIterator i = cxListIterator(ctx->documents);
+ cx_foreach(void *, doc, i) {
+ UiContext *subctx = ui_document_context(doc);
+ uic_context_update_bindings(subctx);
+ }
+ }
+ ui_onchange_events_enable(onchange_enabled);
+ ui_selection_events_enable(onselection_enabled);
+}
+
+void uic_context_attach_document(UiContext *ctx, void *document) {
+ if(ctx->single_document_mode) {
+ if(ctx->document) {
+ uic_context_detach_document(ctx, ctx->document);
+ }
+ }
+
+ cxListAdd(ctx->documents, document);
+ ctx->document = document;
+
+ UiContext *doc_ctx = ui_document_context(document);
+ doc_ctx->parent = ctx;
+ doc_ctx->ref++;
+
+ uic_context_update_bindings(doc_ctx);
+ if(doc_ctx->onattach) {
+ UiEvent event;
+ memset(&event, 0, sizeof(UiEvent));
+ event.document = document;
+ doc_ctx->onattach(&event, doc_ctx->onattachdata);
+ }
+ uic_check_state_widgets(ui_context_toplevel_parent(ctx));
+ UiObject *obj = ui_context_get_parent_obj(ctx);
+ uic_send_status_change(doc_ctx, obj);
+
+ UiContext *obj_ctx = uic_obj_context(ctx);
+ if(obj_ctx) {
+ ui_update_action_bindings(obj_ctx);
+ }
}
static void uic_context_unbind_vars(UiContext *ctx) {
+ int onchange_enabled = ui_onchange_events_is_enabled();
+ int onselection_enabled = ui_selection_events_is_enabled();
ui_onchange_events_enable(FALSE);
+ ui_selection_events_enable(FALSE);
CxMapIterator mi = cxMapIterator(ctx->vars);
cx_foreach(CxMapEntry*, entry, mi) {
- printf("detach %.*s\n", (int)entry->key->len, (char*)entry->key->data);
+ //printf("detach %.*s\n", (int)entry->key->len, (char*)entry->key->data);
UiVar *var = entry->value;
// var->from && var->from_ctx && var->from_ctx != ctx
uic_save_var(var);
}
}
- ui_onchange_events_enable(TRUE);
+ ui_onchange_events_enable(onchange_enabled);
+ ui_selection_events_enable(onselection_enabled);
}
void uic_context_detach_document(UiContext *ctx, void *document) {
cxListRemove(ctx->documents, docIndex);
ctx->document = cxListAt(ctx->documents, 0);
- UiContext *docctx = ui_document_context(document);
- uic_context_unbind_vars(docctx); // unbind all doc/subdoc vars from the parent
- docctx->parent = NULL;
+ UiContext *doc_ctx = ui_document_context(document);
+ uic_context_unbind_vars(doc_ctx); // unbind all doc/subdoc vars from the parent
+ doc_ctx->parent = NULL;
+
+ UiContext *obj_ctx = uic_obj_context(ctx);
+ if(obj_ctx) {
+ ui_update_action_bindings(obj_ctx);
+ }
+ if(doc_ctx->ondetach) {
+ UiEvent event;
+ memset(&event, 0, sizeof(UiEvent));
+ event.document = document;
+ doc_ctx->ondetach(&event, doc_ctx->ondetachdata);
+ }
+
+ uic_check_state_widgets(ui_context_toplevel_parent(ctx));
+ uic_send_status_change(doc_ctx, NULL);
+ ui_document_unref(document);
}
void uic_context_detach_all(UiContext *ctx) {
// detach documents
i = cxListIterator(ls);
cx_foreach(void *, doc, i) {
- ctx->detach_document2(ctx, doc);
+ uic_context_detach_document(ctx, doc);
}
cxListFree(ls);
+ ui_update_action_bindings(ctx);
+}
+
+static void send_status_change(UiContext *ctx, UiEvent *event, UiObject *obj) {
+ CxIterator i = cxListIterator(ctx->documents);
+ cx_foreach(void *, doc, i) {
+ UiContext *doc_ctx = ui_document_context(doc);
+ if(doc_ctx->onattachmentstatuschange) {
+ event->obj = doc_ctx->obj ? doc_ctx->obj : obj;
+ event->window = event->obj ? event->obj->window : NULL;
+ event->document = doc_ctx->self_doc ? doc_ctx->self_doc : doc_ctx->document;
+ doc_ctx->onattachmentstatuschange(event, doc_ctx->onattachmentstatuschangedata);
+ }
+ }
+
+ if(ctx->onattachmentstatuschange) {
+ event->obj = ctx->obj ? ctx->obj : obj;
+ event->window = event->obj ? event->obj->window : NULL;
+ event->document = ctx->self_doc ? ctx->self_doc : ctx->document;
+ ctx->onattachmentstatuschange(event, ctx->onattachmentstatuschangedata);
+ }
+}
+
+void uic_send_status_change(UiContext *ctx, UiObject *obj) {
+ UiEvent event;
+ memset(&event, 0, sizeof(UiEvent));
+ send_status_change(ctx, &event, obj);
}
+
static UiVar* ctx_getvar(UiContext *ctx, CxHashKey key) {
UiVar *var = cxMapGet(ctx->vars, key);
if(!var && ctx->documents) {
case UI_VAR_LIST: {
UiList *f = from;
UiList *t = to;
+ // save selection
+ ui_list_selection_free(f->saved_selection);
+ if(f->getselection && f->save_selection) {
+ f->saved_selection = ui_list_get_selection_allocated(f);
+ } else {
+ f->saved_selection = NULL;
+ }
+
uic_list_copy(f, t);
ui_list_update(t);
+ if(t->setselection && t->saved_selection) {
+ t->setselection(t, *t->saved_selection);
+ }
+ ui_list_selection_free(t->saved_selection);
+ t->saved_selection = NULL;
break;
}
case UI_VAR_RANGE: {
}
void ui_context_closefunc(UiContext *ctx, ui_callback fnc, void *udata) {
- ctx->close_callback = fnc;
- ctx->close_data = udata;
-}
-
-void ui_context_destroy(UiContext *ctx) {
- CxIterator i = cxListIterator(ctx->destroy_handler);
- cx_foreach(UiDestroyHandler *, h, i) {
- h->destructor(h->data);
- }
- cxMempoolFree(ctx->mp);
+ ctx->onclose = fnc;
+ ctx->onclosedata = udata;
}
UiContext* ui_context_parent(UiContext *ctx) {
return ctx->parent;
}
+UiContext* ui_context_toplevel_parent(UiContext *ctx) {
+ if(ctx->obj) {
+ return ctx;
+ } else if (ctx->parent) {
+ return ui_context_toplevel_parent(ctx->parent);
+ }
+ return NULL;
+}
+
void ui_set_state(UiContext *ctx, int state) {
if(!cxListIndexValid(ctx->states, cxListFind(ctx->states, &state))) {
}
// enable/disable group widgets
- uic_check_state_widgets(ctx);
+ uic_check_state_widgets(ui_context_toplevel_parent(ctx));
}
void ui_unset_state(UiContext *ctx, int state) {
}
// enable/disable group widgets
- uic_check_state_widgets(ctx);
+ uic_check_state_widgets(ui_context_toplevel_parent(ctx));
+}
+
+void ui_suppress_state(UiContext *ctx, int state) {
+ if(!cxListIndexValid(ctx->suppressed_states, cxListFind(ctx->suppressed_states, &state))) {
+ cxListAdd(ctx->suppressed_states, &state);
+ }
+
+ // enable/disable group widgets
+ uic_check_state_widgets(ui_context_toplevel_parent(ctx));
+}
+
+void ui_unsuppress_state(UiContext *ctx, int state) {
+ int i = cxListFind(ctx->suppressed_states, &state);
+ if(i != -1) {
+ cxListRemove(ctx->suppressed_states, i);
+ }
+
+ // enable/disable group widgets
+ uic_check_state_widgets(ui_context_toplevel_parent(ctx));
+}
+
+typedef struct StatesList {
+ CX_ARRAY(int, states);
+ CX_ARRAY(int, suppressed);
+} StatesList;
+
+static void add_ctx_states(UiContext *ctx, StatesList *states) {
+ size_t nstates = cxListSize(ctx->states);
+ int *ctx_states = cxListAt(ctx->states, 0);
+
+ size_t nsuppressed = cxListSize(ctx->suppressed_states);
+ int *ctx_suppressed_states = cxListAt(ctx->suppressed_states, 0);
+
+ cx_array_add_array(states->states, ctx_states, nstates);
+ cx_array_add_array(states->suppressed, ctx_suppressed_states, nsuppressed);
+
+ CxIterator i = cxListIterator(ctx->documents);
+ cx_foreach(void *, doc, i) {
+ UiContext *doc_ctx = ui_document_context(doc);
+ add_ctx_states(doc_ctx, states);
+ }
}
int* ui_active_states(UiContext *ctx, int *nstates) {
- *nstates = cxListSize(ctx->states);
- return cxListAt(ctx->states, 0);
+ StatesList states;
+ cx_array_init(states.states, 32);
+ cx_array_init(states.suppressed, 8);
+ add_ctx_states(ctx, &states);
+
+ // remove suppressed states
+ for(size_t i=0;i<states.suppressed.size;i++) {
+ int suppressed = states.suppressed.data[i];
+ // important to use ssize_t for the index here
+ for(ssize_t s=0;s<states.states.size;s++) {
+ if(states.states.data[s] == suppressed) {
+ // this state is suppressed
+ if(s+1 < states.states.size) {
+ // copy last element to the current position
+ states.states.data[s] = states.states.data[states.states.size-1];
+ // we need to check the current index again
+ s--;
+ }
+ states.states.size--;
+ }
+ }
+ }
+
+ free(states.suppressed.data);
+ *nstates = (int)states.states.size;
+ return states.states.data;
}
void uic_check_state_widgets(UiContext *ctx) {
- int ngroups = 0;
- int *groups = ui_active_states(ctx, &ngroups);
+ if(!ctx) {
+ return;
+ }
+
+ int nstates = 0;
+ int *states = ui_active_states(ctx, &nstates);
CxIterator i = cxListIterator(ctx->state_widgets);
cx_foreach(UiStateWidget *, gw, i) {
char *check = calloc(1, gw->numstates);
- for(int i=0;i<ngroups;i++) {
+ for(int i=0;i<nstates;i++) {
for(int k=0;k<gw->numstates;k++) {
- if(groups[i] == gw->states[k]) {
+ if(states[i] == gw->states[k]) {
check[k] = 1;
}
}
free(check);
gw->enable(gw->widget, enable);
}
+
+ free(states);
}
void ui_widget_set_states(UiContext *ctx, UIWIDGET widget, ui_enablefunc enable, ...) {
}
void* ui_malloc(UiContext *ctx, size_t size) {
- return ctx ? cxMalloc(ctx->allocator, size) : NULL;
+ return ctx ? cxMalloc(ctx->allocator, size) : malloc(size);
}
void* ui_calloc(UiContext *ctx, size_t nelem, size_t elsize) {
- return ctx ? cxCalloc(ctx->allocator, nelem, elsize) : NULL;
+ return ctx ? cxCalloc(ctx->allocator, nelem, elsize) : calloc(nelem, elsize);
}
void ui_free(UiContext *ctx, void *ptr) {
- if(ctx && ptr) {
- cxFree(ctx->allocator, ptr);
+ if(ptr) {
+ if(ctx) {
+ cxFree(ctx->allocator, ptr);
+ } else {
+ free(ptr);
+ }
}
}
void* ui_realloc(UiContext *ctx, void *ptr, size_t size) {
- return ctx ? cxRealloc(ctx->allocator, ptr, size) : NULL;
+ return ctx ? cxRealloc(ctx->allocator, ptr, size) : realloc(ptr, size);
}
char* ui_strdup(UiContext *ctx, const char *str) {
if(!ctx) {
- return NULL;
+ return strdup(str ? str : "");
}
cxstring s = cx_str(str);
cxmutstr d = cx_strdup_a(ctx->allocator, s);
}
void ui_reg_destructor(UiContext *ctx, void *data, ui_destructor_func destr) {
- cxMempoolRegister(ctx->mp, data, (cx_destructor_func)destr);
+ //cxMempoolRegister(ctx->mp, data, (cx_destructor_func)destr);
+ uic_context_add_destructor(ctx, destr, data);
+}
+
+void ui_remove_destructor(UiContext *ctx, void *data) {
+ uic_context_remove_destructor(ctx, data);
}
void ui_set_destructor(void *mem, ui_destructor_func destr) {
UiVar *var = uic_get_var_t(ctx, name, UI_VAR_GENERIC);
return var ? var->value : NULL;
}
+
+
+
+void ui_context_onattach(UiContext *ctx, ui_callback cb, void *data) {
+ ctx->onattach = cb;
+ ctx->onattachdata = data;
+}
+
+void ui_context_ondetach(UiContext *ctx, ui_callback cb, void *data) {
+ ctx->ondetach = cb;
+ ctx->ondetachdata = data;
+}
+
+void ui_context_onattachmentstatuschange(UiContext *ctx, ui_callback cb, void *data) {
+ ctx->onattachmentstatuschange = cb;
+ ctx->onattachmentstatuschangedata = data;
+}
+
+static void attachment_action_callback(UiEvent *event, void *action) {
+ if(event->document) {
+ UiContext *ctx = ui_document_context(event->document);
+ ui_call_action_on(ctx, action);
+ }
+}
+
+void ui_context_onattach_action(UiContext *ctx, const char *action) {
+ ctx->onattach = attachment_action_callback;
+ ctx->onattachdata = ui_strdup(ctx, action);
+}
+
+void ui_context_ondetach_action(UiContext *ctx, const char *action) {
+ ctx->ondetach = attachment_action_callback;
+ ctx->ondetachdata = ui_strdup(ctx, action);
+}
+
+void ui_context_onattachmentstatuschange_action(UiContext *ctx, const char *action) {
+ ctx->onattachmentstatuschange = attachment_action_callback;
+ ctx->onattachmentstatuschangedata = ui_strdup(ctx, action);
+}
+
+
+int ui_context_is_attached(UiContext *ctx) {
+ return ctx->parent != NULL;
+}
+
+int ui_context_is_attached_to_obj(UiContext *ctx) {
+ return uic_obj_context(ctx) != NULL;
+}
+
+UIEXPORT UiObject* ui_context_get_parent_obj(UiContext *ctx) {
+ UiContext *obj_ctx = uic_obj_context(ctx);
+ return obj_ctx ? obj_ctx->obj : NULL;
+}
+
+UiContext* uic_obj_context(UiContext *ctx) {
+ if(ctx->obj) {
+ return ctx;
+ }
+ if(ctx->parent == NULL) {
+ return NULL;
+ }
+ return uic_obj_context(ctx->parent);
+}
struct UiContext {
UiContext *parent;
UiObject *obj;
- CxMempool *mp;
+ CxMempool *mp;
const CxAllocator *allocator;
CxList *destroy_handler;
+ // document pointer, if this is a document context
+ void *self_doc;
+
void *document;
CxList *documents;
CxMap *vars;
CxList *states; // int list
+ CxList *suppressed_states; // int list
CxList *state_widgets; // UiGroupWidget list
CxMap *actions; // key: action name (string), value: UiAction
CxList *action_bindings; // UiActionBinding list
- void (*attach_document)(UiContext *ctx, void *document);
- void (*detach_document2)(UiContext *ctx, void *document);
-
char *title;
#ifdef UI_GTK
// attaching a document will automatically detach the current document
UiBool single_document_mode;
- ui_callback close_callback;
- void *close_data;
+ ui_callback onattach;
+ void *onattachdata;
+
+ ui_callback ondetach;
+ void *ondetachdata;
+
+ ui_callback onattachmentstatuschange;
+ void *onattachmentstatuschangedata;
+
+ ui_callback onclose;
+ void *onclosedata;
+
+ unsigned int ref;
};
struct UiVar {
UiContext* uic_context(UiObject *toplevel, CxMempool *mp);
UiContext* uic_root_context(UiContext *ctx);
void uic_context_add_destructor(UiContext *ctx, cx_destructor_func func, void *data);
+void uic_context_remove_destructor(UiContext *ctx, void *data);
void uic_context_prepare_close(UiContext *ctx);
+void uic_context_destroy(UiContext *ctx, void *document);
+void uic_context_update_bindings(UiContext *ctx);
void uic_context_attach_document(UiContext *ctx, void *document);
void uic_context_detach_document(UiContext *ctx, void *document);
void uic_context_attach_context(UiContext *ctx, UiContext *doc_ctx); // TODO
void uic_context_detach_context(UiContext *ctx, UiContext *doc_ctx); // TODO
void uic_context_detach_all(UiContext *ctx);
+void uic_send_status_change(UiContext *ctx, UiObject *obj);
+
UiVar* uic_get_var(UiContext *ctx, const char *name);
UiVar* uic_get_var_t(UiContext *ctx, const char *name, UiVarType type);
UiVar* uic_create_var(UiContext *ctx, const char *name, UiVarType type);
void uic_add_state_widget_i(UiContext *ctx, void *widget, ui_enablefunc enable, const int *states, size_t numstates);
void uic_remove_state_widget(UiContext *ctx, void *widget);
+UiContext* uic_obj_context(UiContext *ctx);
+
+UIEXPORT void ui_context_onattach(UiContext *ctx, ui_callback cb, void *data);
+UIEXPORT void ui_context_ondetach(UiContext *ctx, ui_callback cb, void *data);
+UIEXPORT void ui_context_onattachmentstatuschange(UiContext *ctx, ui_callback cb, void *data);
+UIEXPORT void ui_context_onattach_action(UiContext *ctx, const char *action);
+UIEXPORT void ui_context_ondetach_action(UiContext *ctx, const char *action);
+UIEXPORT void ui_context_onattachmentstatuschange_action(UiContext *ctx, const char *action);
+
+UIEXPORT int ui_context_is_attached(UiContext *ctx);
+UIEXPORT int ui_context_is_attached_to_obj(UiContext *ctx);
+UIEXPORT UiObject* ui_context_get_parent_obj(UiContext *ctx);
+
#ifdef __cplusplus
}
#endif
UiDoc *document = cxCalloc(a, sizeof(UiDoc) + size, 1);
document->ctx = ctx;
- return &document->doc;
+ ctx->self_doc = &document->doc;
+ return ctx->self_doc;
}
void ui_document_destroy(void *doc) {
+ uic_context_destroy(ui_document_context(doc), doc);
+}
+
+void ui_document_ref(void *doc) {
UiContext *ctx = ui_document_context(doc);
if(ctx) {
- UiEvent ev;
- ev.window = NULL;
- ev.document = doc;
- ev.obj = NULL;
- ev.eventdata = NULL;
- ev.eventdatatype = 0;
- ev.intval = 0;
-
- if(ctx->close_callback) {
- ctx->close_callback(&ev, ctx->close_data);
+ ctx->ref++;
+ }
+}
+
+void ui_document_unref(void *doc) {
+ UiContext *ctx = ui_document_context(doc);
+ if(ctx) {
+ if(--ctx->ref == 0) {
+ uic_context_destroy(ctx, doc);
}
- cxMempoolFree(ctx->mp);
}
}
return NULL;
}
}
+
+void* ui_context_document(UiContext *ctx) {
+ return ctx->self_doc;
+}
+
+UiObject* ui_context_obj(UiContext *ctx) {
+ return ctx->obj;
+}
+
+void ui_document_onattach(void *doc, ui_callback cb, void *data) {
+ UiContext *ctx = ui_document_context(doc);
+ ui_context_onattach(ctx, cb, data);
+}
+
+void ui_document_ondetach(void *doc, ui_callback cb, void *data) {
+ UiContext *ctx = ui_document_context(doc);
+ ui_context_ondetach(ctx, cb, data);
+}
+
+void ui_document_onattachmentstatuschange(void *doc, ui_callback cb, void *data) {
+ UiContext *ctx = ui_document_context(doc);
+ ui_context_onattachmentstatuschange(ctx, cb, data);
+}
+
+void ui_document_onattach_action(void *doc, const char *action) {
+ UiContext *ctx = ui_document_context(doc);
+ ui_context_onattach_action(ctx, action);
+}
+
+void ui_document_ondetach_action(void *doc, const char *action) {
+ UiContext *ctx = ui_document_context(doc);
+ ui_context_ondetach_action(ctx, action);
+}
+
+void ui_document_onattachmentstatuschange_action(void *doc, const char *action) {
+ UiContext *ctx = ui_document_context(doc);
+ ui_context_onattachmentstatuschange_action(ctx, action);
+}
+
+
+int ui_document_is_attached(void *doc) {
+ UiContext *ctx = ui_document_context(doc);
+ return ui_context_is_attached(ctx);
+}
+
+int ui_document_is_attached_to_obj(void *doc) {
+ UiContext *ctx = ui_document_context(doc);
+ return ui_context_is_attached_to_obj(ctx);
+}
--- /dev/null
+/*
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
+ *
+ * Copyright 2026 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 "icons.h"
+
+const char* ui_icon_name(enum UiIconId icon_id) {
+ switch(icon_id) {
+ case UI_ICON_ID_HOME : return UI_ICON_HOME;
+ case UI_ICON_ID_NEW_WINDOW : return UI_ICON_NEW_WINDOW;
+ case UI_ICON_ID_NEW_TAB : return UI_ICON_NEW_TAB;
+ case UI_ICON_ID_NEW_FOLDER : return UI_ICON_NEW_FOLDER;
+ case UI_ICON_ID_NEW_DOCUMENT : return UI_ICON_NEW_DOCUMENT;
+ case UI_ICON_ID_NEW_APPOINTMENT : return UI_ICON_NEW_APPOINTMENT;
+ case UI_ICON_ID_NEW_CHAT_MESSAGE : return UI_ICON_NEW_CHAT_MESSAGE;
+ case UI_ICON_ID_NEW_CONTACT : return UI_ICON_NEW_CONTACT;
+ case UI_ICON_ID_NEW_MAIL : return UI_ICON_NEW_MAIL;
+ case UI_ICON_ID_ADD_BOOKMARK : return UI_ICON_ADD_BOOKMARK;
+ case UI_ICON_ID_ADD_IMAGE : return UI_ICON_ADD_IMAGE;
+ case UI_ICON_ID_ADD_LINK : return UI_ICON_ADD_LINK;
+ case UI_ICON_ID_ADD_TEXT : return UI_ICON_ADD_TEXT;
+ case UI_ICON_ID_ADD : return UI_ICON_ADD;
+ case UI_ICON_ID_REMOVE : return UI_ICON_REMOVE;
+ case UI_ICON_ID_REFRESH : return UI_ICON_REFRESH;
+ case UI_ICON_ID_UPLOAD : return UI_ICON_UPLOAD;
+ case UI_ICON_ID_SAVE_LOCAL : return UI_ICON_SAVE_LOCAL;
+ case UI_ICON_ID_EDIT_COPY : return UI_ICON_EDIT_COPY;
+ case UI_ICON_ID_EDIT_CUT : return UI_ICON_EDIT_CUT;
+ case UI_ICON_ID_EDIT_DELETE : return UI_ICON_EDIT_DELETE;
+ case UI_ICON_ID_EDIT_PASTE : return UI_ICON_EDIT_PASTE ;
+ case UI_ICON_ID_UNDO : return UI_ICON_UNDO;
+ case UI_ICON_ID_REDO : return UI_ICON_REDO;
+ case UI_ICON_ID_SIDEBAR_LEFT : return UI_ICON_SIDEBAR_LEFT;
+ case UI_ICON_ID_SIDEBAR_RIGHT : return UI_ICON_SIDEBAR_RIGHT;
+ case UI_ICON_ID_GO_BACK : return UI_ICON_GO_BACK;
+ case UI_ICON_ID_GO_FORWARD : return UI_ICON_GO_FORWARD ;
+ case UI_ICON_ID_GO_UP : return UI_ICON_GO_UP;
+ case UI_ICON_ID_GO_DOWN : return UI_ICON_GO_DOWN;
+ case UI_ICON_ID_VIEW_LIST : return UI_ICON_VIEW_LIST;
+ case UI_ICON_ID_VIEW_GRID : return UI_ICON_VIEW_GRID;
+ case UI_ICON_ID_VIEW_DUAL : return UI_ICON_VIEW_DUAL;
+ case UI_ICON_ID_VIEW_FULLSCREEN : return UI_ICON_VIEW_FULLSCREEN;
+ case UI_ICON_ID_VIEW_RESTORE : return UI_ICON_VIEW_RESTORE;
+ case UI_ICON_ID_TEXT_BOLD : return UI_ICON_TEXT_BOLD;
+ case UI_ICON_ID_TEXT_ITALIC : return UI_ICON_TEXT_ITALIC;
+ case UI_ICON_ID_TEXT_UNDERLINE : return UI_ICON_TEXT_UNDERLINE;
+ case UI_ICON_ID_LIST_BULLET : return UI_ICON_LIST_BULLET ;
+ case UI_ICON_ID_LIST_ORDERED : return UI_ICON_LIST_ORDERED;
+ case UI_ICON_ID_LIST_CHECK : return UI_ICON_LIST_CHECK;
+ case UI_ICON_ID_CHECKBOX : return UI_ICON_CHECKBOX;
+ case UI_ICON_ID_STAR : return UI_ICON_STAR;
+ case UI_ICON_ID_VIEW_REVEAL : return UI_ICON_VIEW_REVEAL;
+ case UI_ICON_ID_VIEW_CONCEAL : return UI_ICON_VIEW_CONCEAL;
+ case UI_ICON_ID_SETTINGS : return UI_ICON_SETTINGS;
+ case UI_ICON_ID_MEDIA_PLAY : return UI_ICON_MEDIA_PLAY;
+ case UI_ICON_ID_MEDIA_STOP : return UI_ICON_MEDIA_STOP;
+ case UI_ICON_ID_MEDIA_PAUSE : return UI_ICON_MEDIA_PAUSE;
+ case UI_ICON_ID_MEDIA_SEEK_BACKWARD : return UI_ICON_MEDIA_SEEK_BACKWARD;
+ case UI_ICON_ID_MEDIA_SEEK_FORWARD : return UI_ICON_MEDIA_SEEK_FORWARD;
+ case UI_ICON_ID_MEDIA_SKIP_BACKWARD : return UI_ICON_MEDIA_SKIP_BACKWARD;
+ case UI_ICON_ID_MEDIA_SKIP_FORWARD : return UI_ICON_MEDIA_SKIP_FORWARD;
+ case UI_ICON_ID_CALL_START : return UI_ICON_CALL_START;
+ case UI_ICON_ID_CALL_STOP : return UI_ICON_CALL_STOP;
+ case UI_ICON_ID_CALL_INCOMING : return UI_ICON_CALL_INCOMING;
+ case UI_ICON_ID_CALL_OUTGOING : return UI_ICON_CALL_OUTGOING;
+ case UI_ICON_ID_MICROPHONE_ON : return UI_ICON_MICROPHONE_ON;
+ case UI_ICON_ID_MICROPHONE_OFF : return UI_ICON_MICROPHONE_OFF;
+ case UI_ICON_ID_LOCKED : return UI_ICON_LOCKED;
+ case UI_ICON_ID_UNLOCKED : return UI_ICON_UNLOCKED;
+ case UI_ICON_ID_SECURE : return UI_ICON_SECURE;
+ case UI_ICON_ID_INSECURE : return UI_ICON_INSECURE;
+ }
+ return NULL;
+}
--- /dev/null
+/*
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
+ *
+ * Copyright 2026 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 UIC_ICONS_H
+#define UIC_ICONS_H
+
+#include "../ui/icons.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* UIC_ICONS_H */
+
static void *tmp_eventdata;
static int tmp_eventdata_type;
+
+static void* getvalue_wrapper(UiList *list, void *elm, int row, int col, void *userdata, UiBool *freeResult) {
+ ui_getvaluefunc getvalue = (ui_getvaluefunc)userdata;
+ return getvalue(elm, col);
+}
+
+static void* str_getvalue(UiList *list, void *elm, int row, int col, void *userdata, UiBool *freeResult) {
+ return elm;
+}
+
+
void uic_set_tmp_eventdata(void *eventdata, int type) {
tmp_eventdata = eventdata;
tmp_eventdata_type = type;
item->item.next = NULL;
item->item.type = UI_MENU_ITEM;
+ item->action = nl_strdup(args->action);
item->label = nl_strdup(args->label);
item->icon = nl_strdup(args->icon);
item->userdata = args->onclickdata;
item->item.prev = NULL;
item->item.next = NULL;
item->item.type = UI_MENU_ITEM_LIST;
- item->getvalue = args->getvalue;
+ if(args->getvalue2) {
+ item->getvalue = args->getvalue2;
+ item->getvaluedata = args->getvaluedata;
+ } else if(args->getvalue) {
+ item->getvalue = getvalue_wrapper;
+ item->getvaluedata = (void*)args->getvalue;
+ } else {
+ item->getvalue = str_getvalue;
+ }
item->callback = args->onselect;
item->userdata = args->onselectdata;
item->varname = nl_strdup(args->varname);
item->item.prev = NULL;
item->item.next = NULL;
item->item.type = UI_MENU_CHECKITEM_LIST;
+ if(args->getvalue2) {
+ item->getvalue = args->getvalue2;
+ item->getvaluedata = args->getvaluedata;
+ } else if(args->getvalue) {
+ item->getvalue = getvalue_wrapper;
+ item->getvaluedata = (void*)args->getvalue;
+ } else {
+ item->getvalue = str_getvalue;
+ }
item->callback = args->onselect;
item->userdata = args->onselectdata;
item->varname = nl_strdup(args->varname);
item->item.prev = NULL;
item->item.next = NULL;
item->item.type = UI_MENU_RADIOITEM_LIST;
+ if(args->getvalue2) {
+ item->getvalue = args->getvalue2;
+ item->getvaluedata = args->getvaluedata;
+ } else if(args->getvalue) {
+ item->getvalue = getvalue_wrapper;
+ item->getvaluedata = (void*)args->getvalue;
+ } else {
+ item->getvalue = str_getvalue;
+ }
item->callback = args->onselect;
item->userdata = args->onselectdata;
item->varname = nl_strdup(args->varname);
struct UiMenuItem {
UiMenuItemI item;
ui_callback callback;
+ char *action;
char *label;
char *icon;
void *userdata;
};
struct UiMenuItemList {
- UiMenuItemI item;
- ui_getvaluefunc getvalue;
- ui_callback callback;
- void *userdata;
- char *varname;
- UiBool addseparator;
+ UiMenuItemI item;
+ ui_getvaluefunc2 getvalue;
+ void *getvaluedata;
+ ui_callback callback;
+ void *userdata;
+ char *varname;
+ UiBool addseparator;
};
static CxList *creation_callbacks;
static CxList *destruction_callbacks;
+static CxList *objects;
+
typedef struct objcallback {
ui_object_callback func;
void *userdata;
}
void uic_object_created(UiObject *obj) {
+ if(!objects) {
+ objects = cxLinkedListCreate(NULL, CX_STORE_POINTERS);
+ }
+ cxListAdd(objects, obj);
+
CxIterator i = cxListIterator(creation_callbacks);
cx_foreach(objcallback *, cb, i) {
cb->func(obj, cb->userdata);
}
void uic_object_destroyed(UiObject *obj) {
+ if(objects) {
+ cxListFindRemove(objects, obj);
+ }
+
CxIterator i = cxListIterator(destruction_callbacks);
cx_foreach(objcallback *, cb, i) {
cb->func(obj, cb->userdata);
}
}
+CxList* uic_object_list(void) {
+ return objects ? objects : cxEmptyList;
+}
+
void ui_object_ref(UiObject *obj) {
obj->ref++;
}
// it is possible to have 0 references, in case
// a window was created but ui_show was never called
if(obj->ref == 0 || --obj->ref == 0) {
+ uic_context_prepare_close(obj->ctx);
if(obj->destroy) {
obj->destroy(obj);
+ } else {
+ uic_object_destroy(obj);
}
- uic_object_destroy(obj);
return 0;
}
return 1;
}
void uic_object_destroy(UiObject *obj) {
- if(obj->ctx->close_callback) {
- UiEvent ev;
- ev.window = obj->window;
- ev.document = obj->ctx->document;
- ev.obj = obj;
- ev.eventdata = NULL;
- ev.eventdatatype = 0;
- ev.intval = 0;
- obj->ctx->close_callback(&ev, obj->ctx->close_data);
- }
uic_object_destroyed(obj);
- cxMempoolFree(obj->ctx->mp);
+ uic_context_destroy(obj->ctx, obj->ctx->document);
}
UiObject* uic_object_new_toplevel(void) {
return newobj;
}
-void uic_object_push_container(UiObject *toplevel, UiContainerX *newcontainer) {
+void uic_object_push_container(UiObject *toplevel, UiContainer *newcontainer) {
newcontainer->prev = toplevel->container_end;
if(toplevel->container_end) {
toplevel->container_end->next = newcontainer;
*/
void uic_object_remove_second_last_container(UiObject *toplevel) {
if(toplevel->container_end && toplevel->container_end->prev) {
- UiContainerX *end = toplevel->container_end;
- UiContainerX *rm = toplevel->container_end->prev;
+ UiContainer *end = toplevel->container_end;
+ UiContainer *rm = toplevel->container_end->prev;
end->prev = rm->prev;
if(rm->prev) {
void uic_object_destroyed(UiObject *obj);
void uic_object_destroy(UiObject *obj);
+
+CxList* uic_object_list(void);
UiObject* uic_object_new_toplevel(void);
UiObject* uic_object_new(UiObject *toplevel, UIWIDGET widget);
UiObject* uic_ctx_object_new(UiContext *ctx, UIWIDGET widget);
-void uic_object_push_container(UiObject *toplevel, UiContainerX *newcontainer);
+void uic_object_push_container(UiObject *toplevel, UiContainer *newcontainer);
void uic_object_pop_container(UiObject *toplevel);
void uic_object_remove_second_last_container(UiObject *toplevel);
COMMON_OBJ += wrapper$(OBJ_EXT)
COMMON_OBJ += utils$(OBJ_EXT)
COMMON_OBJ += message$(OBJ_EXT)
+COMMON_OBJ += icons$(OBJ_EXT)
TOOLKITOBJS += $(COMMON_OBJ:%=$(COMMON_OBJPRE)uic_%)
TOOLKITSOURCE += $(COMMON_OBJ:%$(OBJ_EXT)=common/%.c)
newargs.tooltip = nl_strdup(args->tooltip);\r
newargs.onclick = args->onclick;\r
newargs.onclickdata = args->onclickdata;\r
+ newargs.action = nl_strdup(args->action);\r
newargs.states = uic_copy_states(args->states, ngroups);\r
newargs.visibility_states = uic_copy_states(args->visibility_states, nvstates);\r
return newargs;\r
newargs.varname = nl_strdup(args->varname);\r
newargs.onchange = args->onchange;\r
newargs.onchangedata = args->onchangedata;\r
+ newargs.action = nl_strdup(args->action);\r
+ newargs.states = uic_copy_states(args->states, ngroups);\r
+ newargs.visibility_states = uic_copy_states(args->visibility_states, nvstates);\r
+ return newargs;\r
+}\r
+\r
+static UiToolbarContentToggleItemArgs contenttoggleitemargs_copy(UiToolbarContentToggleItemArgs *args, size_t *ngroups, size_t *nvstates) {\r
+ UiToolbarContentToggleItemArgs newargs;\r
+ newargs.label0 = nl_strdup(args->label0);\r
+ newargs.icon0 = nl_strdup(args->icon0);\r
+ newargs.tooltip0 = nl_strdup(args->tooltip0);\r
+ newargs.label1 = nl_strdup(args->label1);\r
+ newargs.icon1 = nl_strdup(args->icon1);\r
+ newargs.tooltip1 = nl_strdup(args->tooltip1);\r
+ newargs.varname = nl_strdup(args->varname);\r
+ newargs.onchange = args->onchange;\r
+ newargs.onchangedata = args->onchangedata;\r
+ newargs.action = nl_strdup(args->action);\r
+ newargs.toggled_by_state = args->toggled_by_state;\r
+ newargs.istogglebutton = args->istogglebutton;\r
newargs.states = uic_copy_states(args->states, ngroups);\r
newargs.visibility_states = uic_copy_states(args->visibility_states, nvstates);\r
return newargs;\r
cxMapPut(toolbar_items, name, item);\r
}\r
\r
+void ui_toolbar_content_toggleitem_create(const char* name, UiToolbarContentToggleItemArgs *args) {\r
+ UiToolbarContentToggleItem* item = malloc(sizeof(UiToolbarContentToggleItem));\r
+ item->item.type = UI_TOOLBAR_CONTENT_TOGGLEITEM;\r
+ item->args = contenttoggleitemargs_copy(args, &item->nstates, &item->nvstates);\r
+ cxMapPut(toolbar_items, name, item);\r
+}\r
+\r
static UiToolbarMenuArgs menuargs_copy(UiToolbarMenuArgs *args, size_t *nvstates) {\r
UiToolbarMenuArgs newargs;\r
newargs.label = nl_strdup(args->label);\r
extern "C" {\r
#endif\r
\r
-typedef struct UiToolbarItemI UiToolbarItemI;\r
+typedef struct UiToolbarItemI UiToolbarItemI;\r
\r
-typedef struct UiToolbarItem UiToolbarItem;\r
-typedef struct UiToolbarToggleItem UiToolbarToggleItem;\r
+typedef struct UiToolbarItem UiToolbarItem;\r
+typedef struct UiToolbarToggleItem UiToolbarToggleItem;\r
+typedef struct UiToolbarContentToggleItem UiToolbarContentToggleItem;\r
\r
-typedef struct UiToolbarMenuItem UiToolbarMenuItem;\r
+typedef struct UiToolbarMenuItem UiToolbarMenuItem;\r
\r
enum UiToolbarItemType {\r
UI_TOOLBAR_ITEM = 0,\r
UI_TOOLBAR_TOGGLEITEM,\r
+ UI_TOOLBAR_CONTENT_TOGGLEITEM,\r
UI_TOOLBAR_MENU\r
};\r
\r
size_t nvstates;\r
};\r
\r
+struct UiToolbarContentToggleItem {\r
+ UiToolbarItemI item;\r
+ UiToolbarContentToggleItemArgs args;\r
+ size_t nstates;\r
+ size_t nvstates;\r
+};\r
+\r
struct UiToolbarMenuItem {\r
UiToolbarItemI item;\r
UiMenu menu;\r
/* --------------------------- UiList --------------------------- */
void uic_ucx_list_init(UiContext *ctx, UiList *list, void *unused) {
- list->data = cxArrayListCreate(ctx->mp->allocator, CX_STORE_POINTERS, 32);
+ const CxAllocator *a = ctx ? ctx->allocator : cxDefaultAllocator;
+ list->destroy = uic_ucx_list_destroy;
+ list->data = cxArrayListCreate(a, CX_STORE_POINTERS, 32);
list->first = ui_list_first;
list->next = ui_list_next;
list->get = ui_list_get;
void uic_ucx_list_destroy(UiContext *ctx, UiList *list, void *unused) {
cxListFree(list->data);
- ui_free(ctx, list);
}
UiList* ui_list_new(UiContext *ctx, const char *name) {
}
UiList* ui_list_new2(UiContext *ctx, const char *name, ui_list_init_func listinit, void *userdata) {
- UiList *list = cxMalloc(ctx->mp->allocator, sizeof(UiList));
+ UiList *list = ui_malloc(ctx, sizeof(UiList));
memset(list, 0, sizeof(UiList));
listinit(ctx, list, userdata);
+ list->save_selection = TRUE;
- if(name) {
+ if(name && ctx) {
uic_reg_var(ctx, name, UI_VAR_LIST, list);
}
}
void ui_list_free(UiContext *ctx, UiList *list) {
- if(!default_list_destroy) {
+ if(list->destroy) {
+ list->destroy(ctx, list, NULL);
+ } else if(!default_list_destroy) {
uic_ucx_list_destroy(ctx, list, NULL);
} else {
default_list_destroy(ctx, list, default_list_destroy_userdata);
}
-
+ ui_list_selection_free(list->saved_selection);
+ ui_free(ctx, list);
}
void* ui_list_first(UiList *list) {
cxListInsert(list->data, 0, data);
}
+void ui_list_insert(UiList *list, int index, void *data) {
+ cxListInsert(list->data, (size_t)index, data);
+}
+
void ui_list_remove(UiList *list, int i) {
if(i >= 0) {
cxListRemove(list->data, i);
ui_notify(list->observers, list);
}
+void ui_list_clear_saved_selection(UiList *list) {
+ ui_list_selection_free(list->saved_selection);
+ list->saved_selection = NULL;
+}
+
typedef struct {
int type;
UiModel* ui_model(UiContext *ctx, ...) {
UiModel *info = ui_calloc(ctx, 1, sizeof(UiModel));
info->ctx = ctx;
+ info->ref = 1;
va_list ap;
va_start(ap, ctx);
UiModel* ui_model_new(UiContext *ctx) {
UiModel *info = ui_calloc(ctx, 1, sizeof(UiModel));
info->ctx = ctx;
+ info->ref = 1;
info->alloc = UI_MODEL_DEFAULT_ALLOC_SIZE;
info->types = ui_calloc(ctx, UI_MODEL_DEFAULT_ALLOC_SIZE, sizeof(UiModelType));
info->titles = ui_calloc(ctx, UI_MODEL_DEFAULT_ALLOC_SIZE, sizeof(char*));
void ui_model_free(UiModel *mi) {
UiContext *ctx = mi->ctx;
- const CxAllocator* a = ctx->allocator;
+ const CxAllocator* a = ctx ? ctx->allocator : cxDefaultAllocator;
for(int i=0;i<mi->columns;i++) {
ui_free(ctx, mi->titles[i]);
}
UiInteger* ui_int_new(UiContext *ctx, const char *name) {
UiInteger *i = ui_malloc(ctx, sizeof(UiInteger));
memset(i, 0, sizeof(UiInteger));
- if(name) {
+ if(name && ctx) {
uic_reg_var(ctx, name, UI_VAR_INTEGER, i);
}
return i;
UiDouble* ui_double_new(UiContext *ctx, const char *name) {
UiDouble *d = ui_malloc(ctx, sizeof(UiDouble));
memset(d, 0, sizeof(UiDouble));
- if(name) {
+ if(name && ctx) {
uic_reg_var(ctx, name, UI_VAR_DOUBLE, d);
}
return d;
UiString *s = ui_malloc(ctx, sizeof(UiString));
memset(s, 0, sizeof(UiString));
ui_set_destructor(s, (ui_destructor_func)string_destroy);
- if(name) {
+ if(name && ctx) {
uic_reg_var(ctx, name, UI_VAR_STRING, s);
}
return s;
}
static void text_destroy(UiText *t) {
+ if(t->value.free) {
+ t->value.free(t->value.ptr);
+ }
if(t->destroy) {
t->destroy(t);
}
UiText *t = ui_malloc(ctx, sizeof(UiText));
memset(t, 0, sizeof(UiText));
ui_set_destructor(t, (ui_destructor_func)text_destroy);
- if(name) {
+ if(name && ctx) {
uic_reg_var(ctx, name, UI_VAR_TEXT, t);
}
return t;
UiRange* ui_range_new(UiContext *ctx, const char *name) {
UiRange *r = ui_malloc(ctx, sizeof(UiRange));
memset(r, 0, sizeof(UiRange));
- if(name) {
+ if(name && ctx) {
uic_reg_var(ctx, name, UI_VAR_RANGE, r);
}
return r;
UiGeneric* ui_generic_new(UiContext *ctx, const char *name) {
UiGeneric *g = ui_malloc(ctx, sizeof(UiGeneric));
memset(g, 0, sizeof(UiGeneric));
- ui_set_destructor(g, (ui_destructor_func)generic_destroy);
- if(name) {
+ if(ctx) {
+ ui_set_destructor(g, (ui_destructor_func)generic_destroy);
+ }
+ if(name && ctx) {
uic_reg_var(ctx, name, UI_VAR_GENERIC, g);
}
return g;
to->selection = from->selection;
to->length = from->length;
to->remove = from->remove;
+ to->setreadonly = from->setreadonly;
to->restore = from->restore;
to->save = from->save;
to->destroy = from->destroy;
void uic_generic_save(UiGeneric *g) {
if(!g->obj) return;
+ // TODO: this leaks memory
+ // we can't just use get on Generic and ignore the result
+ // probably a separate save method is required
g->get(g);
}
}
void uic_text_unbind(UiText *t) {
+ t->obj = NULL;
+ if(t->data1 && t->datatype == UI_TEXT_TYPE_BUFFER) {
+ // the binding functions all work with t->data1, not t->obj
+ // and we don't want to NULL them, because they will be still
+ // functional even without a widget binding
+ return;
+ }
+
t->set = NULL;
t->get = NULL;
t->getsubstr = NULL;
t->replace = NULL;
t->setposition = NULL;
t->position = NULL;
+ t->showposition = NULL;
t->selection = NULL;
t->setselection = NULL;
t->length = NULL;
t->remove = NULL;
- t->obj = NULL;
+ t->setreadonly = NULL;
}
void uic_range_unbind(UiRange *r) {
}
+
+UiListSelection* ui_list_get_selection_allocated(UiList *list) {
+ UiListSelection *sel = malloc(sizeof(UiListSelection));
+ *sel = ui_list_get_selection(list);
+ return sel;
+
+}
+
+void ui_list_selection_free(UiListSelection *sel) {
+ if(!sel) {
+ return;
+ }
+ ui_listselection_free(*sel);
+ free(sel);
+}
+
+
UIEXPORT int ui_list_getselection(UiList *list) {
int selection = -1;
if (list->getselection) {
default_list_destroy_userdata = userdata;
}
+UIEXPORT void ui_list_class_set_destructor(UiList *list, ui_list_destroy_func destroy) {
+ list->destroy = destroy;
+}
+
void ui_list_class_set_first(UiList *list, void*(*first)(UiList *list)) {
list->first = first;
}
void ui_list_class_set_iter(UiList *list, void *iter) {
list->iter = iter;
}
+
+/* ---------------- Text functions ---------------- */
+
+char* ui_text_getsubstr(UiText *text, int begin, int end) {
+ if(text->getsubstr) {
+ return text->getsubstr(text, begin, end);
+ } else {
+ return NULL;
+ }
+}
+
+void ui_text_insert(UiText *text, int pos, const char *str) {
+ if(text->insert) {
+ text->insert(text, pos, str);
+ }
+}
+
+void ui_text_replace(UiText *text, int begin, int end, const char *str) {
+ if(text->replace) {
+ text->replace(text, begin, end, str);
+ }
+}
+
+void ui_text_setposition(UiText *text, int pos) {
+ if(text->setposition) {
+ text->setposition(text, pos);
+ }
+}
+
+int ui_text_position(UiText *text) {
+ if(text->position) {
+ return text->position(text);
+ } else {
+ return 0;
+ }
+}
+
+void ui_text_showposition(UiText *text, int pos) {
+ if(text->showposition) {
+ text->showposition(text, pos);
+ }
+}
+
+void ui_text_setselection(UiText *text, int begin, int end) {
+ if(text->setselection) {
+ text->setselection(text, begin, end);
+ }
+}
+
+void ui_text_selection(UiText *text, int *begin, int *end) {
+ if(text->selection) {
+ text->selection(text, begin, end);
+ } else {
+ if(begin) {
+ *begin = 0;
+ }
+ if(end) {
+ *end = 0;
+ }
+ }
+}
+
+int ui_text_length(UiText *text) {
+ if(text->length) {
+ return text->length(text);
+ } else {
+ return 0;
+ }
+}
+void ui_text_remove(UiText *text, int begin, int end) {
+ if(text->remove) {
+ text->remove(text, begin, end);
+ }
+}
+
+void ui_text_setreadonly(UiText *text, int readonly) {
+ if(text->setreadonly) {
+ text->setreadonly(text, readonly);
+ } else {
+ text->readonly = readonly;
+ }
+}
void uic_list_unbind(UiList *l);
void uic_generic_unbind(UiGeneric *g);
+UIEXPORT UiListSelection* ui_list_get_selection_allocated(UiList *list);
+UIEXPORT void ui_list_selection_free(UiListSelection *sel);
+
void uic_list_register_observer_destructor(UiContext *ctx, UiList *list, UiObserver *observer);
#ifdef __cplusplus
+++ /dev/null
-/*
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
- *
- * Copyright 2017 Mike Becker, 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 "ucx_properties.h"
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-
-UcxProperties *ucx_properties_new() {
- UcxProperties *parser = (UcxProperties*)malloc(
- sizeof(UcxProperties));
- if(!parser) {
- return NULL;
- }
-
- parser->buffer = NULL;
- parser->buflen = 0;
- parser->pos = 0;
- parser->tmp = NULL;
- parser->tmplen = 0;
- parser->tmpcap = 0;
- parser->error = 0;
- parser->delimiter = '=';
- parser->comment1 = '#';
- parser->comment2 = 0;
- parser->comment3 = 0;
-
- return parser;
-}
-
-void ucx_properties_free(UcxProperties *parser) {
- if(parser->tmp) {
- free(parser->tmp);
- }
- free(parser);
-}
-
-void ucx_properties_fill(UcxProperties *parser, char *buf, size_t len) {
- parser->buffer = buf;
- parser->buflen = len;
- parser->pos = 0;
-}
-
-static void parser_tmp_append(UcxProperties *parser, char *buf, size_t len) {
- if(parser->tmpcap - parser->tmplen < len) {
- size_t newcap = parser->tmpcap + len + 64;
- parser->tmp = (char*)realloc(parser->tmp, newcap);
- parser->tmpcap = newcap;
- }
- memcpy(parser->tmp + parser->tmplen, buf, len);
- parser->tmplen += len;
-}
-
-int ucx_properties_next(UcxProperties *parser, cxstring *name, cxstring *value) {
- if(parser->tmplen > 0) {
- char *buf = parser->buffer + parser->pos;
- size_t len = parser->buflen - parser->pos;
- cxstring str = cx_strn(buf, len);
- cxstring nl = cx_strchr(str, '\n');
- if(nl.ptr) {
- size_t newlen = (size_t)(nl.ptr - buf) + 1;
- parser_tmp_append(parser, buf, newlen);
- // the tmp buffer contains exactly one line now
-
- char *orig_buf = parser->buffer;
- size_t orig_len = parser->buflen;
-
- parser->buffer = parser->tmp;
- parser->buflen = parser->tmplen;
- parser->pos = 0;
- parser->tmp = NULL;
- parser->tmpcap = 0;
- parser->tmplen = 0;
- // run ucx_properties_next with the tmp buffer as main buffer
- int ret = ucx_properties_next(parser, name, value);
-
- // restore original buffer
- parser->tmp = parser->buffer;
- parser->buffer = orig_buf;
- parser->buflen = orig_len;
- parser->pos = newlen;
-
- /*
- * if ret == 0 the tmp buffer contained just space or a comment
- * we parse again with the original buffer to get a name/value
- * or a new tmp buffer
- */
- return ret ? ret : ucx_properties_next(parser, name, value);
- } else {
- parser_tmp_append(parser, buf, len);
- return 0;
- }
- } else if(parser->tmp) {
- free(parser->tmp);
- parser->tmp = NULL;
- }
-
- char comment1 = parser->comment1;
- char comment2 = parser->comment2;
- char comment3 = parser->comment3;
- char delimiter = parser->delimiter;
-
- // get one line and parse it
- while(parser->pos < parser->buflen) {
- char *buf = parser->buffer + parser->pos;
- size_t len = parser->buflen - parser->pos;
-
- /*
- * First we check if we have at least one line. We also get indices of
- * delimiter and comment chars
- */
- size_t delimiter_index = 0;
- size_t comment_index = 0;
- int has_comment = 0;
-
- size_t i = 0;
- char c = 0;
- for(;i<len;i++) {
- c = buf[i];
- if(c == comment1 || c == comment2 || c == comment3) {
- if(comment_index == 0) {
- comment_index = i;
- has_comment = 1;
- }
- } else if(c == delimiter) {
- if(delimiter_index == 0 && !has_comment) {
- delimiter_index = i;
- }
- } else if(c == '\n') {
- break;
- }
- }
-
- if(c != '\n') {
- // we don't have enough data for a line
- // store remaining bytes in temporary buffer for next round
- parser->tmpcap = len + 128;
- parser->tmp = (char*)malloc(parser->tmpcap);
- parser->tmplen = len;
- memcpy(parser->tmp, buf, len);
- return 0;
- }
-
- cxstring line = has_comment ? cx_strn(buf, comment_index) : cx_strn(buf, i);
- // check line
- if(delimiter_index == 0) {
- line = cx_strtrim(line);
- if(line.length != 0) {
- parser->error = 1;
- }
- } else {
- cxstring n = cx_strn(buf, delimiter_index);
- cxstring v = cx_strn(
- buf + delimiter_index + 1,
- line.length - delimiter_index - 1);
- n = cx_strtrim(n);
- v = cx_strtrim(v);
- if(n.length != 0 || v.length != 0) {
- *name = n;
- *value = v;
- parser->pos += i + 1;
- return 1;
- } else {
- parser->error = 1;
- }
- }
-
- parser->pos += i + 1;
- }
-
- return 0;
-}
-
-int ucx_properties2map(UcxProperties *parser, CxMap *map) {
- cxstring name;
- cxstring value;
- while(ucx_properties_next(parser, &name, &value)) {
- cxmutstr mutvalue = cx_strdup_a(map->collection.allocator, value);
- if(!mutvalue.ptr) {
- return 1;
- }
- if(cxMapPut(map, cx_hash_key_cxstr(name), mutvalue.ptr)) {
- cxFree(map->collection.allocator, mutvalue.ptr);
- return 1;
- }
- }
- if (parser->error) {
- return parser->error;
- } else {
- return 0;
- }
-}
-
-// buffer size is documented - change doc, when you change bufsize!
-#define UCX_PROPLOAD_BUFSIZE 1024
-int ucx_properties_load(CxMap *map, FILE *file) {
- UcxProperties *parser = ucx_properties_new();
- if(!(parser && map && file)) {
- return 1;
- }
-
- int error = 0;
- size_t r;
- char buf[UCX_PROPLOAD_BUFSIZE];
- while((r = fread(buf, 1, UCX_PROPLOAD_BUFSIZE, file)) != 0) {
- ucx_properties_fill(parser, buf, r);
- error = ucx_properties2map(parser, map);
- if (error) {
- break;
- }
- }
- ucx_properties_free(parser);
- return error;
-}
-
-int ucx_properties_store(CxMap *map, FILE *file) {
- CxMapIterator iter = cxMapIterator(map);
- cxstring value;
- size_t written;
-
- cx_foreach(CxMapEntry *, v, iter) {
- value = cx_str(v->value);
-
- written = 0;
- written += fwrite(v->key->data, 1, v->key->len, file);
- written += fwrite(" = ", 1, 3, file);
- written += fwrite(value.ptr, 1, value.length, file);
- written += fwrite("\n", 1, 1, file);
-
- if (written != v->key->len + value.length + 4) {
- return 1;
- }
- }
-
- return 0;
-}
-
+++ /dev/null
-/*
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
- *
- * Copyright 2017 Mike Becker, 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.
- */
-/**
- * @file properties.h
- *
- * Load / store utilities for properties files.
- *
- * @author Mike Becker
- * @author Olaf Wintermann
- */
-
-#ifndef UCX_PROPERTIES_H
-#define UCX_PROPERTIES_H
-
-#include <cx/hash_map.h>
-#include <cx/string.h>
-
-#include <stdio.h>
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-/**
- * UcxProperties object for parsing properties data.
- * Most of the fields are for internal use only. You may configure the
- * properties parser, e.g. by changing the used delimiter or specifying
- * up to three different characters that shall introduce comments.
- */
-typedef struct {
- /**
- * Input buffer (don't set manually).
- * Automatically set by calls to ucx_properties_fill().
- */
- char *buffer;
-
- /**
- * Length of the input buffer (don't set manually).
- * Automatically set by calls to ucx_properties_fill().
- */
- size_t buflen;
-
- /**
- * Current buffer position (don't set manually).
- * Used by ucx_properties_next().
- */
- size_t pos;
-
- /**
- * Internal temporary buffer (don't set manually).
- * Used by ucx_properties_next().
- */
- char *tmp;
-
- /**
- * Internal temporary buffer length (don't set manually).
- * Used by ucx_properties_next().
- */
- size_t tmplen;
-
- /**
- * Internal temporary buffer capacity (don't set manually).
- * Used by ucx_properties_next().
- */
- size_t tmpcap;
-
- /**
- * Parser error code.
- * This is always 0 on success and a nonzero value on syntax errors.
- * The value is set by ucx_properties_next().
- */
- int error;
-
- /**
- * The delimiter that shall be used.
- * This is '=' by default.
- */
- char delimiter;
-
- /**
- * The first comment character.
- * This is '#' by default.
- */
- char comment1;
-
- /**
- * The second comment character.
- * This is not set by default.
- */
- char comment2;
-
- /**
- * The third comment character.
- * This is not set by default.
- */
- char comment3;
-} UcxProperties;
-
-
-/**
- * Constructs a new UcxProperties object.
- * @return a pointer to the new UcxProperties object
- */
-UcxProperties *ucx_properties_new();
-
-/**
- * Destroys a UcxProperties object.
- * @param prop the UcxProperties object to destroy
- */
-void ucx_properties_free(UcxProperties *prop);
-
-/**
- * Sets the input buffer for the properties parser.
- *
- * After calling this function, you may parse the data by calling
- * ucx_properties_next() until it returns 0. The function ucx_properties2map()
- * is a convenience function that reads as much data as possible by using this
- * function.
- *
- *
- * @param prop the UcxProperties object
- * @param buf a pointer to the new buffer
- * @param len the payload length of the buffer
- * @see ucx_properties_next()
- * @see ucx_properties2map()
- */
-void ucx_properties_fill(UcxProperties *prop, char *buf, size_t len);
-
-/**
- * Retrieves the next key/value-pair.
- *
- * This function returns a nonzero value as long as there are key/value-pairs
- * found. If no more key/value-pairs are found, you may refill the input buffer
- * with ucx_properties_fill().
- *
- * <b>Attention:</b> the cxstring.ptr pointers of the output parameters point to
- * memory within the input buffer of the parser and will get invalid some time.
- * If you want long term copies of the key/value-pairs, use sstrdup() after
- * calling this function.
- *
- * @param prop the UcxProperties object
- * @param name a pointer to the cxstring that shall contain the property name
- * @param value a pointer to the cxstring that shall contain the property value
- * @return Nonzero, if a key/value-pair was successfully retrieved
- * @see ucx_properties_fill()
- */
-int ucx_properties_next(UcxProperties *prop, cxstring *name, cxstring *value);
-
-/**
- * Retrieves all available key/value-pairs and puts them into a UcxMap.
- *
- * This is done by successive calls to ucx_properties_next() until no more
- * key/value-pairs can be retrieved.
- *
- * The memory for the map values is allocated by the map's own allocator.
- *
- * @param prop the UcxProperties object
- * @param map the target map
- * @return The UcxProperties.error code (i.e. 0 on success).
- * @see ucx_properties_fill()
- * @see UcxMap.allocator
- */
-int ucx_properties2map(UcxProperties *prop, CxMap *map);
-
-/**
- * Loads a properties file to a UcxMap.
- *
- * This is a convenience function that reads data from an input
- * stream until the end of the stream is reached.
- *
- * @param map the map object to write the key/value-pairs to
- * @param file the <code>FILE*</code> stream to read from
- * @return 0 on success, or a non-zero value on error
- *
- * @see ucx_properties_fill()
- * @see ucx_properties2map()
- */
-int ucx_properties_load(CxMap *map, FILE *file);
-
-/**
- * Stores a UcxMap to a file.
- *
- * The key/value-pairs are written by using the following format:
- *
- * <code>[key] = [value]\\n</code>
- *
- * @param map the map to store
- * @param file the <code>FILE*</code> stream to write to
- * @return 0 on success, or a non-zero value on error
- */
-int ucx_properties_store(CxMap *map, FILE *file);
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* UCX_PROPERTIES_H */
-
obj->window = windowdata;
}
+void ui_object_set_onclose(UiObject *obj, ui_callback callback, void *userdata) {
+ obj->onclose = callback;
+ obj->onclosedata = userdata;
+}
+
+static int obj_unref(void *ptr) {
+ ui_object_unref(ptr);
+ return 0;
+}
+
+void ui_mainthread_object_unref(UiObject *obj) {
+ // TODO: detect if this is already the main thread and call
+ // ui_object_unref directly in that case
+ ui_call_mainthread(obj_unref, obj);
+}
+
+static int doc_unref(void *ptr) {
+ ui_document_unref(ptr);
+ return 0;
+}
+
+void ui_mainthread_document_unref(void *doc) {
+ // TODO: see ui_mainthread_object_unref
+ ui_call_mainthread(doc_unref, doc);
+}
+
+static int app_unref(void *unused) {
+ ui_app_unref();
+ return 0;
+}
+
+void ui_mainthread_app_unref() {
+ ui_call_mainthread(app_unref, NULL);
+}
/* ---------------------------- UiList ---------------------------- */
list->iter = iter;
}
+void ui_list_set_save_selection(UiList *list, UiBool value) {
+ list->save_selection = value;
+}
+
+UiBool ui_list_get_save_selection(UiList *list) {
+ return list->save_selection;
+}
/* ------------------------------ UiSublist ------------------------------ */
}
+/* ---------------------------- UiTypedObj ---------------------------- */
+
+void* ui_typed_obj_get_ptr(UiTypedObj *obj) {
+ return obj->ptr;
+}
+
+uint64_t ui_typed_obj_get_type(UiTypedObj *obj) {
+ return obj->type;
+}
+
+
/* ------------------------- SubListItem (public) ------------------------- */
void ui_sublist_item_set_icon(UiSubListItem *item, const char *icon) {
/* ---------------------------- UiListSelection ---------------------------- */
-UiListSelection* ui_list_get_selection_allocated(UiList *list) {
- UiListSelection *sel = malloc(sizeof(UiListSelection));
- *sel = ui_list_get_selection(list);
- return sel;
-
-}
-
int ui_list_selection_get_count(UiListSelection *sel) {
return sel->count;
}
}
}
-void ui_list_selection_free(UiListSelection *sel) {
- ui_listselection_free(*sel);
- free(sel);
+
+/* -------------------------- UiTextChangedEvent -------------------------- */
+
+int ui_text_change_event_get_type(UiTextChangeEventData *event) {
+ return event->type;
+}
+
+int ui_text_change_event_get_begin(UiTextChangeEventData *event) {
+ return event->begin;
+}
+
+int ui_text_change_event_get_end(UiTextChangeEventData *event) {
+ return event->end;
+}
+
+const char* ui_text_change_event_get_text(UiTextChangeEventData *event) {
+ return event->text;
+}
+
+int ui_text_change_event_get_length(UiTextChangeEventData *event) {
+ return event->length;
}
/* ---------------------------- UiFileList ---------------------------- */
#include "../ui/toolkit.h"
#include "../ui/list.h"
+#include "../ui/text.h"
#ifdef __cplusplus
extern "C" {
UIEXPORT UiContext* ui_object_get_context(UiObject *obj);
UIEXPORT void* ui_object_get_windowdata(UiObject *obj);
UIEXPORT void ui_object_set_windowdata(UiObject *obj, void *windowdata);
+UIEXPORT void ui_object_set_onclose(UiObject *obj, ui_callback callback, void *userdata);
+
+UIEXPORT void ui_mainthread_object_unref(UiObject *obj);
+UIEXPORT void ui_mainthread_document_unref(void *doc);
+UIEXPORT void ui_mainthread_app_unref();
UIEXPORT void* ui_list_get_data(UiList *list);
UIEXPORT void* ui_list_get_iter(UiList *list);
UIEXPORT void ui_list_set_iter(UiList *list, void *iter);
+UIEXPORT void ui_list_set_save_selection(UiList *list, UiBool value);
+UIEXPORT UiBool ui_list_get_save_selection(UiList *list);
UIEXPORT UiSubList* ui_sublist_new(void);
UIEXPORT void ui_sublist_set_value(UiSubList *sublist, UiList *value);
UIEXPORT int ui_event_get_int(UiEvent *event);
UIEXPORT int ui_event_get_set(UiEvent *event);
-UIEXPORT UiListSelection* ui_list_get_selection_allocated(UiList *list);
+UIEXPORT void* ui_typed_obj_get_ptr(UiTypedObj *obj);
+UIEXPORT uint64_t ui_typed_obj_get_type(UiTypedObj *obj);
+
UIEXPORT int ui_list_selection_get_count(UiListSelection *sel);
UIEXPORT int* ui_list_selection_get_rows(UiListSelection *sel);
UIEXPORT void ui_list_set_selected_indices(UiList *list, int *indices, int num);
-UIEXPORT void ui_list_selection_free(UiListSelection *sel);
+
+UIEXPORT int ui_text_change_event_get_type(UiTextChangeEventData *event);
+UIEXPORT int ui_text_change_event_get_begin(UiTextChangeEventData *event);
+UIEXPORT int ui_text_change_event_get_end(UiTextChangeEventData *event);
+UIEXPORT const char* ui_text_change_event_get_text(UiTextChangeEventData *event);
+UIEXPORT int ui_text_change_event_get_length(UiTextChangeEventData *event);
UIEXPORT int ui_filelist_count(UiFileList *flist);
UIEXPORT char* ui_filelist_get(UiFileList *flist, int index);
# POSSIBILITY OF SUCH DAMAGE.
#
-$(GTK_OBJPRE)%.o: gtk/%.c
- $(CC) -o $@ -c -I../ucx $(CFLAGS) $(SHLIB_CFLAGS) $(TK_CFLAGS) $<
-
$(UI_LIB): $(OBJ)
$(AR) $(ARFLAGS) $(UI_LIB) $(OBJ)
$(UI_SHLIB): $(OBJ)
$(CC) -o $(UI_SHLIB) $(LDFLAGS) $(SHLIB_LDFLAGS) $(TK_LDFLAGS) $(OBJ) -L../build/lib -lucx
+
+FORCE:
+
+$(GTK_OBJPRE)action.o: gtk/action.c gtk/action.h gtk/../ui/toolkit.h \
+ gtk/../common/action.h gtk/../common/../ui/toolkit.h
+ $(CC) -o $@ $(CFLAGS) -I../ucx $(SHLIB_CFLAGS) $(TK_CFLAGS) -c $<
+
+$(GTK_OBJPRE)button.o: gtk/button.c gtk/button.h gtk/../ui/toolkit.h \
+ gtk/../ui/button.h gtk/../ui/toolkit.h gtk/toolkit.h \
+ gtk/../common/context.h gtk/../common/../ui/toolkit.h \
+ gtk/../common/action.h gtk/../common/object.h gtk/container.h \
+ gtk/../ui/container.h gtk/widget.h gtk/../ui/widget.h \
+ gtk/../common/action.h
+ $(CC) -o $@ $(CFLAGS) -I../ucx $(SHLIB_CFLAGS) $(TK_CFLAGS) -c $<
+
+$(GTK_OBJPRE)container.o: gtk/container.c gtk/container.h \
+ gtk/../ui/toolkit.h gtk/../ui/container.h gtk/../ui/toolkit.h \
+ gtk/toolkit.h gtk/../common/context.h gtk/../common/../ui/toolkit.h \
+ gtk/../common/action.h gtk/../common/object.h gtk/headerbar.h \
+ gtk/../ui/toolbar.h gtk/../common/toolbar.h \
+ gtk/../common/../ui/toolbar.h gtk/../common/menu.h \
+ gtk/../common/../ui/menu.h gtk/../common/../ui/toolkit.h \
+ gtk/../common/container.h gtk/../common/../ui/container.h \
+ gtk/../ui/properties.h
+ $(CC) -o $@ $(CFLAGS) -I../ucx $(SHLIB_CFLAGS) $(TK_CFLAGS) -c $<
+
+$(GTK_OBJPRE)display.o: gtk/display.c gtk/display.h gtk/../ui/toolkit.h \
+ gtk/toolkit.h gtk/../common/context.h gtk/../common/../ui/toolkit.h \
+ gtk/../common/action.h gtk/../common/object.h gtk/container.h \
+ gtk/../ui/container.h gtk/../ui/toolkit.h gtk/../ui/display.h
+ $(CC) -o $@ $(CFLAGS) -I../ucx $(SHLIB_CFLAGS) $(TK_CFLAGS) -c $<
+
+$(GTK_OBJPRE)dnd.o: gtk/dnd.c gtk/dnd.h gtk/../ui/dnd.h \
+ gtk/../ui/toolkit.h gtk/toolkit.h gtk/../ui/toolkit.h \
+ gtk/../common/context.h gtk/../common/../ui/toolkit.h \
+ gtk/../common/action.h gtk/../common/object.h
+ $(CC) -o $@ $(CFLAGS) -I../ucx $(SHLIB_CFLAGS) $(TK_CFLAGS) -c $<
+
+$(GTK_OBJPRE)draw_cairo.o: gtk/draw_cairo.c gtk/container.h \
+ gtk/../ui/toolkit.h gtk/../ui/container.h gtk/../ui/toolkit.h \
+ gtk/toolkit.h gtk/../common/context.h gtk/../common/../ui/toolkit.h \
+ gtk/../common/action.h gtk/../common/object.h gtk/draw_cairo.h \
+ gtk/graphics.h gtk/../ui/graphics.h
+ $(CC) -o $@ $(CFLAGS) -I../ucx $(SHLIB_CFLAGS) $(TK_CFLAGS) -c $<
+
+$(GTK_OBJPRE)draw_gdk.o: gtk/draw_gdk.c gtk/container.h \
+ gtk/../ui/toolkit.h gtk/../ui/container.h gtk/../ui/toolkit.h \
+ gtk/toolkit.h gtk/../common/context.h gtk/../common/../ui/toolkit.h \
+ gtk/../common/action.h gtk/../common/object.h gtk/draw_gdk.h \
+ gtk/graphics.h gtk/../ui/graphics.h
+ $(CC) -o $@ $(CFLAGS) -I../ucx $(SHLIB_CFLAGS) $(TK_CFLAGS) -c $<
+
+$(GTK_OBJPRE)entry.o: gtk/entry.c gtk/../common/context.h \
+ gtk/../common/../ui/toolkit.h gtk/../common/action.h \
+ gtk/../common/object.h gtk/container.h gtk/../ui/toolkit.h \
+ gtk/../ui/container.h gtk/../ui/toolkit.h gtk/toolkit.h gtk/entry.h \
+ gtk/../ui/entry.h
+ $(CC) -o $@ $(CFLAGS) -I../ucx $(SHLIB_CFLAGS) $(TK_CFLAGS) -c $<
+
+$(GTK_OBJPRE)graphics.o: gtk/graphics.c gtk/graphics.h \
+ gtk/../ui/graphics.h gtk/../ui/toolkit.h gtk/toolkit.h \
+ gtk/../ui/toolkit.h gtk/../common/context.h \
+ gtk/../common/../ui/toolkit.h gtk/../common/action.h \
+ gtk/../common/object.h gtk/container.h gtk/../ui/container.h \
+ gtk/draw_cairo.h
+ $(CC) -o $@ $(CFLAGS) -I../ucx $(SHLIB_CFLAGS) $(TK_CFLAGS) -c $<
+
+$(GTK_OBJPRE)headerbar.o: gtk/headerbar.c gtk/headerbar.h gtk/toolkit.h \
+ gtk/../ui/toolkit.h gtk/../common/context.h \
+ gtk/../common/../ui/toolkit.h gtk/../common/action.h \
+ gtk/../common/object.h gtk/../ui/toolbar.h gtk/../ui/toolkit.h \
+ gtk/../common/toolbar.h gtk/../common/../ui/toolbar.h \
+ gtk/../common/menu.h gtk/../common/../ui/menu.h \
+ gtk/../common/../ui/toolkit.h gtk/button.h gtk/../ui/button.h gtk/menu.h \
+ gtk/../ui/menu.h gtk/../common/menu.h gtk/../ui/properties.h
+ $(CC) -o $@ $(CFLAGS) -I../ucx $(SHLIB_CFLAGS) $(TK_CFLAGS) -c $<
+
+$(GTK_OBJPRE)icon.o: gtk/icon.c gtk/toolkit.h gtk/../ui/toolkit.h \
+ gtk/../common/context.h gtk/../common/../ui/toolkit.h \
+ gtk/../common/action.h gtk/../common/object.h gtk/icon.h \
+ gtk/../ui/icons.h gtk/../ui/toolkit.h gtk/../common/properties.h \
+ gtk/../common/../ui/properties.h gtk/../common/../ui/toolkit.h
+ $(CC) -o $@ $(CFLAGS) -I../ucx $(SHLIB_CFLAGS) $(TK_CFLAGS) -c $<
+
+$(GTK_OBJPRE)image.o: gtk/image.c gtk/image.h gtk/../ui/image.h \
+ gtk/../ui/toolkit.h gtk/toolkit.h gtk/../ui/toolkit.h \
+ gtk/../common/context.h gtk/../common/../ui/toolkit.h \
+ gtk/../common/action.h gtk/../common/object.h gtk/container.h \
+ gtk/../ui/container.h gtk/menu.h gtk/../ui/menu.h gtk/../common/menu.h \
+ gtk/../common/../ui/menu.h gtk/widget.h gtk/../ui/widget.h
+ $(CC) -o $@ $(CFLAGS) -I../ucx $(SHLIB_CFLAGS) $(TK_CFLAGS) -c $<
+
+$(GTK_OBJPRE)list.o: gtk/list.c gtk/../common/context.h \
+ gtk/../common/../ui/toolkit.h gtk/../common/action.h \
+ gtk/../common/object.h gtk/../common/action.h gtk/container.h \
+ gtk/../ui/toolkit.h gtk/../ui/container.h gtk/../ui/toolkit.h \
+ gtk/toolkit.h gtk/list.h gtk/../ui/list.h gtk/button.h \
+ gtk/../ui/button.h gtk/icon.h gtk/../ui/icons.h gtk/menu.h \
+ gtk/../ui/menu.h gtk/../common/menu.h gtk/../common/../ui/menu.h \
+ gtk/dnd.h gtk/../ui/dnd.h
+ $(CC) -o $@ $(CFLAGS) -I../ucx $(SHLIB_CFLAGS) $(TK_CFLAGS) -c $<
+
+$(GTK_OBJPRE)menu.o: gtk/menu.c gtk/menu.h gtk/../ui/menu.h \
+ gtk/../ui/toolkit.h gtk/../common/menu.h gtk/../common/../ui/menu.h \
+ gtk/toolkit.h gtk/../ui/toolkit.h gtk/../common/context.h \
+ gtk/../common/../ui/toolkit.h gtk/../common/action.h \
+ gtk/../common/object.h gtk/widget.h gtk/../ui/widget.h \
+ gtk/../common/types.h gtk/../common/action.h gtk/../ui/properties.h \
+ gtk/../ui/window.h gtk/container.h gtk/../ui/container.h
+ $(CC) -o $@ $(CFLAGS) -I../ucx $(SHLIB_CFLAGS) $(TK_CFLAGS) -c $<
+
+$(GTK_OBJPRE)range.o: gtk/range.c gtk/range.h gtk/toolkit.h \
+ gtk/../ui/toolkit.h gtk/../common/context.h \
+ gtk/../common/../ui/toolkit.h gtk/../common/action.h \
+ gtk/../common/object.h gtk/../ui/range.h gtk/../ui/toolkit.h \
+ gtk/container.h gtk/../ui/container.h
+ $(CC) -o $@ $(CFLAGS) -I../ucx $(SHLIB_CFLAGS) $(TK_CFLAGS) -c $<
+
+$(GTK_OBJPRE)text.o: gtk/text.c gtk/text.h gtk/../ui/text.h \
+ gtk/../ui/toolkit.h gtk/toolkit.h gtk/../ui/toolkit.h \
+ gtk/../common/context.h gtk/../common/../ui/toolkit.h \
+ gtk/../common/action.h gtk/../common/object.h gtk/container.h \
+ gtk/../ui/container.h gtk/widget.h gtk/../ui/widget.h \
+ gtk/../common/types.h
+ $(CC) -o $@ $(CFLAGS) -I../ucx $(SHLIB_CFLAGS) $(TK_CFLAGS) -c $<
+
+$(GTK_OBJPRE)toolbar.o: gtk/toolbar.c gtk/toolbar.h gtk/../ui/toolbar.h \
+ gtk/../ui/toolkit.h gtk/../common/toolbar.h \
+ gtk/../common/../ui/toolbar.h gtk/../common/menu.h \
+ gtk/../common/../ui/menu.h gtk/../common/../ui/toolkit.h gtk/list.h \
+ gtk/../ui/list.h gtk/toolkit.h gtk/../ui/toolkit.h \
+ gtk/../common/context.h gtk/../common/../ui/toolkit.h \
+ gtk/../common/action.h gtk/../common/object.h gtk/menu.h \
+ gtk/../ui/menu.h gtk/../common/menu.h gtk/button.h gtk/../ui/button.h \
+ gtk/icon.h gtk/../ui/icons.h
+ $(CC) -o $@ $(CFLAGS) -I../ucx $(SHLIB_CFLAGS) $(TK_CFLAGS) -c $<
+
+$(GTK_OBJPRE)toolkit.o: gtk/toolkit.c gtk/toolkit.h gtk/../ui/toolkit.h \
+ gtk/../common/context.h gtk/../common/../ui/toolkit.h \
+ gtk/../common/action.h gtk/../common/object.h gtk/toolbar.h \
+ gtk/../ui/toolbar.h gtk/../ui/toolkit.h gtk/../common/toolbar.h \
+ gtk/../common/../ui/toolbar.h gtk/../common/menu.h \
+ gtk/../common/../ui/menu.h gtk/../common/../ui/toolkit.h gtk/list.h \
+ gtk/../ui/list.h gtk/window.h gtk/icon.h gtk/../ui/icons.h \
+ gtk/../common/document.h gtk/../common/context.h \
+ gtk/../common/properties.h gtk/../common/../ui/properties.h \
+ gtk/../common/menu.h gtk/../common/threadpool.h gtk/../common/app.h
+ $(CC) -o $@ $(CFLAGS) -I../ucx $(SHLIB_CFLAGS) $(TK_CFLAGS) -c $<
+
+$(GTK_OBJPRE)webview.o: gtk/webview.c gtk/toolkit.h gtk/../ui/toolkit.h \
+ gtk/../common/context.h gtk/../common/../ui/toolkit.h \
+ gtk/../common/action.h gtk/../common/object.h gtk/container.h \
+ gtk/../ui/container.h gtk/../ui/toolkit.h gtk/webview.h \
+ gtk/../ui/webview.h gtk/widget.h gtk/../ui/widget.h
+ $(CC) -o $@ $(CFLAGS) -I../ucx $(SHLIB_CFLAGS) $(TK_CFLAGS) -c $<
+
+$(GTK_OBJPRE)widget.o: gtk/widget.c gtk/widget.h gtk/../ui/widget.h \
+ gtk/../ui/toolkit.h gtk/container.h gtk/../ui/toolkit.h \
+ gtk/../ui/container.h gtk/toolkit.h gtk/../common/context.h \
+ gtk/../common/../ui/toolkit.h gtk/../common/action.h \
+ gtk/../common/object.h
+ $(CC) -o $@ $(CFLAGS) -I../ucx $(SHLIB_CFLAGS) $(TK_CFLAGS) -c $<
+
+$(GTK_OBJPRE)window.o: gtk/window.c gtk/../ui/window.h \
+ gtk/../ui/toolkit.h gtk/../ui/properties.h gtk/../common/context.h \
+ gtk/../common/../ui/toolkit.h gtk/../common/action.h \
+ gtk/../common/menu.h gtk/../common/../ui/menu.h \
+ gtk/../common/../ui/toolkit.h gtk/../common/toolbar.h \
+ gtk/../common/../ui/toolbar.h gtk/../common/menu.h gtk/../common/utils.h \
+ gtk/../common/../ui/text.h gtk/menu.h gtk/../ui/menu.h gtk/toolkit.h \
+ gtk/../ui/toolkit.h gtk/../common/object.h gtk/toolbar.h \
+ gtk/../ui/toolbar.h gtk/list.h gtk/../ui/list.h gtk/container.h \
+ gtk/../ui/container.h gtk/headerbar.h gtk/button.h gtk/../ui/button.h \
+ gtk/window.h
+ $(CC) -o $@ $(CFLAGS) -I../ucx $(SHLIB_CFLAGS) $(TK_CFLAGS) -c $<
+
--- /dev/null
+/*
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
+ *
+ * Copyright 2026 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 "action.h"
+
+#include <stdio.h>
+#include <stdlib.h>
+
+
+
+/* ------------------------------ public API ------------------------------ */
+
+void ui_add_action(UiContext *ctx, const char *name, ui_callback callback, void *userdata) {
+ uic_add_action(ctx, name, callback, userdata, NULL, NULL);
+}
+
+void ui_add_action_with_accelerator(
+ UiContext *ctx,
+ const char *name,
+ ui_callback callback,
+ void *userdata,
+ const char *accelerator,
+ const char *accelerator_text)
+{
+ uic_add_action(ctx, name, callback, userdata, accelerator, accelerator_text);
+
+ // TODO: accelerator
+}
--- /dev/null
+/*
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
+ *
+ * Copyright 2026 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 ACTION_H
+#define ACTION_H
+
+#include "../ui/toolkit.h"
+#include "../common/action.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* ACTION_H */
+
#include "button.h"
#include "container.h"
+#include "widget.h"
#include <cx/allocator.h>
#include <cx/buffer.h>
#include <cx/json.h>
#include "../common/context.h"
#include "../common/object.h"
+#include "../common/action.h"
void ui_button_set_icon_name(GtkWidget *button, const char *icon) {
if(!icon) {
const char *tooltip,
ui_callback onclick,
void *userdata,
+ const char *action,
int event_value,
bool activate_event)
{
gtk_widget_set_tooltip_text(button, tooltip);
}
- if(onclick) {
+ if(onclick || action) {
UiEventData *event = malloc(sizeof(UiEventData));
event->obj = obj;
event->userdata = userdata;
event->callback = onclick;
event->value = event_value;
+ event->action = action ? strdup(action) : NULL;
event->customdata = NULL;
event->customint = 0;
g_signal_connect(
button,
"destroy",
- G_CALLBACK(ui_destroy_userdata),
+ G_CALLBACK(ui_destroy_eventdata),
event);
if(activate_event) {
g_signal_connect(
G_CALLBACK(ui_button_clicked),
event);
}
+
+ if(action) {
+ uic_bind_action(obj->ctx, action, button, (ui_enablefunc)ui_set_enabled);
+ UiAction *ui_action = uic_resolve_action(obj->ctx, action);
+ if(!ui_action) {
+ ui_set_enabled(button, FALSE);
+ }
+ }
}
return button;
}
UIWIDGET ui_button_create(UiObject *obj, UiButtonArgs *args) {
- GtkWidget *button = ui_create_button(obj, args->label, args->icon, args->tooltip, args->onclick, args->onclickdata, 0, FALSE);
+ GtkWidget *button = ui_create_button(obj, args->label, args->icon, args->tooltip, args->onclick, args->onclickdata, args->action, 0, FALSE);
ui_set_name_and_style(button, args->name, args->style_class);
ui_set_widget_states(obj->ctx, button, args->states);
UiContainerPrivate *ct = (UiContainerPrivate*)obj->container_end;
e.eventdatatype = 0;
e.intval = event->value;
e.set = ui_get_setop();
- event->callback(&e, event->userdata);
+ if(event->callback) {
+ event->callback(&e, event->userdata);
+ }
+
+ if(event->action) {
+ uic_action_callback(&e, event->action);
+ }
}
void ui_button_set_label(UIWIDGET button, const char *label) {
ui_button_set_icon_name(button, icon);
}
+void ui_button_set_tooltip(UIWIDGET button, const char *tooltip) {
+ gtk_widget_set_tooltip_text(GTK_WIDGET(button), tooltip);
+}
+
+void ui_togglebutton_set_label(UIWIDGET button, const char *label) {
+ ui_button_set_label(button, label);
+}
+
+void ui_togglebutton_set_icon(UIWIDGET button, const char *icon) {
+ ui_button_set_icon(button, icon);
+}
+
+void ui_togglebutton_set_tooltip(UIWIDGET button, const char *tooltip) {
+ ui_button_set_tooltip(button, tooltip);
+}
+
+void ui_checkbox_set_label(UIWIDGET button, const char *label) {
+ ui_button_set_label(button, label);
+}
+
+void ui_checkbox_set_icon(UIWIDGET button, const char *icon) {
+ ui_button_set_icon(button, icon);
+}
+
+void ui_checkbox_set_tooltip(UIWIDGET button, const char *tooltip) {
+ ui_button_set_tooltip(button, tooltip);
+}
+
+void ui_radiobutton_set_label(UIWIDGET button, const char *label) {
+ ui_button_set_label(button, label);
+}
+
+void ui_radiobutton_set_icon(UIWIDGET button, const char *icon) {
+ ui_button_set_icon(button, icon);
+}
+
+void ui_radiobutton_set_tooltip(UIWIDGET button, const char *tooltip) {
+ ui_button_set_tooltip(button, tooltip);
+}
+
+
int64_t ui_toggle_button_get(UiInteger *integer) {
GtkToggleButton *button = integer->obj;
integer->value = (int)gtk_toggle_button_get_active(button);
e.eventdatatype = 0;
e.intval = gtk_toggle_button_get_active(widget);
e.set = ui_get_setop();
- event->callback(&e, event->userdata);
+
+ if(event->callback) {
+ event->callback(&e, event->userdata);
+ }
+
+ if(event->action) {
+ uic_action_callback(&e, event->action);
+ }
}
static void ui_togglebutton_enable_state_callback(GtkToggleButton *widget, UiEventData *event) {
UiInteger *value,
ui_callback onchange,
void *onchangedata,
+ const char *action,
int enable_state)
{
if(label) {
gtk_widget_set_tooltip_text(togglebutton, tooltip);
}
+ if(action) {
+ uic_bind_action(obj->ctx, action, togglebutton, (ui_enablefunc)ui_set_enabled);
+ UiAction *ui_action = uic_resolve_action(obj->ctx, action);
+ if(!ui_action) {
+ ui_set_enabled(togglebutton, FALSE);
+ }
+ }
+
ui_bind_togglebutton(
obj,
togglebutton,
(ui_toggled_func)ui_toggled_callback,
onchange,
onchangedata,
+ action,
(ui_toggled_func)ui_togglebutton_enable_state_callback,
enable_state
);
void (*toggled_callback)(void*, void*),
ui_callback onchange,
void *onchangedata,
+ const char *action,
void (*enable_state_func)(void*, void*),
int enable_state)
{
event);
}
- if(onchange) {
+ if(onchange || action) {
UiEventData *event = malloc(sizeof(UiEventData));
event->obj = obj;
event->userdata = onchangedata;
event->callback = onchange;
+ event->action = action ? strdup(action) : NULL,
event->value = 0;
event->customdata = NULL;
event->customint = 0;
g_signal_connect(
widget,
"destroy",
- G_CALLBACK(ui_destroy_userdata),
+ G_CALLBACK(ui_destroy_eventdata),
event);
}
-
+
if(enable_state > 0) {
UiEventData *event = malloc(sizeof(UiEventData));
event->obj = obj;
args->value,
args->onchange,
args->onchangedata,
+ args->action,
args->enable_state);
ui_set_name_and_style(widget, args->name, args->style_class);
ui_set_widget_states(obj->ctx, widget, args->states);
(ui_toggled_func)ui_checkbox_callback,
args->onchange,
args->onchangedata,
+ args->action,
(ui_toggled_func)ui_checkbox_enable_state,
args->enable_state);
#endif
+static void content_toggle_button_changed(UiContentToggleButton *button) {
+ if(button->toggled) {
+ gtk_button_set_label(GTK_BUTTON(button->widget), button->label1);
+ ui_button_set_icon_name(button->widget, button->icon1);
+ gtk_widget_set_tooltip_text(button->widget, button->tooltip1);
+ } else {
+ gtk_button_set_label(GTK_BUTTON(button->widget), button->label0);
+ ui_button_set_icon_name(button->widget, button->icon0);
+ gtk_widget_set_tooltip_text(button->widget, button->tooltip0);
+ }
+
+ UiEvent e;
+ e.obj = button->obj;
+ e.window = button->obj->window;
+ e.document = button->obj->ctx->document;
+ e.eventdata = NULL;
+ e.eventdatatype = 0;
+ e.intval = button->toggled;
+ e.set = ui_get_setop();
+
+ if(button->onchange) {
+ button->onchange(&e, button->onchangedata);
+ }
+
+ if(button->onchange_action) {
+ uic_action_callback(&e, button->onchange_action);
+ }
+}
+
+static void ui_content_toggle_button_toggled(GtkWidget *widget, UiContentToggleButton *button) {
+ button->toggled = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(widget));
+ if(ui_get_setop() == 0) {
+ content_toggle_button_changed(button);
+ }
+}
+
+static void ui_content_toggle_button_clicked(GtkWidget *widget, UiContentToggleButton *button) {
+ button->toggled = !button->toggled;
+ content_toggle_button_changed(button);
+}
+
+static void ui_destroy_content_togglebutton(GtkWidget *widget, UiContentToggleButton *button) {
+ free(button->label0);
+ free(button->icon0);
+ free(button->tooltip0);
+ free(button->label1);
+ free(button->icon1);
+ free(button->tooltip1);
+ free(button->onchange_action);
+ free(button);
+}
+
+static void ui_content_togglebutton_enabled_by_state(void *data, int enabled) {
+ UiContentToggleButton *button = data;
+ if(button->toggled != enabled) {
+ button->toggled = enabled;
+ content_toggle_button_changed(button);
+ }
+}
+
+UIWIDGET ui_create_content_togglebutton(UiObject *obj, UiContentToggleArgs *args) {
+ UiContentToggleButton *button = malloc(sizeof(UiContentToggleButton));
+ memset(button, 0, sizeof(UiContentToggleButton));
+ button->obj = obj;
+ button->label0 = args->label0 ? strdup(args->label0) : NULL;
+ button->icon0 = args->icon0 ? strdup(args->icon0) : NULL;
+ button->tooltip0 = args->tooltip0 ? strdup(args->tooltip0) : NULL;
+ button->label1 = args->label1 ? strdup(args->label1) : NULL;
+ button->icon1 = args->icon1 ? strdup(args->icon1) : NULL;
+ button->tooltip1 = args->tooltip1 ? strdup(args->tooltip1) : NULL;
+ button->enable_state = args->enable_state;
+ button->var = uic_widget_var(obj->ctx, obj->ctx, args->value, args->varname, UI_VAR_INTEGER);
+ button->onchange = args->onchange;
+ button->onchangedata = args->onchangedata;
+ button->onchange_action = args->action ? strdup(args->action) : NULL;
+
+ const char *label = args->label0;
+ const char *icon = args->icon0;
+ const char *tooltip = args->tooltip0;
+ if(button->var) {
+ UiInteger *i = button->var->value;
+ i->obj = button;
+ i->get = ui_ctntogglebutton_get;
+ i->set = ui_ctntogglebutton_set;
+
+ if(i->value) {
+ label = args->label1;
+ icon = args->label1;
+ tooltip = args->tooltip1;
+ button->toggled = 1;
+ }
+ }
+
+ GtkWidget *widget;
+ if(args->istogglebutton) {
+ widget = gtk_toggle_button_new_with_label(label);
+
+ g_signal_connect(
+ widget,
+ "toggled",
+ G_CALLBACK(ui_content_toggle_button_toggled),
+ button);
+ } else {
+ widget = gtk_button_new_with_label(label);
+
+ g_signal_connect(
+ widget,
+ "clicked",
+ G_CALLBACK(ui_content_toggle_button_clicked),
+ button);
+ }
+ ui_button_set_icon_name(widget, icon);
+ gtk_widget_set_tooltip_text(widget, tooltip);
+ button->widget = widget;
+
+ if(args->action) {
+ uic_bind_action(obj->ctx, args->action, widget, (ui_enablefunc)ui_set_enabled);
+ UiAction *ui_action = uic_resolve_action(obj->ctx, args->action);
+ if(!ui_action) {
+ ui_set_enabled(widget, FALSE);
+ }
+ }
+
+ if(args->toggled_by_state != 0) {
+ CxList *ls = cxArrayListCreate(NULL, sizeof(int), 1);
+ cxListAdd(ls, &args->toggled_by_state);
+ uic_add_state_widget(obj->ctx, button, ui_content_togglebutton_enabled_by_state, ls);
+ cxListFree(ls);
+ }
+
+ g_signal_connect(
+ widget,
+ "destroy",
+ G_CALLBACK(ui_destroy_content_togglebutton),
+ button);
+
+ g_object_set_data(G_OBJECT(widget), "ui_content_togglebutton", button);
+ return widget;
+}
+
+UIWIDGET ui_content_togglebutton_create(UiObject *obj, UiContentToggleArgs *args) {
+ GtkWidget *widget = ui_create_content_togglebutton(obj, args);
+
+ ui_set_name_and_style(widget, args->name, args->style_class);
+ ui_set_widget_states(obj->ctx, widget, args->states);
+ UiContainerPrivate *ct = (UiContainerPrivate*)obj->container_end;
+ UiLayout layout = UI_ARGS2LAYOUT(args);
+ ct->add(ct, widget, &layout);
+ uic_widget_set_visibility_states(obj->ctx, widget, args->visibility_states);
+ return widget;
+}
+
+int64_t ui_ctntogglebutton_get(UiInteger *value) {
+ UiContentToggleButton *button = value->obj;
+ value->value = button->toggled;
+ return value->value;
+}
+
+void ui_ctntogglebutton_set(UiInteger *value, int64_t i) {
+ UiContentToggleButton *button = value->obj;
+ button->toggled = i != 0;
+ value->value = button->toggled;
+ content_toggle_button_changed(button);
+}
+
#if GTK_MAJOR_VERSION >= 4
#define RADIOBUTTON_NEW(group, label) gtk_check_button_new_with_label(label)
#define RADIOBUTTON_SET_GROUP(button, group)
static void linkbutton_clicked(GtkWidget *widget, UiLinkButton *data) {
linkbutton_callback(widget, data);
if(data->link) {
-#if GTK_CHECK_VERSION(4, 0, 0)
- GtkUriLauncher *launcher = gtk_uri_launcher_new (data->link);
- gtk_uri_launcher_launch (launcher, NULL, NULL, NULL, NULL);
- g_object_unref (launcher);
-#elif GTK_CHECK_VERSION(3, 22, 0)
- GError *error = NULL;
- gtk_show_uri_on_window(NULL, data->link, GDK_CURRENT_TIME, &error);
-#elif
- // TODO: call xdg-open
-#endif
+ ui_open_uri(data->link);
}
}
if(s->value.free) {
s->value.free(s->value.ptr);
}
+ s->value.ptr = NULL;
#if GTK_MAJOR_VERSION == 3
UiLinkButton *data = s->obj;
GtkWidget *child = gtk_bin_get_child(GTK_BIN(data->widget));
extern "C" {
#endif
+typedef struct UiContentToggleButton {
+ UiObject *obj;
+ UiVar *var;
+ GtkWidget *widget;
+ char *label0;
+ char *icon0;
+ char *tooltip0;
+ char *label1;
+ char *icon1;
+ char *tooltip1;
+ ui_callback onchange;
+ void *onchangedata;
+ char *onchange_action;
+ int toggled;
+ int enable_state;
+} UiContentToggleButton;
+
typedef struct UiLinkButton {
UiObject *obj;
GtkWidget *widget;
const char *tooltip,
ui_callback onclick,
void *userdata,
+ const char *action,
int event_value,
bool activate_event);
UiInteger *value,
ui_callback onchange,
void *onchangedata,
+ const char *action,
int enable_state);
void ui_bind_togglebutton(
void (*toggled_callback)(void*, void*),
ui_callback onchange,
void *onchangedata,
+ const char *action,
void (*enable_state_func)(void*, void*),
int enable_state);
void ui_radio_obs(GtkToggleButton *widget, UiVarEventData *event);
+UIWIDGET ui_create_content_togglebutton(UiObject *obj, UiContentToggleArgs *args);
+
int64_t ui_switch_get(UiInteger *value);
void ui_switch_set(UiInteger *value, int64_t i);
+int64_t ui_ctntogglebutton_get(UiInteger *value);
+void ui_ctntogglebutton_set(UiInteger *value, int64_t i);
+
int64_t ui_radiobutton_get(UiInteger *value);
void ui_radiobutton_set(UiInteger *value, int64_t i);
void ui_container_begin_close(UiObject *obj) {
- UiContainerX *ct = obj->container_end;
+ UiContainer *ct = obj->container_end;
ct->close = 1;
}
int ui_container_finish(UiObject *obj) {
- UiContainerX *ct = obj->container_end;
+ UiContainer *ct = obj->container_end;
if(ct->close) {
ui_end_new(obj);
return 0;
{
GtkWidget *sub = NULL;
GtkWidget *add = NULL;
- UiContainerX *container = NULL;
+ UiContainer *container = NULL;
switch(type) {
default: {
sub = ui_gtk_vbox_new(spacing);
container->container.widget = widget;
container->add = add_child;
container->userdata = userdata;
- uic_object_push_container(obj, (UiContainerX*)container);
+ uic_object_push_container(obj, (UiContainer*)container);
}
/* -------------------- Box Container -------------------- */
-UiContainerX* ui_box_container(UiObject *obj, GtkWidget *box, UiSubContainerType type) {
+UiContainer* ui_box_container(UiObject *obj, GtkWidget *box, UiSubContainerType type) {
UiBoxContainer *ct = cxCalloc(
obj->ctx->allocator,
1,
ct->container.widget = box;
ct->container.add = ui_box_container_add;
ct->type = type;
- return (UiContainerX*)ct;
+ return (UiContainer*)ct;
}
void ui_box_container_add(UiContainerPrivate *ct, GtkWidget *widget, UiLayout *layout) {
#endif
}
-UiContainerX* ui_grid_container(
+UiContainer* ui_grid_container(
UiObject *obj,
GtkWidget *grid,
UiBool def_hexpand,
ct->container.add = ui_grid_container_add;
UI_GTK_V2(ct->width = 0);
UI_GTK_V2(ct->height = 1);
- return (UiContainerX*)ct;
+ return (UiContainer*)ct;
}
}
#endif
-UiContainerX* ui_frame_container(UiObject *obj, GtkWidget *frame) {
+UiContainer* ui_frame_container(UiObject *obj, GtkWidget *frame) {
UiContainerPrivate *ct = cxCalloc(
obj->ctx->allocator,
1,
sizeof(UiContainerPrivate));
ct->widget = frame;
ct->add = ui_frame_container_add;
- return (UiContainerX*)ct;
+ return (UiContainer*)ct;
}
void ui_frame_container_add(UiContainerPrivate *ct, GtkWidget *widget, UiLayout *layout) {
FRAME_SET_CHILD(ct->widget, widget);
}
-UiContainerX* ui_expander_container(UiObject *obj, GtkWidget *expander) {
+UiContainer* ui_expander_container(UiObject *obj, GtkWidget *expander) {
UiContainerPrivate *ct = cxCalloc(
obj->ctx->allocator,
1,
sizeof(UiContainerPrivate));
ct->widget = expander;
ct->add = ui_expander_container_add;
- return (UiContainerX*)ct;
+ return (UiContainer*)ct;
}
void ui_expander_container_add(UiContainerPrivate *ct, GtkWidget *widget, UiLayout *layout) {
SCROLLEDWINDOW_SET_CHILD(ct->widget, widget);
}
-UiContainerX* ui_scrolledwindow_container(UiObject *obj, GtkWidget *scrolledwindow) {
+UiContainer* ui_scrolledwindow_container(UiObject *obj, GtkWidget *scrolledwindow) {
UiContainerPrivate *ct = cxCalloc(
obj->ctx->allocator,
1,
sizeof(UiContainerPrivate));
ct->widget = scrolledwindow;
ct->add = ui_scrolledwindow_container_add;
- return (UiContainerX*)ct;
+ return (UiContainer*)ct;
}
-UiContainerX* ui_tabview_container(UiObject *obj, GtkWidget *tabview) {
+UiContainer* ui_tabview_container(UiObject *obj, GtkWidget *tabview) {
UiTabViewContainer *ct = cxCalloc(
obj->ctx->allocator,
1,
sizeof(UiTabViewContainer));
ct->container.widget = tabview;
ct->container.add = ui_tabview_container_add;
- return (UiContainerX*)ct;
+ return (UiContainer*)ct;
}
void ui_tabview_container_add(UiContainerPrivate *ct, GtkWidget *widget, UiLayout *layout) {
ui_set_name_and_style(box, args->name, args->style_class);
ct->add(ct, box, &layout);
- UiContainerX *container = ui_box_container(obj, box, type);
+ UiContainer *container = ui_box_container(obj, box, type);
uic_object_push_container(obj, container);
uic_widget_set_visibility_states(obj->ctx, box, args->visibility_states);
ui_set_name_and_style(grid, args->name, args->style_class);
ct->add(ct, grid, &layout);
- UiContainerX *container = ui_grid_container(obj, grid, args->def_hexpand, args->def_vexpand, args->def_hfill, args->def_vfill);
+ UiContainer *container = ui_grid_container(obj, grid, args->def_hexpand, args->def_vexpand, args->def_hfill, args->def_vfill);
uic_object_push_container(obj, container);
uic_widget_set_visibility_states(obj->ctx, grid, args->visibility_states);
if(sub) {
FRAME_SET_CHILD(frame, sub);
} else {
- UiContainerX *container = ui_frame_container(obj, frame);
+ UiContainer *container = ui_frame_container(obj, frame);
uic_object_push_container(obj, container);
}
if(sub) {
EXPANDER_SET_CHILD(expander, sub);
} else {
- UiContainerX *container = ui_expander_container(obj, expander);
+ UiContainer *container = ui_expander_container(obj, expander);
uic_object_push_container(obj, container);
}
if(sub) {
SCROLLEDWINDOW_SET_CHILD(sw, sub);
} else {
- UiContainerX *container = ui_scrolledwindow_container(obj, sw);
+ UiContainer *container = ui_scrolledwindow_container(obj, sw);
uic_object_push_container(obj, container);
}
UiLayout layout = UI_ARGS2LAYOUT(args);
ct->add(ct, widget, &layout);
- UiContainerX *container = ui_tabview_container(obj, widget);
+ UiContainer *container = ui_tabview_container(obj, widget);
uic_object_push_container(obj, container);
uic_widget_set_visibility_states(obj->ctx, widget, args->visibility_states);
}
static GtkWidget* create_tab(UiObject *obj, UiGtkTabView *tabview, const char *title, int tab) {
- UiContainerX *container;
+ UiContainer *container;
GtkWidget *sub;
switch(tabview->subcontainer) {
default: {
sizeof(UiHeaderbarContainer));
memcpy(hb, ct, sizeof(UiHeaderbarContainer));
hb->part = part;
- uic_object_push_container(obj, (UiContainerX*)hb);
+ uic_object_push_container(obj, (UiContainer*)hb);
}
void ui_headerbar_start_create(UiObject *obj) {
ui_set_name_and_style(box, args->name, args->style_class);
ct->add(ct, box, &layout);
- UiContainerX *container = ui_headerbar_fallback_container(obj, box);
+ UiContainer *container = ui_headerbar_fallback_container(obj, box);
uic_object_push_container(obj, container);
return box;
UiContainerPrivate *ct = (UiContainerPrivate*)obj->container_end;
GtkWidget *headerbar = ct->widget;
- UiContainerX *container = ui_headerbar_container(obj, headerbar);
+ UiContainer *container = ui_headerbar_container(obj, headerbar);
uic_object_push_container(obj, container);
UiHeaderbarContainer *hb = (UiHeaderbarContainer*)container;
hb->part = part;
}
-UiContainerX* ui_headerbar_fallback_container(UiObject *obj, GtkWidget *headerbar) {
+UiContainer* ui_headerbar_fallback_container(UiObject *obj, GtkWidget *headerbar) {
UiHeaderbarContainer *ct = cxCalloc(
obj->ctx->allocator,
1,
sizeof(UiHeaderbarContainer));
ct->container.widget = headerbar;
ct->container.add = ui_headerbar_fallback_container_add;
- return (UiContainerX*)ct;
+ return (UiContainer*)ct;
}
void ui_headerbar_fallback_container_add(UiContainerPrivate *ct, GtkWidget *widget, UiLayout *layout) {
return ui_headerbar_fallback_create(obj, args);
}
- UiContainerX *container = ui_headerbar_container(obj, headerbar);
+ UiContainer *container = ui_headerbar_container(obj, headerbar);
uic_object_push_container(obj, container);
return headerbar;
}
-UiContainerX* ui_headerbar_container(UiObject *obj, GtkWidget *headerbar) {
+UiContainer* ui_headerbar_container(UiObject *obj, GtkWidget *headerbar) {
UiHeaderbarContainer *ct = cxCalloc(
obj->ctx->allocator,
1,
sizeof(UiHeaderbarContainer));
ct->container.widget = headerbar;
ct->container.add = ui_headerbar_container_add;
- return (UiContainerX*)ct;
+ return (UiContainer*)ct;
}
void ui_headerbar_container_add(UiContainerPrivate *ct, GtkWidget *widget, UiLayout *layout) {
ui_gtk_set_margin(box, args->margin, args->margin_left, args->margin_right, args->margin_top, args->margin_bottom);
adw_toolbar_view_set_content(ADW_TOOLBAR_VIEW(sidebar_toolbar_view), box);
- UiContainerX *container = ui_box_container(obj, box, UI_CONTAINER_VBOX);
+ UiContainer *container = ui_box_container(obj, box, UI_CONTAINER_VBOX);
uic_object_push_container(obj, container);
return box;
ui_gtk_set_margin(box, args->margin, args->margin_left, args->margin_right, args->margin_top, args->margin_bottom);
BOX_ADD_EXPAND(sidebar_vbox, box);
- UiContainerX *container = ui_box_container(obj, box, UI_CONTAINER_VBOX);
+ UiContainer *container = ui_box_container(obj, box, UI_CONTAINER_VBOX);
uic_object_push_container(obj, container);
return box;
ui_gtk_set_margin(box, args->margin, args->margin_left, args->margin_right, args->margin_top, args->margin_bottom);
BOX_ADD_EXPAND(pbox, box);
- UiContainerX *container = ui_box_container(obj, box, UI_CONTAINER_VBOX);
+ UiContainer *container = ui_box_container(obj, box, UI_CONTAINER_VBOX);
uic_object_push_container(obj, container);
return box;
}
UiSplitPane *splitpane = ui_create_splitpane_data(pane0, orientation, max, args->initial_position);
- UiContainerX *container = ui_splitpane_container(obj, pane0, splitpane);
+ UiContainer *container = ui_splitpane_container(obj, pane0, splitpane);
uic_object_push_container(obj, container);
g_object_set_data(G_OBJECT(pane0), "ui_splitpane", splitpane);
return ct;
}
-UiContainerX* ui_splitpane_container(UiObject *obj, GtkWidget *pane, UiSplitPane *data) {
+UiContainer* ui_splitpane_container(UiObject *obj, GtkWidget *pane, UiSplitPane *data) {
UiSplitPaneContainer *ct = ui_calloc(obj->ctx, 1, sizeof(UiSplitPaneContainer));
ct->container.widget = pane;
ct->container.add = ui_splitpane_container_add;
ct->splitpane = data;
- return (UiContainerX*)ct;
+ return (UiContainer*)ct;
}
void ui_splitpane_container_add(UiContainerPrivate *ct, GtkWidget *widget, UiLayout *layout) {
typedef struct UiContainerPrivate UiContainerPrivate;
struct UiContainerPrivate {
- UiContainerX container;
+ UiContainer container;
GtkWidget *widget;
UIMENU menu;
GtkWidget* ui_gtk_set_margin(GtkWidget *widget, int margin, int margin_left, int margin_right, int margin_top, int margin_bottom);
UIWIDGET ui_box_create(UiObject *obj, UiContainerArgs *args, UiSubContainerType type);
-UiContainerX* ui_box_container(UiObject *obj, GtkWidget *box, UiSubContainerType type);
+UiContainer* ui_box_container(UiObject *obj, GtkWidget *box, UiSubContainerType type);
void ui_box_container_add(UiContainerPrivate *ct, GtkWidget *widget, UiLayout *layout);
GtkWidget* ui_create_grid_widget(int colspacing, int rowspacing);
-UiContainerX* ui_grid_container(
+UiContainer* ui_grid_container(
UiObject *obj,
GtkWidget *grid,
UiBool def_hexpand,
UiBool def_vfill);
void ui_grid_container_add(UiContainerPrivate *ct, GtkWidget *widget, UiLayout *layout);
-UiContainerX* ui_frame_container(UiObject *obj, GtkWidget *frame);
+UiContainer* ui_frame_container(UiObject *obj, GtkWidget *frame);
void ui_frame_container_add(UiContainerPrivate *ct, GtkWidget *widget, UiLayout *layout);
-UiContainerX* ui_expander_container(UiObject *obj, GtkWidget *expander);
+UiContainer* ui_expander_container(UiObject *obj, GtkWidget *expander);
void ui_expander_container_add(UiContainerPrivate *ct, GtkWidget *widget, UiLayout *layout);
-UiContainerX* ui_scrolledwindow_container(UiObject *obj, GtkWidget *scrolledwindow);
+UiContainer* ui_scrolledwindow_container(UiObject *obj, GtkWidget *scrolledwindow);
void ui_scrolledwindow_container_add(UiContainerPrivate *ct, GtkWidget *widget, UiLayout *layout);
-UiContainerX* ui_tabview_container(UiObject *obj, GtkWidget *tabview);
+UiContainer* ui_tabview_container(UiObject *obj, GtkWidget *tabview);
void ui_tabview_container_add(UiContainerPrivate *ct, GtkWidget *widget, UiLayout *layout);
UiSplitPane* ui_create_splitpane_data(GtkWidget *pane, UiOrientation orientation, int max, int init);
-UiContainerX* ui_splitpane_container(UiObject *obj, GtkWidget *pane, UiSplitPane *data);
+UiContainer* ui_splitpane_container(UiObject *obj, GtkWidget *pane, UiSplitPane *data);
void ui_splitpane_container_add(UiContainerPrivate *ct, GtkWidget *widget, UiLayout *layout);
int64_t ui_splitpane_get(UiInteger *i);
void ui_gtk_notebook_select_tab(GtkWidget *widget, int tab);
#if GTK_CHECK_VERSION(3, 10, 0)
-UiContainerX* ui_headerbar_container(UiObject *obj, GtkWidget *headerbar);
+UiContainer* ui_headerbar_container(UiObject *obj, GtkWidget *headerbar);
void ui_headerbar_container_add(UiContainerPrivate *ct, GtkWidget *widget, UiLayout *layout);
#endif
-UiContainerX* ui_headerbar_fallback_container(UiObject *obj, GtkWidget *headerbar);
+UiContainer* ui_headerbar_fallback_container(UiObject *obj, GtkWidget *headerbar);
void ui_headerbar_fallback_container_add(UiContainerPrivate *ct, GtkWidget *widget, UiLayout *layout);
#ifdef __cplusplus
#include "button.h"
#include "menu.h"
+#include "../ui/widget.h"
+
+#include <cx/array_list.h>
#include "../ui/properties.h"
}
// main toolbar
- ui_headerbar_add_items(obj, main_headerbar, left_defaults, UI_TOOLBAR_LEFT);
- ui_headerbar_add_items(obj, main_headerbar, center_defaults, UI_TOOLBAR_CENTER);
+ ui_headerbar_add_items(obj, main_headerbar, left_defaults, UI_TOOLBAR_LEFT, NULL);
+ ui_headerbar_add_items(obj, main_headerbar, center_defaults, UI_TOOLBAR_CENTER, NULL);
if(appmenu && appmenu_pos == UI_TOOLBAR_RIGHT) {
ui_add_headerbar_menu(main_headerbar, NULL, appmenu, obj, UI_TOOLBAR_RIGHT);
}
- ui_headerbar_add_items(obj, main_headerbar, right_defaults, UI_TOOLBAR_RIGHT);
+ ui_headerbar_add_items(obj, main_headerbar, right_defaults, UI_TOOLBAR_RIGHT, NULL);
// sidebar
if(sidebar_headerbar) {
// ui_headerbar_add_items pos parameter uses only UI_TOOLBAR_LEFT, UI_TOOLBAR_CENTER, UI_TOOLBAR_RIGHT
- ui_headerbar_add_items(obj, sidebar_headerbar, sidebar_left_defaults, UI_TOOLBAR_LEFT);
+ ui_headerbar_add_items(obj, sidebar_headerbar, sidebar_left_defaults, UI_TOOLBAR_LEFT, NULL);
if(appmenu && appmenu_pos == UI_TOOLBAR_SIDEBAR_RIGHT) {
ui_add_headerbar_menu(sidebar_headerbar, NULL, appmenu, obj, UI_TOOLBAR_RIGHT);
}
- ui_headerbar_add_items(obj, sidebar_headerbar, sidebar_right_defaults, UI_TOOLBAR_RIGHT);
+ ui_headerbar_add_items(obj, sidebar_headerbar, sidebar_right_defaults, UI_TOOLBAR_RIGHT, NULL);
}
// right panel
if(right_headerbar) {
- ui_headerbar_add_items(obj, right_headerbar, rightpanel_left_defaults, UI_TOOLBAR_LEFT);
- ui_headerbar_add_items(obj, right_headerbar, rightpanel_center_defaults, UI_TOOLBAR_CENTER);
+ // also add central toolbar items, in case the central pane is hidden
+ CxList *backup_toolbar_widgets = cxArrayListCreate(obj->ctx->allocator, CX_STORE_POINTERS, 16);
+ ui_headerbar_add_items(obj, right_headerbar, left_defaults, UI_TOOLBAR_LEFT, backup_toolbar_widgets);
+ ui_headerbar_add_items(obj, right_headerbar, center_defaults, UI_TOOLBAR_LEFT, backup_toolbar_widgets);
+ ui_headerbar_add_items(obj, right_headerbar, right_defaults, UI_TOOLBAR_LEFT, backup_toolbar_widgets);
+ CxIterator i = cxListIterator(backup_toolbar_widgets);
+ cx_foreach(GtkWidget *, w, i) {
+ ui_set_visible(w, FALSE);
+ }
+ g_object_set_data(G_OBJECT(obj->widget), "ui_toolbar_center_backup", backup_toolbar_widgets);
+
+ // main items for the right panel
+ ui_headerbar_add_items(obj, right_headerbar, rightpanel_left_defaults, UI_TOOLBAR_LEFT, NULL);
+ ui_headerbar_add_items(obj, right_headerbar, rightpanel_center_defaults, UI_TOOLBAR_CENTER, NULL);
if(appmenu && appmenu_pos == UI_TOOLBAR_RIGHTPANEL_RIGHT) {
ui_add_headerbar_menu(right_headerbar, NULL, appmenu, obj, UI_TOOLBAR_RIGHT);
}
- ui_headerbar_add_items(obj, right_headerbar, rightpanel_right_defaults, UI_TOOLBAR_RIGHT);
+ ui_headerbar_add_items(obj, right_headerbar, rightpanel_right_defaults, UI_TOOLBAR_RIGHT, NULL);
}
}
-static void create_item(UiObject *obj, GtkWidget *headerbar, GtkWidget *box, UiToolbarItemI *i, enum UiToolbarPos pos) {
+static GtkWidget* create_item(UiObject *obj, GtkWidget *headerbar, GtkWidget *box, UiToolbarItemI *i, enum UiToolbarPos pos) {
switch(i->type) {
case UI_TOOLBAR_ITEM: {
- ui_add_headerbar_item(headerbar, box, (UiToolbarItem*)i, obj, pos);
- break;
+ return ui_add_headerbar_item(headerbar, box, (UiToolbarItem*)i, obj, pos);
}
case UI_TOOLBAR_TOGGLEITEM: {
- ui_add_headerbar_toggleitem(headerbar, box, (UiToolbarToggleItem*)i, obj, pos);
- break;
+ return ui_add_headerbar_toggleitem(headerbar, box, (UiToolbarToggleItem*)i, obj, pos);
+ }
+ case UI_TOOLBAR_CONTENT_TOGGLEITEM: {
+ return ui_add_headerbar_content_toggleitem(headerbar, box, (UiToolbarContentToggleItem*)i, obj, pos);
}
case UI_TOOLBAR_MENU: {
- ui_add_headerbar_menu(headerbar, box, (UiToolbarMenuItem*)i, obj, pos);
- break;
+ return ui_add_headerbar_menu(headerbar, box, (UiToolbarMenuItem*)i, obj, pos);
}
default: fprintf(stderr, "toolbar item type unimplemented: %d\n", (int)i->type);
}
+ return NULL;
}
static void headerbar_add(GtkWidget *headerbar, GtkWidget *box, GtkWidget *item, enum UiToolbarPos pos) {
}
}
-void ui_headerbar_add_items(UiObject *obj, GtkWidget *headerbar, CxList *items, enum UiToolbarPos pos) {
+void ui_headerbar_add_items(UiObject *obj, GtkWidget *headerbar, CxList *items, enum UiToolbarPos pos, CxList *out_items) {
GtkWidget *box = NULL;
if(pos == UI_TOOLBAR_CENTER && cxListSize(items) > 0) {
box = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 6);
UI_HEADERBAR_SET_TITLE_WIDGET(headerbar, box);
+ if(out_items) {
+ cxListAdd(out_items, box);
+ }
}
CxIterator i = pos == UI_TOOLBAR_RIGHT ? cxListBackwardsIterator(items) : cxListIterator(items);
fprintf(stderr, "unknown toolbar item: %s\n", def);
continue;
}
- create_item(obj, headerbar, box, item, pos);
+ GtkWidget *item_widget = create_item(obj, headerbar, box, item, pos);
+ if(out_items && !box) {
+ cxListAdd(out_items, item_widget);
+ }
}
}
-void ui_add_headerbar_item(
+GtkWidget* ui_add_headerbar_item(
GtkWidget *headerbar,
GtkWidget *box,
UiToolbarItem *item,
UiObject *obj,
enum UiToolbarPos pos)
{
- GtkWidget *button = ui_create_button(obj, item->args.label, item->args.icon, item->args.tooltip, item->args.onclick, item->args.onclickdata, 0, FALSE);
+ GtkWidget *button = ui_create_button(obj, item->args.label, item->args.icon, item->args.tooltip, item->args.onclick, item->args.onclickdata, item->args.action, 0, FALSE);
ui_set_widget_states(obj->ctx, button, item->args.states);
ui_set_widget_visibility_states(obj->ctx, button, item->args.visibility_states);
WIDGET_ADD_CSS_CLASS(button, "flat");
headerbar_add(headerbar, box, button, pos);
+ return button;
}
-void ui_add_headerbar_toggleitem(
+GtkWidget* ui_add_headerbar_toggleitem(
GtkWidget *headerbar,
GtkWidget *box,
UiToolbarToggleItem *item,
ui_set_widget_states(obj->ctx, button, item->args.states);
ui_set_widget_visibility_states(obj->ctx, button, item->args.visibility_states);
WIDGET_ADD_CSS_CLASS(button, "flat");
- ui_setup_togglebutton(obj, button, item->args.label, item->args.icon, item->args.tooltip, item->args.varname, NULL, item->args.onchange, item->args.onchangedata, 0);
+ ui_setup_togglebutton(obj, button, item->args.label, item->args.icon, item->args.tooltip, item->args.varname, NULL, item->args.onchange, item->args.onchangedata, item->args.action, 0);
headerbar_add(headerbar, box, button, pos);
+ return button;
}
-void ui_add_headerbar_menu(
+GtkWidget* ui_add_headerbar_content_toggleitem(
+ GtkWidget *headerbar,
+ GtkWidget *box,
+ UiToolbarContentToggleItem *item,
+ UiObject *obj,
+ enum UiToolbarPos pos)
+{
+ UiContentToggleArgs args = { 0 };
+ args.label0 = item->args.label0;
+ args.icon0 = item->args.icon0;
+ args.tooltip0 = item->args.tooltip0;
+ args.label1 = item->args.label1;
+ args.icon1 = item->args.icon1;
+ args.tooltip1 = item->args.tooltip1;
+ args.varname = item->args.varname;
+ args.onchange = item->args.onchange;
+ args.onchangedata = item->args.onchangedata;
+ args.action = item->args.action;
+ args.istogglebutton = item->args.istogglebutton;
+ args.toggled_by_state = item->args.toggled_by_state;
+
+ GtkWidget *button = ui_create_content_togglebutton(obj, &args);
+ WIDGET_ADD_CSS_CLASS(button, "flat");
+ headerbar_add(headerbar, box, button, pos);
+ return button;
+}
+
+GtkWidget* ui_add_headerbar_menu(
GtkWidget *headerbar,
GtkWidget *box,
UiToolbarMenuItem *item,
#endif
headerbar_add(headerbar, box, menubutton, pos);
+
+ return menubutton;
}
#endif // GTK_CHECK_VERSION(3, 10, 0)
void ui_fill_headerbar(UiObject *obj, GtkWidget *sidebar_headerbar, GtkWidget *main_headerbar, GtkWidget *right_headerbar);
-void ui_headerbar_add_items(UiObject *obj, GtkWidget *headerbar, CxList *items, enum UiToolbarPos pos);
+void ui_headerbar_add_items(UiObject *obj, GtkWidget *headerbar, CxList *items, enum UiToolbarPos pos, CxList *out_items);
-void ui_add_headerbar_item(
+GtkWidget* ui_add_headerbar_item(
GtkWidget *headerbar,
GtkWidget *box,
UiToolbarItem *item,
UiObject *obj,
enum UiToolbarPos pos);
-void ui_add_headerbar_toggleitem(
+GtkWidget* ui_add_headerbar_toggleitem(
GtkWidget *headerbar,
GtkWidget *box,
UiToolbarToggleItem *item,
UiObject *obj,
enum UiToolbarPos pos);
-void ui_add_headerbar_menu(
+GtkWidget* ui_add_headerbar_content_toggleitem(
+ GtkWidget *headerbar,
+ GtkWidget *box,
+ UiToolbarContentToggleItem *item,
+ UiObject *obj,
+ enum UiToolbarPos pos);
+
+GtkWidget* ui_add_headerbar_menu(
GtkWidget *headerbar,
GtkWidget *box,
UiToolbarMenuItem *item,
char *path = g_file_get_path(file);
if(!path) {
icon = ui_icon("application-x-generic", size);
+ } else {
+ g_free(path);
}
#else
if(!icon) {
GError *error = NULL;
char *path = g_file_get_path(file);
icon->pixbuf = gdk_pixbuf_new_from_file(path, &error);
+ g_free(path);
}
return icon->pixbuf;
}
#include "../common/context.h"
#include "../common/object.h"
+#include "../common/action.h"
#include "container.h"
#include <cx/array_list.h>
tableview->multiselection = args->multiselection;
tableview->onactivate = args->onactivate;
tableview->onactivatedata = args->onactivatedata;
+ tableview->onactivate_action = args->onactivate_action ? strdup(args->onactivate_action) : NULL;
tableview->onselection = args->onselection;
tableview->onselectiondata = args->onselectiondata;
+ tableview->onselection_action = args->onselection_action ? strdup(args->onselection_action) : NULL;
tableview->ondragstart = args->ondragstart;
tableview->ondragstartdata = args->ondragstartdata;
+ tableview->ondragstart_action = args->ondragstart_action ? strdup(args->ondragstart_action) : NULL;
tableview->ondragcomplete = args->ondragcomplete;
tableview->ondragcompletedata = args->ondragcompletedata;
+ tableview->ondragcomplete_action = args->ondragcomplete_action ? strdup(args->ondragcomplete_action) : NULL;
tableview->ondrop = args->ondrop;
tableview->ondropdata = args->ondropdata;
+ tableview->ondrop_action = args->ondrop_action ? strdup(args->ondrop_action) : NULL;
tableview->selection.count = 0;
tableview->selection.rows = NULL;
tableview->current_row = -1;
} else if(type == UI_BOOL_EDITABLE) {
GtkWidget *checkbox = gtk_check_button_new();
gtk_list_item_set_child(item, checkbox);
- }else {
+ } else {
GtkWidget *label = gtk_label_new(NULL);
gtk_label_set_xalign(GTK_LABEL(label), 0);
gtk_list_item_set_child(item, label);
}
case UI_STRING: {
gtk_label_set_label(GTK_LABEL(child), data);
+ gtk_label_set_ellipsize(GTK_LABEL(child), PANGO_ELLIPSIZE_END);
if(freevalue) {
free(data);
}
}
// event handling
- if(args->onactivate) {
+ if(args->onactivate || args->onactivate_action) {
// columnview and listview can use the same callback function, because
// the first parameter (which is technically a different pointer type)
// is ignored
}
// event handling
- if(args->onactivate) {
+ if(args->onactivate || args->onactivate_action) {
g_signal_connect(view, "activate", G_CALLBACK(ui_columnview_activate), tableview);
}
if(args->contextmenu) {
return sel;
}
-static void listview_event(ui_callback cb, void *cbdata, UiListView *view) {
+static void listview_event(ui_callback cb, void *cbdata, const char *action, UiListView *view) {
UiEvent event;
event.obj = view->obj;
event.document = event.obj->ctx->document;
if(cb) {
cb(&event, cbdata);
}
+
+ if(action) {
+ uic_action_callback(&event, action);
+ }
}
static void listview_update_selection(UiListView *view) {
if(view->selection.count == 0) {
listview_update_selection(view);
}
- listview_event(view->onactivate, view->onactivatedata, view);
+ listview_event(view->onactivate, view->onactivatedata, view->onactivate_action, view);
}
void ui_listview_selection_changed(GtkSelectionModel* self, guint position, guint n_items, gpointer userdata) {
UiListView *view = userdata;
listview_update_selection(view);
if(ui_selection_events_is_enabled()) {
- listview_event(view->onselection, view->onselectiondata, view);
+ listview_event(view->onselection, view->onselectiondata, view->onselection_action, view);
}
}
if(i < 0) {
cxMapClear(view->bound_rows);
ui_update_liststore(view->liststore, list);
+ free(view->selection.rows);
+ view->selection.rows = NULL;
+ view->selection.count = 0;
} else {
void *value = list->get(list, i);
if(value) {
return store;
}
+static void ui_destroy_tree_eventdata(GtkWidget *object, UiTreeEventData *data) {
+ free(data->activate_action);
+ free(data->selection_action);
+ free(data);
+}
UIWIDGET ui_listview_create(UiObject *obj, UiListArgs *args) {
// create treeview
event->obj = obj;
event->activate = args->onactivate;
event->activatedata = args->onactivatedata;
+ event->activate_action = args->onactivate_action ? strdup(args->onactivate_action) : NULL;
event->selection = args->onselection;
event->selectiondata = args->onselectiondata;
+ event->selection_action = args->onselection_action ? strdup(args->onselection_action) : NULL;
g_signal_connect(
view,
"destroy",
- G_CALLBACK(ui_destroy_userdata),
+ G_CALLBACK(ui_destroy_tree_eventdata),
event);
-
- if(args->onactivate) {
+ if(args->onactivate || args->onactivate_action) {
g_signal_connect(
view,
"row-activated",
G_CALLBACK(ui_listview_activate_event),
event);
}
- if(args->onselection) {
+ if(args->onselection || args->onselection_action) {
GtkTreeSelection *selection = gtk_tree_view_get_selection(
GTK_TREE_VIEW(view));
g_signal_connect(
list->obj = tableview;
// add callback
- UiTreeEventData *event = ui_malloc(obj->ctx, sizeof(UiTreeEventData));
+ UiTreeEventData *event = malloc(sizeof(UiTreeEventData));
event->obj = obj;
event->activate = args->onactivate;
- event->selection = args->onselection;
event->activatedata = args->onactivatedata;
+ event->activate_action = args->onactivate_action ? strdup(args->onactivate_action) : NULL;
+ event->selection = args->onselection;
event->selectiondata = args->onselectiondata;
- if(args->onactivate) {
+ event->selection_action = args->onselection_action ? strdup(args->onselection_action) : NULL;
+ g_signal_connect(
+ view,
+ "destroy",
+ G_CALLBACK(ui_destroy_tree_eventdata),
+ event);
+ if(args->onactivate || args->onactivate_action) {
g_signal_connect(
view,
"row-activated",
G_CALLBACK(ui_listview_activate_event),
event);
}
- if(args->onselection) {
+ if(args->onselection || args->onselection_action) {
GtkTreeSelection *selection = gtk_tree_view_get_selection(
GTK_TREE_VIEW(view));
g_signal_connect(
G_CALLBACK(ui_listview_selection_event),
event);
}
- // TODO: destroy callback
-
if(args->ondragstart) {
ui_listview_add_dnd(tableview, args);
e.window = event->obj->window;
e.document = event->obj->ctx->document;
e.eventdata = &selection;
+ e.eventdatatype = UI_EVENT_DATA_LIST_SELECTION;
e.intval = selection.count > 0 ? selection.rows[0] : -1;
e.set = ui_get_setop();
- event->activate(&e, event->activatedata);
- if(selection.count > 0) {
- free(selection.rows);
+ if(event->activate) {
+ event->activate(&e, event->activatedata);
}
+ if(event->activate_action) {
+ uic_action_callback(&e, event->activate_action);
+ }
+
+ free(selection.rows);
}
void ui_listview_selection_event(
e.window = event->obj->window;
e.document = event->obj->ctx->document;
e.eventdata = &selection;
+ e.eventdatatype = UI_EVENT_DATA_LIST_SELECTION;
e.intval = selection.count > 0 ? selection.rows[0] : -1;
e.set = ui_get_setop();
- event->selection(&e, event->selectiondata);
-
- if(selection.count > 0) {
- free(selection.rows);
+ if(event->selection) {
+ event->selection(&e, event->selectiondata);
+ }
+ if(event->selection_action) {
+ uic_action_callback(&e, event->selection_action);
}
+
+ free(selection.rows);
}
UiListSelection ui_listview_get_selection(
*/
void ui_listview_destroy(GtkWidget *w, UiListView *v) {
+ free(v->onactivate_action);
+ free(v->onselection_action);
+ free(v->ondragstart_action);
+ free(v->ondragcomplete_action);
+ free(v->ondrop_action);
//gtk_tree_view_set_model(GTK_TREE_VIEW(w), NULL);
if(v->var) {
ui_destroy_boundvar(v->obj->ctx, v->var);
#endif
ui_callback onactivate;
void *onactivatedata;
+ char *onactivate_action;
ui_callback onselection;
void *onselectiondata;
+ char *onselection_action;
ui_callback ondragstart;
void *ondragstartdata;
+ char *ondragstart_action;
ui_callback ondragcomplete;
void *ondragcompletedata;
+ char *ondragcomplete_action;
ui_callback ondrop;
void *ondropdata;
+ char *ondrop_action;
ui_list_savefunc onsave;
void *onsavedata;
UiListSelection selection;
ui_callback selection;
void *activatedata;
void *selectiondata;
+ char *activate_action;
+ char *selection_action;
} UiTreeEventData;
typedef struct UiListBox UiListBox;
#include "../common/context.h"
#include "../common/menu.h"
#include "../common/types.h"
+#include "../common/action.h"
#include "../ui/properties.h"
#include "../ui/window.h"
#include "container.h"
ls->index = index;
ls->oldcount = 0;
ls->getvalue = il->getvalue;
+ ls->getvaluedata = il->getvaluedata;
UiVar* var = uic_create_var(ui_global_context(), il->varname, UI_VAR_LIST);
//UiVar* var = uic_create_var(obj->ctx, il->varname, UI_VAR_LIST);
gtk_widget_show(widget);
}
- ui_getvaluefunc getvalue = list->getvalue;
+ ui_getvaluefunc2 getvalue = list->getvalue;
+ void *getvaluedata = list->getvaluedata;
int i = 1;
+ int row = 0;
while(elm) {
- char *label = (char*) (getvalue ? getvalue(elm, 0) : elm);
+ UiBool freeResult = FALSE;
+ char *label = (char*) (getvalue ? getvalue(ls, elm, row, 0, getvaluedata, &freeResult) : elm);
GtkWidget *widget = gtk_menu_item_new_with_label(label);
gtk_menu_shell_insert(list->menu, widget, list->index + i);
elm = ui_list_next(ls);
i++;
+ row++;
+
+ if(freeResult) {
+ free(label);
+ }
}
list->oldcount = i;
cxListFree(groups);
}
- if(i->callback != NULL) {
+ if(i->action) {
+ uic_bind_action(obj->ctx, i->action, action, (ui_enablefunc)action_enable);
+ UiAction *ui_action = uic_resolve_action(obj->ctx, i->action);
+ if(!ui_action) {
+ action_enable(action, FALSE);
+ }
+ }
+
+ if(i->callback != NULL || i->action) {
UiEventData *event = malloc(sizeof(UiEventData));
event->obj = obj;
event->userdata = i->userdata;
event->value = 0;
event->customdata = NULL;
event->customint = 0;
+ event->action = i->action ? strdup(i->action) : NULL;
g_signal_connect(
action,
g_signal_connect(
obj->widget,
"destroy",
- G_CALLBACK(ui_destroy_userdata),
+ G_CALLBACK(ui_destroy_eventdata),
event);
}
char action_name[32];
snprintf(action_name, 32, "win.%s", item->id);
-
+
g_menu_append(parent, i->label, action_name);
}
CxIterator iter = cxListIterator(group->callbacks);
cx_foreach(UiCallbackData *, cb, iter) {
- event.intval = intval == iter.index;
+ event.intval = intval-1 == iter.index;
if(cb->callback) {
cb->callback(&event, cb->userdata);
}
cxListAdd(group->callbacks, &cb);
- cxmutstr action_name = cx_asprintf("win.%s::%d", i->varname, (int)item_index);
+ cxmutstr action_name = cx_asprintf("win.%s::%d", i->varname, (int)item_index+1);
g_menu_append(parent, i->label, action_name.ptr);
free(action_name.ptr);
}
ls->index = index;
ls->oldcount = 0;
ls->getvalue = il->getvalue;
+ ls->getvaluedata = il->getvalue;
GSimpleAction *action = g_simple_action_new(item->id, g_variant_type_new("i"));
g_action_map_add_action(obj->ctx->action_map, G_ACTION(action));
evt.eventdatatype = uic_get_tmp_eventdata_type();
}
evt.intval = intval;
- event->callback(&evt, event->userdata);
+ if(event->callback) {
+ event->callback(&evt, event->userdata);
+ }
+ if(event->action) {
+ uic_action_callback(&evt, event->action);
+ }
uic_set_tmp_eventdata(NULL, 0);
}
UiList *ls = list->var->value;
// add list items
- ui_getvaluefunc getvalue = list->getvalue;
+ ui_getvaluefunc2 getvalue = list->getvalue;
+ void *getvaluedata = list->getvaluedata;
int i = 0;
void* elm = ui_list_first(ls);
while(elm) {
- char *label = (char*) (getvalue ? getvalue(elm, 0) : elm);
+ UiBool freeResult = FALSE;
+ char *label = (char*) (getvalue ? getvalue(ls, elm, i, 0, getvaluedata, &freeResult) : elm);
GMenuItem *item = g_menu_item_new(label, NULL);
GVariant *v = g_variant_new("i", i);
elm = ui_list_next(ls);
i++;
+
+ if(freeResult) {
+ free(label);
+ }
}
list->oldcount = i;
int index;
int oldcount;
UiVar *var;
- ui_getvaluefunc getvalue;
+ ui_getvaluefunc2 getvalue;
+ void *getvaluedata;
ui_callback callback;
void *userdata;
};
int index;
int oldcount;
UiVar *var;
- ui_getvaluefunc getvalue;
+ ui_getvaluefunc2 getvalue;
+ void *getvaluedata;
ui_callback callback;
void *userdata;
};
GTKOBJ += headerbar.o
GTKOBJ += webview.o
GTKOBJ += widget.o
+GTKOBJ += action.o
TOOLKITOBJS += $(GTKOBJ:%=$(GTK_OBJPRE)%)
TOOLKITSOURCE += $(GTKOBJ:%.o=gtk/%.c)
int sel = gtk_text_buffer_get_selection_bounds (buf, &begin, &end);
if(sel != textview->last_selection_state) {
if(sel) {
- ui_set_state(textview->ctx, UI_GROUP_SELECTION);
+ ui_set_state(textview->ctx, UI_STATE_SELECTION);
} else {
- ui_unset_state(textview->ctx, UI_GROUP_SELECTION);
+ ui_unset_state(textview->ctx, UI_STATE_SELECTION);
}
}
textview->last_selection_state = sel;
"changed",
G_CALLBACK(ui_textbuf_changed),
textarea);
+
+ g_signal_connect(
+ buf,
+ "insert-text",
+ G_CALLBACK(ui_textbuf_change_insert),
+ textarea);
+ g_signal_connect(
+ buf,
+ "delete-range",
+ G_CALLBACK(ui_textbuf_change_delete),
+ textarea);
} else {
fprintf(stderr, "Error: create_textbuffer: textarea == NULL\n");
}
uitext->last_selection_state = 0;
uitext->onchange = args->onchange;
uitext->onchangedata = args->onchangedata;
+ uitext->onchange_action = args->onchange_action ? strdup(args->onchange_action) : NULL;
+ uitext->ontextchanged = args->ontextchanged;
+ uitext->ontextchangeddata = args->ontextchangeddata;
+ uitext->ontextchanged_action = args->ontextchanged_action ? strdup(args->ontextchanged_action) : NULL;
g_object_set_data(G_OBJECT(text_area), "ui_textarea", uitext);
g_object_set_data(G_OBJECT(text_area), "ui_textarea_widget", text_area);
value->value.free(value->value.ptr);
}
}
+
+ if(value->readonly) {
+ gtk_text_view_set_editable(GTK_TEXT_VIEW(text_area), FALSE);
+ }
+
gtk_text_view_set_buffer(GTK_TEXT_VIEW(text_area), buf);
value->obj = text_area;
value->save = ui_textarea_save;
value->selection = ui_textarea_selection;
value->length = ui_textarea_length;
value->remove = ui_textarea_remove;
+ value->setreadonly = ui_textarea_setreadonly;
value->data1 = buf;
value->data2 = NULL;
value->datatype == UI_TEXT_TYPE_BUFFER;
if(textarea->var) {
ui_destroy_boundvar(textarea->ctx, textarea->var);
}
+ free(textarea->onchange_action);
+ free(textarea->ontextchanged_action);
free(textarea);
}
GtkWidget *widget = ui_textarea_gettextwidget(textarea);
if(!widget) {
fprintf(stderr, "Error: ui_textarea_scroll_to: widget is not a textarea\n");
+ return;
}
GtkTextBuffer *buf = gtk_text_view_get_buffer(GTK_TEXT_VIEW(widget));
gtk_text_view_scroll_to_iter(GTK_TEXT_VIEW(widget), &offset, 0.2, FALSE, 0, 0);
}
+void ui_textarea_focus(UIWIDGET textarea) {
+ GtkWidget *widget = ui_textarea_gettextwidget(textarea);
+ if(!widget) {
+ fprintf(stderr, "Error: ui_textarea_focus: widget is not a textarea\n");
+ return;
+ }
+ gtk_widget_grab_focus(widget);
+}
+
+void ui_textarea_set_selection(UIWIDGET textarea, int begin, int end) {
+ GtkWidget *widget = ui_textarea_gettextwidget(textarea);
+ if(!widget) {
+ fprintf(stderr, "Error: ui_textarea_set_selection: widget is not a textarea\n");
+ return;
+ }
+
+ GtkTextBuffer *buf = gtk_text_view_get_buffer(GTK_TEXT_VIEW(widget));
+ 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_select_range(buf, &ib, &ie);
+}
+
+void ui_textarea_select_all(UIWIDGET textarea) {
+ GtkWidget *widget = ui_textarea_gettextwidget(textarea);
+ if(!widget) {
+ fprintf(stderr, "Error: ui_textarea_select_all: widget is not a textarea\n");
+ return;
+ }
+ GtkTextBuffer *buf = gtk_text_view_get_buffer(GTK_TEXT_VIEW(widget));
+ GtkTextIter start;
+ GtkTextIter end;
+ gtk_text_buffer_get_bounds(buf, &start, &end);
+ gtk_text_buffer_select_range(buf, &start, &end);
+}
+
+void ui_textarea_set_editable(UIWIDGET textarea, UiBool editable) {
+ GtkWidget *widget = ui_textarea_gettextwidget(textarea);
+ if(!widget) {
+ fprintf(stderr, "Error: ui_textarea_set_editable: widget is not a textarea\n");
+ return;
+ }
+ gtk_text_view_set_editable(GTK_TEXT_VIEW(widget), editable);
+}
+
+UiBool ui_textarea_is_editable(UIWIDGET textarea) {
+ GtkWidget *widget = ui_textarea_gettextwidget(textarea);
+ if(!widget) {
+ fprintf(stderr, "Error: ui_textarea_is_editable: widget is not a textarea\n");
+ return 0;
+ }
+ return gtk_text_view_get_editable(GTK_TEXT_VIEW(widget));
+}
+
+void ui_textarea_set_position(UIWIDGET textarea, int pos) {
+ GtkWidget *widget = ui_textarea_gettextwidget(textarea);
+ if(!widget) {
+ fprintf(stderr, "Error: ui_textarea_set_position: widget is not a textarea\n");
+ return;
+ }
+ GtkTextBuffer *buf = gtk_text_view_get_buffer(GTK_TEXT_VIEW(widget));
+ GtkTextIter iter;
+ gtk_text_buffer_get_iter_at_offset(buf, &iter, pos);
+ gtk_text_buffer_place_cursor(buf, &iter);
+}
+
+int ui_textarea_get_position(UIWIDGET textarea) {
+ GtkWidget *widget = ui_textarea_gettextwidget(textarea);
+ if(!widget) {
+ fprintf(stderr, "Error: ui_textarea_get_position: widget is not a textarea\n");
+ return 0;
+ }
+ GtkTextBuffer *buf = gtk_text_view_get_buffer(GTK_TEXT_VIEW(widget));
+ GtkTextIter begin;
+ GtkTextIter end;
+ gtk_text_buffer_get_selection_bounds(buf, &begin, &end);
+ return gtk_text_iter_get_offset(&begin);
+}
+
UIWIDGET ui_textarea_gettextwidget(UIWIDGET textarea) {
return g_object_get_data(G_OBJECT(textarea), "ui_textarea_widget");
}
text->datatype = UI_TEXT_TYPE_BUFFER;
}
gtk_text_view_set_buffer(GTK_TEXT_VIEW(textarea), text->data1);
+ gtk_text_view_set_editable(GTK_TEXT_VIEW(textarea), !text->readonly);
}
void ui_textarea_text_destroy(UiText *text) {
}
void ui_textarea_showposition(UiText *text, int pos) {
- ui_textarea_scroll_to(text->obj, pos);
+ if(text->obj) {
+ ui_textarea_scroll_to(text->obj, pos);
+ }
}
void ui_textarea_setselection(UiText *text, int begin, int end) {
gtk_text_buffer_delete(buf, &ib, &ie);
}
+void ui_textarea_setreadonly(UiText *text, int readonly) {
+ if(text->obj) {
+ gtk_text_view_set_editable(GTK_TEXT_VIEW(text->obj), !readonly);
+ }
+ text->readonly = readonly;
+}
+
void ui_textarea_realize_event(GtkWidget *widget, gpointer data) {
gtk_widget_grab_focus(widget);
}
+static void textbuf_change_event(UiTextArea *textarea, UiTextChangeEventData *data) {
+ if(!ui_onchange_events_is_enabled()) {
+ return;
+ }
+
+ UiEvent e;
+ e.obj = textarea->obj;
+ e.window = e.obj->window;
+ e.document = textarea->ctx->document;
+ e.eventdata = data;
+ e.eventdatatype = UI_EVENT_DATA_TEXT_CHANGED;
+ e.intval = 0;
+ e.set = ui_get_setop();
+
+ if(textarea->onchange) {
+ textarea->onchange(&e, textarea->onchangedata);
+ }
+
+ if(textarea->onchange_action) {
+ uic_action_callback(&e, textarea->onchange_action);
+ }
+}
+
+void ui_textbuf_change_insert(
+ GtkTextBuffer *textbuffer,
+ GtkTextIter *location,
+ char *text,
+ int length,
+ UiTextArea *textarea)
+{
+ UiTextChangeEventData event;
+ event.type = UI_TEXT_INSERT;
+ event.begin = gtk_text_iter_get_offset(location);
+ event.end = event.begin + length;
+ event.text = text;
+ event.length = length;
+ textbuf_change_event(textarea, &event);
+}
+
+void ui_textbuf_change_delete(
+ GtkTextBuffer *self,
+ const GtkTextIter *start,
+ const GtkTextIter *end,
+ UiTextArea *textarea)
+{
+ UiTextChangeEventData event;
+ event.type = UI_TEXT_DELETE;
+ event.begin = gtk_text_iter_get_offset(start);
+ event.end = gtk_text_iter_get_offset(end);
+ event.text = NULL;
+ event.length = 0;
+ textbuf_change_event(textarea, &event);
+}
+
void ui_textbuf_changed(GtkTextBuffer *textbuffer, UiTextArea *textarea) {
if(!ui_onchange_events_is_enabled()) {
e.intval = 0;
e.set = ui_get_setop();
- if(textarea->onchange) {
- textarea->onchange(&e, textarea->onchangedata);
+ if(textarea->ontextchanged) {
+ textarea->ontextchanged(&e, textarea->ontextchangeddata);
+ }
+
+ if(textarea->ontextchanged_action) {
+ uic_action_callback(&e, textarea->ontextchanged_action);
}
if(value->observers) {
if(!value->data2) {
value->data2 = ui_create_undomgr();
}
+ GtkTextBuffer *buf = value->data1;
UiUndoMgr *mgr = value->data2;
if(!mgr->event) {
return;
}
}
- char *text = gtk_text_buffer_get_text(value->obj, start, end, FALSE);
+ char *text = gtk_text_buffer_get_text(buf, start, end, FALSE);
UiTextBufOp *op = malloc(sizeof(UiTextBufOp));
op->prev = NULL;
}
void ui_text_undo(UiText *value) {
+ GtkTextBuffer *buf = value->data1;
UiUndoMgr *mgr = value->data2;
if(mgr->cur) {
case UI_TEXTBUF_INSERT: {
GtkTextIter begin;
GtkTextIter end;
- gtk_text_buffer_get_iter_at_offset(value->obj, &begin, op->start);
- gtk_text_buffer_get_iter_at_offset(value->obj, &end, op->end);
- gtk_text_buffer_delete(value->obj, &begin, &end);
+ gtk_text_buffer_get_iter_at_offset(buf, &begin, op->start);
+ gtk_text_buffer_get_iter_at_offset(buf, &end, op->end);
+ gtk_text_buffer_delete(buf, &begin, &end);
break;
}
case UI_TEXTBUF_DELETE: {
GtkTextIter begin;
GtkTextIter end;
- gtk_text_buffer_get_iter_at_offset(value->obj, &begin, op->start);
- gtk_text_buffer_get_iter_at_offset(value->obj, &end, op->end);
- gtk_text_buffer_insert(value->obj, &begin, op->text, op->len);
+ gtk_text_buffer_get_iter_at_offset(buf, &begin, op->start);
+ gtk_text_buffer_get_iter_at_offset(buf, &end, op->end);
+ gtk_text_buffer_insert(buf, &begin, op->text, op->len);
break;
}
}
}
void ui_text_redo(UiText *value) {
+ GtkTextBuffer *buf = value->data1;
UiUndoMgr *mgr = value->data2;
UiTextBufOp *elm = NULL;
case UI_TEXTBUF_INSERT: {
GtkTextIter begin;
GtkTextIter end;
- gtk_text_buffer_get_iter_at_offset(value->obj, &begin, op->start);
- gtk_text_buffer_get_iter_at_offset(value->obj, &end, op->end);
- gtk_text_buffer_insert(value->obj, &begin, op->text, op->len);
+ gtk_text_buffer_get_iter_at_offset(buf, &begin, op->start);
+ gtk_text_buffer_get_iter_at_offset(buf, &end, op->end);
+ gtk_text_buffer_insert(buf, &begin, op->text, op->len);
break;
}
case UI_TEXTBUF_DELETE: {
GtkTextIter begin;
GtkTextIter end;
- gtk_text_buffer_get_iter_at_offset(value->obj, &begin, op->start);
- gtk_text_buffer_get_iter_at_offset(value->obj, &end, op->end);
- gtk_text_buffer_delete(value->obj, &begin, &end);
+ gtk_text_buffer_get_iter_at_offset(buf, &begin, op->start);
+ gtk_text_buffer_get_iter_at_offset(buf, &end, op->end);
+ gtk_text_buffer_delete(buf, &begin, &end);
break;
}
}
uitext->onchangedata = args->onchangedata;
uitext->onactivate = args->onactivate;
uitext->onactivatedata = args->onactivatedata;
+ uitext->onactivate_action = args->onactivate_action ? strdup(args->onactivate_action) : NULL;
+ uitext->onchange_action = args->onchange_action ? strdup(args->onchange_action) : NULL;
g_signal_connect(
textfield,
value->obj = GTK_ENTRY(textfield);
}
- if(args->onchange || var) {
+ if(args->onchange || args->onchange_action || var) {
g_signal_connect(
textfield,
"changed",
uitext);
}
- if(args->onactivate) {
+ if(args->onactivate || args->onactivate_action) {
g_signal_connect(
textfield,
"activate",
}
void ui_textfield_destroy(GtkWidget *object, UiTextField *textfield) {
+ free(textfield->onactivate_action);
+ free(textfield->onchange_action);
free(textfield);
}
e.window = e.obj->window;
e.document = textfield->obj->ctx->document;
e.eventdata = value;
- e.eventdatatype = value ? UI_EVENT_DATA_TEXT_VALUE : 0;
+ e.eventdatatype = value ? UI_EVENT_DATA_STRING_VALUE : 0;
e.intval = 0;
e.set = ui_get_setop();
if(textfield->var) {
ui_notify_evt(value->observers, &e);
}
+
+ if(textfield->onchange_action) {
+ uic_action_callback(&e, textfield->onchange_action);
+ }
}
void ui_textfield_activate(GtkEntry* self, UiTextField *textfield) {
- if(textfield->onactivate) {
- UiString *value = textfield->var ? textfield->var->value : NULL;
+ UiString *value = textfield->var ? textfield->var->value : NULL;
- UiEvent e;
- e.obj = textfield->obj;
- e.window = e.obj->window;
- e.document = textfield->obj->ctx->document;
- e.eventdata = value;
- e.eventdatatype = value ? UI_EVENT_DATA_TEXT_VALUE : 0;
- e.intval = 0;
- e.set = ui_get_setop();
+ UiEvent e;
+ e.obj = textfield->obj;
+ e.window = e.obj->window;
+ e.document = textfield->obj->ctx->document;
+ e.eventdata = value;
+ e.eventdatatype = value ? UI_EVENT_DATA_TEXT_VALUE : 0;
+ e.intval = 0;
+ e.set = ui_get_setop();
+
+ if(textfield->onactivate) {
textfield->onactivate(&e, textfield->onactivatedata);
}
+
+ if(textfield->onactivate_action) {
+ uic_action_callback(&e, textfield->onactivate_action);
+ }
}
char* ui_textfield_get(UiString *str) {
int last_selection_state;
ui_callback onchange;
void *onchangedata;
+ char *onchange_action;
+ ui_callback ontextchanged;
+ void *ontextchangeddata;
+ char *ontextchanged_action;
} UiTextArea;
typedef struct UiTextField {
void *onchangedata;
ui_callback onactivate;
void *onactivatedata;
+ char *onactivate_action;
+ char *onchange_action;
} UiTextField;
typedef struct UiPathTextField {
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_setreadonly(UiText *text, int readonly);
void ui_textarea_realize_event(GtkWidget *widget, gpointer data);
+//void ui_textbuf_changed(GtkTextBuffer *textbuffer, UiTextArea *textarea);
+void ui_textbuf_change_insert(
+ GtkTextBuffer *textbuffer,
+ GtkTextIter *location,
+ char *text,
+ int length,
+ UiTextArea *textarea);
+void ui_textbuf_change_delete(
+ GtkTextBuffer *self,
+ const GtkTextIter *start,
+ const GtkTextIter *end,
+ UiTextArea *textarea);
+
void ui_textbuf_changed(GtkTextBuffer *textbuffer, UiTextArea *textarea);
void ui_textbuf_insert(
ui_set_widget_nstates(obj->ctx, GTK_WIDGET(button), item->args.states, item->nstates);
- if(item->args.onclick) {
+ if(item->args.onclick || item->args.action) {
UiEventData *event = cxMalloc(
obj->ctx->allocator,
sizeof(UiEventData));
event->obj = obj;
event->callback = item->args.onclick;
event->userdata = item->args.onclickdata;
+ event->action = item->args.action ? ui_strdup(obj->ctx, item->args.action) : NULL;
event->customdata = NULL;
event->customint = 0;
event->value = 0;
event->obj = obj;
event->callback = item->args.onchange;
event->userdata = item->args.onchangedata;
+ event->action = item->args.action ? ui_strdup(obj->ctx, item->args.action) : NULL;;
event->var = var;
g_signal_connect(
if(i) {
ui_notify_evt(i->observers, &e);
}
+
+ if(event->action) {
+ uic_action_callback(&e, event->action);
+ }
}
int64_t ui_tool_toggle_button_get(UiInteger *integer) {
#if UI_GTK2 || UI_GTK3
-typedef struct UiToolItemI UiToolItemI;
-typedef struct UiToolItem UiToolItem;
-typedef struct UiStToolItem UiStToolItem;
-typedef struct UiToggleToolItem UiToggleToolItem;
-
-typedef struct UiToolbarComboBox UiToolbarComboBox;
-typedef struct UiToolbarComboBoxNV UiToolbarComboBoxNV;
-
-typedef void(*ui_toolbar_add_f)(GtkToolbar*, UiToolItemI*, UiObject*);
-
-struct UiToolItemI {
- ui_toolbar_add_f add_to;
-};
-
-struct UiToolItem {
- UiToolItemI item;
- const char *label;
- const char *image;
- ui_callback callback;
- void *userdata;
- const char *varname;
- CxList *groups;
- int isimportant;
-};
-
-struct UiStToolItem {
- UiToolItemI item;
- const char *stockid;
- ui_callback callback;
- void *userdata;
- const char *varname;
- CxList *groups;
- int isimportant;
-};
-
-struct UiToggleToolItem {
- UiToolItemI item;
- const char *label;
- const char *image;
- const char *stockid;
- UiInteger *value;
- const char *var;
- CxList *groups;
- int isimportant;
-};
-
-struct UiToolbarComboBox {
- UiToolItemI item;
- UiVar *var;
- ui_getvaluefunc getvalue;
- ui_callback callback;
- void *userdata;
-};
-
-struct UiToolbarComboBoxNV {
- UiToolItemI item;
- char *listname;
- ui_getvaluefunc getvalue;
- ui_callback callback;
- void *userdata;
-};
-
void ui_toolitem_vstgr(
char *name,
static UiBool exit_on_shutdown;
+// NOOP on most platforms, expect macos
+void ui_set_main_thread_error_msg(const char *msg) {}
+
UIEXPORT void ui_init(const char *appname, int argc, char **argv) {
- application_name = appname;
+ application_name = appname ? strdup(appname) : NULL;
uic_init_global_context();
#if GTK_MAJOR_VERSION >= 4
void ui_show(UiObject *obj) {
gboolean visible = FALSE;
- uic_check_state_widgets(obj->ctx);
if(obj->widget) {
visible = gtk_widget_is_visible(obj->widget);
#if GTK_MAJOR_VERSION >= 4
gtk_widget_show_all(obj->widget);
#endif
}
+ uic_check_state_widgets(obj->ctx);
if(!visible) {
obj->ref++;
}
void ui_close(UiObject *obj) {
- uic_context_prepare_close(obj->ctx); // TODO: should this be moved to the close event handler?
- if(obj->widget) {
-#if GTK_CHECK_VERSION(4, 0, 0)
- gtk_window_close(GTK_WINDOW(obj->widget));
-#else
- gtk_widget_destroy(obj->widget);
-#endif
- } else {
- ui_window_close_request(obj);
- }
+ ui_window_close_request(obj);
}
#endif
}
-void ui_set_visible(UIWIDGET widget, UiBool visible) {
+void ui_set_visible(UIWIDGET widget, int visible) {
#if GTK_MAJOR_VERSION >= 4
gtk_widget_set_visible(widget, visible);
#else
free(userdata);
}
+void ui_destroy_eventdata(GtkWidget *object, UiEventData *data) {
+ free(data->action);
+ free(data);
+}
+
void ui_destroy_vardata(GtkWidget *unused, UiVarEventData *data) {
if(data->var) {
ui_destroy_boundvar(data->obj->ctx, data->var);
ui_set_visible(widget, FALSE);
}
}
+
+void ui_open_uri(const char *uri) {
+#if GTK_CHECK_VERSION(4, 0, 0)
+ GtkUriLauncher *launcher = gtk_uri_launcher_new(uri);
+ gtk_uri_launcher_launch(launcher, NULL, NULL, NULL, NULL);
+ g_object_unref(launcher);
+#elif GTK_CHECK_VERSION(3, 22, 0)
+ GError *error = NULL;
+ gtk_show_uri_on_window(NULL, uri, GDK_CURRENT_TIME, &error);
+#elif
+ // TODO: call xdg-open
+#endif
+}
int value;
int customint;
void *customdata;
+ char *action;
} UiEventData;
typedef struct UiEventDataExt {
UiVar *var;
UiObserver **observers;
ui_callback callback;
+ char *action;
void *userdata;
int customint1;
int customint2;
void ui_set_widget_nvisibility_states(UiContext *ctx, GtkWidget *widget, const int *states, size_t ngroups);
void ui_destroy_userdata(GtkWidget *object, void *userdata);
+void ui_destroy_eventdata(GtkWidget *object, UiEventData *data);
void ui_destroy_vardata(GtkWidget *unused, UiVarEventData *data);
void ui_destroy_widget_var(GtkWidget *object, UiVar *var);
void ui_destroy_boundvar(UiContext *ctx, UiVar *var);
#include "headerbar.h"
#include "button.h"
#include "window.h"
+#include "widget.h"
static int nwindows = 0;
}
}
- obj->ref--;
+ if(obj->ref > 0) {
+ obj->ref--;
+ } else {
+ // warn about invalid reference counting
+ fprintf(stderr, "Error: UiObject %p ref == 0\n", obj);
+ }
if(obj->ref > 0) {
#if GTK_CHECK_VERSION(2, 18, 0)
gtk_widget_set_visible(obj->widget, FALSE);
#endif
return TRUE;
} else {
- if(obj->ctx->close_callback) {
- UiEvent ev;
- ev.window = obj->window;
- ev.document = obj->ctx->document;
- ev.obj = obj;
- ev.eventdata = NULL;
- ev.eventdatatype = 0;
- ev.intval = 0;
- obj->ctx->close_callback(&ev, obj->ctx->close_data);
- obj->ctx->close_callback = NULL;
- }
-
+ // this cleans up any widget references from the context
uic_context_prepare_close(obj->ctx);
+ ui_window_widget_destroy(obj);
return FALSE;
}
}
+static void window_onclose_callback(UiObject *obj) {
+ if(obj->onclose) {
+ UiEvent event;
+ memset(&event, 0, sizeof(UiEvent));
+ event.obj = obj;
+ event.window = obj->window;
+ event.document = obj->ctx->document;
+ obj->onclose(&event, obj->onclosedata);
+ }
+}
+
#if GTK_MAJOR_VERSION >= 4
static gboolean close_request(GtkWindow* self, UiObject *obj) {
+ window_onclose_callback(obj);
return ui_window_close_request(obj);
}
#else
static gboolean close_request(GtkWidget* self, GdkEvent* event, UiObject *obj) {
+ window_onclose_callback(obj);
return ui_window_close_request(obj);
}
#endif
g_object_set_data(G_OBJECT(obj->widget), "ui_window_splitview", content);
g_object_set_data(G_OBJECT(obj->widget), "ui_left_panel", vbox);
g_object_set_data(G_OBJECT(obj->widget), "ui_right_panel", right_vbox);
+ g_object_set_data(G_OBJECT(obj->widget), "ui_left_panel_top", toolbar_view);
+ g_object_set_data(G_OBJECT(obj->widget), "ui_right_panel_top", right_panel);
}
GtkWidget *content_box = vbox;
adw_header_bar_set_show_title(ADW_HEADER_BAR(headerbar_sidebar), FALSE);
} else if(!strcmp(show_title, "sidebar")) {
adw_header_bar_set_show_title(ADW_HEADER_BAR(headerbar_main), FALSE);
- adw_header_bar_set_show_title(ADW_HEADER_BAR(headerbar_sidebar), TRUE);
+ if(headerbar_sidebar) {
+ adw_header_bar_set_show_title(ADW_HEADER_BAR(headerbar_sidebar), TRUE);
+ }
} else if(!strcmp(show_title, "false")) {
- adw_header_bar_set_show_title(ADW_HEADER_BAR(headerbar_sidebar), FALSE);
+ if(headerbar_sidebar) {
+ adw_header_bar_set_show_title(ADW_HEADER_BAR(headerbar_sidebar), FALSE);
+ }
adw_header_bar_set_show_title(ADW_HEADER_BAR(headerbar_main), FALSE);
} else {
fprintf(stderr, "Unknown value '%s' for property ui.gtk.window.showtitle\n", show_title);
- adw_header_bar_set_show_title(ADW_HEADER_BAR(headerbar_sidebar), FALSE);
+ if(headerbar_sidebar) {
+ adw_header_bar_set_show_title(ADW_HEADER_BAR(headerbar_sidebar), FALSE);
+ }
}
} else {
adw_header_bar_set_show_title(ADW_HEADER_BAR(headerbar_main), FALSE);
- if(sidebar) {
+ if(headerbar_sidebar) {
adw_header_bar_set_show_title(ADW_HEADER_BAR(headerbar_sidebar), TRUE);
}
}
g_object_set_data(G_OBJECT(obj->widget), "ui_window_splitview", content_paned);
g_object_set_data(G_OBJECT(obj->widget), "ui_left_panel", content_box);
g_object_set_data(G_OBJECT(obj->widget), "ui_right_panel", right_content_box);
+ g_object_set_data(G_OBJECT(obj->widget), "ui_left_panel_top", content_box);
+ g_object_set_data(G_OBJECT(obj->widget), "ui_right_panel_top", right_content_box);
} else {
PANED_SET_CHILD2(paned, content_box);
}
gtk_container_add(GTK_CONTAINER(frame), content_box);
obj->container = ui_box_container(obj, content_box);
*/
- UiContainerX *container = ui_box_container(obj, content_box, UI_CONTAINER_VBOX);
+ UiContainer *container = ui_box_container(obj, content_box, UI_CONTAINER_VBOX);
uic_object_push_container(obj, container);
nwindows++;
UIEXPORT void ui_splitview_window_set_visible(UiObject *obj, int pane, UiBool visible) {
GtkWidget *panel = NULL;
+ CxList *backup_items = NULL;
if(pane == 0) {
- panel = g_object_get_data(G_OBJECT(obj->widget), "ui_left_panel");
+ panel = g_object_get_data(G_OBJECT(obj->widget), "ui_left_panel_top");
+ backup_items = g_object_get_data(G_OBJECT(obj->widget), "ui_toolbar_center_backup");
} else if(pane == 1) {
- panel = g_object_get_data(G_OBJECT(obj->widget), "ui_right_panel");
+ panel = g_object_get_data(G_OBJECT(obj->widget), "ui_right_panel_top");
+ // TODO: backup toolbar items
}
if(panel == NULL) {
}
gtk_widget_set_visible(panel, visible);
+
+ if(backup_items) {
+ CxIterator i = cxListIterator(backup_items);
+ cx_foreach(GtkWidget*, w, i) {
+ ui_set_visible(w, !visible);
+ }
+ }
}
#ifdef UI_LIBADWAITA
if(data->callback) {
data->callback(&evt, data->userdata);
}
+
+ ui_app_unref();
}
void ui_dialog_create(UiObject *parent, UiDialogArgs *args) {
event);
g_signal_connect(dialog, "response", G_CALLBACK(dialog_response), event);
- adw_dialog_present(dialog, parent->widget);
+ ui_app_ref();
+ adw_dialog_present(dialog, parent ? parent->widget : NULL);
if(entry) {
gtk_entry_grab_focus_without_selecting(GTK_ENTRY(entry));
UiEventData *data = user_data;
UiEvent evt;
evt.obj = data->obj;
- evt.document = evt.obj->ctx->document;
- evt.window = evt.obj->window;
+ if(evt.obj) {
+ evt.document = evt.obj->ctx->document;
+ evt.window = evt.obj->window;
+ } else {
+ evt.document = NULL;
+ evt.window = NULL;
+ }
+
evt.eventdata = NULL;
evt.intval = 0;
#endif
GtkWidget *content_vbox = ui_gtk_vbox_new(0);
- UiContainerX *container = ui_box_container(obj, content_vbox, UI_CONTAINER_VBOX);
+ UiContainer *container = ui_box_container(obj, content_vbox, UI_CONTAINER_VBOX);
uic_object_push_container(obj, container);
if(args->lbutton1 || args->lbutton2 || args->rbutton3 || args->rbutton4) {
#if GTK_CHECK_VERSION(3, 10, 0)
}
if(args->lbutton1) {
- GtkWidget *button = ui_create_button(obj, args->lbutton1, NULL, NULL/*tooltip*/, args->onclick, args->onclickdata, 1, args->default_button == 1);
+ GtkWidget *button = ui_create_button(obj, args->lbutton1, NULL, NULL/*tooltip*/, args->onclick, args->onclickdata, NULL, 1, args->default_button == 1);
gtk_header_bar_pack_start(GTK_HEADER_BAR(headerbar), button);
if(args->default_button == 1) {
WIDGET_ADD_CSS_CLASS(button, "suggested-action");
}
}
if(args->lbutton2) {
- GtkWidget *button = ui_create_button(obj, args->lbutton2, NULL, NULL/*tooltip*/, args->onclick, args->onclickdata, 2, args->default_button == 2);
+ GtkWidget *button = ui_create_button(obj, args->lbutton2, NULL, NULL/*tooltip*/, args->onclick, args->onclickdata, NULL, 2, args->default_button == 2);
gtk_header_bar_pack_start(GTK_HEADER_BAR(headerbar), button);
if(args->default_button == 2) {
WIDGET_ADD_CSS_CLASS(button, "suggested-action");
}
if(args->rbutton4) {
- GtkWidget *button = ui_create_button(obj, args->rbutton4, NULL, NULL/*tooltip*/, args->onclick, args->onclickdata, 4, args->default_button == 4);
+ GtkWidget *button = ui_create_button(obj, args->rbutton4, NULL, NULL/*tooltip*/, args->onclick, args->onclickdata, NULL, 4, args->default_button == 4);
gtk_header_bar_pack_end(GTK_HEADER_BAR(headerbar), button);
if(args->default_button == 4) {
WIDGET_ADD_CSS_CLASS(button, "suggested-action");
}
}
if(args->rbutton3) {
- GtkWidget *button = ui_create_button(obj, args->rbutton3, NULL, NULL/*tooltip*/, args->onclick, args->onclickdata, 3, args->default_button == 3);
+ GtkWidget *button = ui_create_button(obj, args->rbutton3, NULL, NULL/*tooltip*/, args->onclick, args->onclickdata, NULL, 3, args->default_button == 3);
gtk_header_bar_pack_end(GTK_HEADER_BAR(headerbar), button);
if(args->default_button == 3) {
WIDGET_ADD_CSS_CLASS(button, "suggested-action");
gtk_grid_set_column_homogeneous(GTK_GRID(grid), TRUE);
if(args->lbutton1) {
- GtkWidget *button = ui_create_button(obj, args->lbutton1, NULL, NULL/*tooltip*/, args->onclick, args->onclickdata, 1, args->default_button == 1);
+ GtkWidget *button = ui_create_button(obj, args->lbutton1, NULL, NULL/*tooltip*/, args->onclick, args->onclickdata, NULL, 1, args->default_button == 1);
gtk_grid_attach(GTK_GRID(grid), button, 0, 0, 1, 1);
if(args->default_button == 1) {
WIDGET_ADD_CSS_CLASS(button, "suggested-action");
}
}
if(args->lbutton2) {
- GtkWidget *button = ui_create_button(obj, args->lbutton2, NULL, NULL/*tooltip*/, args->onclick, args->onclickdata, 2, args->default_button == 2);
+ GtkWidget *button = ui_create_button(obj, args->lbutton2, NULL, NULL/*tooltip*/, args->onclick, args->onclickdata, NULL, 2, args->default_button == 2);
gtk_grid_attach(GTK_GRID(grid), button, 1, 0, 1, 1);
if(args->default_button == 2) {
WIDGET_ADD_CSS_CLASS(button, "suggested-action");
gtk_widget_set_hexpand(space, TRUE);
gtk_grid_attach(GTK_GRID(grid), space, 2, 0, 1, 1);
if(args->rbutton3) {
- GtkWidget *button = ui_create_button(obj, args->rbutton3, NULL, NULL/*tooltip*/, args->onclick, args->onclickdata, 3, args->default_button == 3);
+ GtkWidget *button = ui_create_button(obj, args->rbutton3, NULL, NULL/*tooltip*/, args->onclick, args->onclickdata, NULL, 3, args->default_button == 3);
gtk_grid_attach(GTK_GRID(grid), button, 3, 0, 1, 1);
if(args->default_button == 3) {
WIDGET_ADD_CSS_CLASS(button, "suggested-action");
}
}
if(args->rbutton4) {
- GtkWidget *button = ui_create_button(obj, args->rbutton4, NULL, NULL/*tooltip*/, args->onclick, args->onclickdata, 4, args->default_button == 4);
+ GtkWidget *button = ui_create_button(obj, args->rbutton4, NULL, NULL/*tooltip*/, args->onclick, args->onclickdata, NULL, 4, args->default_button == 4);
gtk_grid_attach(GTK_GRID(grid), button, 4, 0, 1, 1);
if(args->default_button == 4) {
WIDGET_ADD_CSS_CLASS(button, "suggested-action");
--- /dev/null
+/*
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
+ *
+ * Copyright 2026 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 WINDOW_H
+#define WINDOW_H
+
+#include "toolkit.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+gboolean ui_window_close_request(UiObject *obj);
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* WINDOW_H */
+
const char *tooltip;
UiLabelType labeltype;
ui_callback onclick;
- void *onclickdata;
+ void *onclickdata;
+ const char *action;
const int *states;
const int *visibility_states;
const char *name;
const char *style_class;
- const char *label;
- const char *icon;
- const char *tooltip;
+ const char *label;
+ const char *icon;
+ const char *tooltip;
UiLabelType labeltype;
- UiInteger *value;
- const char *varname;
+ UiInteger *value;
+ const char *varname;
ui_callback onchange;
- void *onchangedata;
- int enable_state;
+ void *onchangedata;
+ const char *action;
+ int enable_state;
- const int *states;
- const int *visibility_states;
+ const int *states;
+ const int *visibility_states;
} UiToggleArgs;
+typedef struct UiContentToggleArgs {
+ UiBool fill;
+ UiBool hexpand;
+ UiBool vexpand;
+ UiBool hfill;
+ UiBool vfill;
+ UiBool override_defaults;
+ int margin;
+ int margin_left;
+ int margin_right;
+ int margin_top;
+ int margin_bottom;
+ int colspan;
+ int rowspan;
+ const char *name;
+ const char *style_class;
+
+ const char *label0;
+ const char *icon0;
+ const char *tooltip0;
+ const char *label1;
+ const char *icon1;
+ const char *tooltip1;
+ UiLabelType labeltype;
+ UiInteger *value;
+ const char *varname;
+ ui_callback onchange;
+ void *onchangedata;
+ const char *action;
+ UiBool istogglebutton;
+ int enable_state;
+ int toggled_by_state;
+
+ const int *states;
+ const int *visibility_states;
+} UiContentToggleArgs;
+
typedef struct UiLinkButtonArgs {
UiBool fill;
UiBool hexpand;
const char *varname;
ui_callback onclick;
void *onclickdata;
+ const char *action;
UiBool nofollow;
UiLinkType type;
#define ui_togglebutton(obj, ...) ui_togglebutton_create(obj, &(UiToggleArgs){ __VA_ARGS__ } )
#define ui_checkbox(obj, ...) ui_checkbox_create(obj, &(UiToggleArgs){ __VA_ARGS__ } )
#define ui_switch(obj, ...) ui_switch_create(obj, &(UiToggleArgs){ __VA_ARGS__ } )
+#define ui_content_togglebutton(obj, ...) ui_content_togglebutton_create(obj, &(UiContentToggleArgs){ __VA_ARGS__ } )
#define ui_radiobutton(obj, ...) ui_radiobutton_create(obj, &(UiToggleArgs){ __VA_ARGS__ } )
#define ui_linkbutton(obj, ...) ui_linkbutton_create(obj, &(UiLinkButtonArgs){ __VA_ARGS__ })
UIEXPORT UIWIDGET ui_togglebutton_create(UiObject *obj, UiToggleArgs *args);
UIEXPORT UIWIDGET ui_checkbox_create(UiObject *obj, UiToggleArgs *args);
UIEXPORT UIWIDGET ui_switch_create(UiObject *obj, UiToggleArgs *args);
+UIEXPORT UIWIDGET ui_content_togglebutton_create(UiObject *obj, UiContentToggleArgs *args);
UIEXPORT UIWIDGET ui_radiobutton_create(UiObject *obj, UiToggleArgs *args);
UIEXPORT UIWIDGET ui_linkbutton_create(UiObject *obj, UiLinkButtonArgs *args);
UIEXPORT void ui_button_set_label(UIWIDGET button, const char *label);
UIEXPORT void ui_button_set_icon(UIWIDGET button, const char *icon);
+UIEXPORT void ui_button_set_tooltip(UIWIDGET button, const char *tooltip);
+
+UIEXPORT void ui_togglebutton_set_label(UIWIDGET button, const char *label);
+UIEXPORT void ui_togglebutton_set_icon(UIWIDGET button, const char *icon);
+UIEXPORT void ui_togglebutton_set_tooltip(UIWIDGET button, const char *tooltip);
+
+UIEXPORT void ui_checkbox_set_label(UIWIDGET button, const char *label);
+UIEXPORT void ui_checkbox_set_icon(UIWIDGET button, const char *icon);
+UIEXPORT void ui_checkbox_set_tooltip(UIWIDGET button, const char *tooltip);
+
+UIEXPORT void ui_radiobutton_set_label(UIWIDGET button, const char *label);
+UIEXPORT void ui_radiobutton_set_icon(UIWIDGET button, const char *icon);
+UIEXPORT void ui_radiobutton_set_tooltip(UIWIDGET button, const char *tooltip);
UIEXPORT void ui_linkbutton_value_set(UiString *str, const char *label, const char *uri);
UIEXPORT void ui_linkbutton_value_set_label(UiString *str, const char *label);
int rowspan;
};
-struct UiContainerX {
+struct UiContainer {
void *container;
UiBool close;
UiBool newline;
- UiContainerX *prev;
- UiContainerX *next;
+ UiContainer *prev;
+ UiContainer *next;
};
typedef void(*ui_addwidget_func)(UiObject *obj, UIWIDGET parent, UIWIDGET child, void *userdata);
UIEXPORT void ui_custom_container_create(UiObject *obj, UIWIDGET widget, ui_addwidget_func add_child, void *userdata);
-// TODO
-UIEXPORT UiTabbedPane* ui_tabbed_document_view(UiObject *obj);
-UIEXPORT UiObject* ui_document_tab(UiTabbedPane *view);
-
/* used for macro */
#ifdef UI_GTK
#define UI_ICON_HOME "go-home"
-#define UI_ICON_NEW_WINDOW "list-add"
-#define UI_ICON_REFRESH "view-refresh"
+#define UI_ICON_NEW_WINDOW "window-new"
+#define UI_ICON_NEW_TAB "tab-new"
#define UI_ICON_NEW_FOLDER "folder-new"
-#define UI_ICON_ADD "document-new"
+#define UI_ICON_NEW_DOCUMENT "document-new"
+#define UI_ICON_NEW_APPOINTMENT "appointment-new"
+#define UI_ICON_NEW_CHAT_MESSAGE "chat-message-new"
+#define UI_ICON_NEW_CONTACT "contact-new"
+#define UI_ICON_NEW_MAIL "mail-message-new"
+#define UI_ICON_ADD_BOOKMARK "bookmark-new"
+#define UI_ICON_ADD_IMAGE "insert-image"
+#define UI_ICON_ADD_LINK "insert-link"
+#define UI_ICON_ADD_TEXT "insert-text"
+#define UI_ICON_ADD "list-add"
+#define UI_ICON_REMOVE "list-remove"
+#define UI_ICON_REFRESH "view-refresh"
#define UI_ICON_UPLOAD "document-open"
#define UI_ICON_SAVE_LOCAL "document-save-as"
-#define UI_ICON_DELETE "edit-delete"
-#define UI_ICON_DOCK_LEFT ""
-#define UI_ICON_DOCK_RIGHT ""
+#define UI_ICON_EDIT_COPY "edit-copy"
+#define UI_ICON_EDIT_CUT "edit-cut"
+#define UI_ICON_EDIT_DELETE "edit-delete"
+#define UI_ICON_EDIT_PASTE "edit-paste"
+#define UI_ICON_UNDO "edit-undo"
+#define UI_ICON_REDO "edit-redo"
+#define UI_ICON_SIDEBAR_LEFT "sidebar-show"
+#define UI_ICON_SIDEBAR_RIGHT "sidebar-show-right"
#define UI_ICON_GO_BACK "go-previous"
#define UI_ICON_GO_FORWARD "go-next"
#define UI_ICON_GO_UP "go-up"
#define UI_ICON_GO_DOWN "go-down"
+#define UI_ICON_VIEW_LIST "view-list"
+#define UI_ICON_VIEW_GRID "view-grid"
+#define UI_ICON_VIEW_DUAL "view-dual"
+#define UI_ICON_VIEW_FULLSCREEN "view-fullscreen"
+#define UI_ICON_VIEW_RESTORE "view-restore"
+#define UI_ICON_TEXT_BOLD "format-text-bold"
+#define UI_ICON_TEXT_ITALIC "format-text-italic"
+#define UI_ICON_TEXT_UNDERLINE "format-text-underline"
+#define UI_ICON_LIST_BULLET "view-list-bullet"
+#define UI_ICON_LIST_ORDERED "view-list-ordered"
+#define UI_ICON_LIST_CHECK "checkbox-checked"
+#define UI_ICON_CHECKBOX "checkbox-checked"
+#define UI_ICON_STAR "starred"
+#define UI_ICON_VIEW_REVEAL "view-reveal"
+#define UI_ICON_VIEW_CONCEAL "view-conceal"
+#define UI_ICON_SETTINGS "applications-system"
+#define UI_ICON_MEDIA_PLAY "media-playback-start"
+#define UI_ICON_MEDIA_STOP "media-playback-stop"
+#define UI_ICON_MEDIA_PAUSE "media-playback-pause"
+#define UI_ICON_MEDIA_SEEK_BACKWARD "media-seek-backward"
+#define UI_ICON_MEDIA_SEEK_FORWARD "media-seek-forward"
+#define UI_ICON_MEDIA_SKIP_BACKWARD "media-skip-backward"
+#define UI_ICON_MEDIA_SKIP_FORWARD "media-skip-forward"
+#define UI_ICON_CALL_START "call-start"
+#define UI_ICON_CALL_STOP "call-stop"
+#define UI_ICON_CALL_INCOMING "call-incoming"
+#define UI_ICON_CALL_OUTGOING "call-outgoing"
+#define UI_ICON_MICROPHONE_ON "microphone-sensitivity-high"
+#define UI_ICON_MICROPHONE_OFF "microphone-disabled"
+#define UI_ICON_LOCKED "changes-allow"
+#define UI_ICON_UNLOCKED "changes-prevent"
+#define UI_ICON_SECURE "channel-secure"
+#define UI_ICON_INSECURE "channel-insecure"
+
#endif /* UI_GTK */
+#ifdef UI_QT
+
+#define UI_ICON_HOME "go-home"
+#define UI_ICON_NEW_WINDOW "window-new"
+#define UI_ICON_NEW_TAB "tab-new"
+#define UI_ICON_NEW_FOLDER "folder-new"
+#define UI_ICON_NEW_DOCUMENT "document-new"
+#define UI_ICON_NEW_APPOINTMENT "appointment-new"
+#define UI_ICON_NEW_CHAT_MESSAGE "chat-message-new"
+#define UI_ICON_NEW_CONTACT "contact-new"
+#define UI_ICON_NEW_MAIL "mail-message-new"
+#define UI_ICON_ADD_BOOKMARK "bookmark-new"
+#define UI_ICON_ADD_IMAGE "insert-image"
+#define UI_ICON_ADD_LINK "insert-link"
+#define UI_ICON_ADD_TEXT "insert-text"
+#define UI_ICON_ADD "list-add"
+#define UI_ICON_REMOVE "list-remove"
+#define UI_ICON_REFRESH "view-refresh"
+#define UI_ICON_UPLOAD "document-open"
+#define UI_ICON_SAVE_LOCAL "document-save-as"
+#define UI_ICON_EDIT_COPY "edit-copy"
+#define UI_ICON_EDIT_CUT "edit-cut"
+#define UI_ICON_EDIT_DELETE "edit-delete"
+#define UI_ICON_EDIT_PASTE "edit-paste"
+#define UI_ICON_UNDO "edit-undo"
+#define UI_ICON_REDO "edit-redo"
+#define UI_ICON_SIDEBAR_LEFT "sidebar-show"
+#define UI_ICON_SIDEBAR_RIGHT "sidebar-show-right"
+#define UI_ICON_GO_BACK "go-previous"
+#define UI_ICON_GO_FORWARD "go-next"
+#define UI_ICON_GO_UP "go-up"
+#define UI_ICON_GO_DOWN "go-down"
+#define UI_ICON_VIEW_LIST "view-list"
+#define UI_ICON_VIEW_GRID "view-grid"
+#define UI_ICON_VIEW_DUAL "view-dual"
+#define UI_ICON_VIEW_FULLSCREEN "view-fullscreen"
+#define UI_ICON_VIEW_RESTORE "view-restore"
+#define UI_ICON_TEXT_BOLD "format-text-bold"
+#define UI_ICON_TEXT_ITALIC "format-text-italic"
+#define UI_ICON_TEXT_UNDERLINE "format-text-underline"
+#define UI_ICON_LIST_BULLET "view-list-bullet"
+#define UI_ICON_LIST_ORDERED "view-list-ordered"
+#define UI_ICON_LIST_CHECK "checkbox-checked"
+#define UI_ICON_CHECKBOX "checkbox-checked"
+#define UI_ICON_STAR "starred"
+#define UI_ICON_VIEW_REVEAL "view-reveal"
+#define UI_ICON_VIEW_CONCEAL "view-conceal"
+#define UI_ICON_SETTINGS "applications-system"
+#define UI_ICON_MEDIA_PLAY "media-playback-start"
+#define UI_ICON_MEDIA_STOP "media-playback-stop"
+#define UI_ICON_MEDIA_PAUSE "media-playback-pause"
+#define UI_ICON_MEDIA_SEEK_BACKWARD "media-seek-backward"
+#define UI_ICON_MEDIA_SEEK_FORWARD "media-seek-forward"
+#define UI_ICON_MEDIA_SKIP_BACKWARD "media-skip-backward"
+#define UI_ICON_MEDIA_SKIP_FORWARD "media-skip-forward"
+#define UI_ICON_CALL_START "call-start"
+#define UI_ICON_CALL_STOP "call-stop"
+#define UI_ICON_CALL_INCOMING "call-incoming"
+#define UI_ICON_CALL_OUTGOING "call-outgoing"
+#define UI_ICON_MICROPHONE_ON "microphone-sensitivity-high"
+#define UI_ICON_MICROPHONE_OFF "microphone-disabled"
+#define UI_ICON_LOCKED "changes-allow"
+#define UI_ICON_UNLOCKED "changes-prevent"
+#define UI_ICON_SECURE "channel-secure"
+#define UI_ICON_INSECURE "channel-insecure"
+#endif /* UI_QT */
#ifdef UI_WINUI
#define UI_ICON_GO_FORWARD "Forward"
#define UI_ICON_GO_UP "Up"
#define UI_ICON_GO_DOWN "" // TODO: implement workaround for missing down symbol
+#define UI_ICON_LIST "List"
#endif /* UI_WINUI */
+
+#ifdef UI_COCOA
+
+#define UI_ICON_HOME "go-home"
+#define UI_ICON_NEW_WINDOW "macwindow.badge.plus"
+#define UI_ICON_NEW_TAB "plus.square"
+#define UI_ICON_NEW_FOLDER "folder.badge.plus"
+#define UI_ICON_NEW_DOCUMENT "document.badge.plus"
+#define UI_ICON_NEW_APPOINTMENT "calendar.badge.plus"
+#define UI_ICON_NEW_CHAT_MESSAGE "plus.bubble"
+#define UI_ICON_NEW_CONTACT "person.badge.plus"
+#define UI_ICON_NEW_MAIL "envelope.badge.plus"
+#define UI_ICON_ADD_BOOKMARK "book.badge.plus"
+#define UI_ICON_ADD_IMAGE "photo.badge.plus"
+#define UI_ICON_ADD_LINK "link.badge.plus"
+#define UI_ICON_ADD_TEXT "text.badge.plus"
+#define UI_ICON_ADD "plus"
+#define UI_ICON_REMOVE "minus"
+#define UI_ICON_REFRESH "arrow.clockwise"
+#define UI_ICON_UPLOAD "square.and.arrow.up"
+#define UI_ICON_SAVE_LOCAL "square.and.arrow.down"
+#define UI_ICON_EDIT_COPY "document.on.document"
+#define UI_ICON_EDIT_CUT "scissors"
+#define UI_ICON_EDIT_DELETE "minus.circle"
+#define UI_ICON_EDIT_PASTE "document.on.clipboard"
+#define UI_ICON_UNDO "arrow.uturn.backward"
+#define UI_ICON_REDO "arrow.uturn.forward"
+#define UI_ICON_SIDEBAR_LEFT "sidebar.left"
+#define UI_ICON_SIDEBAR_RIGHT "sidebar.right"
+#define UI_ICON_GO_BACK "chevron.left"
+#define UI_ICON_GO_FORWARD "chevron.right"
+#define UI_ICON_GO_UP "chevron.up"
+#define UI_ICON_GO_DOWN "chevron.down"
+#define UI_ICON_VIEW_LIST "list.bullet"
+#define UI_ICON_VIEW_GRID "square.grid.2x2"
+#define UI_ICON_VIEW_DUAL "rectangle.split.2x1"
+#define UI_ICON_VIEW_FULLSCREEN "arrow.up.left.and.arrow.down.right.rectangle"
+#define UI_ICON_VIEW_RESTORE "arrow.down.forward.and.arrow.up.backward.rectangle"
+#define UI_ICON_TEXT_BOLD "bold"
+#define UI_ICON_TEXT_ITALIC "italic"
+#define UI_ICON_TEXT_UNDERLINE "underline"
+#define UI_ICON_LIST_BULLET "list.bullet"
+#define UI_ICON_LIST_ORDERED "list.number"
+#define UI_ICON_LIST_CHECK "checklist"
+#define UI_ICON_CHECKBOX "checkmark.square"
+#define UI_ICON_STAR "star"
+#define UI_ICON_VIEW_REVEAL "eye"
+#define UI_ICON_VIEW_CONCEAL "eye.slash"
+#define UI_ICON_SETTINGS "gearshape"
+#define UI_ICON_MEDIA_PLAY "play.fill"
+#define UI_ICON_MEDIA_STOP "stop.fill"
+#define UI_ICON_MEDIA_PAUSE "pause.fill"
+#define UI_ICON_MEDIA_SEEK_BACKWARD "backward.fill"
+#define UI_ICON_MEDIA_SEEK_FORWARD "forward.fill"
+#define UI_ICON_MEDIA_SKIP_BACKWARD "backward.end.fill"
+#define UI_ICON_MEDIA_SKIP_FORWARD "forward.end.fill"
+#define UI_ICON_CALL_START "phone"
+#define UI_ICON_CALL_STOP "phone.down"
+#define UI_ICON_CALL_INCOMING "phone.arrow.down.left"
+#define UI_ICON_CALL_OUTGOING "phone.arrow.up.right"
+#define UI_ICON_MICROPHONE_ON "microphone"
+#define UI_ICON_MICROPHONE_OFF "microphone.slash"
+#define UI_ICON_LOCKED "lock"
+#define UI_ICON_UNLOCKED "lock.open"
+#define UI_ICON_SECURE "lock"
+#define UI_ICON_INSECURE "lock.trianglebadge.exclamationmark"
+
+#endif /* UI_COCOA */
+
+#ifdef UI_MOTIF
+
+#define UI_ICON_HOME ""
+#define UI_ICON_NEW_WINDOW ""
+#define UI_ICON_NEW_TAB ""
+#define UI_ICON_NEW_FOLDER ""
+#define UI_ICON_NEW_DOCUMENT ""
+#define UI_ICON_NEW_APPOINTMENT ""
+#define UI_ICON_NEW_CHAT_MESSAGE ""
+#define UI_ICON_NEW_CONTACT ""
+#define UI_ICON_NEW_MAIL ""
+#define UI_ICON_ADD_BOOKMARK ""
+#define UI_ICON_ADD_IMAGE ""
+#define UI_ICON_ADD_LINK ""
+#define UI_ICON_ADD_TEXT ""
+#define UI_ICON_ADD ""
+#define UI_ICON_REMOVE ""
+#define UI_ICON_REFRESH ""
+#define UI_ICON_UPLOAD ""
+#define UI_ICON_SAVE_LOCAL ""
+#define UI_ICON_EDIT_COPY ""
+#define UI_ICON_EDIT_CUT ""
+#define UI_ICON_EDIT_DELETE ""
+#define UI_ICON_EDIT_PASTE ""
+#define UI_ICON_UNDO ""
+#define UI_ICON_REDO ""
+#define UI_ICON_SIDEBAR_LEFT ""
+#define UI_ICON_SIDEBAR_RIGHT ""
+#define UI_ICON_GO_BACK ""
+#define UI_ICON_GO_FORWARD ""
+#define UI_ICON_GO_UP ""
+#define UI_ICON_GO_DOWN ""
+#define UI_ICON_VIEW_LIST ""
+#define UI_ICON_VIEW_GRID ""
+#define UI_ICON_VIEW_DUAL ""
+#define UI_ICON_VIEW_FULLSCREEN ""
+#define UI_ICON_VIEW_RESTORE ""
+#define UI_ICON_TEXT_BOLD ""
+#define UI_ICON_TEXT_ITALIC ""
+#define UI_ICON_TEXT_UNDERLINE ""
+#define UI_ICON_LIST_BULLET ""
+#define UI_ICON_LIST_ORDERED ""
+#define UI_ICON_LIST_CHECK ""
+#define UI_ICON_CHECKBOX ""
+#define UI_ICON_STAR ""
+#define UI_ICON_VIEW_REVEAL ""
+#define UI_ICON_VIEW_CONCEAL ""
+#define UI_ICON_SETTINGS ""
+#define UI_ICON_MEDIA_PLAY ""
+#define UI_ICON_MEDIA_STOP ""
+#define UI_ICON_MEDIA_PAUSE ""
+#define UI_ICON_MEDIA_SEEK_BACKWARD ""
+#define UI_ICON_MEDIA_SEEK_FORWARD ""
+#define UI_ICON_MEDIA_SKIP_BACKWARD ""
+#define UI_ICON_MEDIA_SKIP_FORWARD ""
+#define UI_ICON_CALL_START ""
+#define UI_ICON_CALL_STOP ""
+#define UI_ICON_CALL_INCOMING ""
+#define UI_ICON_CALL_OUTGOING ""
+#define UI_ICON_MICROPHONE_ON ""
+#define UI_ICON_MICROPHONE_OFF ""
+#define UI_ICON_LOCKED ""
+#define UI_ICON_UNLOCKED ""
+#define UI_ICON_SECURE ""
+#define UI_ICON_INSECURE ""
+#endif /* UI_MOTIF */
+
+#ifdef UI_WIN32
+
+#define UI_ICON_HOME ""
+#define UI_ICON_NEW_WINDOW ""
+#define UI_ICON_NEW_TAB ""
+#define UI_ICON_NEW_FOLDER ""
+#define UI_ICON_NEW_DOCUMENT ""
+#define UI_ICON_NEW_APPOINTMENT ""
+#define UI_ICON_NEW_CHAT_MESSAGE ""
+#define UI_ICON_NEW_CONTACT ""
+#define UI_ICON_NEW_MAIL ""
+#define UI_ICON_ADD_BOOKMARK ""
+#define UI_ICON_ADD_IMAGE ""
+#define UI_ICON_ADD_LINK ""
+#define UI_ICON_ADD_TEXT ""
+#define UI_ICON_ADD ""
+#define UI_ICON_REMOVE ""
+#define UI_ICON_REFRESH ""
+#define UI_ICON_UPLOAD ""
+#define UI_ICON_SAVE_LOCAL ""
+#define UI_ICON_EDIT_COPY ""
+#define UI_ICON_EDIT_CUT ""
+#define UI_ICON_EDIT_DELETE ""
+#define UI_ICON_EDIT_PASTE ""
+#define UI_ICON_UNDO ""
+#define UI_ICON_REDO ""
+#define UI_ICON_SIDEBAR_LEFT ""
+#define UI_ICON_SIDEBAR_RIGHT ""
+#define UI_ICON_GO_BACK ""
+#define UI_ICON_GO_FORWARD ""
+#define UI_ICON_GO_UP ""
+#define UI_ICON_GO_DOWN ""
+#define UI_ICON_VIEW_LIST ""
+#define UI_ICON_VIEW_GRID ""
+#define UI_ICON_VIEW_DUAL ""
+#define UI_ICON_VIEW_FULLSCREEN ""
+#define UI_ICON_VIEW_RESTORE ""
+#define UI_ICON_TEXT_BOLD ""
+#define UI_ICON_TEXT_ITALIC ""
+#define UI_ICON_TEXT_UNDERLINE ""
+#define UI_ICON_LIST_BULLET ""
+#define UI_ICON_LIST_ORDERED ""
+#define UI_ICON_LIST_CHECK ""
+#define UI_ICON_CHECKBOX ""
+#define UI_ICON_STAR ""
+#define UI_ICON_VIEW_REVEAL ""
+#define UI_ICON_VIEW_CONCEAL ""
+#define UI_ICON_SETTINGS ""
+#define UI_ICON_MEDIA_PLAY ""
+#define UI_ICON_MEDIA_STOP ""
+#define UI_ICON_MEDIA_PAUSE ""
+#define UI_ICON_MEDIA_SEEK_BACKWARD ""
+#define UI_ICON_MEDIA_SEEK_FORWARD ""
+#define UI_ICON_MEDIA_SKIP_BACKWARD ""
+#define UI_ICON_MEDIA_SKIP_FORWARD ""
+#define UI_ICON_CALL_START ""
+#define UI_ICON_CALL_STOP ""
+#define UI_ICON_CALL_INCOMING ""
+#define UI_ICON_CALL_OUTGOING ""
+#define UI_ICON_MICROPHONE_ON ""
+#define UI_ICON_MICROPHONE_OFF ""
+#define UI_ICON_LOCKED ""
+#define UI_ICON_UNLOCKED ""
+#define UI_ICON_SECURE ""
+#define UI_ICON_INSECURE ""
+
+#endif /* UI_MOTIF */
+
+
+enum UiIconId {
+ UI_ICON_ID_HOME,
+ UI_ICON_ID_NEW_WINDOW,
+ UI_ICON_ID_NEW_TAB,
+ UI_ICON_ID_NEW_FOLDER,
+ UI_ICON_ID_NEW_DOCUMENT,
+ UI_ICON_ID_NEW_APPOINTMENT,
+ UI_ICON_ID_NEW_CHAT_MESSAGE,
+ UI_ICON_ID_NEW_CONTACT,
+ UI_ICON_ID_NEW_MAIL,
+ UI_ICON_ID_ADD_BOOKMARK,
+ UI_ICON_ID_ADD_IMAGE,
+ UI_ICON_ID_ADD_LINK,
+ UI_ICON_ID_ADD_TEXT,
+ UI_ICON_ID_ADD,
+ UI_ICON_ID_REMOVE,
+ UI_ICON_ID_REFRESH,
+ UI_ICON_ID_UPLOAD,
+ UI_ICON_ID_SAVE_LOCAL,
+ UI_ICON_ID_EDIT_COPY,
+ UI_ICON_ID_EDIT_CUT,
+ UI_ICON_ID_EDIT_DELETE,
+ UI_ICON_ID_EDIT_PASTE,
+ UI_ICON_ID_UNDO,
+ UI_ICON_ID_REDO,
+ UI_ICON_ID_SIDEBAR_LEFT,
+ UI_ICON_ID_SIDEBAR_RIGHT,
+ UI_ICON_ID_GO_BACK,
+ UI_ICON_ID_GO_FORWARD,
+ UI_ICON_ID_GO_UP,
+ UI_ICON_ID_GO_DOWN,
+ UI_ICON_ID_VIEW_LIST,
+ UI_ICON_ID_VIEW_GRID,
+ UI_ICON_ID_VIEW_DUAL,
+ UI_ICON_ID_VIEW_FULLSCREEN,
+ UI_ICON_ID_VIEW_RESTORE,
+ UI_ICON_ID_TEXT_BOLD,
+ UI_ICON_ID_TEXT_ITALIC,
+ UI_ICON_ID_TEXT_UNDERLINE,
+ UI_ICON_ID_LIST_BULLET,
+ UI_ICON_ID_LIST_ORDERED,
+ UI_ICON_ID_LIST_CHECK,
+ UI_ICON_ID_CHECKBOX,
+ UI_ICON_ID_STAR,
+ UI_ICON_ID_VIEW_REVEAL,
+ UI_ICON_ID_VIEW_CONCEAL,
+ UI_ICON_ID_SETTINGS,
+ UI_ICON_ID_MEDIA_PLAY,
+ UI_ICON_ID_MEDIA_STOP,
+ UI_ICON_ID_MEDIA_PAUSE,
+ UI_ICON_ID_MEDIA_SEEK_BACKWARD,
+ UI_ICON_ID_MEDIA_SEEK_FORWARD,
+ UI_ICON_ID_MEDIA_SKIP_BACKWARD,
+ UI_ICON_ID_MEDIA_SKIP_FORWARD,
+ UI_ICON_ID_CALL_START,
+ UI_ICON_ID_CALL_STOP,
+ UI_ICON_ID_CALL_INCOMING,
+ UI_ICON_ID_CALL_OUTGOING,
+ UI_ICON_ID_MICROPHONE_ON,
+ UI_ICON_ID_MICROPHONE_OFF,
+ UI_ICON_ID_LOCKED,
+ UI_ICON_ID_UNLOCKED,
+ UI_ICON_ID_SECURE,
+ UI_ICON_ID_INSECURE
+};
UIEXPORT UiIcon* ui_icon(const char* name, size_t size);
UIEXPORT UiIcon* ui_icon_unscaled(const char *name, int size);
UIEXPORT UiIcon* ui_fileicon(size_t size);
+UIEXPORT const char* ui_icon_name(enum UiIconId icon_id);
+
#ifdef __cplusplus
}
#endif
void *getstyledata;
ui_callback onactivate;
void *onactivatedata;
+ const char *onactivate_action;
ui_callback onselection;
void *onselectiondata;
+ const char *onselection_action;
ui_callback ondragstart;
void *ondragstartdata;
+ const char *ondragstart_action;
ui_callback ondragcomplete;
void *ondragcompletedata;
+ const char *ondragcomplete_action;
ui_callback ondrop;
void *ondropdata;
+ const char *ondrop_action;
UiBool multiselection;
UiBool hide_header;
UiMenuBuilder *contextmenu;
typedef struct UiMenuItemArgs {
const char *label;
const char *icon;
-
+
ui_callback onclick;
void *onclickdata;
const char *action;
typedef struct UiMenuItemListArgs {
const char *varname;
ui_getvaluefunc getvalue;
+ ui_getvaluefunc2 getvalue2;
+ void *getvaluedata;
ui_callback onselect;
void *onselectdata;
const char *action;
const char *varname;
ui_callback onchange;
void *onchangedata;
+ const char *onchange_action;
+ ui_callback ontextchanged;
+ void *ontextchangeddata;
+ const char *ontextchanged_action;
const int *states;
const int *visibility_states;
} UiTextAreaArgs;
+
+typedef enum UiTextChangedEventType {
+ UI_TEXT_INSERT = 0,
+ UI_TEXT_DELETE
+} UiTextChangedEventType;
+
+typedef struct UiTextChangeEventData {
+ UiTextChangedEventType type;
+ int begin;
+ int end;
+ const char *text;
+ int length;
+} UiTextChangeEventData;
typedef struct UiTextFieldArgs {
UiBool fill;
void *onchangedata;
ui_callback onactivate;
void *onactivatedata;
+ const char *onactivate_action;
+ const char *onchange_action;
const int *states;
const int *visibility_states;
ui_callback onactivate;
void *onactivatedata;
+ const char *action;
ui_callback ondragstart;
void *ondragstartdata;
UIEXPORT void ui_text_undo(UiText *value);
UIEXPORT void ui_text_redo(UiText *value);
+UIEXPORT void ui_textarea_focus(UIWIDGET textarea);
+UIEXPORT void ui_textarea_set_selection(UIWIDGET textarea, int begin, int end);
+UIEXPORT void ui_textarea_select_all(UIWIDGET textarea);
+UIEXPORT void ui_textarea_set_editable(UIWIDGET textarea, UiBool editable);
+UIEXPORT UiBool ui_textarea_is_editable(UIWIDGET textarea);
+UIEXPORT void ui_textarea_set_position(UIWIDGET textarea, int pos);
+UIEXPORT int ui_textarea_get_position(UIWIDGET textarea);
UIEXPORT void ui_textarea_scroll_to(UIWIDGET textarea, int pos);
#define ui_textfield(obj, ...) ui_textfield_create(obj, &(UiTextFieldArgs) { __VA_ARGS__ })
const int *visibility_states;
} UiToolbarToggleItemArgs;
+typedef struct UiToolbarContentToggleItemArgs {
+ const char *label0;
+ const char *icon0;
+ const char *tooltip0;
+ const char *label1;
+ const char *icon1;
+ const char *tooltip1;
+
+ const char *varname;
+ ui_callback onchange;
+ void *onchangedata;
+ const char *action;
+ const char *accelerator;
+ const char *accelerator_text;
+
+ int toggled_by_state;
+ UiBool istogglebutton;
+
+ const int *states;
+ const int *visibility_states;
+} UiToolbarContentToggleItemArgs;
+
typedef struct UiToolbarMenuArgs {
const char *label;
const char *icon;
#define ui_toolbar_item(name, ...) ui_toolbar_item_create(name, &(UiToolbarItemArgs){ __VA_ARGS__ } )
#define ui_toolbar_toggleitem(name, ...) ui_toolbar_toggleitem_create(name, &(UiToolbarToggleItemArgs){ __VA_ARGS__ } )
+#define ui_toolbar_content_toggleitem(name, ...) ui_toolbar_toggleitem_create(name, &(UiToolbarToggleItemArgs){ __VA_ARGS__ } )
#define ui_toolbar_menu(name, ...) for(ui_toolbar_menu_create(name, &(UiToolbarMenuArgs){ __VA_ARGS__ });ui_menu_is_open();ui_menu_close())
#define ui_toolbar_appmenu() for(ui_toolbar_menu_create(NULL, &(UiToolbarMenuArgs){ 0 });ui_menu_is_open();ui_menu_close())
UIEXPORT void ui_toolbar_item_create(const char* name, UiToolbarItemArgs *args);
UIEXPORT void ui_toolbar_toggleitem_create(const char* name, UiToolbarToggleItemArgs *args);
+UIEXPORT void ui_toolbar_content_toggleitem_create(const char* name, UiToolbarContentToggleItemArgs *args);
UIEXPORT void ui_toolbar_menu_create(const char* name, UiToolbarMenuArgs *args);
UIEXPORT void ui_toolbar_add_default(const char *name, enum UiToolbarPos pos);
#include <gtk/gtk.h>
#define UIWIDGET GtkWidget*
+#define UIWINDOW void*
#if UI_GTK2 || UI_GTK3
#define UIMENU GtkMenu*
#include <Xm/XmAll.h>
#define UIWIDGET Widget
+#define UIWINDOW void*
#define UIMENU Widget
#define UIWINDOW UiWidget*
#define UIMENU void*
+#else
+
+#define UI_GENERIC
+#define UIWIDGET void*
+#define UIWINDOW void*
+#define UIMENU void*
+
#endif
#ifndef TRUE
extern "C" {
#endif
-#define UI_GROUP_SELECTION 20000
+#define UI_STATE_SELECTION 20000
-#define UI_GROUPS(...) (const int[]){ __VA_ARGS__, -1 }
+#define UI_STATES(...) (const int[]){ __VA_ARGS__, -1 }
/* public types */
#ifndef __cplusplus
#endif
typedef struct UiObject UiObject;
-typedef struct UiContainerX UiContainerX;
typedef struct UiEvent UiEvent;
typedef struct UiMouseEvent UiMouseEvent;
typedef struct UiObserver UiObserver;
typedef struct UiTextStyle UiTextStyle;
typedef struct UiColor UiColor;
+typedef enum UiEventType UiEventType;
+
/* begin opaque types */
typedef struct UiContext UiContext;
typedef struct UiContainer UiContainer;
typedef struct UiThreadpool UiThreadpool;
/* end opaque types */
-typedef struct UiTabbedPane UiTabbedPane;
-
typedef enum UiTri {
UI_DEFAULT = 0,
UI_ON,
*/
UIWIDGET widget;
-#if defined(UI_COCOA) || defined(UI_WINUI)
/*
* native window object
*/
UIWINDOW wobj;
-#endif
/*
* user window data
/*
* container list
- * TODO: remove old UiContainer and rename UiContainerX to UiContainer
*/
- UiContainerX *container_begin;
- UiContainerX *container_end;
+ UiContainer *container_begin;
+ UiContainer *container_end;
/*
- * next container object
+ * called when someone requests to close the window
*/
- UiObject *next;
+ void (*onclose)(UiEvent *event, void *userdata);
+ void *onclosedata;
/*
* obj destroy func
unsigned int ref;
};
-struct UiTabbedPane {
- /*
- * native widget
- */
- UIWIDGET widget;
-
- /*
- * current document
- */
- void *document;
-
- /*
- * parent context
- */
- UiContext *ctx;
+enum UiEventType {
+ UI_EVENT_DATA_NULL = 0,
+ UI_EVENT_DATA_POINTER,
+ UI_EVENT_DATA_STRING,
+ UI_EVENT_DATA_INTEGER_VALUE,
+ UI_EVENT_DATA_STRING_VALUE,
+ UI_EVENT_DATA_TEXT_VALUE,
+ UI_EVENT_DATA_DOUBLE_VALUE,
+ UI_EVENT_DATA_RANGE_VALUE,
+ UI_EVENT_DATA_TEXT_CHANGED,
+ UI_EVENT_DATA_LIST_SELECTION,
+ UI_EVENT_DATA_LIST_ELM,
+ UI_EVENT_DATA_DND,
+ UI_EVENT_DATA_SUBLIST,
+ UI_EVENT_DATA_FILE_LIST,
+ UI_EVENT_DATA_TYPED_OBJECT
};
struct UiEvent {
- UiObject *obj;
- void *document;
- void *window;
- void *eventdata;
- int eventdatatype;
- int intval;
- int set;
+ UiObject *obj;
+ void *document;
+ void *window;
+ void *eventdata;
+ UiEventType eventdatatype;
+ int intval;
+ int set;
};
struct UiMouseEvent {
void (*selection)(UiText*, int*, int*); /* text, begin, end */
int (*length)(UiText*);
void (*remove)(UiText*, int, int); /* text, begin, end */
+ void (*setreadonly)(UiText*, int);
UiStr value;
int pos;
+ int readonly;
void *obj;
int datatype;
void *data1;
void *data2;
- // TODO: replacefunc, ...
UiObserver *observers;
};
* abstract list
*/
struct UiList {
- /* get the first element */
+ // destructor
+ ui_list_destroy_func destroy;
+ // get the first element
void*(*first)(UiList *list);
- /* get the next element */
+ // get the next element
void*(*next)(UiList *list);
- /* get the nth element */
+ // get the nth element
void*(*get)(UiList *list, int i);
- /* get the number of elements */
+ // get the number of elements
int(*count)(UiList *list);
- /* iterator changes after first() next() and get() */
+ // iterator changes after first() next() and get()
void *iter;
- /* private - implementation dependent */
+ // private - implementation dependent
void *data;
- /* binding functions */
+ // binding functions
void (*update)(UiList *list, int i);
UiListSelection (*getselection)(UiList *list);
void (*setselection)(UiList *list, UiListSelection selection);
- /* binding object */
+ // binding object
void *obj;
+ // saved selection after unbind
+ UiListSelection *saved_selection;
+ // enable selection saving
+ UiBool save_selection;
- /* list of observers */
+ // list of observers
UiObserver *observers;
};
int intdata;
} UiCondVar;
-enum UiEventType {
- UI_EVENT_DATA_NULL = 0,
- UI_EVENT_DATA_POINTER,
- UI_EVENT_DATA_STRING,
- UI_EVENT_DATA_INTEGER_VALUE,
- UI_EVENT_DATA_STRING_VALUE,
- UI_EVENT_DATA_TEXT_VALUE,
- UI_EVENT_DATA_DOUBLE_VALUE,
- UI_EVENT_DATA_RANGE_VALUE,
- UI_EVENT_DATA_LIST_SELECTION,
- UI_EVENT_DATA_LIST_ELM,
- UI_EVENT_DATA_DND,
- UI_EVENT_DATA_SUBLIST,
- UI_EVENT_DATA_FILE_LIST
-};
+// eventdata in case eventdatatype is UI_EVENT_DATA_TYPED_OBJECT
+typedef struct UiTypedObj {
+ void *ptr;
+ uint64_t type;
+} UiTypedObj;
#define UI_COLOR(r, g, b) (UiColor){r, g, b}
struct UiColor {
UIEXPORT void ui_init(const char *appname, int argc, char **argv);
-UIEXPORT const char* ui_appname();
+UIEXPORT const char* ui_appname(void);
UIEXPORT void ui_add_styledata(const char *styledata, int len);
UIEXPORT void ui_context_closefunc(UiContext *ctx, ui_callback fnc, void *udata);
-UIEXPORT void ui_context_destroy(UiContext *ctx);
-
UIEXPORT UiContext* ui_context_parent(UiContext *ctx);
+UIEXPORT UiContext* ui_context_toplevel_parent(UiContext *ctx);
UIEXPORT void ui_object_ref(UiObject *obj);
UIEXPORT int ui_object_unref(UiObject *obj);
UIEXPORT void ui_onstartup(ui_callback f, void *userdata);
+UIEXPORT void ui_onnewwindow(ui_callback f, void *userdata);
UIEXPORT void ui_onopen(ui_callback f, void *userdata);
UIEXPORT void ui_onexit(ui_callback f, void *userdata);
+UIEXPORT void ui_newwindow(void);
+
UIEXPORT int ui_app_save_settings(void);
UIEXPORT void ui_app_exit_on_shutdown(UiBool exitapp);
UIEXPORT void ui_threadpool_job(UiThreadpool* pool, UiObject* obj, ui_threadfunc tf, void* td, ui_callback f, void* fd);
UIEXPORT void* ui_document_new(size_t size);
+UIEXPORT void ui_document_ref(void *doc);
+UIEXPORT void ui_document_unref(void *doc);
UIEXPORT void ui_document_destroy(void *doc);
+UIEXPORT void ui_document_onattach(void *doc, ui_callback cb, void *data);
+UIEXPORT void ui_document_ondetach(void *doc, ui_callback cb, void *data);
+UIEXPORT void ui_document_onattachmentstatuschange(void *doc, ui_callback cb, void *data);
+UIEXPORT void ui_document_onattach_action(void *doc, const char *action);
+UIEXPORT void ui_document_ondetach_action(void *doc, const char *action);
+UIEXPORT void ui_document_onattachmentstatuschange_action(void *doc, const char *action);
-UIEXPORT void* ui_get_subdocument(void *document); // deprecated
+UIEXPORT int ui_document_is_attached(void *doc);
+UIEXPORT int ui_document_is_attached_to_obj(void *doc);
UIEXPORT UiContext* ui_document_context(void *doc);
+UIEXPORT void* ui_context_document(UiContext *ctx);
+UIEXPORT UiObject* ui_context_obj(UiContext *ctx);
UIEXPORT void* ui_context_get_document(UiContext *ctx);
UIEXPORT void ui_context_single_attachment_mode(UiContext *ctx, UiBool enable);
UIEXPORT void ui_widget_set_states2(UiContext *ctx, UIWIDGET widget, ui_enablefunc enable, const int *states, int nstates);
UIEXPORT void ui_widget_set_visibility_states(UiContext *ctx, UIWIDGET widget, const int *states, int nstates);
+UIEXPORT void ui_add_action(UiContext *ctx, const char *name, ui_callback callback, void *userdata);
+UIEXPORT void ui_add_action_with_accelerator(
+ UiContext *ctx,
+ const char *name,
+ ui_callback callback,
+ void *userdata,
+ const char *accelerator,
+ const char *accelerator_text);
+UIEXPORT void ui_update_action_bindings(UiContext *ctx);
+UIEXPORT int ui_call_action(UiContext *ctx, const char *action_name);
+UIEXPORT int ui_call_action2(UiContext *ctx, const char *action_name, void *eventdata, int intval);
+UIEXPORT int ui_call_action3(UiContext *ctx, const char *action_name, void *ptr, uint64_t type_id);
+UIEXPORT void ui_broadcast_action(const char *action_name);
+UIEXPORT void ui_broadcast_action2(const char *action_name, void *eventdata, int intval);
+UIEXPORT void ui_broadcast_action3(const char *action_name, void *ptr, uint64_t type_id);
+UIEXPORT void ui_mainthread_broadcast(const char *action_name);
+UIEXPORT void ui_mainthread_broadcast2(const char *action_name, void *eventdata, int intval);
+UIEXPORT void ui_mainthread_broadcast3(const char *action_name, void *ptr, uint64_t type_id);
+UIEXPORT void ui_call_action_on(UiContext *ctx, const char *action);
+
UIEXPORT void ui_set_state(UiContext *ctx, int state);
UIEXPORT void ui_unset_state(UiContext *ctx, int state);
+UIEXPORT void ui_suppress_state(UiContext *ctx, int state);
+UIEXPORT void ui_unsuppress_state(UiContext *ctx, int state);
UIEXPORT int* ui_active_states(UiContext *ctx, int *nstates);
UIEXPORT void* ui_allocator(UiContext *ctx);
UIEXPORT void* ui_realloc(UiContext *ctx, void *ptr, size_t size);
UIEXPORT char* ui_strdup(UiContext *ctx, const char *str);
UIEXPORT void ui_reg_destructor(UiContext *ctx, void *data, ui_destructor_func destr);
+UIEXPORT void ui_remove_destructor(UiContext *ctx, void *data);
UIEXPORT void ui_set_destructor(void *mem, ui_destructor_func destr);
// types
UIEXPORT int ui_list_count(UiList *list);
UIEXPORT void ui_list_append(UiList *list, void *data);
UIEXPORT void ui_list_prepend(UiList *list, void *data);
+UIEXPORT void ui_list_insert(UiList *list, int index, void *data);
UIEXPORT void ui_list_remove(UiList *list, int i);
UIEXPORT void ui_list_clear(UiList *list);
UIEXPORT void ui_list_update(UiList *list);
UIEXPORT void ui_list_set_selection(UiList *list, UiListSelection sel);
UIEXPORT void ui_list_addobsv(UiList *list, ui_callback f, void *data);
UIEXPORT void ui_list_notify(UiList *list);
+UIEXPORT void ui_list_clear_saved_selection(UiList *list);
UIEXPORT int ui_list_getselection(UiList *list);
UIEXPORT void ui_list_setselection(UiList *list, int index);
UIEXPORT void ui_add_image(char *imgname, char *filename); // TODO: remove?
-
+UIEXPORT char* ui_text_getsubstr(UiText *text, int begin, int end);
+UIEXPORT void ui_text_insert(UiText *text, int pos, const char *str);
+UIEXPORT void ui_text_replace(UiText *text, int begin, int end, const char *str);
+UIEXPORT void ui_text_setposition(UiText *text, int pos);
+UIEXPORT int ui_text_position(UiText *text);
+UIEXPORT void ui_text_showposition(UiText *text, int pos);
+UIEXPORT void ui_text_setselection(UiText *text, int begin, int end);
+UIEXPORT void ui_text_selection(UiText *text, int *begin, int *end);
+UIEXPORT int ui_text_length(UiText *text);
+UIEXPORT void ui_text_remove(UiText *text, int begin, int end);
+UIEXPORT void ui_text_setreadonly(UiText *text, int readonly);
UIEXPORT UiStr ui_str(char *cstr);
UIEXPORT UiStr ui_str_free(char *str, void (*free)(void *v));
UIEXPORT void ui_global_list_initializer(ui_list_init_func func, void *userdata);
UIEXPORT void ui_global_list_destructor(ui_list_destroy_func func, void *userdata);
+UIEXPORT void ui_list_class_set_destructor(UiList *list, ui_list_destroy_func destroy);
UIEXPORT void ui_list_class_set_first(UiList *list, void*(*first)(UiList *list));
UIEXPORT void ui_list_class_set_next(UiList *list, void*(*next)(UiList *list));
UIEXPORT void ui_list_class_set_get(UiList *list, void*(*get)(UiList *list, int i));
UIEXPORT void ui_app_ref(void);
UIEXPORT void ui_app_unref(void);
+UIEXPORT void ui_open_uri(const char *uri);
+
#ifdef __cplusplus
}
#endif
const char *style_class;
} UiWidgetArgs;
+#ifndef UI_GENERIC
+
#ifdef UI_GTK
typedef UIWIDGET (*ui_createwidget_func)(UiObject *obj, UiWidgetArgs *args, void *userdata);
#elif defined(UI_QT)
#define ui_customwidget(obj, create_widget, userdata, ...) ui_customwidget_create(obj, create_widget, userdata, &(UiWidgetArgs) { __VA_ARGS__ })
+#endif
UIEXPORT UIWIDGET ui_separator_create(UiObject *obj, UiWidgetArgs *args);