From 6b15e84dfe3b259bb4399d0754261fdefd5c523a Mon Sep 17 00:00:00 2001 From: Olaf Wintermann Date: Sat, 12 Jul 2025 19:15:28 +0200 Subject: [PATCH] update toolkit --- application/Makefile | 4 +- application/notebook.c | 6 +- application/window.c | 2 +- application/window.h | 2 +- configure | 15 ++ make/project.xml | 6 + ucx/Makefile | 12 +- ui/Makefile | 7 +- ui/common/args.c | 537 ++++++++++++++++++++++++++++++++++++++++- ui/common/args.h | 121 +++++++++- ui/common/context.c | 16 +- ui/common/context.h | 10 +- ui/common/document.c | 38 --- ui/common/object.c | 51 +++- ui/common/object.h | 9 + ui/common/objs.mk | 1 + ui/common/types.c | 68 ++++-- ui/common/types.h | 5 +- ui/common/wrapper.c | 188 +++++++++++++++ ui/common/wrapper.h | 76 ++++++ ui/gtk/list.c | 104 +++++--- ui/gtk/list.h | 1 + ui/gtk/window.c | 10 +- ui/motif/image.c | 9 + ui/motif/list.c | 47 +++- ui/motif/list.h | 3 +- ui/motif/window.c | 3 +- ui/qt/Makefile | 4 + ui/qt/image.cpp | 39 +++ ui/qt/image.h | 36 +++ ui/qt/list.cpp | 19 +- ui/qt/model.cpp | 37 ++- ui/qt/model.h | 5 +- ui/qt/qt5.pro | 2 + ui/qt/window.cpp | 5 +- ui/ui/toolkit.h | 38 +-- ui/ui/tree.h | 33 ++- ui/win32/Makefile | 3 + ui/win32/image.c | 37 +++ ui/win32/image.h | 42 ++++ ui/win32/objs.mk | 1 + ui/win32/toolkit.c | 15 +- ui/win32/window.c | 7 +- ui/winui/container.cpp | 139 +++++------ ui/winui/container.h | 8 +- ui/winui/image.cpp | 24 +- ui/winui/image.h | 6 + ui/winui/text.cpp | 1 - ui/winui/window.cpp | 3 +- 49 files changed, 1599 insertions(+), 256 deletions(-) create mode 100644 ui/common/wrapper.c create mode 100644 ui/common/wrapper.h create mode 100644 ui/qt/image.cpp create mode 100644 ui/qt/image.h create mode 100644 ui/win32/image.c create mode 100644 ui/win32/image.h diff --git a/application/Makefile b/application/Makefile index b07061b..27eb93b 100644 --- a/application/Makefile +++ b/application/Makefile @@ -58,10 +58,10 @@ TEST_BIN = ../build/bin/notetest$(APP_EXT) all: $(APP_BIN) $(TEST_BIN) $(APP_BIN): $(MAIN_OBJ) $(OBJ) $(BUILD_ROOT)/build/lib/libuitk.a - $(LD) -o $(APP_BIN) $(MAIN_OBJ) $(OBJ) -L$(BUILD_ROOT)/build/lib -luitk -lucx -lidav -ldbutils -lmd4c $(LDFLAGS) $(TK_LDFLAGS) $(DAV_LDFLAGS) $(DBU_LDFLAGS) + $(LD) -o $(APP_BIN) $(MAIN_OBJ) $(OBJ) -L$(BUILD_ROOT)/build/lib $(BUILD_ROOT)/build/$(BUILD_LIB_DIR)/$(LIB_PREFIX)uitk$(LIB_EXT) $(BUILD_ROOT)/build/$(BUILD_LIB_DIR)/$(LIB_PREFIX)ucx$(LIB_EXT) -lidav -ldbutils -lmd4c $(LDFLAGS) $(TK_LDFLAGS) $(DAV_LDFLAGS) $(DBU_LDFLAGS) $(TEST_BIN): $(OBJ) $(TEST_OBJ) $(BUILD_ROOT)/build/lib/libuitk.a - $(CC) -o $(TEST_BIN) $(TEST_OBJ) $(OBJ) -L$(BUILD_ROOT)/build/lib -luitk -lucx -lidav -ldbutils -lmd4c $(LDFLAGS) $(TK_LDFLAGS) $(DAV_LDFLAGS) $(DBU_LDFLAGS) + $(CC) -o $(TEST_BIN) $(TEST_OBJ) $(OBJ) -L$(BUILD_ROOT)/build/lib $(BUILD_ROOT)/build/$(BUILD_LIB_DIR)/$(LIB_PREFIX)uitk$(LIB_EXT) $(BUILD_ROOT)/build/$(BUILD_LIB_DIR)/$(LIB_PREFIX)ucx$(LIB_EXT) -lidav -ldbutils -lmd4c $(LDFLAGS) $(TK_LDFLAGS) $(DAV_LDFLAGS) $(DBU_LDFLAGS) ../build/application/%$(OBJ_EXT): %.c $(CC) $(CFLAGS) $(TK_CFLAGS) $(DAV_CFLAGS) -o $@ -c $< diff --git a/application/notebook.c b/application/notebook.c index 7f361fb..89cc77f 100644 --- a/application/notebook.c +++ b/application/notebook.c @@ -84,7 +84,7 @@ void notebookmodel_detach(NotebookModel *model) { } if(model->window) { - ui_detach_document2(model->window->obj->ctx, model); + ui_detach_document(model->window->obj->ctx, model); model->window->current_notebook = NULL; } } @@ -130,7 +130,7 @@ void notebookmodel_attach_note(NotebookModel *model, Note *note) { if(model->current_note == note) { // workaround, see top comment - ui_detach_document2(model->ctx, model->current_note->model); + ui_detach_document(model->ctx, model->current_note->model); model->current_note = NULL; } else{ notebookmodel_detach_current_note(model); @@ -169,7 +169,7 @@ void notebookmodel_detach_current_note(NotebookModel *model) { // of all vars, but it seems this doesn't work // without note_save, the content is not saved (internally) if(current_note->model) { - ui_detach_document2(model->ctx, current_note->model); + ui_detach_document(model->ctx, current_note->model); } model->current_note = NULL; } diff --git a/application/window.c b/application/window.c index 43e871d..576c7ff 100644 --- a/application/window.c +++ b/application/window.c @@ -136,7 +136,7 @@ void window_notelist_setvisible(MainWindow *window, UiBool visible) { window->notelist_isvisible = visible; } -void window_sidebar_getvalue(void *sublist_userdata, void *rowdata, int index, UiSubListItem *item) { +void window_sidebar_getvalue(void *sublist_userdata, void *rowdata, int index, UiSubListItem *item, void *userdata) { Resource *notebook = rowdata; item->label = strdup(notebook->displayname ? notebook->displayname : notebook->nodename); diff --git a/application/window.h b/application/window.h index 589e839..4a134fb 100644 --- a/application/window.h +++ b/application/window.h @@ -53,7 +53,7 @@ void window_create(); MainWindow* window_init_data(UiObject *obj); -void window_sidebar_getvalue(void *sublist_userdata, void *rowdata, int index, UiSubListItem *item); +void window_sidebar_getvalue(void *sublist_userdata, void *rowdata, int index, UiSubListItem *item, void *userdata); void window_notelist_setvisible(MainWindow *window, UiBool visible); diff --git a/configure b/configure index 181088d..bab46c4 100755 --- a/configure +++ b/configure @@ -896,6 +896,7 @@ do cat >> "$TEMP_DIR/make.mk" << __EOF__ OBJ_EXT = .o LIB_EXT = .a +SHLIB_EXT = .dylib LIB_PREFIX = lib PACKAGE_SCRIPT = package_osx.sh __EOF__ @@ -917,6 +918,7 @@ do cat >> "$TEMP_DIR/make.mk" << __EOF__ OBJ_EXT = .o LIB_EXT = .a +SHLIB_EXT = .so LIB_PREFIX = lib PACKAGE_SCRIPT = package_unix.sh __EOF__ @@ -925,6 +927,19 @@ __EOF__ break done while true +do + while true + do + + cat >> "$TEMP_DIR/make.mk" << __EOF__ +BUILD_BIN_DIR = bin +BUILD_LIB_DIR = lib +__EOF__ + break + done + break +done +while true do if notisplatform "bsd"; then break diff --git a/make/project.xml b/make/project.xml index 47a61f1..9ba21b6 100644 --- a/make/project.xml +++ b/make/project.xml @@ -127,15 +127,21 @@ OBJ_EXT = .o LIB_EXT = .a + SHLIB_EXT = .dylib LIB_PREFIX = lib PACKAGE_SCRIPT = package_osx.sh OBJ_EXT = .o LIB_EXT = .a + SHLIB_EXT = .so LIB_PREFIX = lib PACKAGE_SCRIPT = package_unix.sh + + BUILD_BIN_DIR = bin + BUILD_LIB_DIR = lib + -I/usr/local/include diff --git a/ucx/Makefile b/ucx/Makefile index e24476e..1005259 100644 --- a/ucx/Makefile +++ b/ucx/Makefile @@ -49,16 +49,20 @@ SRC += json.c OBJ = $(SRC:%.c=../build/ucx/%$(OBJ_EXT)) -UCX_LIB = ../build/lib/libucx$(LIB_EXT) +UCX_LIB = ../build/$(BUILD_LIB_DIR)/$(LIB_PREFIX)ucx$(LIB_EXT) +UCX_SHLIB = ../build/$(BUILD_LIB_DIR)/$(LIB_PREFIX)ucx$(SHLIB_EXT) -all: ../build/ucx $(UCX_LIB) +all: $(UCX_LIB) $(UCX_SHLIB) $(UCX_LIB): $(OBJ) - $(AR) $(ARFLAGS) $(UCX_LIB) $(OBJ) + $(AR) $(ARFLAGS) $@ $(OBJ) + +$(UCX_SHLIB): $(OBJ) + $(CC) -o $@ $(LDFLAGS) $(SHLIB_LDFLAGS) $(OBJ) ../build/ucx: mkdir -p ../build/ucx ../build/ucx/%$(OBJ_EXT): %.c - $(CC) $(CFLAGS) -o $@ -c $< + $(CC) $(CFLAGS) $(SHLIB_CFLAGS) -o $@ -c $< diff --git a/ui/Makefile b/ui/Makefile index 6905986..ad5aad0 100644 --- a/ui/Makefile +++ b/ui/Makefile @@ -33,15 +33,16 @@ OBJ_DIR = ../build/ include common/objs.mk -UI_LIB = ../build/lib/$(LIB_PREFIX)uitk$(LIB_EXT) +UI_LIB = ../build/$(BUILD_LIB_DIR)/$(LIB_PREFIX)uitk$(LIB_EXT) +UI_SHLIB = ../build/$(BUILD_LIB_DIR)/$(LIB_PREFIX)uitk$(SHLIB_EXT) include $(TOOLKIT)/objs.mk OBJ = $(TOOLKITOBJS) $(COMMONOBJS) -all: $(UI_LIB) +all: $(UI_LIB) $(UI_SHLIB) include $(TOOLKIT)/Makefile $(COMMON_OBJPRE)uic_%$(OBJ_EXT): common/%.c - $(CC) -o $@ -c -I../ucx/ $(CFLAGS) $(TK_CFLAGS) $< + $(CC) -o $@ -c -I../ucx/ $(CFLAGS) $(SHLIB_CFLAGS) $(TK_CFLAGS) $< diff --git a/ui/common/args.c b/ui/common/args.c index f80692a..c99ce0c 100644 --- a/ui/common/args.c +++ b/ui/common/args.c @@ -142,6 +142,128 @@ void ui_menuitemlist_args_free(UiMenuItemListArgs *args){ free(args); } +/* --------------------------- UiToolbarItemArgs --------------------------- */ + +UiToolbarItemArgs* ui_toolbar_item_args_new(void) { + UiToolbarItemArgs *args = malloc(sizeof(UiToolbarItemArgs)); + memset(args, 0, sizeof(UiToolbarItemArgs)); + return args; +} + +void ui_toolbar_item_args_set_label(UiToolbarItemArgs *args, const char *label) { + args->label = strdup(label); +} + +void ui_toolbar_item_args_set_stockid(UiToolbarItemArgs *args, const char *stockid) { + args->stockid = strdup(stockid); +} + +void ui_toolbar_item_args_set_icon(UiToolbarItemArgs *args, const char *icon) { + args->icon = strdup(icon); +} + +void ui_toolbar_item_args_set_onclick(UiToolbarItemArgs *args, ui_callback callback) { + args->onclick = callback; +} + +void ui_toolbar_item_args_set_onclickdata(UiToolbarItemArgs *args, void *onclickdata) { + args->onclickdata = onclickdata; +} + +void ui_toolbar_item_args_set_groups(UiToolbarItemArgs *args, int *groups) { + // TODO +} +void ui_toolbar_item_args_free(UiToolbarItemArgs *args) { + free((void*)args->label); + free((void*)args->stockid); + free((void*)args->icon); + free(args); +} + +/* ---------------------------- UiToolbarToggleItemArgs ---------------------------- */ + +UiToolbarToggleItemArgs* ui_toolbar_toggleitem_args_new(void) { + UiToolbarToggleItemArgs *args = malloc(sizeof(UiToolbarToggleItemArgs)); + memset(args, 0, sizeof(UiToolbarToggleItemArgs)); + return args; +} + + +void ui_toolbar_toggleitem_args_set_label(UiToolbarToggleItemArgs *args, const char *label) { + args->label = strdup(label); +} + + +void ui_toolbar_toggleitem_args_set_stockid(UiToolbarToggleItemArgs *args, const char *stockid) { + args->stockid = strdup(stockid); +} + + +void ui_toolbar_toggleitem_args_set_icon(UiToolbarToggleItemArgs *args, const char *icon) { + args->icon = strdup(icon); +} + + +void ui_toolbar_toggleitem_args_set_varname(UiToolbarToggleItemArgs *args, const char *varname) { + args->varname = strdup(varname); +} + + +void ui_toolbar_toggleitem_args_set_onchange(UiToolbarToggleItemArgs *args, ui_callback callback) { + args->onchange = callback; +} + + +void ui_toolbar_toggleitem_args_set_onchangedata(UiToolbarToggleItemArgs *args, void *onchangedata) { + args->onchangedata = onchangedata; +} + + +void ui_toolbar_toggleitem_args_set_groups(UiToolbarToggleItemArgs *args, int *groups) { + // TODO +} + + +void ui_toolbar_toggleitem_args_free(UiToolbarToggleItemArgs *args) { + free((void*)args->label); + free((void*)args->stockid); + free((void*)args->icon); + free((void*)args->varname); + free(args); +} + +/* ---------------------------- UiToolbarMenuArgs ---------------------------- */ + + +UiToolbarMenuArgs* ui_toolbar_menu_args_new(void) { + UiToolbarMenuArgs *args = malloc(sizeof(UiToolbarMenuArgs)); + memset(args, 0, sizeof(UiToolbarMenuArgs)); + return args; +} + + +void ui_toolbar_menu_args_set_label(UiToolbarMenuArgs *args, const char *label) { + args->label = strdup(label); +} + + +void ui_toolbar_menu_args_set_stockid(UiToolbarMenuArgs *args, const char *stockid) { + args->stockid = strdup(stockid); +} + + +void ui_toolbar_menu_args_set_icon(UiToolbarMenuArgs *args, const char *icon) { + args->icon = strdup(icon); +} + + +void ui_toolbar_menu_args_free(UiToolbarMenuArgs *args) { + free((void*)args->label); + free((void*)args->stockid); + free((void*)args->icon); + free(args); +} + /* ---------------------------- UiContainerArgs ---------------------------- */ @@ -185,7 +307,7 @@ void ui_container_args_set_colspan(UiContainerArgs *args, int colspan) { } -void ui_container_args_set_rolspan(UiContainerArgs *args, int rowspan) { +void ui_container_args_set_rowspan(UiContainerArgs *args, int rowspan) { args->rowspan = rowspan; } @@ -291,7 +413,7 @@ void ui_frame_args_set_colspan(UiFrameArgs *args, int colspan) { } -void ui_frame_args_set_rolspan(UiFrameArgs *args, int rowspan) { +void ui_frame_args_set_rowspan(UiFrameArgs *args, int rowspan) { args->rowspan = rowspan; } @@ -344,11 +466,153 @@ void ui_frame_args_free(UiFrameArgs *args) { } +/* ---------------------------- UiSidebarArgs -------------------------------*/ + +UiSidebarArgs* ui_sidebar_args_new(void) { + UiSidebarArgs *args = malloc(sizeof(UiSidebarArgs)); + memset(args, 0, sizeof(UiSidebarArgs)); + return args; +} + + +void ui_sidebar_args_set_name(UiSidebarArgs *args, const char *name) { + args->name = strdup(name); +} + + +void ui_sidebar_args_set_style_class(UiSidebarArgs *args, const char *classname) { + args->style_class = strdup(classname); +} + + +void ui_sidebar_args_set_margin(UiSidebarArgs *args, int value) { + args->margin = value; +} + + +void ui_sidebar_args_set_spacing(UiSidebarArgs *args, int value) { + args->spacing = value; +} + + +void ui_sidebar_args_free(UiSidebarArgs *args) { + free((void*)args->name); + free((void*)args->style_class); + free(args); +} + + +/* --------------------------- UiSplitPaneArgs ------------------------------*/ + +UiSplitPaneArgs* ui_splitpane_args_new(void) { + UiSplitPaneArgs *args = malloc(sizeof(UiSplitPaneArgs)); + memset(args, 0, sizeof(UiSplitPaneArgs)); + return args; +} + + +void ui_splitpane_args_set_fill(UiSplitPaneArgs *args, UiBool fill) { + args->fill = fill ? UI_ON : UI_OFF; +} + + +void ui_splitpane_args_set_hexpand(UiSplitPaneArgs *args, UiBool value) { + args->hexpand = value; +} + + +void ui_splitpane_args_set_vexpand(UiSplitPaneArgs *args, UiBool value) { + args->vexpand = value; +} + + +void ui_splitpane_args_set_hfill(UiSplitPaneArgs *args, UiBool value) { + args->hfill = value; +} + + +void ui_splitpane_args_set_vfill(UiSplitPaneArgs *args, UiBool value) { + args->vfill = value; +} + + +void ui_splitpane_args_set_override_defaults(UiSplitPaneArgs *args, UiBool value) { + args->override_defaults = value; +} + + +void ui_splitpane_args_set_colspan(UiSplitPaneArgs *args, int colspan) { + args->colspan = colspan; +} + + +void ui_splitpane_args_set_rowspan(UiSplitPaneArgs *args, int rowspan) { + args->rowspan = rowspan; +} + + +void ui_splitpane_args_set_name(UiSplitPaneArgs *args, const char *name) { + args->name = strdup(name); +} + + +void ui_splitpane_args_set_style_class(UiSplitPaneArgs *args, const char *classname) { + args->style_class = strdup(classname); +} + + +void ui_splitpane_args_set_margin(UiSplitPaneArgs *args, int value) { + args->margin = value; +} + + +void ui_splitpane_args_set_spacing(UiSplitPaneArgs *args, int value) { + args->spacing = value; +} + + +void ui_splitpane_args_set_columnspacing(UiSplitPaneArgs *args, int value) { + args->columnspacing = value; +} + + +void ui_splitpane_args_set_rowspacing(UiSplitPaneArgs *args, int value) { + args->rowspacing = value; +} + + +void ui_splitpane_args_set_initial_position(UiSplitPaneArgs *args, int pos) { + args->initial_position = pos; +} + + +void ui_splitpane_args_set_varname(UiSplitPaneArgs *args, const char *varname) { + args->varname = strdup(varname); +} + + +void ui_splitpane_args_set_value(UiSplitPaneArgs *args, UiInteger *value) { + args->value = value; +} + +void ui_splitpane_args_set_max_panes(UiSplitPaneArgs *args, int max) { + args->max_panes = max; +} + + +void ui_splitpane_args_free(UiSplitPaneArgs *args) { + free((void*)args->name); + free((void*)args->style_class); + free((void*)args->varname); + free(args); +} + + /* ---------------------------- UiButtonArgs -------------------------------*/ UiButtonArgs* ui_button_args_new(void) { UiButtonArgs *args = malloc(sizeof(UiButtonArgs)); - memset(args, 0, sizeof(UiContainerArgs)); + memset(args, 0, sizeof(UiButtonArgs)); return args; } @@ -388,7 +652,7 @@ void ui_button_args_set_colspan(UiButtonArgs *args, int colspan) { } -void ui_button_args_set_rolspan(UiButtonArgs *args, int rowspan) { +void ui_button_args_set_rowspan(UiButtonArgs *args, int rowspan) { args->rowspan = rowspan; } @@ -450,7 +714,7 @@ void ui_button_args_free(UiButtonArgs *args) { UiToggleArgs* ui_toggle_args_new(void) { UiToggleArgs *args = malloc(sizeof(UiToggleArgs)); - memset(args, 0, sizeof(UiContainerArgs)); + memset(args, 0, sizeof(UiToggleArgs)); return args; } @@ -490,7 +754,7 @@ void ui_toggle_args_set_colspan(UiToggleArgs *args, int colspan) { } -void ui_toggle_args_set_rolspan(UiToggleArgs *args, int rowspan) { +void ui_toggle_args_set_rowspan(UiToggleArgs *args, int rowspan) { args->rowspan = rowspan; } @@ -559,3 +823,264 @@ void ui_toggle_args_free(UiToggleArgs *args) { free(args); } + +/* ------------------------- UiListArgs ----------------------------*/ + +UiListArgs* ui_list_args_new(void) { + UiListArgs *args = malloc(sizeof(UiListArgs)); + memset(args, 0, sizeof(UiListArgs)); + return args; +} + +void ui_list_args_set_fill(UiListArgs *args, UiBool fill) { + args->fill = fill ? UI_ON : UI_OFF; +} + +void ui_list_args_set_hexpand(UiListArgs *args, UiBool value) { + args->hexpand = value; +} + +void ui_list_args_set_vexpand(UiListArgs *args, UiBool value) { + args->vexpand = value; +} + +void ui_list_args_set_hfill(UiListArgs *args, UiBool value) { + args->hfill = value; +} + +void ui_list_args_set_vfill(UiListArgs *args, UiBool value) { + args->vfill = value; +} + +void ui_list_args_set_override_defaults(UiListArgs *args, UiBool value) { + args->override_defaults = value; +} + +void ui_list_args_set_colspan(UiListArgs *args, int colspan) { + args->colspan = colspan; +} + +void ui_list_args_set_rowspan(UiListArgs *args, int rowspan) { + args->rowspan = rowspan; +} + +void ui_list_args_set_name(UiListArgs *args, const char *name) { + args->name = strdup(name); +} + +void ui_list_args_set_style_class(UiListArgs *args, const char *classname) { + args->style_class = classname; +} + +void ui_list_args_set_varname(UiListArgs *args, const char *varname) { + args->varname = strdup(varname); +} + +void ui_list_args_set_value(UiListArgs *args, UiList *value) { + args->list = value; +} + +void ui_list_args_set_model(UiListArgs *args, UiModel *model) { + args->model = model; +} + +void ui_list_args_set_static_elements(UiListArgs *args, char **strarray, size_t nelm) { + char **array = calloc(nelm, sizeof(char*)); + for(int i=0;istatic_elements = array; + args->static_nelm = nelm; +} + +void ui_list_args_set_getvalue_func(UiListArgs *args, ui_getvaluefunc getvalue) { + args->getvalue = getvalue; +} + +void ui_list_args_set_getvalue_func2(UiListArgs *args, ui_getvaluefunc2 getvalue) { + args->getvalue2 = getvalue; +} + +void ui_list_args_set_getvalue_data(UiListArgs *args, void *userdata) { + args->getvalue2data = userdata; +} + +void ui_list_args_set_onactivate(UiListArgs *args, ui_callback callback) { + args->onactivate = callback; +} + +void ui_list_args_set_onactivatedata(UiListArgs *args, void *userdata) { + args->onactivatedata = userdata; +} + +void ui_list_args_set_onselection(UiListArgs *args, ui_callback callback) { + args->onselection = callback; +} + +void ui_list_args_set_onselectiondata(UiListArgs *args, void *userdata) { + args->onselectiondata = userdata; +} + +void ui_list_args_set_ondragstart(UiListArgs *args, ui_callback callback) { + args->ondragstart = callback; +} + +void ui_list_args_set_ondragstartdata(UiListArgs *args, void *userdata) { + args->ondragstartdata = userdata; +} + +void ui_list_args_set_ondragcomplete(UiListArgs *args, ui_callback callback) { + args->ondragcomplete = callback; +} + +void ui_list_args_set_ondragcompletedata(UiListArgs *args, void *userdata) { + args->ondragcompletedata = userdata; +} + +void ui_list_args_set_ondrop(UiListArgs *args, ui_callback callback) { + args->ondrop = callback; +} + +void ui_list_args_set_ondropdata(UiListArgs *args, void *userdata) { + args->ondropdata = userdata; +} + +void ui_list_args_set_multiselection(UiListArgs *args, UiBool multiselection) { + args->multiselection = multiselection; +} + +void ui_list_args_set_contextmenu(UiListArgs *args, UiMenuBuilder *menubuilder) { + args->contextmenu = menubuilder; +} + +void ui_list_args_set_groups(UiListArgs *args, int *groups) { + // TODO +} + +void ui_list_args_free(UiListArgs *args) { + free((void*)args->name); + free((void*)args->style_class); + free((void*)args->varname); + if(args->static_elements) { + for(int i=0;istatic_nelm;i++) { + free(args->static_elements[i]); + } + free(args->static_elements); + } + free(args); +} + + + +/* ---------------------- SurceList ------------------------------------- */ + +UiSourceListArgs* ui_sourcelist_args_new(void) { + UiSourceListArgs *args = malloc(sizeof(UiSourceListArgs)); + memset(args, 0, sizeof(UiSourceListArgs)); + return args; +} + + +void ui_sourcelist_args_set_fill(UiSourceListArgs *args, UiBool fill) { + args->fill = fill ? UI_ON : UI_OFF; +} + + +void ui_sourcelist_args_set_hexpand(UiSourceListArgs *args, UiBool value) { + args->hexpand = value; +} + + +void ui_sourcelist_args_set_vexpand(UiSourceListArgs *args, UiBool value) { + args->vexpand = value; +} + + +void ui_sourcelist_args_set_hfill(UiSourceListArgs *args, UiBool value) { + args->hfill = value; +} + + +void ui_sourcelist_args_set_vfill(UiSourceListArgs *args, UiBool value) { + args->vfill = value; +} + + +void ui_sourcelist_args_set_override_defaults(UiSourceListArgs *args, UiBool value) { + args->override_defaults = value; +} + + +void ui_sourcelist_args_set_colspan(UiSourceListArgs *args, int colspan) { + args->colspan = colspan; +} + + +void ui_sourcelist_args_set_rowspan(UiSourceListArgs *args, int rowspan) { + args->rowspan = rowspan; +} + + +void ui_sourcelist_args_set_name(UiSourceListArgs *args, const char *name) { + args->name = strdup(name); +} + + +void ui_sourcelist_args_set_style_class(UiSourceListArgs *args, const char *classname) { + args->style_class = strdup(classname); +} + +UIEXPORT void ui_sourcelist_args_set_static_sublists(UiSourceListArgs *args, UiSubList *sublists, size_t numsublists) { + args->sublists = calloc(numsublists, sizeof(UiSubList)); + memcpy(args->sublists, sublists, numsublists * sizeof(UiSubList)); + args->numsublists = numsublists; +} + +void ui_sourcelist_args_set_varname(UiSourceListArgs *args, const char *varname) { + args->varname = strdup(varname); +} + + +void ui_sourcelist_args_set_dynamic_sublists(UiSourceListArgs *args, UiList *value) { + args->dynamic_sublist = value; +} + + +void ui_sourcelist_args_set_getvalue_func(UiSourceListArgs *args, ui_sublist_getvalue_func getvalue) { + args->getvalue = getvalue; +} + +void ui_sourcelist_args_set_getvalue_userdata(UiSourceListArgs *args, void *userdata) { + args->getvaluedata = userdata; +} + +void ui_sourcelist_args_set_onactivate(UiSourceListArgs *args, ui_callback callback) { + args->onactivate = callback; +} + + +void ui_sourcelist_args_set_onactivatedata(UiSourceListArgs *args, void *userdata) { + args->onactivatedata = userdata; +} + + +void ui_sourcelist_args_set_onbuttonclick(UiSourceListArgs *args, ui_callback callback) { + args->onbuttonclick = callback; + +} + + +void ui_sourcelist_args_set_onbuttonclickdata(UiSourceListArgs *args, void *userdata) { + args->onbuttonclickdata = userdata; +} + + +void ui_sourcelist_args_free(UiSourceListArgs *args) { + free((void*)args->name); + free((void*)args->style_class); + free((void*)args->varname); + free((void*)args->sublists); + free(args); +} + + diff --git a/ui/common/args.h b/ui/common/args.h index ae74837..6499594 100644 --- a/ui/common/args.h +++ b/ui/common/args.h @@ -32,6 +32,8 @@ #include "../ui/container.h" #include "../ui/button.h" #include "../ui/menu.h" +#include "../ui/toolbar.h" +#include "../ui/tree.h" #ifdef __cplusplus extern "C" { @@ -52,7 +54,7 @@ UIEXPORT void ui_menutoggleitem_args_set_stockid(UiMenuToggleItemArgs *args, con UIEXPORT void ui_menutoggleitem_args_set_icon(UiMenuToggleItemArgs *args, const char *icon); 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 *onclickdata); +UIEXPORT void ui_menutoggleitem_args_set_onchangedata(UiMenuToggleItemArgs *args, void *onchangedata); UIEXPORT void ui_menutoggleitem_args_free(UiMenuToggleItemArgs *args); UIEXPORT UiMenuItemListArgs* ui_menuitemlist_args_new(void); @@ -62,6 +64,31 @@ UIEXPORT void ui_menuitemlist_args_set_onselect(UiMenuItemListArgs *args, ui_cal 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_menuitemlist_args_free(UiMenuItemListArgs *args); + +UIEXPORT UiToolbarItemArgs* ui_toolbar_item_args_new(void); +UIEXPORT void ui_toolbar_item_args_set_label(UiToolbarItemArgs *args, const char *label); +UIEXPORT void ui_toolbar_item_args_set_stockid(UiToolbarItemArgs *args, const char *stockid); +UIEXPORT void ui_toolbar_item_args_set_icon(UiToolbarItemArgs *args, const char *icon); +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_groups(UiToolbarItemArgs *args, int *groups); +UIEXPORT void ui_toolbar_item_args_free(UiToolbarItemArgs *args); + +UIEXPORT UiToolbarToggleItemArgs* ui_toolbar_toggleitem_args_new(void); +UIEXPORT void ui_toolbar_toggleitem_args_set_label(UiToolbarToggleItemArgs *args, const char *label); +UIEXPORT void ui_toolbar_toggleitem_args_set_stockid(UiToolbarToggleItemArgs *args, const char *stockid); +UIEXPORT void ui_toolbar_toggleitem_args_set_icon(UiToolbarToggleItemArgs *args, const char *icon); +UIEXPORT void ui_toolbar_toggleitem_args_set_varname(UiToolbarToggleItemArgs *args, const char *varname); +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_groups(UiToolbarToggleItemArgs *args, int *groups); +UIEXPORT void ui_toolbar_toggleitem_args_free(UiToolbarToggleItemArgs *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_stockid(UiToolbarMenuArgs *args, const char *stockid); +UIEXPORT void ui_toolbar_menu_args_set_icon(UiToolbarMenuArgs *args, const char *icon); +UIEXPORT void ui_toolbar_menu_args_free(UiToolbarMenuArgs *args); UIEXPORT UiContainerArgs* ui_container_args_new(void); UIEXPORT void ui_container_args_set_fill(UiContainerArgs *args, UiBool fill); @@ -71,7 +98,7 @@ UIEXPORT void ui_container_args_set_hfill(UiContainerArgs *args, UiBool value); UIEXPORT void ui_container_args_set_vfill(UiContainerArgs *args, UiBool value); UIEXPORT void ui_container_args_set_override_defaults(UiContainerArgs *args, UiBool value); UIEXPORT void ui_container_args_set_colspan(UiContainerArgs *args, int colspan); -UIEXPORT void ui_container_args_set_rolspan(UiContainerArgs *args, int rowspan); +UIEXPORT void ui_container_args_set_rowspan(UiContainerArgs *args, int rowspan); UIEXPORT void ui_container_args_set_def_hexpand(UiContainerArgs *args, UiBool value); UIEXPORT void ui_container_args_set_def_vexpand(UiContainerArgs *args, UiBool value); UIEXPORT void ui_container_args_set_def_hfill(UiContainerArgs *args, UiBool value); @@ -93,7 +120,7 @@ UIEXPORT void ui_frame_args_set_hfill(UiFrameArgs *args, UiBool value); UIEXPORT void ui_frame_args_set_vfill(UiFrameArgs *args, UiBool value); UIEXPORT void ui_frame_args_set_override_defaults(UiFrameArgs *args, UiBool value); UIEXPORT void ui_frame_args_set_colspan(UiFrameArgs *args, int colspan); -UIEXPORT void ui_frame_args_set_rolspan(UiFrameArgs *args, int rowspan); +UIEXPORT void ui_frame_args_set_rowspan(UiFrameArgs *args, int rowspan); UIEXPORT void ui_frame_args_set_name(UiFrameArgs *args, const char *name); UIEXPORT void ui_frame_args_set_style_class(UiFrameArgs *args, const char *classname); UIEXPORT void ui_frame_args_set_margin(UiFrameArgs *args, int value); @@ -104,6 +131,33 @@ UIEXPORT void ui_frame_args_set_expanded(UiFrameArgs *args, UiBool value); UIEXPORT void ui_frame_args_set_label(UiFrameArgs *args, const char *label); UIEXPORT void ui_frame_args_free(UiFrameArgs *args); +UIEXPORT UiSidebarArgs* ui_sidebar_args_new(void); +UIEXPORT void ui_sidebar_args_set_name(UiSidebarArgs *args, const char *name); +UIEXPORT void ui_sidebar_args_set_style_class(UiSidebarArgs *args, const char *classname); +UIEXPORT void ui_sidebar_args_set_margin(UiSidebarArgs *args, int value); +UIEXPORT void ui_sidebar_args_set_spacing(UiSidebarArgs *args, int value); +UIEXPORT void ui_sidebar_args_free(UiSidebarArgs *args); + +UIEXPORT UiSplitPaneArgs* ui_splitpane_args_new(void); +UIEXPORT void ui_splitpane_args_set_fill(UiSplitPaneArgs *args, UiBool fill); +UIEXPORT void ui_splitpane_args_set_hexpand(UiSplitPaneArgs *args, UiBool value); +UIEXPORT void ui_splitpane_args_set_vexpand(UiSplitPaneArgs *args, UiBool value); +UIEXPORT void ui_splitpane_args_set_hfill(UiSplitPaneArgs *args, UiBool value); +UIEXPORT void ui_splitpane_args_set_vfill(UiSplitPaneArgs *args, UiBool value); +UIEXPORT void ui_splitpane_args_set_override_defaults(UiSplitPaneArgs *args, UiBool value); +UIEXPORT void ui_splitpane_args_set_colspan(UiSplitPaneArgs *args, int colspan); +UIEXPORT void ui_splitpane_args_set_rowspan(UiSplitPaneArgs *args, int rowspan); +UIEXPORT void ui_splitpane_args_set_name(UiSplitPaneArgs *args, const char *name); +UIEXPORT void ui_splitpane_args_set_style_class(UiSplitPaneArgs *args, const char *classname); +UIEXPORT void ui_splitpane_args_set_margin(UiSplitPaneArgs *args, int value); +UIEXPORT void ui_splitpane_args_set_spacing(UiSplitPaneArgs *args, int value); +UIEXPORT void ui_splitpane_args_set_columnspacing(UiSplitPaneArgs *args, int value); +UIEXPORT void ui_splitpane_args_set_rowspacing(UiSplitPaneArgs *args, int value); +UIEXPORT void ui_splitpane_args_set_initial_position(UiSplitPaneArgs *args, int pos); +UIEXPORT void ui_splitpane_args_set_varname(UiSplitPaneArgs *args, const char *varname); +UIEXPORT void ui_splitpane_args_set_value(UiSplitPaneArgs *args, UiInteger *value); +UIEXPORT void ui_splitpane_args_set_max_panes(UiSplitPaneArgs *args, int max); +UIEXPORT void ui_splitpane_args_free(UiSplitPaneArgs *args); UIEXPORT UiButtonArgs* ui_button_args_new(void); UIEXPORT void ui_button_args_set_fill(UiButtonArgs *args, UiBool fill); @@ -113,7 +167,7 @@ UIEXPORT void ui_button_args_set_hfill(UiButtonArgs *args, UiBool value); UIEXPORT void ui_button_args_set_vfill(UiButtonArgs *args, UiBool value); UIEXPORT void ui_button_args_set_override_defaults(UiButtonArgs *args, UiBool value); UIEXPORT void ui_button_args_set_colspan(UiButtonArgs *args, int colspan); -UIEXPORT void ui_button_args_set_rolspan(UiButtonArgs *args, int rowspan); +UIEXPORT void ui_button_args_set_rowspan(UiButtonArgs *args, int rowspan); UIEXPORT void ui_button_args_set_name(UiButtonArgs *args, const char *name); UIEXPORT void ui_button_args_set_style_class(UiButtonArgs *args, const char *classname); UIEXPORT void ui_button_args_set_label(UiButtonArgs *args, const char *label); @@ -123,7 +177,7 @@ 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_groups(UiButtonArgs *args, int *groups); - +UIEXPORT void ui_button_args_free(UiButtonArgs *args); UIEXPORT UiToggleArgs* ui_toggle_args_new(void); UIEXPORT void ui_toggle_args_set_fill(UiToggleArgs *args, UiBool fill); @@ -133,7 +187,7 @@ UIEXPORT void ui_toggle_args_set_hfill(UiToggleArgs *args, UiBool value); UIEXPORT void ui_toggle_args_set_vfill(UiToggleArgs *args, UiBool value); UIEXPORT void ui_toggle_args_set_override_defaults(UiToggleArgs *args, UiBool value); UIEXPORT void ui_toggle_args_set_colspan(UiToggleArgs *args, int colspan); -UIEXPORT void ui_toggle_args_set_rolspan(UiToggleArgs *args, int rowspan); +UIEXPORT void ui_toggle_args_set_rowspan(UiToggleArgs *args, int rowspan); UIEXPORT void ui_toggle_args_set_name(UiToggleArgs *args, const char *name); UIEXPORT void ui_toggle_args_set_style_class(UiToggleArgs *args, const char *classname); UIEXPORT void ui_toggle_args_set_label(UiToggleArgs *args, const char *label); @@ -146,7 +200,62 @@ 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_enablegroup(UiToggleArgs *args, int group); UIEXPORT void ui_toggle_args_set_groups(UiToggleArgs *args, int *groups); +UIEXPORT void ui_toggle_args_free(UiToggleArgs *args); + +UIEXPORT UiListArgs* ui_list_args_new(void); +UIEXPORT void ui_list_args_set_fill(UiListArgs *args, UiBool fill); +UIEXPORT void ui_list_args_set_hexpand(UiListArgs *args, UiBool value); +UIEXPORT void ui_list_args_set_vexpand(UiListArgs *args, UiBool value); +UIEXPORT void ui_list_args_set_hfill(UiListArgs *args, UiBool value); +UIEXPORT void ui_list_args_set_vfill(UiListArgs *args, UiBool value); +UIEXPORT void ui_list_args_set_override_defaults(UiListArgs *args, UiBool value); +UIEXPORT void ui_list_args_set_colspan(UiListArgs *args, int colspan); +UIEXPORT void ui_list_args_set_rowspan(UiListArgs *args, int rowspan); +UIEXPORT void ui_list_args_set_name(UiListArgs *args, const char *name); +UIEXPORT void ui_list_args_set_style_class(UiListArgs *args, const char *classname); +UIEXPORT void ui_list_args_set_varname(UiListArgs *args, const char *varname); +UIEXPORT void ui_list_args_set_value(UiListArgs *args, UiList *value); +UIEXPORT void ui_list_args_set_model(UiListArgs *args, UiModel *model); +UIEXPORT void ui_list_args_set_static_elements(UiListArgs *args, char **strarray, size_t nelm); +UIEXPORT void ui_list_args_set_getvalue_func(UiListArgs *args, ui_getvaluefunc getvalue); +UIEXPORT void ui_list_args_set_getvalue_func2(UiListArgs *args, ui_getvaluefunc2 getvalue); +UIEXPORT void ui_list_args_set_getvalue_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_onselection(UiListArgs *args, ui_callback callback); +UIEXPORT void ui_list_args_set_onselectiondata(UiListArgs *args, void *userdata); +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_ondragcomplete(UiListArgs *args, ui_callback callback); +UIEXPORT void ui_list_args_set_ondragcompletedata(UiListArgs *args, void *userdata); +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_multiselection(UiListArgs *args, UiBool multiselection); +UIEXPORT void ui_list_args_set_contextmenu(UiListArgs *args, UiMenuBuilder *menubuilder); +UIEXPORT void ui_list_args_set_groups(UiListArgs *args, int *groups); +UIEXPORT void ui_list_args_free(UiListArgs *args); +UIEXPORT UiSourceListArgs* ui_sourcelist_args_new(void); +UIEXPORT void ui_sourcelist_args_set_fill(UiSourceListArgs *args, UiBool fill); +UIEXPORT void ui_sourcelist_args_set_hexpand(UiSourceListArgs *args, UiBool value); +UIEXPORT void ui_sourcelist_args_set_vexpand(UiSourceListArgs *args, UiBool value); +UIEXPORT void ui_sourcelist_args_set_hfill(UiSourceListArgs *args, UiBool value); +UIEXPORT void ui_sourcelist_args_set_vfill(UiSourceListArgs *args, UiBool value); +UIEXPORT void ui_sourcelist_args_set_override_defaults(UiSourceListArgs *args, UiBool value); +UIEXPORT void ui_sourcelist_args_set_colspan(UiSourceListArgs *args, int colspan); +UIEXPORT void ui_sourcelist_args_set_rowspan(UiSourceListArgs *args, int rowspan); +UIEXPORT void ui_sourcelist_args_set_name(UiSourceListArgs *args, const char *name); +UIEXPORT void ui_sourcelist_args_set_style_class(UiSourceListArgs *args, const char *classname); +UIEXPORT void ui_sourcelist_args_set_static_sublists(UiSourceListArgs *args, UiSubList *sublists, size_t numsublists); +UIEXPORT void ui_sourcelist_args_set_varname(UiSourceListArgs *args, const char *varname); +UIEXPORT void ui_sourcelist_args_set_dynamic_sublists(UiSourceListArgs *args, UiList *value); +UIEXPORT void ui_sourcelist_args_set_getvalue_func(UiSourceListArgs *args, ui_sublist_getvalue_func getvalue); +UIEXPORT void ui_sourcelist_args_set_getvalue_userdata(UiSourceListArgs *args, void *userdata); +UIEXPORT void ui_sourcelist_args_set_onactivate(UiSourceListArgs *args, ui_callback callback); +UIEXPORT void ui_sourcelist_args_set_onactivatedata(UiSourceListArgs *args, void *userdata); +UIEXPORT void ui_sourcelist_args_set_onbuttonclick(UiSourceListArgs *args, ui_callback callback); +UIEXPORT void ui_sourcelist_args_set_onbuttonclickdata(UiSourceListArgs *args, void *userdata); +UIEXPORT void ui_sourcelist_args_free(UiSourceListArgs *args); #ifdef __cplusplus } diff --git a/ui/common/context.c b/ui/common/context.c index db9d850..d0cd53d 100644 --- a/ui/common/context.c +++ b/ui/common/context.c @@ -67,7 +67,7 @@ UiContext* uic_context(UiObject *toplevel, CxMempool *mp) { ctx->groups = cxArrayListCreate(mp->allocator, cx_cmp_int, sizeof(int), 32); ctx->attach_document = uic_context_attach_document; - ctx->detach_document2 = uic_context_detach_document2; + ctx->detach_document2 = uic_context_detach_document; #if UI_GTK2 || UI_GTK3 if(toplevel && toplevel->widget) { @@ -146,7 +146,7 @@ static void uic_context_unbind_vars(UiContext *ctx) { } } -void uic_context_detach_document2(UiContext *ctx, void *document) { +void uic_context_detach_document(UiContext *ctx, void *document) { // find the document in the documents list size_t docIndex = cxListFind(ctx->documents, document); if(!cxListIndexValid(ctx->documents, docIndex)) { @@ -409,7 +409,7 @@ void uic_unbind_var(UiVar *var) { } } -void uic_reg_var(UiContext *ctx, char *name, UiVarType type, void *value) { +void uic_reg_var(UiContext *ctx, const char *name, UiVarType type, void *value) { // TODO: do we need/want this? Why adding vars to a context after // widgets reference these? Workarounds: // 1. add vars to ctx before creating ui @@ -467,8 +467,8 @@ void ui_attach_document(UiContext *ctx, void *document) { uic_context_attach_document(ctx, document); } -void ui_detach_document2(UiContext *ctx, void *document) { - uic_context_detach_document2(ctx, document); +void ui_detach_document(UiContext *ctx, void *document) { + uic_context_detach_document(ctx, document); } void ui_context_closefunc(UiContext *ctx, ui_callback fnc, void *udata) { @@ -476,7 +476,7 @@ void ui_context_closefunc(UiContext *ctx, ui_callback fnc, void *udata) { ctx->close_data = udata; } -UIEXPORT void ui_context_destroy(UiContext *ctx) { +void ui_context_destroy(UiContext *ctx) { CxIterator i = cxListIterator(ctx->destroy_handler); cx_foreach(UiDestroyHandler *, h, i) { h->destructor(h->data); @@ -484,6 +484,10 @@ UIEXPORT void ui_context_destroy(UiContext *ctx) { cxMempoolFree(ctx->mp); } +UiContext* ui_context_parent(UiContext *ctx) { + return ctx->parent; +} + void ui_set_group(UiContext *ctx, int group) { if(!cxListIndexValid(ctx->groups, cxListFind(ctx->groups, &group))) { diff --git a/ui/common/context.h b/ui/common/context.h index e0ce3de..4fdcfe6 100644 --- a/ui/common/context.h +++ b/ui/common/context.h @@ -119,15 +119,13 @@ void uic_init_global_context(void); 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_set_document(UiContext *ctx, void *document); // deprecated -void uic_context_detach_document(UiContext *ctx); // deprecated void uic_context_prepare_close(UiContext *ctx); void uic_context_attach_document(UiContext *ctx, void *document); -void uic_context_detach_document2(UiContext *ctx, void *document); -void uic_context_attach_context(UiContext *ctx, UiContext *doc_ctx); -void uic_context_detach_context(UiContext *ctx, UiContext *doc_ctx); +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); UiVar* uic_get_var(UiContext *ctx, const char *name); @@ -141,7 +139,7 @@ void uic_copy_binding(UiVar *from, UiVar *to, UiBool copytodoc); void uic_save_var2(UiVar *var); void uic_unbind_var(UiVar *var); -void uic_reg_var(UiContext *ctx, char *name, UiVarType type, void *value); +void uic_reg_var(UiContext *ctx, const char *name, UiVarType type, void *value); void uic_remove_bound_var(UiContext *ctx, UiVar *var); diff --git a/ui/common/document.c b/ui/common/document.c index 07177bd..b2b2fba 100644 --- a/ui/common/document.c +++ b/ui/common/document.c @@ -44,44 +44,6 @@ void uic_docmgr_init() { } } -void ui_set_document(UiObject *obj, void *document) { - uic_context_detach_all(obj->ctx); - obj->ctx->attach_document(obj->ctx, document); -} - -void ui_detach_document(UiObject *obj) { - uic_context_detach_all(obj->ctx); -} - -void* ui_get_document(UiObject *obj) { - return obj->ctx->document; -} - -void ui_set_subdocument(void *document, void *sub) { - UiContext *ctx = ui_document_context(document); - if(!ctx) { - fprintf(stderr, "UI Error: pointer is not a document\n"); - } - // TODO -} - -void ui_detach_subdocument(void *document, void *sub) { - UiContext *ctx = ui_document_context(document); - if(!ctx) { - fprintf(stderr, "UI Error: pointer is not a document\n"); - } - // TODO -} - -void* ui_get_subdocument(void *document) { - UiContext *ctx = ui_document_context(document); - if(!ctx) { - fprintf(stderr, "UI Error: pointer is not a document\n"); - } - // TODO - return NULL; -} - void* ui_document_new(size_t size) { CxMempool *mp = cxMempoolCreateSimple(256); const CxAllocator *a = mp->allocator; diff --git a/ui/common/object.c b/ui/common/object.c index 2c10597..9a42ce4 100644 --- a/ui/common/object.c +++ b/ui/common/object.c @@ -32,8 +32,48 @@ #include "object.h" #include "context.h" +#include + #include "../ui/container.h" +static CxList *creation_callbacks; +static CxList *destruction_callbacks; + +typedef struct objcallback { + ui_object_callback func; + void *userdata; +} objcallback; + +void ui_register_object_creation_callback(ui_object_callback func, void *userdata) { + if(!creation_callbacks) { + creation_callbacks = cxLinkedListCreateSimple(sizeof(objcallback)); + } + objcallback cb = { func, userdata }; + cxListAdd(creation_callbacks, &cb); +} + +void ui_register_object_destruction_callback(ui_object_callback func, void *userdata) { + if(!destruction_callbacks) { + destruction_callbacks = cxLinkedListCreateSimple(sizeof(objcallback)); + } + objcallback cb = { func, userdata }; + cxListAdd(destruction_callbacks, &cb); +} + +void uic_object_created(UiObject *obj) { + CxIterator i = cxListIterator(creation_callbacks); + cx_foreach(objcallback *, cb, i) { + cb->func(obj, cb->userdata); + } +} + +void uic_object_destroyed(UiObject *obj) { + CxIterator i = cxListIterator(destruction_callbacks); + cx_foreach(objcallback *, cb, i) { + cb->func(obj, cb->userdata); + } +} + void ui_end(UiObject *obj) { if(!obj->next) { return; @@ -87,9 +127,18 @@ void uic_object_destroy(UiObject *obj) { ev.intval = 0; obj->ctx->close_callback(&ev, obj->ctx->close_data); } + uic_object_destroyed(obj); cxMempoolFree(obj->ctx->mp); } +UiObject* uic_object_new_toplevel(void) { + CxMempool *mp = cxMempoolCreateSimple(256); + UiObject *obj = cxCalloc(mp->allocator, 1, sizeof(UiObject)); + obj->ctx = uic_context(obj, mp); + uic_object_created(obj); + return obj; +} + UiObject* uic_object_new(UiObject *toplevel, UIWIDGET widget) { return uic_ctx_object_new(toplevel->ctx, widget); } @@ -98,7 +147,7 @@ UiObject* uic_ctx_object_new(UiContext *ctx, UIWIDGET widget) { UiObject *newobj = cxCalloc(ctx->allocator, 1, sizeof(UiObject)); newobj->ctx = ctx; newobj->widget = widget; - + uic_object_created(newobj); return newobj; } diff --git a/ui/common/object.h b/ui/common/object.h index a5011a0..45cf683 100644 --- a/ui/common/object.h +++ b/ui/common/object.h @@ -35,8 +35,17 @@ extern "C" { #endif +typedef void (*ui_object_callback)(UiObject *obj, void *userdata); + +void ui_register_object_creation_callback(ui_object_callback func, void *userdata); +void ui_register_object_destruction_callback(ui_object_callback func, void *userdata); + +void uic_object_created(UiObject *obj); +void uic_object_destroyed(UiObject *obj); + void uic_object_destroy(UiObject *obj); +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_obj_add(UiObject *toplevel, UiObject *ctobj); diff --git a/ui/common/objs.mk b/ui/common/objs.mk index 586e88d..a126b56 100644 --- a/ui/common/objs.mk +++ b/ui/common/objs.mk @@ -40,6 +40,7 @@ COMMON_OBJ += ucx_properties$(OBJ_EXT) COMMON_OBJ += threadpool$(OBJ_EXT) COMMON_OBJ += condvar$(OBJ_EXT) COMMON_OBJ += args$(OBJ_EXT) +COMMON_OBJ += wrapper$(OBJ_EXT) TOOLKITOBJS += $(COMMON_OBJ:%=$(COMMON_OBJPRE)uic_%) TOOLKITSOURCE += $(COMMON_OBJ:%$(OBJ_EXT)=common/%.c) diff --git a/ui/common/types.c b/ui/common/types.c index b87cc3f..024ec0b 100644 --- a/ui/common/types.c +++ b/ui/common/types.c @@ -38,7 +38,8 @@ #include "context.h" #include "../ui/image.h" - +static ui_list_init_func default_list_init; +static void *default_list_init_userdata; UiObserver* ui_observer_new(ui_callback f, void *data) { UiObserver *observer = malloc(sizeof(UiObserver)); @@ -95,20 +96,22 @@ void ui_notify_evt(UiObserver *observer, UiEvent *event) { /* --------------------------- UiList --------------------------- */ -UiList* ui_list_new(UiContext *ctx, char *name) { - UiList *list = malloc(sizeof(UiList)); +void uic_ucx_list_init(UiContext *ctx, UiList *list, void *unused) { + list->data = cxArrayListCreate(ctx->mp->allocator, NULL, CX_STORE_POINTERS, 32); list->first = ui_list_first; list->next = ui_list_next; list->get = ui_list_get; list->count = ui_list_count; - list->observers = NULL; - - list->data = cxArrayListCreate(cxDefaultAllocator, NULL, CX_STORE_POINTERS, 32); - list->iter = NULL; - - list->update = NULL; - list->getselection = NULL; - list->obj = NULL; +} + +UiList* ui_list_new(UiContext *ctx, const char *name) { + return ui_list_new2(ctx, name, default_list_init ? default_list_init : uic_ucx_list_init, default_list_init_userdata); +} + +UiList* ui_list_new2(UiContext *ctx, const char *name, ui_list_init_func listinit, void *userdata) { + UiList *list = cxMalloc(ctx->mp->allocator, sizeof(UiList)); + memset(list, 0, sizeof(UiList)); + listinit(ctx, list, userdata); if(name) { uic_reg_var(ctx, name, UI_VAR_LIST, list); @@ -249,7 +252,7 @@ void ui_model_free(UiContext *ctx, UiModel *mi) { // types // public functions -UiInteger* ui_int_new(UiContext *ctx, char *name) { +UiInteger* ui_int_new(UiContext *ctx, const char *name) { UiInteger *i = ui_malloc(ctx, sizeof(UiInteger)); memset(i, 0, sizeof(UiInteger)); if(name) { @@ -258,7 +261,7 @@ UiInteger* ui_int_new(UiContext *ctx, char *name) { return i; } -UiDouble* ui_double_new(UiContext *ctx, char *name) { +UiDouble* ui_double_new(UiContext *ctx, const char *name) { UiDouble *d = ui_malloc(ctx, sizeof(UiDouble)); memset(d, 0, sizeof(UiDouble)); if(name) { @@ -267,7 +270,7 @@ UiDouble* ui_double_new(UiContext *ctx, char *name) { return d; } -UiString* ui_string_new(UiContext *ctx, char *name) { +UiString* ui_string_new(UiContext *ctx, const char *name) { UiString *s = ui_malloc(ctx, sizeof(UiString)); memset(s, 0, sizeof(UiString)); if(name) { @@ -276,7 +279,7 @@ UiString* ui_string_new(UiContext *ctx, char *name) { return s; } -UiText* ui_text_new(UiContext *ctx, char *name) { +UiText* ui_text_new(UiContext *ctx, const char *name) { UiText *t = ui_malloc(ctx, sizeof(UiText)); memset(t, 0, sizeof(UiText)); if(name) { @@ -285,7 +288,7 @@ UiText* ui_text_new(UiContext *ctx, char *name) { return t; } -UiRange* ui_range_new(UiContext *ctx, char *name) { +UiRange* ui_range_new(UiContext *ctx, const char *name) { UiRange *r = ui_malloc(ctx, sizeof(UiRange)); memset(r, 0, sizeof(UiRange)); if(name) { @@ -294,7 +297,7 @@ UiRange* ui_range_new(UiContext *ctx, char *name) { return r; } -UIEXPORT UiGeneric* ui_generic_new(UiContext *ctx, char *name) { +UIEXPORT UiGeneric* ui_generic_new(UiContext *ctx, const char *name) { UiGeneric *g = ui_malloc(ctx, sizeof(UiGeneric)); memset(g, 0, sizeof(UiGeneric)); if(name) { @@ -661,3 +664,34 @@ void ui_setop_enable(int set) { int ui_get_setop(void) { return ui_set_op; } + +/* ---------------- List initializers and wrapper functions ---------------- */ + +void ui_global_list_initializer(ui_list_init_func func, void *userdata) { + default_list_init = func; + default_list_init_userdata = userdata; +} + +void ui_list_class_set_first(UiList *list, void*(*first)(UiList *list)) { + list->first = first; +} + +void ui_list_class_set_next(UiList *list, void*(*next)(UiList *list)) { + list->next = next; +} + +void ui_list_class_set_get(UiList *list, void*(*get)(UiList *list, int i)) { + list->get = get; +} + +void ui_list_class_set_count(UiList *list, int(*count)(UiList *list)) { + list->count = count; +} + +void ui_list_class_set_data(UiList *list, void *data) { + list->data = data; +} + +void ui_list_class_set_iter(UiList *list, void *iter) { + list->iter = iter; +} diff --git a/ui/common/types.h b/ui/common/types.h index 677199f..46d6c2e 100644 --- a/ui/common/types.h +++ b/ui/common/types.h @@ -34,8 +34,9 @@ #ifdef __cplusplus extern "C" { #endif - - + +void uic_ucx_list_init(UiContext *ctx, UiList *list, void *unused); + void uic_int_copy(UiInteger *from, UiInteger *to); void uic_double_copy(UiDouble *from, UiDouble *to); void uic_string_copy(UiString *from, UiString *to); diff --git a/ui/common/wrapper.c b/ui/common/wrapper.c new file mode 100644 index 0000000..04b7430 --- /dev/null +++ b/ui/common/wrapper.c @@ -0,0 +1,188 @@ +/* + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. + * + * Copyright 2025 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 "wrapper.h" +#include "types.h" +#include + +/* ---------------------------- UiObject ---------------------------- */ + +UiContext* ui_object_get_context(UiObject *obj) { + return obj->ctx; +} + +void* ui_object_get_windowdata(UiObject *obj) { + return obj->window; +} + +void ui_object_set_windowdata(UiObject *obj, void *windowdata) { + obj->window = windowdata; +} + + +/* ---------------------------- UiList ---------------------------- */ + +void* ui_list_get_data(UiList *list) { + return list->data; +} + +void ui_list_set_data(UiList *list, void *data) { + list->data = data; +} + +void* ui_list_get_iter(UiList *list) { + return list->iter; +} + +void ui_list_set_iter(UiList *list, void *iter) { + list->iter = iter; +} + + +/* ------------------------------ UiSublist ------------------------------ */ + +UiSubList* ui_sublist_new(void) { + UiSubList *sublist = malloc(sizeof(UiSubList)); + memset(sublist, 0, sizeof(UiSubList)); + return sublist; +} + +void ui_sublist_set_value(UiSubList *sublist, UiList *value) { + sublist->value = value; +} + +void ui_sublist_set_varname(UiSubList *sublist, const char *varname) { + free((void*)sublist->varname); + sublist->varname = strdup(varname); +} + +void ui_sublist_set_header(UiSubList *sublist, const char *header) { + free((void*)sublist->header); + sublist->header = strdup(header); +} + +void ui_sublist_set_separator(UiSubList *sublist, UiBool separator) { + sublist->separator = separator; +} + +void ui_sublist_set_userdata(UiSubList *sublist, void *userdata) { + sublist->userdata = userdata; +} + +void ui_sublist_free(UiSubList *sublist) { + free((void*)sublist->varname); + free((void*)sublist->header); + free(sublist); +} + + +/* -------------------- Source list (UiList) -------------------- */ + +UiList* ui_srclist_new(UiContext *ctx, const char *name) { + UiList *list = ui_list_new2(ctx, name, uic_ucx_list_init, NULL); + CxList *cxlist = list->data; + cxlist->collection.simple_destructor = (cx_destructor_func)ui_sublist_free; + return list; +} + +void ui_srclist_add(UiList *list, UiSubList *item) { + ui_list_append(list, item); +} + +void ui_srclist_insert(UiList *list, int index, UiSubList *item) { + CxList *cxlist = list->data; + cxListInsert(cxlist, index, item); +} + +void ui_srclist_remove(UiList *list, int index) { + CxList *cxlist = list->data; + cxListRemove(cxlist, index); +} + +void ui_srclist_clear(UiList *list) { + CxList *cxlist = list->data; + cxListClear(cxlist); +} + +int ui_srclist_size(UiList *list) { + return ui_list_count(list); +} + + +/* ---------------------------- UiEvent ---------------------------- */ + +UiObject* ui_event_get_obj(UiEvent *event) { + return event->obj; +} + +void* ui_event_get_document(UiEvent *event) { + return event->document; +} + +void* ui_event_get_windowdata(UiEvent *event) { + return event->window; +} + +void* ui_event_get_eventdata(UiEvent *event) { + return event->eventdata; +} + +int ui_event_get_int(UiEvent *event) { + return event->intval; +} + +int ui_event_get_set(UiEvent *event) { + return event->set; +} + + +/* ------------------------- SubListItem (public) ------------------------- */ + +void ui_sublist_item_set_icon(UiSubListItem *item, const char *icon) { + item->icon = icon ? strdup(icon) : NULL; +} + +void ui_sublist_item_set_label(UiSubListItem *item, const char *label) { + item->label = label ? strdup(label) : NULL; +} + +void ui_sublist_item_set_button_icon(UiSubListItem *item, const char *button_icon) { + item->button_icon = button_icon ? strdup(button_icon) : NULL; +} + +void ui_sublist_item_set_button_label(UiSubListItem *item, const char *button_label) { + item->button_label = button_label ? strdup(button_label) : NULL; +} + +void ui_sublist_item_set_badge(UiSubListItem *item, const char *badge) { + item->badge = badge ? strdup(badge) : NULL; +} + +void ui_sublist_item_set_eventdata(UiSubListItem *item, void *eventdata) { + item->eventdata = NULL; +} diff --git a/ui/common/wrapper.h b/ui/common/wrapper.h new file mode 100644 index 0000000..02794b1 --- /dev/null +++ b/ui/common/wrapper.h @@ -0,0 +1,76 @@ +/* + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. + * + * Copyright 2025 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_WRAPPER_H +#define UIC_WRAPPER_H + +#include "../ui/toolkit.h" +#include "../ui/tree.h" + +#ifdef __cplusplus +extern "C" { +#endif + +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_list_get_data(UiList *list); +UIEXPORT void* ui_list_get_iter(UiList *list); +UIEXPORT void ui_list_set_iter(UiList *list, void *iter); + +UIEXPORT UiSubList* ui_sublist_new(void); +UIEXPORT void ui_sublist_set_value(UiSubList *sublist, UiList *value); +UIEXPORT void ui_sublist_set_varname(UiSubList *sublist, const char *varname); +UIEXPORT void ui_sublist_set_header(UiSubList *sublist, const char *header); +UIEXPORT void ui_sublist_set_separator(UiSubList *sublist, UiBool separator); +UIEXPORT void ui_sublist_set_userdata(UiSubList *sublist, void *userdata); +UIEXPORT void ui_sublist_free(UiSubList *sublist); + +UIEXPORT UiList* ui_srclist_new(UiContext *ctx, const char *name); +UIEXPORT void ui_srclist_add(UiList *list, UiSubList *item); +UIEXPORT void ui_srclist_insert(UiList *list, int index, UiSubList *item); +UIEXPORT void ui_srclist_remove(UiList *list, int index); +UIEXPORT void ui_srclist_clear(UiList *list); +UIEXPORT int ui_srclist_size(UiList *list); + +UIEXPORT UiObject* ui_event_get_obj(UiEvent *event); +UIEXPORT void* ui_event_get_document(UiEvent *event); +UIEXPORT void* ui_event_get_windowdata(UiEvent *event); +UIEXPORT void* ui_event_get_eventdata(UiEvent *event); +UIEXPORT int ui_event_get_int(UiEvent *event); +UIEXPORT int ui_event_get_set(UiEvent *event); + + + +#ifdef __cplusplus +} +#endif + +#endif /* UIC_WRAPPER_H */ + diff --git a/ui/gtk/list.c b/ui/gtk/list.c index 2b2772c..ea96fb0 100644 --- a/ui/gtk/list.c +++ b/ui/gtk/list.c @@ -48,6 +48,15 @@ void* ui_strmodel_getvalue(void *elm, int column) { return column == 0 ? elm : NULL; } +static void* model_getvalue(UiModel *model, UiList *list, void *elm, int row, int col, UiBool *freeResult) { + if(model->getvalue2) { + return model->getvalue2(list, elm, row, col, model->getvalue2data, freeResult); + } else if(model->getvalue) { + return model->getvalue(elm, col); + } + return NULL; +} + /* static GtkTargetEntry targetentries[] = { @@ -73,6 +82,7 @@ static void listview_copy_static_elements(UiListView *listview, char **elm, size typedef struct _ObjWrapper { GObject parent_instance; void *data; + int i; } ObjWrapper; typedef struct _ObjWrapperClass { @@ -89,9 +99,10 @@ static void obj_wrapper_init(ObjWrapper *self) { self->data = NULL; } -ObjWrapper* obj_wrapper_new(void* data) { +ObjWrapper* obj_wrapper_new(void* data, int i) { ObjWrapper *obj = g_object_new(obj_wrapper_get_type(), NULL); obj->data = data; + obj->i = i; return obj; } @@ -122,20 +133,21 @@ static void column_factory_setup(GtkListItemFactory *factory, GtkListItem *item, static void column_factory_bind( GtkListItemFactory *factory, GtkListItem *item, gpointer userdata) { UiColData *col = userdata; + UiList *list = col->listview->var->value; ObjWrapper *obj = gtk_list_item_get_item(item); UiModel *model = col->listview->model; UiModelType type = model->types[col->model_column]; - void *data = model->getvalue(obj->data, col->data_column); + UiBool freevalue = FALSE; + void *data = model_getvalue(model, list, obj->data, obj->i, col->data_column, &freevalue); GtkWidget *child = gtk_list_item_get_child(item); - bool freevalue = TRUE; switch(type) { - case UI_STRING: { - freevalue = FALSE; - } case UI_STRING_FREE: { + freevalue = TRUE; + } + case UI_STRING: { gtk_label_set_label(GTK_LABEL(child), data); if(freevalue) { free(data); @@ -157,10 +169,13 @@ static void column_factory_bind( GtkListItemFactory *factory, GtkListItem *item, break; } case UI_ICON_TEXT: { - freevalue = FALSE; + } case UI_ICON_TEXT_FREE: { - void *data2 = model->getvalue(obj->data, col->data_column+1); + void *data2 = model_getvalue(model, list, obj->data, obj->i, col->data_column+1, &freevalue); + if(type == UI_ICON_TEXT_FREE) { + freevalue = TRUE; + } GtkWidget *image = g_object_get_data(G_OBJECT(child), "image"); GtkWidget *label = g_object_get_data(G_OBJECT(child), "label"); if(data && image) { @@ -203,7 +218,7 @@ static UiListView* create_listview(UiObject *obj, UiListArgs *args) { tableview->ondragcomplete = args->ondragcomplete; tableview->ondragcompletedata = args->ondragcompletedata; tableview->ondrop = args->ondrop; - tableview->ondropdata = args->ondropsdata; + tableview->ondropdata = args->ondropdata; tableview->selection.count = 0; tableview->selection.rows = NULL; return tableview; @@ -215,7 +230,14 @@ UIWIDGET ui_listview_create(UiObject *obj, UiListArgs *args) { // to simplify things and share code with ui_table_create, we also // use a UiModel for the listview UiModel *model = ui_model(obj->ctx, UI_STRING, "", -1); - model->getvalue = args->getvalue ? args->getvalue : ui_strmodel_getvalue; + if(args->getvalue2) { + model->getvalue2 = args->getvalue2; + model->getvalue2data = args->getvalue2data; + } else if(args->getvalue) { + model->getvalue = args->getvalue; + } else { + model->getvalue = ui_strmodel_getvalue; + } args->model = model; GListStore *ls = g_list_store_new(G_TYPE_OBJECT); @@ -298,7 +320,14 @@ UIWIDGET ui_combobox_create(UiObject *obj, UiListArgs *args) { // to simplify things and share code with ui_tableview_create, we also // use a UiModel for the listview UiModel *model = ui_model(obj->ctx, UI_STRING, "", -1); - model->getvalue = args->getvalue ? args->getvalue : ui_strmodel_getvalue; + if(args->getvalue2) { + model->getvalue2 = args->getvalue2; + model->getvalue2data = args->getvalue2data; + } else if(args->getvalue) { + model->getvalue = args->getvalue; + } else { + model->getvalue = ui_strmodel_getvalue; + } args->model = model; GListStore *ls = g_list_store_new(G_TYPE_OBJECT); @@ -569,9 +598,10 @@ void ui_dropdown_activate(GtkDropDown* self, gpointer userdata) { void ui_update_liststore(GListStore *liststore, UiList *list) { g_list_store_remove_all(liststore); + int i = 0; void *elm = list->first(list); while(elm) { - ObjWrapper *obj = obj_wrapper_new(elm); + ObjWrapper *obj = obj_wrapper_new(elm, i++); g_list_store_append(liststore, obj); elm = list->next(list); } @@ -580,7 +610,7 @@ void ui_update_liststore(GListStore *liststore, UiList *list) { void ui_update_liststore_static(GListStore *liststore, char **elm, size_t nelm) { g_list_store_remove_all(liststore); for(int i=0;iget(list, i); if(value) { - ObjWrapper *obj = obj_wrapper_new(value); + ObjWrapper *obj = obj_wrapper_new(value, i); // TODO: if index i is selected, the selection is lost // is it possible to update the item without removing it? int count = g_list_model_get_n_items(G_LIST_MODEL(view->liststore)); @@ -662,19 +692,22 @@ void ui_combobox_setselection(UiList *list, UiListSelection selection) { #else -static void update_list_row(GtkListStore *store, GtkTreeIter *iter, UiModel *model, void *elm) { +static void update_list_row(GtkListStore *store, GtkTreeIter *iter, UiModel *model, UiList *list, void *elm, int row) { // set column values int c = 0; for(int i=0;icolumns;i++,c++) { - void *data = model->getvalue(elm, c); + UiBool freevalue = FALSE; + void *data = model_getvalue(model, list, elm, row, c, &freevalue); GValue value = G_VALUE_INIT; switch(model->types[i]) { - case UI_STRING: case UI_STRING_FREE: { + freevalue = TRUE; + } + case UI_STRING: { g_value_init(&value, G_TYPE_STRING); g_value_set_string(&value, data); - if(model->types[i] == UI_STRING_FREE) { + if(freevalue) { free(data); } break; @@ -727,11 +760,12 @@ static void update_list_row(GtkListStore *store, GtkTreeIter *iter, UiModel *mod } #endif c++; - - char *str = model->getvalue(elm, c); + + freevalue = FALSE; + char *str = model_getvalue(model, list, elm, row, c, &freevalue); g_value_init(&value, G_TYPE_STRING); g_value_set_string(&value, str); - if(model->types[i] == UI_ICON_TEXT_FREE) { + if(model->types[i] == UI_ICON_TEXT_FREE || freevalue) { free(str); } break; @@ -764,12 +798,13 @@ static GtkListStore* create_list_store(UiList *list, UiModel *model) { if(list) { void *elm = list->first(list); + int i = 0; while(elm) { // insert new row GtkTreeIter iter; gtk_list_store_insert (store, &iter, -1); - update_list_row(store, &iter, model, elm); + update_list_row(store, &iter, model, list, elm, i++); // next row elm = list->next(list); @@ -803,7 +838,14 @@ UIWIDGET ui_listview_create(UiObject *obj, UiListArgs *args) { #endif UiModel *model = ui_model(obj->ctx, UI_STRING, "", -1); - model->getvalue = args->getvalue ? args->getvalue : ui_strmodel_getvalue; + if(args->getvalue2) { + model->getvalue2 = args->getvalue2; + model->getvalue2data = args->getvalue2data; + } else if(args->getvalue) { + model->getvalue = args->getvalue; + } else { + model->getvalue = ui_strmodel_getvalue; + } UiVar* var = uic_widget_var(obj->ctx, current->ctx, args->list, args->varname, UI_VAR_LIST); @@ -982,7 +1024,7 @@ UIWIDGET ui_table_create(UiObject *obj, UiListArgs *args) { tableview->ondragcomplete = args->ondragcomplete; tableview->ondragcompletedata = args->ondragcompletedata; tableview->ondrop = args->ondrop; - tableview->ondropdata = args->ondropsdata; + tableview->ondropdata = args->ondropdata; tableview->selection.count = 0; tableview->selection.rows = NULL; g_signal_connect( @@ -1075,7 +1117,7 @@ void ui_listview_update(UiList *list, int i) { GtkTreeModel *store = gtk_tree_view_get_model(GTK_TREE_VIEW(view->widget)); GtkTreeIter iter; if(gtk_tree_model_iter_nth_child(store, &iter, NULL, i)) { - update_list_row(GTK_LIST_STORE(store), &iter, view->model, elm); + update_list_row(GTK_LIST_STORE(store), &iter, view->model, list, elm, i); } } } @@ -1106,7 +1148,14 @@ UIWIDGET ui_combobox_create(UiObject *obj, UiListArgs *args) { UiObject* current = uic_current_obj(obj); UiModel *model = ui_model(obj->ctx, UI_STRING, "", -1); - model->getvalue = args->getvalue ? args->getvalue : ui_strmodel_getvalue; + if(args->getvalue2) { + model->getvalue2 = args->getvalue2; + model->getvalue2data = args->getvalue2data; + } else if(args->getvalue) { + model->getvalue = args->getvalue; + } else { + model->getvalue = ui_strmodel_getvalue; + } UiVar* var = uic_widget_var(obj->ctx, current->ctx, args->list, args->varname, UI_VAR_LIST); @@ -1786,6 +1835,7 @@ UIEXPORT UIWIDGET ui_sourcelist_create(UiObject *obj, UiSourceListArgs *args) { uilistbox->obj = obj; uilistbox->listbox = GTK_LIST_BOX(listbox); uilistbox->getvalue = args->getvalue; + uilistbox->getvaluedata = args->getvaluedata; uilistbox->onactivate = args->onactivate; uilistbox->onactivatedata = args->onactivatedata; uilistbox->onbuttonclick = args->onbuttonclick; @@ -1958,7 +2008,7 @@ void ui_listbox_update_sublist(UiListBox *listbox, UiListBoxSubList *sublist, si void *elm = list->first(list); while(elm) { UiSubListItem item = { NULL, NULL, NULL, NULL, NULL, NULL }; - listbox->getvalue(sublist->userdata, elm, index, &item); + listbox->getvalue(sublist->userdata, elm, index, &item, listbox->getvaluedata); // create listbox item GtkWidget *row = create_listbox_row(listbox, sublist, &item, (int)index); diff --git a/ui/gtk/list.h b/ui/gtk/list.h index 784e644..bd490ab 100644 --- a/ui/gtk/list.h +++ b/ui/gtk/list.h @@ -98,6 +98,7 @@ struct UiListBox { GtkListBox *listbox; CxList *sublists; // contains UiListBoxSubList elements ui_sublist_getvalue_func getvalue; + void *getvaluedata; ui_callback onactivate; void *onactivatedata; ui_callback onbuttonclick; diff --git a/ui/gtk/window.c b/ui/gtk/window.c index ca284c0..1d03948 100644 --- a/ui/gtk/window.c +++ b/ui/gtk/window.c @@ -102,9 +102,7 @@ static gboolean close_request(GtkWidget* self, GdkEvent* event, UiObject *obj) { #endif static UiObject* create_window(const char *title, void *window_data, UiBool sidebar, UiBool simple) { - CxMempool *mp = cxMempoolCreateSimple(256); - UiObject *obj = cxCalloc(mp->allocator, 1, sizeof(UiObject)); - obj->ref = 0; + UiObject *obj = uic_object_new_toplevel(); #ifdef UI_LIBADWAITA obj->widget = adw_application_window_new(ui_get_application()); @@ -114,8 +112,6 @@ static UiObject* create_window(const char *title, void *window_data, UiBool side obj->widget = gtk_window_new(GTK_WINDOW_TOPLEVEL); #endif - - obj->ctx = uic_context(obj, mp); obj->window = window_data; #if GTK_CHECK_VERSION(4, 0, 0) @@ -761,9 +757,7 @@ UiObject* ui_dialog_window_create(UiObject *parent, UiDialogWindowArgs args) { gtk_window_set_modal(GTK_WINDOW(dialog), TRUE); } - CxMempool *mp = cxMempoolCreateSimple(256); - UiObject *obj = cxCalloc(mp->allocator, 1, sizeof(UiObject)); - obj->ctx = uic_context(obj, mp); + UiObject *obj = uic_object_new_toplevel(); obj->widget = dialog; obj->ref = 0; obj->destroy = ui_window_widget_destroy; diff --git a/ui/motif/image.c b/ui/motif/image.c index b3b8a11..5f4e778 100644 --- a/ui/motif/image.c +++ b/ui/motif/image.c @@ -6,3 +6,12 @@ #include "image.h" + + +void ui_image_ref(UIIMAGE img) { + // TODO +} + +void ui_image_unref(UIIMAGE img) { + // TODO +} diff --git a/ui/motif/list.c b/ui/motif/list.c index 4a6a143..aa65be9 100644 --- a/ui/motif/list.c +++ b/ui/motif/list.c @@ -34,6 +34,22 @@ #include "list.h" #include "../common/object.h" +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* model_getvalue(UiModel *model, UiList *list, void *elm, int row, int col, UiBool *freeResult) { + if(model->getvalue2) { + return model->getvalue2(list, elm, row, col, model->getvalue2data, freeResult); + } else if(model->getvalue) { + return model->getvalue(elm, col); + } + return NULL; +} +*/ + UIWIDGET ui_listview_create(UiObject* obj, UiListArgs *args) { Arg xargs[16]; int n = 0; @@ -58,7 +74,16 @@ UIWIDGET ui_listview_create(UiObject* obj, UiListArgs *args) { memset(listview, 0, sizeof(UiListView)); listview->obj = obj; listview->widget = widget; - listview->getvalue = args->getvalue ? args->getvalue : ui_strmodel_getvalue; + if(args->getvalue2) { + listview->getvalue = args->getvalue2; + listview->getvaluedata = args->getvalue2data; + } else if(args->getvalue) { + listview->getvalue = getvalue_wrapper; + listview->getvaluedata = args->getvalue; + } else { + listview->getvalue = getvalue_wrapper; + listview->getvaluedata = ui_strmodel_getvalue; + } listview->var = var; listview->onactivate = args->onactivate; listview->onactivatedata = args->onactivatedata; @@ -139,13 +164,17 @@ void ui_listview_selection(Widget w, UiListView *listview, XmListCallbackStruct } } -static XmStringTable create_stringlist(UiList *list, ui_getvaluefunc getvalue, int *count) { +static XmStringTable create_stringlist(UiList *list, ui_getvaluefunc2 getvalue, void *getvaluedata, int *count) { int num = list->count(list); XmStringTable items = (XmStringTable)XtMalloc(num * sizeof(XmString)); void *data = list->first(list); for(int i=0;inext(list); } @@ -160,6 +189,7 @@ void ui_listview_update(UiList *list, int i) { XmStringTable items = create_stringlist( list, listview->getvalue, + listview->getvaluedata, &count); XtVaSetValues( @@ -245,7 +275,16 @@ UIWIDGET ui_combobox_create(UiObject* obj, UiListArgs *args) { memset(listview, 0, sizeof(UiListView)); listview->obj = obj; listview->widget = widget; - listview->getvalue = args->getvalue ? args->getvalue : ui_strmodel_getvalue; + if(args->getvalue2) { + listview->getvalue = args->getvalue2; + listview->getvaluedata = args->getvalue2data; + } else if(args->getvalue) { + listview->getvalue = getvalue_wrapper; + listview->getvaluedata = args->getvalue; + } else { + listview->getvalue = getvalue_wrapper; + listview->getvaluedata = ui_strmodel_getvalue; + } listview->var = var; listview->onactivate = args->onactivate; listview->onactivatedata = args->onactivatedata; diff --git a/ui/motif/list.h b/ui/motif/list.h index 61a79ee..2d88c72 100644 --- a/ui/motif/list.h +++ b/ui/motif/list.h @@ -42,7 +42,8 @@ typedef struct UiListView { Widget widget; UiVar *var; UiModel* model; - ui_getvaluefunc getvalue; + ui_getvaluefunc2 getvalue; + void *getvaluedata; UiListSelection current_selection; diff --git a/ui/motif/window.c b/ui/motif/window.c index aa999e7..7c3f638 100644 --- a/ui/motif/window.c +++ b/ui/motif/window.c @@ -70,8 +70,7 @@ static void window_close_handler(Widget window, void *udata, void *cdata) { static UiObject* create_window(const char *title, void *window_data, Boolean simple) { CxMempool *mp = cxMempoolCreateSimple(256); const CxAllocator *a = mp->allocator; - UiObject *obj = cxCalloc(a, 1, sizeof(UiObject)); - obj->ctx = uic_context(obj, mp); + UiObject *obj = uic_object_new_toplevel(); obj->window = window_data; obj->destroy = ui_window_widget_destroy; diff --git a/ui/qt/Makefile b/ui/qt/Makefile index 824c467..39d4fc5 100644 --- a/ui/qt/Makefile +++ b/ui/qt/Makefile @@ -37,5 +37,9 @@ $(UI_LIB): $(QT_MAKEFILE) $(OBJ) FORCE $(MAKE) -f $(QT_MAKEFILE) $(AR) $(ARFLAGS) $(UI_LIB) $(OBJ) +$(UI_SHLIB): $(OBJ) + $(MAKE) -f $(QT_MAKEFILE) + $(CXX) -o $(UI_SHLIB) $(LDFLAGS) $(SHLIB_LDFLAGS) $(TK_LDFLAGS) $(OBJ) -L../build/lib -lucx + FORCE: diff --git a/ui/qt/image.cpp b/ui/qt/image.cpp new file mode 100644 index 0000000..1e4d699 --- /dev/null +++ b/ui/qt/image.cpp @@ -0,0 +1,39 @@ +/* + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. + * + * Copyright 2025 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 "image.h" + + + +void ui_image_ref(UIIMAGE img) { + // TODO +} + +void ui_image_unref(UIIMAGE img) { + // TODO +} \ No newline at end of file diff --git a/ui/qt/image.h b/ui/qt/image.h new file mode 100644 index 0000000..40f6a0e --- /dev/null +++ b/ui/qt/image.h @@ -0,0 +1,36 @@ +/* + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. + * + * Copyright 2025 Olaf Wintermann. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef IMAGE_H +#define IMAGE_H + +#include "toolkit.h" +#include "../ui/image.h" + +#endif /* IMAGE_H */ + diff --git a/ui/qt/list.cpp b/ui/qt/list.cpp index 3b404cf..51d9528 100644 --- a/ui/qt/list.cpp +++ b/ui/qt/list.cpp @@ -37,17 +37,32 @@ extern "C" void* ui_strmodel_getvalue(void *elm, int column) { return column == 0 ? elm : NULL; } +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); +} UIWIDGET ui_listview_create(UiObject* obj, UiListArgs *args) { UiContainerPrivate *ctn = ui_obj_container(obj); UI_APPLY_LAYOUT(ctn->layout, args); QListView *view = new QListView(); + ui_getvaluefunc2 getvalue = nullptr; + void *getvaluedata = nullptr; + if(args->getvalue2) { + getvalue = args->getvalue2; + getvaluedata = args->getvalue2data; + } else if(args->getvalue) { + getvalue = getvalue_wrapper; + getvaluedata = (void*)args->getvalue; + } else { + getvalue = getvalue_wrapper; + getvaluedata = (void*)ui_strmodel_getvalue; + } - ui_getvaluefunc getvalue = args->getvalue ? args->getvalue : ui_strmodel_getvalue; UiVar* var = uic_widget_var(obj->ctx, obj->ctx, args->list, args->varname, UI_VAR_LIST); - ListModel *model = new ListModel(obj, view, var, getvalue); + ListModel *model = new ListModel(obj, view, var, getvalue, getvaluedata); view->setModel(model); if(var) { diff --git a/ui/qt/model.cpp b/ui/qt/model.cpp index f3a4b3b..c9fc7bc 100644 --- a/ui/qt/model.cpp +++ b/ui/qt/model.cpp @@ -28,12 +28,21 @@ #include "model.h" +static void* model_getvalue(UiModel *model, UiList *list, void *elm, int row, int col, UiBool *freeResult) { + if(model->getvalue2) { + return model->getvalue2(list, elm, row, col, model->getvalue2data, freeResult); + } else if(model->getvalue) { + return model->getvalue(elm, col); + } + return NULL; +} -ListModel::ListModel(UiObject *obj, QListView *view, UiVar *var, ui_getvaluefunc getvalue){ +ListModel::ListModel(UiObject *obj, QListView *view, UiVar *var, ui_getvaluefunc2 getvalue, void *getvaluedata){ this->obj = obj; this->view = view; this->var = var; this->getvalue = getvalue; + this->getvaluedata = getvaluedata; this->onactivate = nullptr; this->onactivatedata = nullptr; this->onselection = nullptr; @@ -69,9 +78,14 @@ QVariant ListModel::data(const QModelIndex &index, int role) const { UiList *ls = (UiList*)var->value; void *rowData = ls->get(ls, index.row()); if(rowData && getvalue) { - void *value = getvalue(rowData, 0); + UiBool freeResult = false; + void *value = getvalue(ls, rowData, index.row(), 0, getvaluedata, &freeResult); if(value) { - return QString::fromUtf8((char*)value); + auto qs = QString::fromUtf8((char*)value); + if(freeResult) { + free(value); + } + return qs; } } } @@ -144,14 +158,19 @@ QVariant TableModel::data(const QModelIndex &index, int role) const { if(role == Qt::DisplayRole) { UiList *ls = (UiList*)var->value; void *rowData = ls->get(ls, index.row()); - if(rowData && model->getvalue) { + if(rowData) { int col = index.column(); - void *value = model->getvalue(rowData, col); + UiBool freeResult = false; + void *value = model_getvalue(model, ls, rowData, index.row(), col, &freeResult); if(value) { UiModelType type = model->types[col]; switch(type) { case UI_STRING: { - return QString::fromUtf8((char*)value); + auto qs = QString::fromUtf8((char*)value); + if(freeResult) { + free(value); + } + return qs; } case UI_STRING_FREE: { QString s = QString::fromUtf8((char*)value); @@ -163,13 +182,13 @@ QVariant TableModel::data(const QModelIndex &index, int role) const { return QString::number(i); } case UI_ICON: { - break; + break; // TODO } case UI_ICON_TEXT: { - break; + break; // TODO } case UI_ICON_TEXT_FREE: { - break; + break; // TODO } } } diff --git a/ui/qt/model.h b/ui/qt/model.h index 839b38e..faec52a 100644 --- a/ui/qt/model.h +++ b/ui/qt/model.h @@ -44,7 +44,8 @@ class ListModel : public QAbstractListModel { Q_OBJECT - ui_getvaluefunc getvalue; + ui_getvaluefunc2 getvalue; + void *getvaluedata; ui_callback onactivate; void *onactivatedata; ui_callback onselection; @@ -55,7 +56,7 @@ public: UiVar *var; QListView *view; - ListModel(UiObject *obj, QListView *view, UiVar *var, ui_getvaluefunc getvalue); + ListModel(UiObject *obj, QListView *view, UiVar *var, ui_getvaluefunc2 getvalue, void *getvaluedata); void setActivationCallback(ui_callback f, void *userdata); void setSelectionCallback(ui_callback f, void *userdata); diff --git a/ui/qt/qt5.pro b/ui/qt/qt5.pro index a465fac..553ddbd 100644 --- a/ui/qt/qt5.pro +++ b/ui/qt/qt5.pro @@ -53,6 +53,7 @@ SOURCES += label.cpp SOURCES += graphics.cpp SOURCES += widget.cpp SOURCES += entry.cpp +SOURCES += image.cpp HEADERS += toolkit.h HEADERS += window.h @@ -68,4 +69,5 @@ HEADERS += label.h HEADERS += graphics.h HEADERS += widget.h HEADERS += entry.h +HEADERS += image.h diff --git a/ui/qt/window.cpp b/ui/qt/window.cpp index bab1fa6..5a9f189 100644 --- a/ui/qt/window.cpp +++ b/ui/qt/window.cpp @@ -28,6 +28,7 @@ #include #include "../common/context.h" +#include "../common/object.h" #include "window.h" #include "menu.h" @@ -39,9 +40,7 @@ #include static UiObject* create_window(const char *title, void *window_data, bool simple) { - CxMempool *mp = cxMempoolCreateSimple(256); - UiObject *obj = (UiObject*)cxCalloc(mp->allocator, 1, sizeof(UiObject)); - obj->ctx = uic_context(obj, mp); + UiObject *obj = uic_object_new_toplevel(); obj->window = window_data; obj->next = NULL; diff --git a/ui/ui/toolkit.h b/ui/ui/toolkit.h index 39d4c73..ff23a53 100644 --- a/ui/ui/toolkit.h +++ b/ui/ui/toolkit.h @@ -237,7 +237,8 @@ typedef enum UiDnDAction { typedef void(*ui_callback)(UiEvent*, void*); /* event, user data */ -typedef void*(*ui_getvaluefunc)(void*, int); +typedef void*(*ui_getvaluefunc)(void *elm, int col); +typedef void*(*ui_getvaluefunc2)(UiList *list, void *elm, int row, int col, void *userdata, UiBool *freeResult); typedef int(*ui_threadfunc)(void*); @@ -405,6 +406,8 @@ struct UiGeneric { UiObserver *observers; }; +typedef void (*ui_list_init_func)(UiContext *ctx, UiList *list, void *userdata); + /* * abstract list */ @@ -482,6 +485,8 @@ 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 void ui_object_ref(UiObject *obj); UIEXPORT int ui_object_unref(UiObject *obj); @@ -502,17 +507,12 @@ UIEXPORT void ui_threadpool_job(UiThreadpool* pool, UiObject* obj, ui_threadfunc UIEXPORT void* ui_document_new(size_t size); UIEXPORT void ui_document_destroy(void *doc); -UIEXPORT void ui_set_document(UiObject *obj, void *document); // deprecated -UIEXPORT void ui_detach_document(UiObject *obj); // deprecated -UIEXPORT void* ui_get_document(UiObject *obj); // deprecated -UIEXPORT void ui_set_subdocument(void *document, void *sub); // deprecated -UIEXPORT void ui_detach_subdocument(void *document, void *sub); // deprecated UIEXPORT void* ui_get_subdocument(void *document); // deprecated UIEXPORT UiContext* ui_document_context(void *doc); UIEXPORT void ui_attach_document(UiContext *ctx, void *document); -UIEXPORT void ui_detach_document2(UiContext *ctx, void *document); +UIEXPORT void ui_detach_document(UiContext *ctx, void *document); UIEXPORT void ui_widget_set_groups(UiContext *ctx, UIWIDGET widget, ui_enablefunc enable, ...); @@ -531,12 +531,12 @@ UIEXPORT char* ui_strdup(UiContext *ctx, const char *str); // types -UIEXPORT UiInteger* ui_int_new(UiContext *ctx, char *name); -UIEXPORT UiDouble* ui_double_new(UiContext *ctx, char *name); -UIEXPORT UiString* ui_string_new(UiContext *ctx, char *name); -UIEXPORT UiText* ui_text_new(UiContext *ctx, char *name); -UIEXPORT UiRange* ui_range_new(UiContext *ctx, char *name); -UIEXPORT UiGeneric* ui_generic_new(UiContext *ctx, char *name); +UIEXPORT UiInteger* ui_int_new(UiContext *ctx, const char *name); +UIEXPORT UiDouble* ui_double_new(UiContext *ctx, const char *name); +UIEXPORT UiString* ui_string_new(UiContext *ctx, const char *name); +UIEXPORT UiText* ui_text_new(UiContext *ctx, const char *name); +UIEXPORT UiRange* ui_range_new(UiContext *ctx, const char *name); +UIEXPORT UiGeneric* ui_generic_new(UiContext *ctx, const char *name); #define ui_get(v) _Generic(v, \ UiInteger*: ui_int_get, \ @@ -576,7 +576,8 @@ UIEXPORT void ui_notify_except(UiObserver *observer, UiObserver *exc, void *data UIEXPORT void ui_notify_evt(UiObserver *observer, UiEvent *event); -UIEXPORT UiList* ui_list_new(UiContext *ctx, char *name); +UIEXPORT UiList* ui_list_new(UiContext *ctx, const char *name); +UIEXPORT UiList* ui_list_new2(UiContext *ctx, const char *name, ui_list_init_func init, void *userdata); UIEXPORT void ui_list_free(UiList *list); UIEXPORT void* ui_list_first(UiList *list); UIEXPORT void* ui_list_next(UiList *list); @@ -626,6 +627,15 @@ UIEXPORT void ui_condvar_destroy(UiCondVar *var); UIEXPORT void ui_setop_enable(int set); UIEXPORT int ui_get_setop(void); + +UIEXPORT void ui_global_list_initializer(ui_list_init_func func, void *userdata); +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_list_class_set_count(UiList *list, int(*count)(UiList *list)); +UIEXPORT void ui_list_class_set_data(UiList *list, void *data); +UIEXPORT void ui_list_class_set_iter(UiList *list, void *iter); + #ifdef __cplusplus } #endif diff --git a/ui/ui/tree.h b/ui/ui/tree.h index 5f4b157..b9f8672 100644 --- a/ui/ui/tree.h +++ b/ui/ui/tree.h @@ -78,12 +78,23 @@ struct UiModel { int *columnsize; /* + * void*(*ui_getvaluefunc)(void *elm, int col); + * * function for translating model data to view data - * first argument is the pointer returned by UiList->get or UiTree->get + * first argument is the pointer returned by UiList first|next|get * second argument is the column index * TODO: return */ - void*(*getvalue)(void*, int); + ui_getvaluefunc getvalue; + + /* + * void*(*ui_getvaluefunc2)(UiList *list, void *elm, int row, int col, void *userdata) + * + * alternative for getvalue + */ + ui_getvaluefunc2 getvalue2; + + void *getvalue2data; }; struct UiListCallbacks { @@ -121,6 +132,8 @@ struct UiListArgs { char **static_elements; size_t static_nelm; ui_getvaluefunc getvalue; + ui_getvaluefunc2 getvalue2; + void *getvalue2data; ui_callback onactivate; void* onactivatedata; ui_callback onselection; @@ -130,14 +143,14 @@ struct UiListArgs { ui_callback ondragcomplete; void* ondragcompletedata; ui_callback ondrop; - void* ondropsdata; + void* ondropdata; UiBool multiselection; UiMenuBuilder *contextmenu; const int *groups; }; -typedef void (*ui_sublist_getvalue_func)(void *sublist_userdata, void *rowdata, int index, UiSubListItem *item); +typedef void (*ui_sublist_getvalue_func)(void *sublist_userdata, void *rowdata, int index, UiSubListItem *item, void *userdata); struct UiSubList { UiList *value; @@ -219,6 +232,11 @@ struct UiSourceListArgs { */ ui_sublist_getvalue_func getvalue; + /* + * getvalue_func userdata + */ + void *getvaluedata; + /* * activated when a list item is selected */ @@ -256,6 +274,13 @@ UIEXPORT void ui_combobox_select(UIWIDGET dropdown, int index); UIEXPORT UIWIDGET ui_sourcelist_create(UiObject *obj, UiSourceListArgs *args); +UIEXPORT void ui_sublist_item_set_icon(UiSubListItem *item, const char *icon); +UIEXPORT void ui_sublist_item_set_label(UiSubListItem *item, const char *label); +UIEXPORT void ui_sublist_item_set_button_icon(UiSubListItem *item, const char *button_icon); +UIEXPORT void ui_sublist_item_set_button_label(UiSubListItem *item, const char *button_label); +UIEXPORT void ui_sublist_item_set_badge(UiSubListItem *item, const char *badge); +UIEXPORT void ui_sublist_item_set_eventdata(UiSubListItem *item, void *eventdata); + #ifdef __cplusplus } diff --git a/ui/win32/Makefile b/ui/win32/Makefile index 97b3d25..f31efac 100644 --- a/ui/win32/Makefile +++ b/ui/win32/Makefile @@ -31,3 +31,6 @@ $(WIN32_OBJPRE)%.obj: win32/%.c $(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 diff --git a/ui/win32/image.c b/ui/win32/image.c new file mode 100644 index 0000000..53c2588 --- /dev/null +++ b/ui/win32/image.c @@ -0,0 +1,37 @@ +/* +* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. + * + * Copyright 2024 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 "image.h" + +void ui_image_ref(UIIMAGE img) { + // TODO +} + +void ui_image_unref(UIIMAGE img) { + // TODO +} \ No newline at end of file diff --git a/ui/win32/image.h b/ui/win32/image.h new file mode 100644 index 0000000..4af1cc0 --- /dev/null +++ b/ui/win32/image.h @@ -0,0 +1,42 @@ +/* +* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. + * + * Copyright 2024 Olaf Wintermann. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef IMAGE_H +#define IMAGE_H + +#include "../ui/image.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#ifdef __cplusplus +} +#endif + +#endif //IMAGE_H diff --git a/ui/win32/objs.mk b/ui/win32/objs.mk index 0dce885..d861b9f 100644 --- a/ui/win32/objs.mk +++ b/ui/win32/objs.mk @@ -31,6 +31,7 @@ WIN32_OBJPRE = $(OBJ_DIR)$(WIN32_SRC_DIR) WIN32OBJ = toolkit.obj WIN32OBJ += window.obj +WIN32OBJ += image.obj TOOLKITOBJS += $(WIN32OBJ:%=$(WIN32_OBJPRE)%) TOOLKITSOURCE += $(WIN32OBJ:%.obj=win32/%.c) diff --git a/ui/win32/toolkit.c b/ui/win32/toolkit.c index cd1f1ba..63de9c7 100644 --- a/ui/win32/toolkit.c +++ b/ui/win32/toolkit.c @@ -31,6 +31,9 @@ #include "window.h" +#include "../common/menu.h" +#include "../common/toolbar.h" +#include "../common/document.h" #include "../common/properties.h" #include @@ -46,9 +49,15 @@ static ui_callback exit_func; void *exit_data; void ui_init(const char *appname, int argc, char **argv) { - application_name = appname; - - ui_window_init(); + application_name = appname; + + uic_init_global_context(); + uic_docmgr_init(); + uic_menu_init(); + uic_toolbar_init(); + uic_load_app_properties(); + + ui_window_init(); } const char* ui_appname() { diff --git a/ui/win32/window.c b/ui/win32/window.c index 184f7fd..8ee0cbb 100644 --- a/ui/win32/window.c +++ b/ui/win32/window.c @@ -29,6 +29,8 @@ #include "window.h" #include "Windows.h" +#include "../common/object.h" + #include #include @@ -67,10 +69,7 @@ void ui_window_init(void) { } static UiObject* create_window(const char *title, void *window_data, bool simple) { - CxMempool *mp = cxMempoolCreateSimple(256); - const CxAllocator *a = mp->allocator; - UiObject *obj = cxCalloc(a, 1, sizeof(UiObject)); - obj->ctx = uic_context(obj, mp); + UiObject *obj = uic_object_new_toplevel(); obj->window = window_data; HWND hwnd = CreateWindowEx( diff --git a/ui/winui/container.cpp b/ui/winui/container.cpp index bca5d37..0d77cfe 100644 --- a/ui/winui/container.cpp +++ b/ui/winui/container.cpp @@ -34,6 +34,7 @@ #include "../common/object.h" #include "util.h" +#include "../ui/widget.h" void ui_container_begin_close(UiObject* obj) { @@ -51,13 +52,13 @@ int ui_container_finish(UiObject* obj) { } -UIEXPORT UIWIDGET ui_customwidget_create(UiObject *obj, ui_createwidget_func create_widget, void *userdata, UiWidgetArgs args) { +UIWIDGET ui_customwidget_create(UiObject *obj, ui_createwidget_func create_widget, void *userdata, UiWidgetArgs *args) { UiObject* current = uic_current_obj(obj); UIWIDGET widget = create_widget(obj, args, userdata); FrameworkElement w = widget->uielement.as(); - UI_APPLY_LAYOUT1(current, args); + UI_APPLY_LAYOUT2(current, args); current->container->Add(w, false); @@ -66,9 +67,9 @@ UIEXPORT UIWIDGET ui_customwidget_create(UiObject *obj, ui_createwidget_func cre // --------------------- UiBoxContainer --------------------- -static UIWIDGET ui_box(UiObject* obj, UiContainerArgs args, UiBoxContainerType type) { +static UIWIDGET ui_box(UiObject* obj, UiContainerArgs *args, UiBoxContainerType type) { UiObject* current = uic_current_obj(obj); - UI_APPLY_LAYOUT1(current, args); + UI_APPLY_LAYOUT2(current, args); Grid grid = Grid(); current->container->Add(grid, true); @@ -78,18 +79,18 @@ static UIWIDGET ui_box(UiObject* obj, UiContainerArgs args, UiBoxContainerType t ui_context_add_widget_destructor(current->ctx, widget); UiObject* newobj = uic_object_new(obj, widget); - newobj->container = new UiBoxContainer(grid, type, args.margin, args.spacing); + newobj->container = new UiBoxContainer(grid, type, args->margin, args->spacing); ui_context_add_container_destructor(current->ctx, newobj->container); uic_obj_add(obj, newobj); return widget; } -UIWIDGET ui_vbox_create(UiObject* obj, UiContainerArgs args) { +UIWIDGET ui_vbox_create(UiObject* obj, UiContainerArgs *args) { return ui_box(obj, args, UI_BOX_CONTAINER_VBOX); } -UIWIDGET ui_hbox_create(UiObject* obj, UiContainerArgs args) { +UIWIDGET ui_hbox_create(UiObject* obj, UiContainerArgs *args) { return ui_box(obj, args, UI_BOX_CONTAINER_HBOX); } @@ -161,9 +162,9 @@ void UiBoxContainer::Add(FrameworkElement control, UiBool fill) { // --------------------- UiGridContainer --------------------- -UIWIDGET ui_grid_create(UiObject* obj, UiContainerArgs args) { +UIWIDGET ui_grid_create(UiObject* obj, UiContainerArgs *args) { UiObject* current = uic_current_obj(obj); - UI_APPLY_LAYOUT1(current, args); + UI_APPLY_LAYOUT2(current, args); Grid grid = Grid(); current->container->Add(grid, true); @@ -173,7 +174,7 @@ UIWIDGET ui_grid_create(UiObject* obj, UiContainerArgs args) { ui_context_add_widget_destructor(current->ctx, widget); UiObject* newobj = uic_object_new(obj, widget); - newobj->container = new UiGridContainer(grid, args.margin, args.columnspacing, args.rowspacing); + newobj->container = new UiGridContainer(grid, args->margin, args->columnspacing, args->rowspacing); ui_context_add_container_destructor(current->ctx, newobj->container); uic_obj_add(obj, newobj); @@ -303,7 +304,7 @@ void UiGridContainer::Add(FrameworkElement control, UiBool fill) { // --------------------- UI Frame --------------------- -UIWIDGET ui_frame_create(UiObject* obj, UiFrameArgs args) { +UIWIDGET ui_frame_create(UiObject* obj, UiFrameArgs *args) { // create a grid for the frame, that contains the label and a sub-frame Grid frame = Grid(); @@ -320,7 +321,7 @@ UIWIDGET ui_frame_create(UiObject* obj, UiFrameArgs args) { // label int row = 0; - if (args.label) { + if (args->label) { RowDefinition rowdefLabel = RowDefinition(); gl.GridUnitType = GridUnitType::Auto; gl.Value = 0; @@ -328,7 +329,7 @@ UIWIDGET ui_frame_create(UiObject* obj, UiFrameArgs args) { frame.RowDefinitions().Append(rowdefLabel); TextBlock label = TextBlock(); - wchar_t* wlabel = str2wstr(args.label, nullptr); + wchar_t* wlabel = str2wstr(args->label, nullptr); winrt::hstring hstr(wlabel); label.Text(hstr); free(wlabel); @@ -359,7 +360,7 @@ UIWIDGET ui_frame_create(UiObject* obj, UiFrameArgs args) { // add frame to the parent container UiObject* current = uic_current_obj(obj); - UI_APPLY_LAYOUT1(current, args); + UI_APPLY_LAYOUT2(current, args); current->container->Add(frame, true); UIElement elm = frame; @@ -368,18 +369,18 @@ UIWIDGET ui_frame_create(UiObject* obj, UiFrameArgs args) { // sub container UiContainer* ctn = nullptr; - switch (args.subcontainer) { + switch (args->subcontainer) { default: case UI_CONTAINER_VBOX: { - ctn = new UiBoxContainer(workarea, UI_BOX_CONTAINER_VBOX, args.margin, args.spacing); + ctn = new UiBoxContainer(workarea, UI_BOX_CONTAINER_VBOX, args->margin, args->spacing); break; } case UI_CONTAINER_HBOX: { - ctn = new UiBoxContainer(workarea, UI_BOX_CONTAINER_HBOX, args.margin, args.spacing); + ctn = new UiBoxContainer(workarea, UI_BOX_CONTAINER_HBOX, args->margin, args->spacing); break; } case UI_CONTAINER_GRID: { - ctn = new UiGridContainer(workarea, args.margin, args.columnspacing, args.rowspacing); + ctn = new UiGridContainer(workarea, args->margin, args->columnspacing, args->rowspacing); break; } } @@ -394,18 +395,18 @@ UIWIDGET ui_frame_create(UiObject* obj, UiFrameArgs args) { // --------------------- UI Expander --------------------- -UIWIDGET ui_expander_create(UiObject* obj, UiFrameArgs args) { +UIWIDGET ui_expander_create(UiObject* obj, UiFrameArgs *args) { Expander expander = Expander(); - if (args.label) { - wchar_t* wlabel = str2wstr(args.label, nullptr); + if (args->label) { + wchar_t* wlabel = str2wstr(args->label, nullptr); expander.Header(box_value(wlabel)); free(wlabel); } - expander.IsExpanded(args.isexpanded); + expander.IsExpanded(args->isexpanded); // add frame to the parent container UiObject* current = uic_current_obj(obj); - UI_APPLY_LAYOUT1(current, args); + UI_APPLY_LAYOUT2(current, args); current->container->Add(expander, true); UIElement elm = expander; @@ -416,18 +417,18 @@ UIWIDGET ui_expander_create(UiObject* obj, UiFrameArgs args) { expander.Content(content); UiContainer* ctn = nullptr; - switch (args.subcontainer) { + switch (args->subcontainer) { default: case UI_CONTAINER_VBOX: { - ctn = new UiBoxContainer(content, UI_BOX_CONTAINER_VBOX, args.margin, args.spacing); + ctn = new UiBoxContainer(content, UI_BOX_CONTAINER_VBOX, args->margin, args->spacing); break; } case UI_CONTAINER_HBOX: { - ctn = new UiBoxContainer(content, UI_BOX_CONTAINER_HBOX, args.margin, args.spacing); + ctn = new UiBoxContainer(content, UI_BOX_CONTAINER_HBOX, args->margin, args->spacing); break; } case UI_CONTAINER_GRID: { - ctn = new UiGridContainer(content, args.margin, args.columnspacing, args.rowspacing); + ctn = new UiGridContainer(content, args->margin, args->columnspacing, args->rowspacing); break; } } @@ -442,12 +443,12 @@ UIWIDGET ui_expander_create(UiObject* obj, UiFrameArgs args) { // --------------------- UI ScrolledWindow --------------------- -UIWIDGET ui_scrolledwindow_create(UiObject* obj, UiFrameArgs args) { +UIWIDGET ui_scrolledwindow_create(UiObject* obj, UiFrameArgs *args) { ScrollViewer scrollW = ScrollViewer(); // add frame to the parent container UiObject* current = uic_current_obj(obj); - UI_APPLY_LAYOUT1(current, args); + UI_APPLY_LAYOUT2(current, args); current->container->Add(scrollW, true); UIElement elm = scrollW; @@ -459,18 +460,18 @@ UIWIDGET ui_scrolledwindow_create(UiObject* obj, UiFrameArgs args) { scrollW.Content(content); UiContainer* ctn = nullptr; - switch (args.subcontainer) { + switch (args->subcontainer) { default: case UI_CONTAINER_VBOX: { - ctn = new UiBoxContainer(content, UI_BOX_CONTAINER_VBOX, args.margin, args.spacing); + ctn = new UiBoxContainer(content, UI_BOX_CONTAINER_VBOX, args->margin, args->spacing); break; } case UI_CONTAINER_HBOX: { - ctn = new UiBoxContainer(content, UI_BOX_CONTAINER_HBOX, args.margin, args.spacing); + ctn = new UiBoxContainer(content, UI_BOX_CONTAINER_HBOX, args->margin, args->spacing); break; } case UI_CONTAINER_GRID: { - ctn = new UiGridContainer(content, args.margin, args.columnspacing, args.rowspacing); + ctn = new UiGridContainer(content, args->margin, args->columnspacing, args->rowspacing); break; } } @@ -520,21 +521,21 @@ static UiObject* create_subcontainer_obj(UiObject* current, Grid subcontainer, U return newobj; } -static UiTabView* tabview_pivot_create(UiObject* obj, UiTabViewArgs args) { +static UiTabView* tabview_pivot_create(UiObject* obj, UiTabViewArgs *args) { Pivot pivot = Pivot(); UiPivotTabView* tabview = new UiPivotTabView(obj, pivot, args); return tabview; } -UiPivotTabView::UiPivotTabView(UiObject* obj, Pivot pivot, UiTabViewArgs args) { +UiPivotTabView::UiPivotTabView(UiObject* obj, Pivot pivot, UiTabViewArgs *args) { this->current = obj; this->pivot = pivot; - this->subcontainer = args.subcontainer; - this->margin = args.margin; - this->spacing = args.spacing; - this->columnspacing = args.columnspacing; - this->rowspacing = args.rowspacing; + this->subcontainer = args->subcontainer; + this->margin = args->margin; + this->spacing = args->spacing; + this->columnspacing = args->columnspacing; + this->rowspacing = args->rowspacing; } UiObject* UiPivotTabView::AddTab(const char* label, int index) { @@ -568,7 +569,7 @@ FrameworkElement UiPivotTabView::GetFrameworkElement() { } -static UiTabView* tabview_invisible_create(UiObject *obj, UiTabViewArgs args) { +static UiTabView* tabview_invisible_create(UiObject *obj, UiTabViewArgs *args) { Grid container = Grid(); container.HorizontalAlignment(HorizontalAlignment::Stretch); container.VerticalAlignment(VerticalAlignment::Stretch); @@ -576,14 +577,14 @@ static UiTabView* tabview_invisible_create(UiObject *obj, UiTabViewArgs args) { return tabview; } -UiInvisibleTabView::UiInvisibleTabView(UiObject* obj, Grid container, UiTabViewArgs args) { +UiInvisibleTabView::UiInvisibleTabView(UiObject* obj, Grid container, UiTabViewArgs *args) { this->current = obj; this->container = container; - this->subcontainer = args.subcontainer; - this->margin = args.margin; - this->spacing = args.spacing; - this->columnspacing = args.columnspacing; - this->rowspacing = args.rowspacing; + this->subcontainer = args->subcontainer; + this->margin = args->margin; + this->spacing = args->spacing; + this->columnspacing = args->columnspacing; + this->rowspacing = args->rowspacing; this->currentIndex = -1; GridLength gl; @@ -638,7 +639,7 @@ FrameworkElement UiInvisibleTabView::GetFrameworkElement() { } -static UiTabView* tabview_main_create(UiObject* obj, UiTabViewArgs args) { +static UiTabView* tabview_main_create(UiObject* obj, UiTabViewArgs *args) { TabView tabview = TabView(); tabview.IsAddTabButtonVisible(false); //tabview.CanDragTabs(false); @@ -648,14 +649,14 @@ static UiTabView* tabview_main_create(UiObject* obj, UiTabViewArgs args) { return uitabview; } -UiMainTabView::UiMainTabView(UiObject* obj, TabView tabview, UiTabViewArgs args) { +UiMainTabView::UiMainTabView(UiObject* obj, TabView tabview, UiTabViewArgs *args) { this->current = obj; this->tabview = tabview; - this->subcontainer = args.subcontainer; - this->margin = args.margin; - this->spacing = args.spacing; - this->columnspacing = args.columnspacing; - this->rowspacing = args.rowspacing; + this->subcontainer = args->subcontainer; + this->margin = args->margin; + this->spacing = args->spacing; + this->columnspacing = args->columnspacing; + this->rowspacing = args->rowspacing; } UiObject* UiMainTabView::AddTab(const char* label, int index) { @@ -691,7 +692,7 @@ FrameworkElement UiMainTabView::GetFrameworkElement() { } -static UiTabView* tabview_navigationview_create(UiObject* obj, UiTabViewArgs args, UiTabViewType type) { +static UiTabView* tabview_navigationview_create(UiObject* obj, UiTabViewArgs *args, UiTabViewType type) { NavigationView navigationview = NavigationView(); UiNavigationTabView* tabview = new UiNavigationTabView(obj, navigationview, args, type); navigationview.IsBackButtonVisible(NavigationViewBackButtonVisible::Collapsed); @@ -700,14 +701,14 @@ static UiTabView* tabview_navigationview_create(UiObject* obj, UiTabViewArgs arg return tabview; } -UiNavigationTabView::UiNavigationTabView(UiObject* obj, NavigationView navigationview, UiTabViewArgs args, UiTabViewType type) { +UiNavigationTabView::UiNavigationTabView(UiObject* obj, NavigationView navigationview, UiTabViewArgs *args, UiTabViewType type) { this->current = obj; this->navigationview = navigationview; this->type = type; - this->margin = args.margin; - this->spacing = args.spacing; - this->columnspacing = args.columnspacing; - this->rowspacing = args.rowspacing; + this->margin = args->margin; + this->spacing = args->spacing; + this->columnspacing = args->columnspacing; + this->rowspacing = args->rowspacing; if (type == UI_TABVIEW_NAVIGATION_TOP) { navigationview.PaneDisplayMode(NavigationViewPaneDisplayMode::Top); @@ -773,8 +774,8 @@ static void ui_tabview_set(UiInteger *i, int64_t value) { tabview->Select(value); } -UIWIDGET ui_tabview_create(UiObject* obj, UiTabViewArgs args) { - UiTabViewType type = args.tabview == UI_TABVIEW_DEFAULT ? UI_TABVIEW_NAVIGATION_TOP2 : args.tabview; +UIWIDGET ui_tabview_create(UiObject* obj, UiTabViewArgs *args) { + UiTabViewType type = args->tabview == UI_TABVIEW_DEFAULT ? UI_TABVIEW_NAVIGATION_TOP2 : args->tabview; UiTabView* tabview = nullptr; switch (type) { default: { @@ -806,7 +807,7 @@ UIWIDGET ui_tabview_create(UiObject* obj, UiTabViewArgs args) { // add frame to the parent container UiObject* current = uic_current_obj(obj); - UI_APPLY_LAYOUT1(current, args); + UI_APPLY_LAYOUT2(current, args); current->container->Add(tabview->GetFrameworkElement(), true); UIElement elm = tabview->GetFrameworkElement(); @@ -817,7 +818,7 @@ UIWIDGET ui_tabview_create(UiObject* obj, UiTabViewArgs args) { // TODO: add tabview destructor // bind variable - UiVar* var = uic_widget_var(obj->ctx, current->ctx, args.value, args.varname, UI_VAR_INTEGER); + UiVar* var = uic_widget_var(obj->ctx, current->ctx, args->value, args->varname, UI_VAR_INTEGER); if (var) { UiInteger *i = (UiInteger*)var->value; i->obj = tabview; @@ -861,28 +862,28 @@ UIEXPORT UiObject* ui_tabview_add(UIWIDGET tabview, const char *name, int tab_in // TODO: replace placeholder implementation -UIEXPORT UIWIDGET ui_headerbar_create(UiObject *obj, UiHeaderbarArgs args) { +UIEXPORT UIWIDGET ui_headerbar_create(UiObject *obj, UiHeaderbarArgs *args) { UiContainerArgs boxargs = { }; boxargs.fill = UI_OFF; - return ui_hbox_create(obj, boxargs); + return ui_hbox_create(obj, &boxargs); } UIEXPORT void ui_headerbar_start_create(UiObject *obj) { UiContainerArgs boxargs = { }; boxargs.fill = UI_OFF; - ui_hbox_create(obj, boxargs); + ui_hbox_create(obj, &boxargs); } UIEXPORT void ui_headerbar_center_create(UiObject *obj) { UiContainerArgs boxargs = { }; boxargs.fill = UI_OFF; - ui_hbox_create(obj, boxargs); + ui_hbox_create(obj, &boxargs); } UIEXPORT void ui_headerbar_end_create(UiObject *obj) { UiContainerArgs boxargs = { }; boxargs.fill = UI_OFF; - ui_hbox_create(obj, boxargs); + ui_hbox_create(obj, &boxargs); } diff --git a/ui/winui/container.h b/ui/winui/container.h index 161140b..de63e43 100644 --- a/ui/winui/container.h +++ b/ui/winui/container.h @@ -140,7 +140,7 @@ struct UiTabViewContainer : UiContainer { struct UiPivotTabView : UiTabView { Pivot pivot; - UiPivotTabView(UiObject *obj, Pivot pivot, UiTabViewArgs args); + UiPivotTabView(UiObject *obj, Pivot pivot, UiTabViewArgs *args); UiObject* AddTab(const char* label, int index = -1); void Remove(int index); @@ -151,7 +151,7 @@ struct UiPivotTabView : UiTabView { struct UiMainTabView : UiTabView { TabView tabview; - UiMainTabView(UiObject* obj, TabView tabview, UiTabViewArgs args); + UiMainTabView(UiObject* obj, TabView tabview, UiTabViewArgs *args); UiObject* AddTab(const char* label, int index = -1); void Remove(int index); @@ -164,7 +164,7 @@ struct UiNavigationTabView : UiTabView { UiTabViewType type; std::vector > pages; - UiNavigationTabView(UiObject* obj, NavigationView navigationview, UiTabViewArgs args, UiTabViewType type); + UiNavigationTabView(UiObject* obj, NavigationView navigationview, UiTabViewArgs *args, UiTabViewType type); UiObject* AddTab(const char* label, int index = -1); void Remove(int index); @@ -179,7 +179,7 @@ struct UiInvisibleTabView : UiTabView { std::vector pages; int currentIndex; - UiInvisibleTabView(UiObject *obj, Grid container, UiTabViewArgs args); + UiInvisibleTabView(UiObject *obj, Grid container, UiTabViewArgs *args); UiObject* AddTab(const char* label, int index = -1); void Remove(int index); diff --git a/ui/winui/image.cpp b/ui/winui/image.cpp index cb18ae3..2218985 100644 --- a/ui/winui/image.cpp +++ b/ui/winui/image.cpp @@ -47,6 +47,16 @@ using namespace winrt::Microsoft::UI::Xaml::Media; UiImageSource::UiImageSource(winrt::Microsoft::UI::Xaml::Media::ImageSource& src) : imgsrc(src) {} +void UiImageSource::ref() { + refcount++; +} + +void UiImageSource::unref() { + if (--refcount == 0) { + delete this; + } +} + UIEXPORT UIWIDGET ui_imageviewer_create(UiObject *obj, UiImageViewerArgs args) { UiObject* current = uic_current_obj(obj); @@ -94,9 +104,10 @@ extern "C" int ui_image_set(UiGeneric *g, void *data, const char *type) { UiImageSource *imgdata = (UiImageSource*)data; if (g->value) { UiImageSource *prevData = (UiImageSource*)g->value; - delete prevData; + //prevData->unref(); } g->value = imgdata; + //imgdata->ref(); UiWidget* widget = (UiWidget*)g->obj; Image image = widget->uielement.as(); @@ -117,8 +128,19 @@ UIEXPORT int ui_image_load_file(UiGeneric *obj, const char *path) { UiImageSource *imgdata = new UiImageSource(src); obj->set(obj, imgdata, UI_IMAGE_OBJECT_TYPE); + imgdata->unref(); free(wpath); return 0; } + +void ui_image_ref(UIIMAGE img) { + UiImageSource* imgdata = (UiImageSource*)img; + imgdata->ref(); +} + +void ui_image_unref(UIIMAGE img) { + UiImageSource* imgdata = (UiImageSource*)img; + imgdata->unref(); +} diff --git a/ui/winui/image.h b/ui/winui/image.h index 637ea24..0cf2931 100644 --- a/ui/winui/image.h +++ b/ui/winui/image.h @@ -32,10 +32,16 @@ #include "../ui/image.h" class UiImageSource { + unsigned int refcount = 1; + public: winrt::Microsoft::UI::Xaml::Media::ImageSource imgsrc { nullptr }; UiImageSource(winrt::Microsoft::UI::Xaml::Media::ImageSource& src); + + void ref(); + + void unref(); }; diff --git a/ui/winui/text.cpp b/ui/winui/text.cpp index ce983ff..70b9589 100644 --- a/ui/winui/text.cpp +++ b/ui/winui/text.cpp @@ -68,7 +68,6 @@ UIEXPORT UIWIDGET ui_textarea_create(UiObject *obj, UiTextAreaArgs args) { if (var) { UiText* value = (UiText*)var->value; value->obj = widget; - value->undomgr = NULL; value->set = ui_textarea_set; value->get = ui_textarea_get; value->getsubstr = ui_textarea_getsubstr; diff --git a/ui/winui/window.cpp b/ui/winui/window.cpp index 3682ead..4285e09 100644 --- a/ui/winui/window.cpp +++ b/ui/winui/window.cpp @@ -147,8 +147,7 @@ UiObject* ui_window(const char* title, void* window_data) { } UIEXPORT UiObject* ui_simple_window(const char *title, void *window_data) { - CxMempool* mp = cxMempoolCreateSimple(256); - UiObject* obj = (UiObject*)cxCalloc(mp->allocator, 1, sizeof(UiObject)); + UiObject* obj = uic_object_new_toplevel(); obj->ctx = uic_context(obj, mp); obj->window = window_data; -- 2.47.3