Fri, 10 Nov 2017 17:17:14 +0100
refactors value binding system
--- a/application/main.c Tue Jan 24 18:46:47 2017 +0100 +++ b/application/main.c Fri Nov 10 17:17:14 2017 +0100 @@ -33,49 +33,79 @@ #include <ucx/buffer.h> #include <ucx/utils.h> +typedef struct Document { + UiText *text; + UiString *t1; + UiString *t2; + UiString *t3; + UiInteger *i; +} Document; + +Document *d1; +Document *d2; +int n = 1; + +Document* create_doc(); + +Document* next_doc(void) { + Document *doc = d1; + if(n == 1) { + doc = d2; + printf("doc2\n"); + } else { + printf("doc1\n"); + } + n++; + n = n%2; + return doc; +} + void action_menu(UiEvent *event, void *data) { printf("action_menu\n"); - fflush(stdout); -} - -void action_button(UiEvent *event, void *data) { - printf("action_button\n"); + + Document *doc = event->document; + char *s = doc->text->get(doc->text); + printf("text: {\n%s\n}\n", s); + //int i = doc->i->get(doc->i); + //printf("i: %d\n", i); + fflush(stdout); } -void draw(UiEvent *event, UiGraphics *g, void *data) { - printf("draw: %d, %d\n", g->width, g->height); - fflush(stdout); +Document* create_doc() { + Document *doc = ui_document_new(sizeof(Document)); + UiContext *ctx = ui_document_context(doc); - ui_graphics_color(g, 200, 240, 240); - ui_draw_rect(g, 0, 0, 50, g->height, TRUE); + doc->text = ui_text_new(ctx, "text"); + //doc->t1 = ui_string_new(ctx, "t1"); + //doc->t2 = ui_string_new(ctx, "t2"); + //doc->t3 = ui_string_new(ctx, "t3"); - ui_graphics_color(g, 150, 150, 200); - ui_draw_rect(g, 50, 0, g->width - 50, g->height, TRUE); + //doc->i = ui_int_new(ctx, "int"); + return doc; +} + +void action_newdoc(UiEvent *event, void *data) { + printf("new doc\n"); - ui_graphics_color(g, 0, 0, 0); - ui_draw_line(g, 0, 10, 100, 10); - ui_draw_line(g, 0, 10, 10, 50); - ui_draw_line(g, 10, 50, 50, 50); - ui_draw_line(g, 50, 50, 100, 100); - - ui_draw_rect(g, 15, 15, 80, 80, FALSE); + Document *newd = next_doc(); + printf("newd: %d\n", (int)(intptr_t)newd); + ui_set_document(event->obj, newd); } void application_startup(UiEvent *event, void *data) { - UiObject *obj = ui_window("Test", NULL); - - ui_tabview(obj); + //Document *doc = create_doc(); + d1 = create_doc(); + d2 = create_doc(); - ui_tab(obj, "Tab 1"); - ui_textarea(obj, NULL); - ui_end(obj); + UiObject *obj = ui_window("Test", NULL); + ui_set_document(obj, d1); - ui_tab(obj, "Tab 2"); - ui_textarea(obj, NULL); - ui_end(obj); + ui_textarea_nv(obj, "text"); + - ui_end(obj); + + ui_button(obj, "Switch Document", action_newdoc, NULL); ui_show(obj); } @@ -94,22 +124,7 @@ ui_menuitem("item3", action_menu, NULL); ui_submenu_end(); ui_menuitem("item4", action_menu, NULL); - - // toolbar - ui_toolitem("button1", "Test1", action_button, NULL); - ui_toolitem("button2", "Test2", action_button, NULL); - ui_toolitem("button3", "Test3", action_button, NULL); - ui_toolitem("button4", "Test4", action_button, NULL); - ui_toolitem("button5", "Test5", action_button, NULL); - ui_toolitem("button6", "Test6", action_button, NULL); - ui_toolitem("button7", "Test7", action_button, NULL); - ui_toolbar_add_default("button1"); - ui_toolbar_add_default("button2"); - ui_toolbar_add_default("button3"); - ui_toolbar_add_default("button4"); - ui_toolbar_add_default("button5"); - ui_toolbar_add_default("button6"); - ui_toolbar_add_default("button7"); + ui_main();
--- a/ui/common/context.c Tue Jan 24 18:46:47 2017 +0100 +++ b/ui/common/context.c Fri Nov 10 17:17:14 2017 +0100 @@ -1,7 +1,7 @@ /* * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. * - * Copyright 2014 Olaf Wintermann. All rights reserved. + * Copyright 2017 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: @@ -34,6 +34,7 @@ #include "context.h" #include "../ui/window.h" #include "document.h" +#include "types.h" UiContext* uic_context(UiObject *toplevel, UcxMempool *mp) { @@ -64,85 +65,67 @@ if(ctx->document == document) { return; } + if(ctx->document) { + uic_context_detach_document(ctx); + } + ctx->document = document; UiContext *docctx = ui_document_context(document); if(!docctx) { + fprintf(stderr, "UiError: uic_context_set_document: pointer is not a document\n"); return; } docctx->obj = ctx->obj; docctx->parent = ctx; - if(ctx->document) { - uic_context_detach_document(ctx, ctx->document); + UiContext *root = uic_root_context(ctx); + if(!root->bound || root->bound->count == 0) { + return; } - //obj->document = document; - ctx->document = document; + // there are bound variables in the root ctx + // copy bindings with correct name to doc vars UcxMapIterator i = ucx_map_iterator(docctx->vars); UiVar *var; UCX_MAP_FOREACH(key, var, i) { - UiVar *v = ucx_map_get(uic_root_context(ctx)->vars, key); + UiVar *v = ucx_map_get(root->bound, key); if(v) { - if(v->isextern) { - fprintf( - stderr, - "UI Error: external variable cannot be moved\n"); - return; - } - // check type - if(var->type != v->type) { - fprintf(stderr, "UI Error: var has incompatible type.\n"); - return; - } - - // copy value - uic_move_var(v, var, TRUE); - var->from = v->from; - - // TODO: free var struct - ucx_map_remove(ctx->vars, key); + // copy binding: after this all doc vars with names of previously + // bound variables are bound to the widgets + // the widgets still hold a pointer to the root ctx vars, but this + // vars have a pointer to the document variable value - confusing + uic_copy_binding(v, var, TRUE); } } } -void uic_context_detach_document(UiContext *ctx, void *document) { - UiContext *docctx = ui_document_context(document); - if(!docctx) { - fprintf( - stderr, - "UiError: ui_detach_document: document is not registered\n"); - return; - } - if(ctx->document != document) { - fprintf(stderr, "UiError: ui_detach_document: wrong document\n"); +void uic_context_detach_document(UiContext *ctx) { + if(!ctx->document) { return; } + UiContext *docctx = ui_document_context(ctx->document); + if(!docctx) { + fprintf(stderr, "UiError: Cannot detach document: no context\n"); + return; + } + ctx->document = NULL; + docctx->parent = NULL; + docctx->obj = NULL; + + // unbind all vars UcxMapIterator i = ucx_map_iterator(docctx->vars); UiVar *var; UCX_MAP_FOREACH(key, var, i) { - if(var->from && var->from != docctx->vars) { - // this var is bind to an outer widget, so we move it - UcxAllocator *a = var->from->allocator; - UiVar *newvar = a->malloc(a->pool, sizeof(UiVar)); - newvar->value = uic_create_value(a, var->type); - uic_move_var(var, newvar, 0); - newvar->type = var->type; - newvar->from = var->from; - newvar->isextern = 0; - - ucx_map_put(var->from, key, newvar); - - //ucx_map_remove(doc->vars, key); // TODO: dont remove! + if(var->from) { + // restore old root bound var val + var->from->value = var->from->orig_val; + var->from->orig_val = NULL; + // copy + uic_copy_binding(var, var->from, FALSE); } + uic_unbind_var(var); } - - if(docctx->parent) { - docctx->parent->document = NULL; - } - - docctx->obj = NULL; - docctx->parent = NULL; } UiVar* uic_get_var(UiContext *ctx, char *name) { @@ -161,185 +144,207 @@ return var; } -UiVar* uic_connect_var(UiContext *ctx, char *name, int type) { - // TODO: get current map (Document Container, Tabbed Pane) - UcxMap *from = ctx->vars; +UiVar* uic_create_var(UiContext *ctx, char *name, UiVarType type) { + // check if this context has a var with this name + // otherweise add it to the bound map + UiVar *cv = ucx_map_cstr_get(ctx->vars, name); + if(cv) { + return cv; // I'm not sure if this can actually happen, lol + } + + // create var and add it to the bound map + // this map contains vars that are created by widgets + // the vars can later be moved to subdocuments + UiVar *var = ui_malloc(ctx, sizeof(UiVar)); + var->type = type; + var->value = uic_create_value(ctx, type); + var->orig_val = NULL; + var->from = NULL; // not connected to a doc var - UiVar *var = uic_get_var(ctx, name); - if(var) { - // the value is registered - - // a little type check - if(var->type != type) { - fprintf(stderr, "UI Error: var %s has incompatible type.\n", name); - return NULL; - } else { - // register the current document/wdata map - // if the document is closed, the var will be moved to this map - var->from = from; - - return var; + if(!ctx->bound) { + ctx->bound = ucx_map_new_a(ctx->mempool->allocator, 16); + } + size_t oldcount = ctx->bound->count; + ucx_map_cstr_put(ctx->bound, name, var); + if(ctx->bound->count != oldcount + 1) { + fprintf(stderr, "UiError: var '%s' already bound\n", name); + } + + // if a subdocument has a variable with this name, we must copy + // the binding to the doc var + UiContext *doc_ctx = ui_document_context(ctx->document); + if(doc_ctx) { + UiVar *docvar = uic_get_var(doc_ctx, name); + if(docvar) { + var->orig_val = var->value; + var->value = docvar->value; + docvar->from = var; } - } else { - // create an empty value and add it to the context variables - // it can be moved to the document vars later - void *value = uic_create_value(ctx->mempool->allocator, type); - if(!value) { - fprintf(stderr, "UI Error: Cannot create empty value.\n"); - return NULL; - } - UiVar *var = ucx_mempool_malloc(ctx->mempool, sizeof(UiVar)); - var->value = value; - var->type = type; - var->isextern = 0; - var->from = from; - ucx_map_cstr_put(ctx->vars, name, var); - return var; } + + return var; } -void uic_move_var(UiVar *from, UiVar *to, UiBool set) { +void* uic_create_value(UiContext *ctx, UiVarType type) { + void *val = NULL; + switch(type) { + case UI_VAR_INTEGER: { + val = ui_int_new(ctx, NULL); + break; + } + case UI_VAR_STRING: { + val = ui_string_new(ctx, NULL); + break; + } + case UI_VAR_TEXT: { + val = ui_text_new(ctx, NULL); + break; + } + case UI_VAR_LIST: { + val = NULL; // TODO + break; + } + case UI_VAR_RANGE: { + val = NULL; // TODO + break; + } + } + return val; +} + +void uic_copy_binding(UiVar *from, UiVar *to, UiBool copytodoc) { + if(copytodoc && from->from) { + fprintf(stderr, "UiError: var already connected to a document\n"); + return; + } + + // check type + if(from->type != to->type) { + fprintf(stderr, "UI Error: var has incompatible type.\n"); + return; + } + + // copy binding + // we don't copy the observer, because the from var has never one switch(from->type) { + default: fprintf(stderr, "uic_copy_binding: wtf!\n"); break; + case UI_VAR_SPECIAL: break; case UI_VAR_INTEGER: { - //memcpy(to->value, from->value, sizeof(UiInteger)); UiInteger *f = from->value; UiInteger *t = to->value; - t->get = f->get; - t->set = f->set; - t->obj = f->obj; - if(set) { + if(!copytodoc) { + f->value = f->get(f); + } + uic_int_copy(f, t); + if(t->value != 0) { t->set(t, t->value); - } else { - //t->value = t->get(t); - f->value = f->get(f); - //t->value = 0; } break; } case UI_VAR_STRING: { - // TODO + UiString *f = from->value; + UiString *t = to->value; + uic_string_copy(f, t); + if(!copytodoc) { + f->value = f->get(f); + } else { + char *tvalue = t->value ? t->value : ""; + t->set(t, tvalue); + } + break; } case UI_VAR_TEXT: { UiText *f = from->value; UiText *t = to->value; - char *tvalue = t->value ? t->value : ""; - int tpos = t->pos; - memcpy(t, f, sizeof(UiText)); - if(set) { - t->set(t, tvalue); - t->setposition(t, tpos); + uic_text_copy(f, t); + if(!copytodoc) { + f->value = f->get(f); } else { - f->value = f->get(f); - f->pos = f->position(f); - f->set = NULL; - f->get = NULL; - f->setposition = NULL; - f->position = NULL; + char *tvalue = t->value ? t->value : ""; + t->set(t, tvalue); + t->setposition(t, t->pos); } break; } case UI_VAR_LIST: { - UiListVar *f = from->value; - UiListVar *t = to->value; - UiList *list = t->listptr->list; - UiObserver *observers = f->listptr->list->observers; - t->listptr = f->listptr; - if(set) { - t->listptr->list = list; - list->observers = observers; - ui_notify(observers, list); + UiList *f = from->value; + UiList *t = to->value; + uic_list_copy(f, t); + t->update(t, -1); + } + case UI_VAR_RANGE: { + UiRange *f = from->value; + UiRange *t = to->value; + if(!copytodoc) { + f->value = f->get(f); } - break; + uic_range_copy(f, t); + t->setextent(t, t->extent); + t->setrange(t, t->min, t->max); + t->set(t, t->value); } } + + if(copytodoc) { + to->from = from; + + from->orig_val = from->value; + from->value = to->value; + } +} + +void uic_unbind_var(UiVar *var) { + switch(var->type) { + case UI_VAR_INTEGER: uic_int_unbind(var->value); break; + case UI_VAR_STRING: uic_string_unbind(var->value); break; + case UI_VAR_TEXT: uic_text_unbind(var->value); break; + case UI_VAR_LIST: uic_list_unbind(var->value); break; + case UI_VAR_RANGE: uic_range_unbind(var->value); break; + } } -void uic_reg_var(UiContext *ctx, char *name, int type, size_t vs, void *value) { - UiVar *newvar = ucx_mempool_malloc(ctx->mempool, sizeof(UiVar)); - newvar->isextern = 1; - newvar->type = type; - newvar->value = value; - newvar->from = NULL; +void uic_reg_var(UiContext *ctx, char *name, UiVarType type, void *value) { + UiContext *rootctx = uic_root_context(ctx); + + UiVar *b = NULL; + if(rootctx->bound) { + // some widgets are already bound to some vars + b = ucx_map_cstr_get(rootctx->bound, name); + if(b) { + // a widget is bound to a var with this name + // if ctx is the root context we can remove the var from bound + // because set_doc or detach can't fuck things up + if(ctx == rootctx) { + ucx_map_cstr_remove(ctx->bound, name); + // TODO: free stuff + } + } + } - uic_add_var(ctx, name, newvar, type, vs); + // create new var and add it to doc's vars + UiVar *var = ui_malloc(ctx, sizeof(UiVar)); + var->from = NULL; + var->orig_val = NULL; + var->type = type; + var->value = value; + size_t oldcount = ctx->vars->count; + ucx_map_cstr_put(ctx->vars, name, var); + if(ctx->vars->count != oldcount + 1) { + fprintf(stderr, "UiError: var '%s' already exists\n", name); + } + + // a widget is already bound to a var with this name + // copy the binding (like uic_context_set_document) + if(b) { + uic_copy_binding(b, var, TRUE); + } } -void uic_add_var( - UiContext *ctx, - char *name, - UiVar *newvar, - int type, - size_t vs) -{ - // if a parent context has a variable with this name, we remove it and put - // it to this context - UiVar *var = ctx->obj ? uic_get_var(ctx->obj->ctx, name) : NULL; - - if(var && var->from != ctx->vars) { - // external variables cannot be moved - if(var->isextern) { - fprintf( - stderr, - "UI Error: external variable %s " - "cannot be moved to the document.\n", - name); - return; - } - - // check type - if(var->type != type) { - fprintf(stderr, "UI Error: var %s has incompatible type.\n", name); - return; - } - - // override document var with window context var - memcpy(newvar->value, var->value, vs); - - newvar->from = var->from; - - // TODO: free var struct - ucx_map_cstr_remove(var->from, name); - } - - // finally, add the new variable to the document - ucx_map_cstr_put(ctx->vars, name, newvar); +void uic_remove_bound_var(UiContext *ctx, UiVar *var) { + // TODO: implement } -void* uic_create_value(UcxAllocator *a, int type) { - switch(type) { - case UI_VAR_INTEGER: { - UiInteger *i = a->calloc( - a->pool, - 1, - sizeof(UiInteger)); - return i; - } - case UI_VAR_STRING: { - UiString *s = a->calloc( - a->pool, - 1, - sizeof(UiInteger)); - return s; - } - case UI_VAR_TEXT: { - UiText *t = a->calloc( - a->pool, - 1, - sizeof(UiText)); - return t; - } - case UI_VAR_LIST: { - UiListVar *l = a->malloc(a->pool, sizeof(UiListVar)); - UiListPtr *lp = a->malloc(a->pool, sizeof(UiListPtr)); - l->listptr = lp; - lp->list = NULL; - // TODO: create empty list - return l; - } - } - return NULL; -} // public API @@ -348,81 +353,6 @@ ctx->close_data = udata; } -int ui_getint(UiObject *obj, char *name) { - UiVar *var = uic_get_var(obj->ctx, name); - if(var) { - if(var->type == UI_VAR_INTEGER) { - UiInteger *i = var->value; - if(i->get) { - return i->get(i); - } else { - fprintf( - stderr, - "UI Error: variable %s is not connected.\n", - name); - } - } else { - fprintf( - stderr, - "UI Error: requested variable %s is not an integer.\n", - name); - } - } else { - fprintf(stderr, "UI Error: unkown variable %s.\n", name); - } - return 0; -} - -char* ui_getstr(UiObject *obj, char *name) { - UiVar *var = uic_get_var(obj->ctx, name); - if(var) { - if(var->type == UI_VAR_STRING) { - UiString *s = var->value; - if(s->get) { - return s->get(s); - } else { - fprintf( - stderr, - "UI Error: variable %s is not connected.\n", - name); - } - } else { - fprintf( - stderr, - "UI Error: requested variable %s is not an string.\n", - name); - } - } else { - fprintf(stderr, "UI Error: unkown variable %s.\n", name); - } - return NULL; -} - -char* ui_gettext(UiObject *obj, char *name) { - UiVar *var = uic_get_var(obj->ctx, name); - if(var) { - if(var->type == UI_VAR_TEXT) { - UiText *s = var->value; - if(s->get) { - return s->get(s); - } else { - fprintf( - stderr, - "UI Error: variable %s is not connected.\n", - name); - } - } else { - fprintf( - stderr, - "UI Error: requested variable %s is not a text.\n", - name); - } - } else { - fprintf(stderr, "UI Error: unkown variable %s.\n", name); - } - return NULL; -} - void ui_set_group(UiContext *ctx, int group) {
--- a/ui/common/context.h Tue Jan 24 18:46:47 2017 +0100 +++ b/ui/common/context.h Fri Nov 10 17:17:14 2017 +0100 @@ -1,7 +1,7 @@ /* * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. * - * Copyright 2014 Olaf Wintermann. All rights reserved. + * Copyright 2017 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: @@ -43,17 +43,29 @@ typedef struct UiListVar UiListVar; typedef struct UiGroupWidget UiGroupWidget; +typedef enum UiVarType UiVarType; + +enum UiVarType { + UI_VAR_SPECIAL = 0, + UI_VAR_INTEGER, + UI_VAR_STRING, + UI_VAR_TEXT, + UI_VAR_LIST, + UI_VAR_RANGE +}; + struct UiContext { UiContext *parent; UiObject *obj; UcxMempool *mempool; + UcxMap *bound; // key: char* value: UiVar* UcxMap *vars; // key: char* value: UiVar* void *document; UcxList *groups; // int list UcxList *group_widgets; // UiGroupWidget* list void (*set_document)(UiContext *ctx, void *document); - void (*detach_document)(UiContext *ctx, void *document); + void (*detach_document)(UiContext *ctx); char *title; @@ -66,18 +78,10 @@ }; struct UiVar { - void *value; - int type; - int isextern; - UcxMap *from; -}; - -struct UiListPtr { - UiList *list; -}; - -struct UiListVar { - UiListPtr *listptr; + void *value; + void *orig_val; + UiVarType type; + UiVar *from; }; struct UiGroupWidget { @@ -86,30 +90,22 @@ int numgroups; }; -enum UiVarType { - UI_VAR_INTEGER = 0, - UI_VAR_STRING, - UI_VAR_TEXT, - UI_VAR_LIST -}; UiContext* uic_context(UiObject *toplevel, UcxMempool *mp); UiContext* uic_root_context(UiContext *ctx); void uic_context_set_document(UiContext *ctx, void *document); -void uic_context_detach_document(UiContext *ctx, void *document); +void uic_context_detach_document(UiContext *ctx); + +//UiVar* uic_get_var(UiContext *ctx, char *name); +UiVar* uic_create_var(UiContext *ctx, char *name, UiVarType type); +void* uic_create_value(UiContext *ctx, UiVarType type); -UiVar* uic_get_var(UiContext *ctx, char *name); -UiVar* uic_connect_var(UiContext *ctx, char *name, int type); -void uic_move_var(UiVar *from, UiVar *to, UiBool set); -void uic_reg_var(UiContext *ctx, char *name, int type, size_t vs, void *value); -void uic_add_var( - UiContext *ctx, - char *name, - UiVar *newvar, - int type, - size_t vs); +void uic_copy_binding(UiVar *from, UiVar *to, UiBool copytodoc); +void uic_unbind_var(UiVar *var); -void* uic_create_value(UcxAllocator *a, int type); +void uic_reg_var(UiContext *ctx, char *name, UiVarType type, void *value); + +void uic_remove_bound_var(UiContext *ctx, UiVar *var); void uic_check_group_widgets(UiContext *ctx); void uic_add_group_widget(UiContext *ctx, void *widget, UcxList *groups);
--- a/ui/common/document.c Tue Jan 24 18:46:47 2017 +0100 +++ b/ui/common/document.c Fri Nov 10 17:17:14 2017 +0100 @@ -1,7 +1,7 @@ /* * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. * - * Copyright 2014 Olaf Wintermann. All rights reserved. + * Copyright 2017 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: @@ -42,8 +42,8 @@ obj->ctx->set_document(obj->ctx, document); } -void ui_detach_document(UiObject *obj, void *document) { - obj->ctx->detach_document(obj->ctx, document); +void ui_detach_document(UiObject *obj) { + obj->ctx->detach_document(obj->ctx); } void* ui_get_document(UiObject *obj) { @@ -63,7 +63,7 @@ if(!ctx) { fprintf(stderr, "UI Error: pointer is not a document\n"); } - uic_context_detach_document(ctx, sub); + uic_context_detach_document(ctx); } void* ui_get_subdocument(void *document) { @@ -98,68 +98,3 @@ return NULL; } } - -void* ui_document_malloc(void *doc, size_t size) { - UiContext *uidoc = ui_document_context(doc); - return ucx_mempool_malloc(uidoc->mempool, size); -} - -void* ui_document_calloc(void *doc, size_t nelem, size_t elsize) { - UiContext *uidoc = ucx_map_get(documents, ucx_key(&doc, sizeof(void*))); - return ucx_mempool_calloc(uidoc->mempool, nelem, elsize); -} - -void ui_document_free(void *doc, void *ptr) { - UiContext *uidoc = ucx_map_get(documents, ucx_key(&doc, sizeof(void*))); - ucx_mempool_free(uidoc->mempool, ptr); -} - -void* ui_document_realloc(void *doc, void *ptr, size_t size) { - UiContext *uidoc = ucx_map_get(documents, ucx_key(&doc, sizeof(void*))); - return ucx_mempool_realloc(uidoc->mempool, ptr, size); -} - -void uic_document_addvar(void *doc, char *name, int type, size_t vs) { - // TODO: remove - UiContext *ctx = ui_document_context(doc); - if(ctx) { - UiVar *newvar = ucx_mempool_malloc(ctx->mempool, sizeof(UiVar)); - newvar->isextern = 0; - newvar->type = type; - newvar->value = ucx_mempool_calloc(ctx->mempool, 1, vs); - newvar->from = NULL; - - uic_add_var(ctx, name, newvar, type, vs); - } -} - -void ui_document_addint(void *doc, char *name) { - uic_document_addvar(doc, name, UI_VAR_INTEGER, sizeof(UiInteger)); -} - - - -void ui_document_regint(void *doc, char *name, UiInteger *i) { - UiContext *ctx = ui_document_context(doc); - if(ctx) { - uic_reg_var(ctx, name, UI_VAR_INTEGER, sizeof(UiInteger), i); - } -} - -void ui_document_regtext(void *doc, char *name, UiText *text) { - UiContext *ctx = ui_document_context(doc); - if(ctx) { - uic_reg_var(ctx, name, UI_VAR_TEXT, sizeof(UiText), text); - } -} - -void ui_document_reglist(void *doc, char *name, UiList *list) { - UiContext *ctx = ui_document_context(doc); - if(ctx) { - UiListVar *lv = ui_document_malloc(doc, sizeof(UiListVar)); - UiListPtr *lp = ui_document_malloc(doc, sizeof(UiListPtr)); - lv->listptr = lp; - lp->list = list; - uic_reg_var(ctx, name, UI_VAR_LIST, sizeof(UiListPtr), lv); - } -}
--- a/ui/common/document.h Tue Jan 24 18:46:47 2017 +0100 +++ b/ui/common/document.h Fri Nov 10 17:17:14 2017 +0100 @@ -1,7 +1,7 @@ /* * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. * - * Copyright 2014 Olaf Wintermann. All rights reserved. + * Copyright 2017 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:
--- a/ui/common/object.c Tue Jan 24 18:46:47 2017 +0100 +++ b/ui/common/object.c Fri Nov 10 17:17:14 2017 +0100 @@ -1,7 +1,7 @@ /* * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. * - * Copyright 2014 Olaf Wintermann. All rights reserved. + * Copyright 2017 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:
--- a/ui/common/object.h Tue Jan 24 18:46:47 2017 +0100 +++ b/ui/common/object.h Fri Nov 10 17:17:14 2017 +0100 @@ -1,7 +1,7 @@ /* * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. * - * Copyright 2014 Olaf Wintermann. All rights reserved. + * Copyright 2017 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:
--- a/ui/common/objs.mk Tue Jan 24 18:46:47 2017 +0100 +++ b/ui/common/objs.mk Fri Nov 10 17:17:14 2017 +0100 @@ -1,7 +1,7 @@ # # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. # -# Copyright 2012 Olaf Wintermann. All rights reserved. +# Copyright 2017 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:
--- a/ui/common/properties.c Tue Jan 24 18:46:47 2017 +0100 +++ b/ui/common/properties.c Fri Nov 10 17:17:14 2017 +0100 @@ -1,7 +1,7 @@ /* * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. * - * Copyright 2014 Olaf Wintermann. All rights reserved. + * Copyright 2017 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:
--- a/ui/common/properties.h Tue Jan 24 18:46:47 2017 +0100 +++ b/ui/common/properties.h Fri Nov 10 17:17:14 2017 +0100 @@ -1,7 +1,7 @@ /* * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. * - * Copyright 2014 Olaf Wintermann. All rights reserved. + * Copyright 2017 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:
--- a/ui/common/types.c Tue Jan 24 18:46:47 2017 +0100 +++ b/ui/common/types.c Fri Nov 10 17:17:14 2017 +0100 @@ -1,7 +1,7 @@ /* * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. * - * Copyright 2014 Olaf Wintermann. All rights reserved. + * Copyright 2017 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: @@ -28,6 +28,7 @@ #include <stdio.h> #include <stdlib.h> +#include <string.h> #include <stdarg.h> #include "../../ucx/list.h" @@ -93,6 +94,9 @@ list->data = NULL; list->iter = NULL; + list->update = NULL; + list->obj = NULL; + return list; } @@ -199,3 +203,118 @@ ucx_mempool_free(ctx->mempool, mi->titles); ucx_mempool_free(ctx->mempool, mi); } + +// types + +// public functions +UiInteger* ui_int_new(UiContext *ctx, char *name) { + UiInteger *i = ui_malloc(ctx, sizeof(UiInteger)); + memset(i, 0, sizeof(UiInteger)); + if(name) { + uic_reg_var(ctx, name, UI_VAR_INTEGER, i); + } + return i; +} + +UiString* ui_string_new(UiContext *ctx, char *name) { + UiString *s = ui_malloc(ctx, sizeof(UiString)); + memset(s, 0, sizeof(UiString)); + if(name) { + uic_reg_var(ctx, name, UI_VAR_STRING, s); + } + return s; +} + +UiText* ui_text_new(UiContext *ctx, char *name) { + UiText *t = ui_malloc(ctx, sizeof(UiText)); + memset(t, 0, sizeof(UiText)); + if(name) { + uic_reg_var(ctx, name, UI_VAR_TEXT, t); + } + return t; +} + + +// private functions +void uic_int_copy(UiInteger *from, UiInteger *to) { + to->get = from->get; + to->set = from->set; + to->obj = from->obj; +} + +void uic_string_copy(UiString *from, UiString *to) { + to->get = from->get; + to->set = from->set; + to->obj = from->obj; +} + +void uic_text_copy(UiText *from, UiText *to) { + to->get = from->get; + to->set = from->set; + to->getsubstr = from->getsubstr; + to->insert = from->insert; + to->setposition = from->setposition; + to->position = from->position; + to->selection = from->selection; + to->length = from->length; + to->remove = from->remove; + + to->obj = from->obj; + // do not copy the undo manager +} + +void uic_range_copy(UiRange *from, UiRange *to) { + to->get = from->get; + to->set = from->set; + to->setrange = from->setrange; + to->setextent = from->setextent; + to->obj = from->obj; +} + +void uic_list_copy(UiList *from, UiList *to) { + to->update = from->update; + to->obj = from->obj; +} + + +void uic_int_unbind(UiInteger *i) { + i->value = i->get(i); + i->get = NULL; + i->set = NULL; + i->obj = NULL; +} + +void uic_string_unbind(UiString *s) { + s->value = s->get(s); + s->get = NULL; + s->set = NULL; + s->obj = NULL; +} + +void uic_text_unbind(UiText *t) { + t->value = t->get(t); + t->set = NULL; + t->get = NULL; + t->getsubstr = NULL; + t->insert = NULL; + t->setposition = NULL; + t->position = NULL; + t->selection = NULL; + t->length = NULL; + t->remove = NULL; + t->obj = NULL; +} + +void uic_range_unbind(UiRange *r) { + r->value = r->get(r); + r->get = NULL; + r->set = NULL; + r->setextent = NULL; + r->setrange = NULL; + r->obj = NULL; +} + +void uic_list_unbind(UiList *l) { + l->update = NULL; + l->obj = NULL; +}
--- a/ui/common/types.h Tue Jan 24 18:46:47 2017 +0100 +++ b/ui/common/types.h Fri Nov 10 17:17:14 2017 +0100 @@ -1,7 +1,7 @@ /* * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. * - * Copyright 2014 Olaf Wintermann. All rights reserved. + * Copyright 2017 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: @@ -35,24 +35,18 @@ extern "C" { #endif -/* -UiObserver* ui_observer_new(ui_callback f, void *data); -UiObserver* ui_obsvlist_add(UiObserver *list, UiObserver *observer); -UiObserver* ui_add_observer(UiObserver *list, ui_callback f, void *data); -void ui_notify(UiObserver *observer, void *data); -void ui_notify_except(UiObserver *observer, UiObserver *exc, void *data); - -UiList* ui_list_new(); -void* ui_list_first(UiList *list); -void* ui_list_next(UiList *list); -void* ui_list_get(UiList *list, int i); -int ui_list_count(UiList *list); -void ui_list_append(UiList *list, void *data); -void ui_list_prepend(UiList *list, void *data); -void ui_list_addobsv(UiList *list, ui_callback f, void *data); -void ui_list_notify(UiList *list); -*/ +void uic_int_copy(UiInteger *from, UiInteger *to); +void uic_string_copy(UiString *from, UiString *to); +void uic_text_copy(UiText *from, UiText *to); +void uic_range_copy(UiRange *from, UiRange *to); +void uic_list_copy(UiList *from, UiList *to); + +void uic_int_unbind(UiInteger *i); +void uic_string_unbind(UiString *s); +void uic_text_unbind(UiText *t); +void uic_range_unbind(UiRange *r); +void uic_list_unbind(UiList *l); #ifdef __cplusplus }
--- a/ui/gtk/button.c Tue Jan 24 18:46:47 2017 +0100 +++ b/ui/gtk/button.c Fri Nov 10 17:17:14 2017 +0100 @@ -1,7 +1,7 @@ /* * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. * - * Copyright 2014 Olaf Wintermann. All rights reserved. + * Copyright 2017 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:
--- a/ui/gtk/button.h Tue Jan 24 18:46:47 2017 +0100 +++ b/ui/gtk/button.h Fri Nov 10 17:17:14 2017 +0100 @@ -1,7 +1,7 @@ /* * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. * - * Copyright 2014 Olaf Wintermann. All rights reserved. + * Copyright 2017 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:
--- a/ui/gtk/container.c Tue Jan 24 18:46:47 2017 +0100 +++ b/ui/gtk/container.c Fri Nov 10 17:17:14 2017 +0100 @@ -1,7 +1,7 @@ /* * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. * - * Copyright 2014 Olaf Wintermann. All rights reserved. + * Copyright 2017 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: @@ -481,8 +481,8 @@ //ctx->parent->document = document; } -void ui_tab_detach_document(UiContext *ctx, void *document) { - uic_context_detach_document(ctx->parent, document); +void ui_tab_detach_document(UiContext *ctx) { + uic_context_detach_document(ctx->parent); }
--- a/ui/gtk/container.h Tue Jan 24 18:46:47 2017 +0100 +++ b/ui/gtk/container.h Fri Nov 10 17:17:14 2017 +0100 @@ -1,7 +1,7 @@ /* * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. * - * Copyright 2014 Olaf Wintermann. All rights reserved. + * Copyright 2017 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: @@ -30,6 +30,7 @@ #define CONTAINER_H #include "../ui/toolkit.h" +#include "../ui/container.h" #include <string.h> #ifdef __cplusplus @@ -114,7 +115,7 @@ UiObject* ui_add_document_tab(UiDocumentView *view); void ui_tab_set_document(UiContext *ctx, void *document); -void ui_tab_detach_document(UiContext *ctx, void *document); +void ui_tab_detach_document(UiContext *ctx); #ifdef __cplusplus }
--- a/ui/gtk/draw_cairo.c Tue Jan 24 18:46:47 2017 +0100 +++ b/ui/gtk/draw_cairo.c Fri Nov 10 17:17:14 2017 +0100 @@ -1,7 +1,7 @@ /* * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. * - * Copyright 2013 Olaf Wintermann. All rights reserved. + * Copyright 2017 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:
--- a/ui/gtk/draw_cairo.h Tue Jan 24 18:46:47 2017 +0100 +++ b/ui/gtk/draw_cairo.h Fri Nov 10 17:17:14 2017 +0100 @@ -1,7 +1,7 @@ /* * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. * - * Copyright 2013 Olaf Wintermann. All rights reserved. + * Copyright 2017 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:
--- a/ui/gtk/draw_gdk.c Tue Jan 24 18:46:47 2017 +0100 +++ b/ui/gtk/draw_gdk.c Fri Nov 10 17:17:14 2017 +0100 @@ -1,7 +1,7 @@ /* * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. * - * Copyright 2011 Olaf Wintermann. All rights reserved. + * Copyright 2017 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:
--- a/ui/gtk/draw_gdk.h Tue Jan 24 18:46:47 2017 +0100 +++ b/ui/gtk/draw_gdk.h Fri Nov 10 17:17:14 2017 +0100 @@ -1,7 +1,7 @@ /* * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. * - * Copyright 2012 Olaf Wintermann. All rights reserved. + * Copyright 2017 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:
--- a/ui/gtk/graphics.c Tue Jan 24 18:46:47 2017 +0100 +++ b/ui/gtk/graphics.c Fri Nov 10 17:17:14 2017 +0100 @@ -1,7 +1,7 @@ /* * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. * - * Copyright 2012 Olaf Wintermann. All rights reserved. + * Copyright 2017 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:
--- a/ui/gtk/graphics.h Tue Jan 24 18:46:47 2017 +0100 +++ b/ui/gtk/graphics.h Fri Nov 10 17:17:14 2017 +0100 @@ -1,7 +1,7 @@ /* * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. * - * Copyright 2012 Olaf Wintermann. All rights reserved. + * Copyright 2017 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:
--- a/ui/gtk/image.c Tue Jan 24 18:46:47 2017 +0100 +++ b/ui/gtk/image.c Fri Nov 10 17:17:14 2017 +0100 @@ -1,7 +1,7 @@ /* * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. * - * Copyright 2014 Olaf Wintermann. All rights reserved. + * Copyright 2017 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:
--- a/ui/gtk/image.h Tue Jan 24 18:46:47 2017 +0100 +++ b/ui/gtk/image.h Fri Nov 10 17:17:14 2017 +0100 @@ -1,7 +1,7 @@ /* * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. * - * Copyright 2014 Olaf Wintermann. All rights reserved. + * Copyright 2017 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:
--- a/ui/gtk/label.c Tue Jan 24 18:46:47 2017 +0100 +++ b/ui/gtk/label.c Fri Nov 10 17:17:14 2017 +0100 @@ -1,7 +1,7 @@ /* * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. * - * Copyright 2014 Olaf Wintermann. All rights reserved. + * Copyright 2017 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:
--- a/ui/gtk/label.h Tue Jan 24 18:46:47 2017 +0100 +++ b/ui/gtk/label.h Fri Nov 10 17:17:14 2017 +0100 @@ -1,7 +1,7 @@ /* * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. * - * Copyright 2014 Olaf Wintermann. All rights reserved. + * Copyright 2017 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:
--- a/ui/gtk/menu.c Tue Jan 24 18:46:47 2017 +0100 +++ b/ui/gtk/menu.c Fri Nov 10 17:17:14 2017 +0100 @@ -1,7 +1,7 @@ /* * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. * - * Copyright 2014 Olaf Wintermann. All rights reserved. + * Copyright 2017 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: @@ -346,7 +346,7 @@ GtkWidget *widget = gtk_check_menu_item_new_with_mnemonic(ci->label); gtk_menu_shell_append(GTK_MENU_SHELL(p), widget); - UiVar *var = uic_connect_var(obj->ctx, ci->varname, UI_VAR_INTEGER); + UiVar *var = uic_create_var(obj->ctx, ci->varname, UI_VAR_INTEGER); if(var) { UiInteger *value = var->value; value->obj = widget;
--- a/ui/gtk/menu.h Tue Jan 24 18:46:47 2017 +0100 +++ b/ui/gtk/menu.h Fri Nov 10 17:17:14 2017 +0100 @@ -1,7 +1,7 @@ /* * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. * - * Copyright 2014 Olaf Wintermann. All rights reserved. + * Copyright 2017 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:
--- a/ui/gtk/model.c Tue Jan 24 18:46:47 2017 +0100 +++ b/ui/gtk/model.c Fri Nov 10 17:17:14 2017 +0100 @@ -1,7 +1,7 @@ /* * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. * - * Copyright 2014 Olaf Wintermann. All rights reserved. + * Copyright 2017 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: @@ -92,7 +92,7 @@ static void list_model_init(UiListModel *instance, GObjectClass *cl) { instance->columntypes = NULL; - instance->list = NULL; + instance->var = NULL; instance->numcolumns = 0; instance->stamp = g_random_int(); } @@ -122,10 +122,10 @@ value->g_type = G_TYPE_INVALID; } -UiListModel* ui_list_model_new(UiListPtr *list, UiModelInfo *info) { +UiListModel* ui_list_model_new(UiVar *var, UiModelInfo *info) { UiListModel *model = g_object_new(list_model_type, NULL); model->info = info; - model->list = list; + model->var = var; model->columntypes = calloc(sizeof(GType), 2 * info->columns); int ncol = 0; for(int i=0;i<info->columns;i++) { @@ -168,7 +168,7 @@ { g_assert(IS_UI_LIST_MODEL(tree_model)); UiListModel *model = UI_LIST_MODEL(tree_model); - UiList *list = model->list->list; + UiList *list = model->var->value; // check the depth of the path // a list must have a depth of 1 @@ -215,7 +215,6 @@ g_return_val_if_fail(iter->user_data != NULL, NULL); UiListModel *model = UI_LIST_MODEL(tree_model); - UiList *list = model->list->list; GtkTreePath *path = gtk_tree_path_new(); gtk_tree_path_append_index(path, (int)(intptr_t)iter->user_data2); // list->index @@ -234,7 +233,7 @@ g_return_if_fail(iter->user_data != NULL); UiListModel *model = UI_LIST_MODEL(tree_model); - UiList *list = model->list->list; + UiList *list = model->var->value; g_return_if_fail(column < model->numcolumns); @@ -261,7 +260,7 @@ g_return_val_if_fail(iter->user_data != NULL, FALSE); UiListModel *model = UI_LIST_MODEL(tree_model); - UiList *list = model->list->list; + UiList *list = model->var->value; list->iter = iter->user_data; //list->index = (int)(intptr_t)iter->user_data2; void *val = list->next(list); @@ -282,7 +281,7 @@ g_return_val_if_fail(IS_UI_LIST_MODEL(tree_model), FALSE); UiListModel *model = UI_LIST_MODEL(tree_model); - UiList *list = model->list->list; + UiList *list = model->var->value; if(parent) { return FALSE; @@ -317,7 +316,7 @@ if(!iter) { // return number of rows UiListModel *model = UI_LIST_MODEL(tree_model); - UiList *list = model->list->list; + UiList *list = model->var->value; return list->count(list); } @@ -337,7 +336,7 @@ } UiListModel *model = UI_LIST_MODEL(tree_model); - UiList *list = model->list->list; + UiList *list = model->var->value; // check n if(n == 0) {
--- a/ui/gtk/model.h Tue Jan 24 18:46:47 2017 +0100 +++ b/ui/gtk/model.h Fri Nov 10 17:17:14 2017 +0100 @@ -1,7 +1,7 @@ /* * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. * - * Copyright 2013 Olaf Wintermann. All rights reserved. + * Copyright 2017 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: @@ -45,7 +45,7 @@ struct UiListModel { GObject object; UiModelInfo *info; - UiListPtr *list; + UiVar *var; GType *columntypes; int numcolumns; int stamp; @@ -59,7 +59,7 @@ /* * Creates a UiListModel for a given UiList */ -UiListModel* ui_list_model_new(UiListPtr *list, UiModelInfo *info); +UiListModel* ui_list_model_new(UiVar *var, UiModelInfo *info); // interface functions
--- a/ui/gtk/objs.mk Tue Jan 24 18:46:47 2017 +0100 +++ b/ui/gtk/objs.mk Fri Nov 10 17:17:14 2017 +0100 @@ -1,7 +1,7 @@ # # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. # -# Copyright 2012 Olaf Wintermann. All rights reserved. +# Copyright 2017 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:
--- a/ui/gtk/range.c Tue Jan 24 18:46:47 2017 +0100 +++ b/ui/gtk/range.c Fri Nov 10 17:17:14 2017 +0100 @@ -1,7 +1,7 @@ /* * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. * - * Copyright 2016 Olaf Wintermann. All rights reserved. + * Copyright 2017 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:
--- a/ui/gtk/range.h Tue Jan 24 18:46:47 2017 +0100 +++ b/ui/gtk/range.h Fri Nov 10 17:17:14 2017 +0100 @@ -1,7 +1,7 @@ /* * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. * - * Copyright 2016 Olaf Wintermann. All rights reserved. + * Copyright 2017 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:
--- a/ui/gtk/text.c Tue Jan 24 18:46:47 2017 +0100 +++ b/ui/gtk/text.c Fri Nov 10 17:17:14 2017 +0100 @@ -1,7 +1,7 @@ /* * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. * - * Copyright 2014 Olaf Wintermann. All rights reserved. + * Copyright 2017 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: @@ -32,8 +32,7 @@ #include "text.h" #include "container.h" -#include "../common/context.h" -#include "../common/document.h" + static void selection_handler( GtkTextBuffer *buf, @@ -57,7 +56,7 @@ } } -UIWIDGET ui_textarea(UiObject *obj, UiText *value) { +UIWIDGET ui_textarea_var(UiObject *obj, UiVar *var) { GtkWidget *text_area = gtk_text_view_new(); gtk_text_view_set_wrap_mode(GTK_TEXT_VIEW(text_area), GTK_WRAP_WORD_CHAR); g_signal_connect( @@ -65,17 +64,17 @@ "realize", G_CALLBACK(ui_textarea_realize_event), NULL); - g_signal_connect( - text_area, - "selection-clear-event", - G_CALLBACK(selection_handler), - NULL); + + UiTextArea *uitext = malloc(sizeof(UiTextArea)); + uitext->ctx = obj->ctx; + uitext->var = var; + uitext->last_selection_state = 0; - UiTextArea *uitext = ucx_mempool_malloc( - obj->ctx->mempool, - sizeof(UiTextArea)); - uitext->ctx = obj->ctx; - uitext->last_selection_state = 0; + g_signal_connect( + text_area, + "destroy", + G_CALLBACK(ui_textarea_destroy), + uitext); GtkWidget *scroll_area = gtk_scrolled_window_new (NULL, NULL); gtk_scrolled_window_set_policy( @@ -98,6 +97,7 @@ ct->add(ct, scroll_area, TRUE); // bind value + UiText *value = var->value; if(value) { GtkTextBuffer *buf = gtk_text_view_get_buffer(GTK_TEXT_VIEW(text_area)); @@ -126,12 +126,12 @@ buf, "insert-text", G_CALLBACK(ui_textbuf_insert), - value); + var); g_signal_connect( buf, "delete-range", G_CALLBACK(ui_textbuf_delete), - value); + var); g_signal_connect( buf, @@ -143,11 +143,25 @@ return scroll_area; } +void ui_textarea_destroy(GtkWidget *object, UiTextArea *textarea) { + ui_destroy_boundvar(textarea->ctx, textarea->var); + free(textarea); +} + +UIWIDGET ui_textarea(UiObject *obj, UiText *value) { + UiVar *var = NULL; + if(value) { + var = malloc(sizeof(UiVar)); + var->value = value; + var->type = UI_VAR_SPECIAL; + } + return ui_textarea_var(obj, var); +} + UIWIDGET ui_textarea_nv(UiObject *obj, char *varname) { - UiVar *var = uic_connect_var(obj->ctx, varname, UI_VAR_TEXT); + UiVar *var = uic_create_var(obj->ctx, varname, UI_VAR_TEXT); if(var) { - UiText *value = var->value; - return ui_textarea(obj, value); + return ui_textarea_var(obj, var); } else { // TODO: error } @@ -168,11 +182,11 @@ } void ui_textarea_set(UiText *text, char *str) { + gtk_text_buffer_set_text((GtkTextBuffer*)text->obj, str, -1); if(text->value) { g_free(text->value); } text->value = NULL; - gtk_text_buffer_set_text((GtkTextBuffer*)text->obj, str, -1); } char* ui_textarea_getsubstr(UiText *text, int begin, int end) { @@ -242,24 +256,7 @@ gtk_widget_grab_focus(widget); } -void ui_text_set(UiText *text, char *str) { - if(text->set) { - text->set(text, str); - } else { - if(text->value) { - g_free(text->value); - } - text->value = g_strdup(str); - } -} -char* ui_text_get(UiText *text) { - if(text->get) { - return text->get(text); - } else { - return text->value; - } -} // undo manager functions @@ -271,7 +268,11 @@ int length, void *data) { - UiText *value = data; + UiVar *var = data; + UiText *value = var->value; + if(!value->undomgr) { + value->undomgr = ui_create_undomgr(); + } UiUndoMgr *mgr = value->undomgr; if(!mgr->event) { return; @@ -332,7 +333,11 @@ GtkTextIter *end, void *data) { - UiText *value = data; + UiVar *var = data; + UiText *value = var->value; + if(!value->undomgr) { + value->undomgr = ui_create_undomgr(); + } UiUndoMgr *mgr = value->undomgr; if(!mgr->event) { return; @@ -474,8 +479,19 @@ } -static UIWIDGET create_textfield(UiObject *obj, int width, UiBool frameless, UiBool password, UiString *value) { +static UIWIDGET create_textfield_var(UiObject *obj, int width, UiBool frameless, UiBool password, UiVar *var) { GtkWidget *textfield = gtk_entry_new(); + + UiTextField *uitext = malloc(sizeof(UiTextField)); + uitext->ctx = obj->ctx; + uitext->var = var; + + g_signal_connect( + textfield, + "destroy", + G_CALLBACK(ui_textfield_destroy), + uitext); + if(width > 0) { gtk_entry_set_width_chars(GTK_ENTRY(textfield), width); } @@ -490,11 +506,12 @@ UiContainer *ct = uic_get_current_container(obj); ct->add(ct, textfield, FALSE); - if(value) { + if(var) { + UiString *value = var->value; if(value->value) { gtk_entry_set_text(GTK_ENTRY(textfield), value->value); g_free(value->value); - // TODO: free value + value->value = NULL; } value->get = ui_textfield_get; @@ -507,16 +524,30 @@ } static UIWIDGET create_textfield_nv(UiObject *obj, int width, UiBool frameless, UiBool password, char *varname) { - UiVar *var = uic_connect_var(obj->ctx, varname, UI_VAR_STRING); + UiVar *var = uic_create_var(obj->ctx, varname, UI_VAR_STRING); if(var) { - UiString *value = var->value; - return create_textfield(obj, width, frameless, password, value); + return create_textfield_var(obj, width, frameless, password, var); } else { // TODO: error } return NULL; } +static UIWIDGET create_textfield(UiObject *obj, int width, UiBool frameless, UiBool password, UiString *value) { + UiVar *var = NULL; + if(value) { + var = malloc(sizeof(UiVar)); + var->value = value; + var->type = UI_VAR_SPECIAL; + } + return create_textfield_var(obj, width, frameless, password, var); +} + +void ui_textfield_destroy(GtkWidget *object, UiTextField *textfield) { + ui_destroy_boundvar(textfield->ctx, textfield->var); + free(textfield); +} + UIWIDGET ui_textfield(UiObject *obj, UiString *value) { return create_textfield(obj, 0, FALSE, FALSE, value); }
--- a/ui/gtk/text.h Tue Jan 24 18:46:47 2017 +0100 +++ b/ui/gtk/text.h Fri Nov 10 17:17:14 2017 +0100 @@ -1,7 +1,7 @@ /* * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. * - * Copyright 2014 Olaf Wintermann. All rights reserved. + * Copyright 2017 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: @@ -32,6 +32,7 @@ #include "../ui/text.h" #include "toolkit.h" #include "../../ucx/list.h" +#include "../common/context.h" #ifdef __cplusplus extern "C" { @@ -56,9 +57,19 @@ typedef struct UiTextArea { UiContext *ctx; - int last_selection_state; + UiVar *var; + int last_selection_state; } UiTextArea; +typedef struct UiTextField { + UiContext *ctx; + UiVar *var; + // TODO: validatefunc +} UiTextField; + +UIWIDGET ui_textarea_var(UiObject *obj, UiVar *var); +void ui_textarea_destroy(GtkWidget *object, UiTextArea *textarea); + char* ui_textarea_get(UiText *text); void ui_textarea_set(UiText *text, char *str); char* ui_textarea_getsubstr(UiText *text, int begin, int end); @@ -85,6 +96,8 @@ void ui_free_textbuf_op(UiTextBufOp *op); int ui_check_insertstr(char *oldstr, int oldlen, char *newstr, int newlen); +void ui_textfield_destroy(GtkWidget *object, UiTextField *textfield); + char* ui_textfield_get(UiString *str); void ui_textfield_set(UiString *str, char *value);
--- a/ui/gtk/toolbar.c Tue Jan 24 18:46:47 2017 +0100 +++ b/ui/gtk/toolbar.c Fri Nov 10 17:17:14 2017 +0100 @@ -1,7 +1,7 @@ /* * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. * - * Copyright 2014 Olaf Wintermann. All rights reserved. + * Copyright 2017 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: @@ -164,8 +164,11 @@ void *udata) { UiToolbarComboBox *cb = malloc(sizeof(UiToolbarComboBox)); - cb->item.add_to = (ui_toolbar_add_f)add_toolbar_combobox; - cb->list = list; + cb->item.add_to = (ui_toolbar_add_f)add_toolbar_combobox; + UiVar *var = malloc(sizeof(UiVar)); + var->value = list; + var->type = UI_VAR_SPECIAL; + cb->var = var; cb->getvalue = getvalue; cb->callback = f; cb->userdata = udata; @@ -357,9 +360,7 @@ void add_toolbar_combobox(GtkToolbar *tb, UiToolbarComboBox *cb, UiObject *obj) { UiModelInfo *modelinfo = ui_model_info(obj->ctx, UI_STRING, "", -1); modelinfo->getvalue = cb->getvalue; - UiListPtr *listptr = ucx_mempool_malloc(obj->ctx->mempool, sizeof(UiListPtr)); - listptr->list = cb->list; - UiListModel *model = ui_list_model_new(listptr, modelinfo); + UiListModel *model = ui_list_model_new(cb->var, modelinfo); GtkWidget *combobox = ui_create_combobox(obj, model, cb->callback, cb->userdata); GtkToolItem *item = gtk_tool_item_new(); @@ -368,6 +369,16 @@ } void add_toolbar_combobox_nv(GtkToolbar *tb, UiToolbarComboBoxNV *cb, UiObject *obj) { - // TODO + UiVar *var = uic_create_var(obj->ctx, cb->listname, UI_VAR_LIST); + if(var) { + UiModelInfo *modelinfo = ui_model_info(obj->ctx, UI_STRING, "", -1); + modelinfo->getvalue = cb->getvalue; + UiListModel *model = ui_list_model_new(var, modelinfo); + + GtkWidget *combobox = ui_create_combobox(obj, model, cb->callback, cb->userdata); + GtkToolItem *item = gtk_tool_item_new(); + gtk_container_add(GTK_CONTAINER(item), combobox); + gtk_toolbar_insert(tb, item, -1); + } }
--- a/ui/gtk/toolbar.h Tue Jan 24 18:46:47 2017 +0100 +++ b/ui/gtk/toolbar.h Fri Nov 10 17:17:14 2017 +0100 @@ -1,7 +1,7 @@ /* * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. * - * Copyright 2014 Olaf Wintermann. All rights reserved. + * Copyright 2017 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: @@ -74,7 +74,7 @@ struct UiToolbarComboBox { UiToolItemI item; - UiList *list; + UiVar *var; ui_model_getvalue_f getvalue; ui_callback callback; void *userdata;
--- a/ui/gtk/toolkit.c Tue Jan 24 18:46:47 2017 +0100 +++ b/ui/gtk/toolkit.c Fri Nov 10 17:17:14 2017 +0100 @@ -1,7 +1,7 @@ /* * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. * - * Copyright 2014 Olaf Wintermann. All rights reserved. + * Copyright 2017 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: @@ -226,6 +226,14 @@ free(userdata); } +void ui_destroy_boundvar(UiContext *ctx, UiVar *var) { + if(var->type == UI_VAR_SPECIAL) { + free(var); + } else { + uic_remove_bound_var(ctx, var); + } +} + void ui_set_active_window(UiObject *obj) { active_window = obj; }
--- a/ui/gtk/toolkit.h Tue Jan 24 18:46:47 2017 +0100 +++ b/ui/gtk/toolkit.h Fri Nov 10 17:17:14 2017 +0100 @@ -1,7 +1,7 @@ /* * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. * - * Copyright 2014 Olaf Wintermann. All rights reserved. + * Copyright 2017 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: @@ -62,6 +62,8 @@ void ui_destroy_userdata(GtkWidget *object, void *userdata); +void ui_destroy_boundvar(UiContext *ctx, UiVar *var); + void ui_set_active_window(UiObject *obj); UiObject *ui_get_active_window();
--- a/ui/gtk/tree.c Tue Jan 24 18:46:47 2017 +0100 +++ b/ui/gtk/tree.c Fri Nov 10 17:17:14 2017 +0100 @@ -1,7 +1,7 @@ /* * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. * - * Copyright 2014 Olaf Wintermann. All rights reserved. + * Copyright 2017 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: @@ -46,7 +46,7 @@ return ui_listview(obj, list, ui_strmodel_getvalue, f, udata); } -UIWIDGET ui_listview_var(UiObject *obj, UiListPtr *list, ui_model_getvalue_f getvalue, ui_callback f, void *udata) { +UIWIDGET ui_listview_var(UiObject *obj, UiVar *var, ui_model_getvalue_f getvalue, ui_callback f, void *udata) { // create treeview GtkWidget *view = gtk_tree_view_new(); GtkCellRenderer *renderer = gtk_cell_renderer_text_new(); @@ -66,19 +66,24 @@ UiModelInfo *modelinfo = ui_model_info(obj->ctx, UI_STRING, "", -1); modelinfo->getvalue = getvalue; - UiListModel *model = ui_list_model_new(list, modelinfo); + UiList *list = var->value; + UiListModel *model = ui_list_model_new(var, modelinfo); gtk_tree_view_set_model(GTK_TREE_VIEW(view), GTK_TREE_MODEL(model)); - // add TreeView as observer to the UiList to update the TreeView if the - // data changes - UiTableView *listview = ucx_mempool_malloc(obj->ctx->mempool, sizeof(UiTableView)); + UiListView *listview = ucx_mempool_malloc(obj->ctx->mempool, sizeof(UiListView)); + listview->ctx = obj->ctx; listview->widget = view; - listview->list = list; + listview->var = var; listview->modelinfo = modelinfo; - list->list->observers = ui_add_observer( - list->list->observers, - (ui_callback)ui_listview_update, - listview); + g_signal_connect( + view, + "destroy", + G_CALLBACK(ui_listview_destroy), + listview); + + // bind var + list->update = ui_listview_update; + list->obj = listview; // add callback if(f) { @@ -114,16 +119,16 @@ } UIWIDGET ui_listview(UiObject *obj, UiList *list, ui_model_getvalue_f getvalue, ui_callback f, void *udata) { - UiListPtr *listptr = ucx_mempool_malloc(obj->ctx->mempool, sizeof(UiListPtr)); - listptr->list = list; - return ui_listview_var(obj, listptr, getvalue, f, udata); + UiVar *var = malloc(sizeof(UiVar)); + var->value = list; + var->type = UI_VAR_SPECIAL; + return ui_listview_var(obj, var, getvalue, f, udata); } UIWIDGET ui_listview_nv(UiObject *obj, char *varname, ui_model_getvalue_f getvalue, ui_callback f, void *udata) { - UiVar *var = uic_connect_var(obj->ctx, varname, UI_VAR_LIST); + UiVar *var = uic_create_var(obj->ctx, varname, UI_VAR_LIST); if(var) { - UiListVar *value = var->value; - return ui_listview_var(obj, value->listptr, getvalue, f, udata); + return ui_listview_var(obj, var, getvalue, f, udata); } else { // TODO: error } @@ -131,7 +136,7 @@ } -UIWIDGET ui_table_var(UiObject *obj, UiListPtr *list, UiModelInfo *modelinfo) { +UIWIDGET ui_table_var(UiObject *obj, UiVar *var, UiModelInfo *modelinfo) { // create treeview GtkWidget *view = gtk_tree_view_new(); int addi = 0; @@ -172,19 +177,26 @@ #endif - UiListModel *model = ui_list_model_new(list, modelinfo); + UiList *list = var->value; + UiListModel *model = ui_list_model_new(var, modelinfo); gtk_tree_view_set_model(GTK_TREE_VIEW(view), GTK_TREE_MODEL(model)); // add TreeView as observer to the UiList to update the TreeView if the // data changes - UiTableView *tableview = ucx_mempool_malloc(obj->ctx->mempool, sizeof(UiTableView)); + UiListView *tableview = ucx_mempool_malloc(obj->ctx->mempool, sizeof(UiListView)); + tableview->ctx = obj->ctx; tableview->widget = view; - tableview->list = list; + tableview->var = var; tableview->modelinfo = modelinfo; - list->list->observers = ui_add_observer( - list->list->observers, - (ui_callback)ui_listview_update, - tableview); + g_signal_connect( + view, + "destroy", + G_CALLBACK(ui_listview_destroy), + tableview); + + // bind var + list->update = ui_listview_update; + list->obj = tableview; // add callback UiTreeEventData *event = ui_malloc(obj->ctx, sizeof(UiTreeEventData)); @@ -232,31 +244,36 @@ } UIWIDGET ui_table(UiObject *obj, UiList *list, UiModelInfo *modelinfo) { - UiListPtr *listptr = ucx_mempool_malloc(obj->ctx->mempool, sizeof(UiListPtr)); - listptr->list = list; - return ui_table_var(obj, listptr, modelinfo); + UiVar *var = malloc(sizeof(UiVar)); + var->value = list; + var->type = UI_VAR_SPECIAL; + return ui_table_var(obj, var, modelinfo); } UIWIDGET ui_table_nv(UiObject *obj, char *varname, UiModelInfo *modelinfo) { - UiVar *var = uic_connect_var(obj->ctx, varname, UI_VAR_LIST); + UiVar *var = uic_create_var(obj->ctx, varname, UI_VAR_LIST); if(var) { - UiListVar *value = var->value; - return ui_table_var(obj, value->listptr, modelinfo); + return ui_table_var(obj, var, modelinfo); } else { // TODO: error } return NULL; } - - -void ui_listview_update(UiEvent *event, UiTableView *view) { - UiListModel *model = ui_list_model_new(view->list, view->modelinfo); - gtk_tree_view_set_model(GTK_TREE_VIEW(view->widget), GTK_TREE_MODEL(model)); - +void ui_listview_update(UiList *list, int i) { + UiListView *view = list->obj; + UiListModel *model = ui_list_model_new(view->var, view->modelinfo); + gtk_tree_view_set_model(GTK_TREE_VIEW(view->widget), GTK_TREE_MODEL(model)); // TODO: free old model } +void ui_listview_destroy(GtkWidget *w, UiListView *v) { + ui_destroy_boundvar(v->ctx, v->var); + // TODO: destroy model? + free(v); +} + + void ui_listview_activate_event( GtkTreeView *treeview, GtkTreePath *path, @@ -339,26 +356,27 @@ } UIWIDGET ui_combobox(UiObject *obj, UiList *list, ui_model_getvalue_f getvalue, ui_callback f, void *udata) { - UiListPtr *listptr = ucx_mempool_malloc(obj->ctx->mempool, sizeof(UiListPtr)); - listptr->list = list; - return ui_combobox_var(obj, listptr, getvalue, f, udata); + UiVar *var = malloc(sizeof(UiVar)); + var->value = list; + var->type = UI_VAR_SPECIAL; + return ui_combobox_var(obj, var, getvalue, f, udata); } UIWIDGET ui_combobox_nv(UiObject *obj, char *varname, ui_model_getvalue_f getvalue, ui_callback f, void *udata) { - UiVar *var = uic_connect_var(obj->ctx, varname, UI_VAR_LIST); + UiVar *var = uic_create_var(obj->ctx, varname, UI_VAR_LIST); if(var) { - UiListVar *value = var->value; - return ui_combobox_var(obj, value->listptr, getvalue, f, udata); + return ui_combobox_var(obj, var, getvalue, f, udata); } else { // TODO: error } return NULL; } -UIWIDGET ui_combobox_var(UiObject *obj, UiListPtr *list, ui_model_getvalue_f getvalue, ui_callback f, void *udata) { +UIWIDGET ui_combobox_var(UiObject *obj, UiVar *var, ui_model_getvalue_f getvalue, ui_callback f, void *udata) { UiModelInfo *modelinfo = ui_model_info(obj->ctx, UI_STRING, "", -1); modelinfo->getvalue = getvalue; - UiListModel *model = ui_list_model_new(list, modelinfo); + UiList *list = var->value; + UiListModel *model = ui_list_model_new(var, modelinfo); GtkWidget *combobox = ui_create_combobox(obj, model, f, udata); UiContainer *ct = uic_get_current_container(obj); @@ -368,11 +386,22 @@ GtkWidget* ui_create_combobox(UiObject *obj, UiListModel *model, ui_callback f, void *udata) { GtkWidget *combobox = gtk_combo_box_new_with_model(GTK_TREE_MODEL(model)); - UiList *list = model->list->list; - list->observers = ui_add_observer( - list->observers, - (ui_callback)ui_listview_update, - combobox); + UiListView *uicbox = malloc(sizeof(UiListView)); + uicbox->ctx = obj->ctx; + uicbox->widget = combobox; + uicbox->var = model->var; + uicbox->modelinfo = model->info; + + g_signal_connect( + combobox, + "destroy", + G_CALLBACK(ui_listview_destroy), + uicbox); + + // bind var + UiList *list = model->var->value; + list->update = ui_combobox_modelupdate; + list->obj = uicbox; GtkCellRenderer *renderer = gtk_cell_renderer_text_new(); gtk_cell_layout_pack_start(GTK_CELL_LAYOUT(combobox), renderer, TRUE); @@ -412,8 +441,9 @@ e->callback(&event, e->userdata); } -void ui_combobox_update(UiEvent *event, void *combobox) { - printf("ui_combobox_update\n"); - printf("TODO: implement\n"); +void ui_combobox_modelupdate(UiList *list, int i) { + UiListView *view = list->obj; + UiListModel *model = ui_list_model_new(view->var, view->modelinfo); + gtk_combo_box_set_model(GTK_COMBO_BOX(view->widget), GTK_TREE_MODEL(model)); }
--- a/ui/gtk/tree.h Tue Jan 24 18:46:47 2017 +0100 +++ b/ui/gtk/tree.h Fri Nov 10 17:17:14 2017 +0100 @@ -1,7 +1,7 @@ /* * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. * - * Copyright 2014 Olaf Wintermann. All rights reserved. + * Copyright 2017 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: @@ -37,11 +37,12 @@ extern "C" { #endif -typedef struct UiTableView { - GtkWidget *widget; - UiListPtr *list; - UiModelInfo *modelinfo; -} UiTableView; +typedef struct UiListView { + UiContext *ctx; + GtkWidget *widget; + UiVar *var; + UiModelInfo *modelinfo; +} UiListView; typedef struct UiTreeEventData { UiObject *obj; @@ -52,10 +53,12 @@ void* ui_strmodel_getvalue(void *elm, int column); -UIWIDGET ui_listview_var(UiObject *obj, UiListPtr *list, ui_model_getvalue_f getvalue, ui_callback f, void *udata); -UIWIDGET ui_table_var(UiObject *obj, UiListPtr *list, UiModelInfo *modelinfo); +UIWIDGET ui_listview_var(UiObject *obj, UiVar *var, ui_model_getvalue_f getvalue, ui_callback f, void *udata); +UIWIDGET ui_table_var(UiObject *obj, UiVar *var, UiModelInfo *modelinfo); -void ui_listview_update(UiEvent *event, UiTableView *view); +void ui_listview_update(UiList *list, int i); +void ui_listview_destroy(GtkWidget *w, UiListView *v); + void ui_listview_activate_event( GtkTreeView *tree_view, GtkTreePath *path, @@ -69,10 +72,10 @@ UiTreeEventData *event); int ui_tree_path_list_index(GtkTreePath *path); -UIWIDGET ui_combobox_var(UiObject *obj, UiListPtr *list, ui_model_getvalue_f getvalue, ui_callback f, void *udata); +UIWIDGET ui_combobox_var(UiObject *obj, UiVar *var, ui_model_getvalue_f getvalue, ui_callback f, void *udata); GtkWidget* ui_create_combobox(UiObject *obj, UiListModel *model, ui_callback f, void *udata); void ui_combobox_change_event(GtkComboBox *widget, UiEventData *e); -void ui_combobox_update(UiEvent *event, void *combobox); +void ui_combobox_modelupdate(UiList *list, int i); #ifdef __cplusplus }
--- a/ui/gtk/window.c Tue Jan 24 18:46:47 2017 +0100 +++ b/ui/gtk/window.c Fri Nov 10 17:17:14 2017 +0100 @@ -1,7 +1,7 @@ /* * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. * - * Copyright 2014 Olaf Wintermann. All rights reserved. + * Copyright 2017 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:
--- a/ui/ui/button.h Tue Jan 24 18:46:47 2017 +0100 +++ b/ui/ui/button.h Fri Nov 10 17:17:14 2017 +0100 @@ -1,7 +1,7 @@ /* * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. * - * Copyright 2014 Olaf Wintermann. All rights reserved. + * Copyright 2017 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:
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/ui/ui/container.h Fri Nov 10 17:17:14 2017 +0100 @@ -0,0 +1,76 @@ +/* + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. + * + * Copyright 2017 Olaf Wintermann. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef UI_CONTAINER_H +#define UI_CONTAINER_H + +#include "toolkit.h" + +#ifdef __cplusplus +extern "C" { +#endif + +UIWIDGET ui_vbox(UiObject *obj); +UIWIDGET ui_hbox(UiObject *obj); +UIWIDGET ui_vbox_sp(UiObject *obj, int margin, int spacing); +UIWIDGET ui_hbox_sp(UiObject *obj, int margin, int spacing); + +UIWIDGET ui_grid(UiObject *obj); +UIWIDGET ui_grid_sp(UiObject *obj, int margin, int columnspacing, int rowspacing); + +UIWIDGET ui_scrolledwindow(UiObject *obj); + +UIWIDGET ui_sidebar(UiObject *obj); +void ui_end(UiObject *obj); + +UIWIDGET ui_tabview(UiObject *obj); +void ui_tab(UiObject *obj, char *title); +void ui_select_tab(UIWIDGET tabview, int tab); + +// box container layout functions +void ui_layout_fill(UiObject *obj, UiBool fill); +// grid container layout functions +void ui_layout_hexpand(UiObject *obj, UiBool expand); +void ui_layout_vexpand(UiObject *obj, UiBool expand); +void ui_layout_gridwidth(UiObject *obj, int width); +void ui_newline(UiObject *obj); + + +UiTabbedPane* ui_tabbed_document_view(UiObject *obj); + +UiObject* ui_document_tab(UiTabbedPane *view); + + + + +#ifdef __cplusplus +} +#endif + +#endif /* UI_CONTAINER_H */ +
--- a/ui/ui/graphics.h Tue Jan 24 18:46:47 2017 +0100 +++ b/ui/ui/graphics.h Fri Nov 10 17:17:14 2017 +0100 @@ -1,7 +1,7 @@ /* * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. * - * Copyright 2015 Olaf Wintermann. All rights reserved. + * Copyright 2017 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:
--- a/ui/ui/menu.h Tue Jan 24 18:46:47 2017 +0100 +++ b/ui/ui/menu.h Fri Nov 10 17:17:14 2017 +0100 @@ -1,7 +1,7 @@ /* * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. * - * Copyright 2014 Olaf Wintermann. All rights reserved. + * Copyright 2017 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:
--- a/ui/ui/properties.h Tue Jan 24 18:46:47 2017 +0100 +++ b/ui/ui/properties.h Fri Nov 10 17:17:14 2017 +0100 @@ -1,7 +1,7 @@ /* * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. * - * Copyright 2014 Olaf Wintermann. All rights reserved. + * Copyright 2017 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:
--- a/ui/ui/range.h Tue Jan 24 18:46:47 2017 +0100 +++ b/ui/ui/range.h Fri Nov 10 17:17:14 2017 +0100 @@ -1,7 +1,7 @@ /* * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. * - * Copyright 2016 Olaf Wintermann. All rights reserved. + * Copyright 2017 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:
--- a/ui/ui/stock.h Tue Jan 24 18:46:47 2017 +0100 +++ b/ui/ui/stock.h Fri Nov 10 17:17:14 2017 +0100 @@ -1,7 +1,7 @@ /* * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. * - * Copyright 2014 Olaf Wintermann. All rights reserved. + * Copyright 2017 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:
--- a/ui/ui/text.h Tue Jan 24 18:46:47 2017 +0100 +++ b/ui/ui/text.h Fri Nov 10 17:17:14 2017 +0100 @@ -1,7 +1,7 @@ /* * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. * - * Copyright 2014 Olaf Wintermann. All rights reserved. + * Copyright 2017 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:
--- a/ui/ui/toolbar.h Tue Jan 24 18:46:47 2017 +0100 +++ b/ui/ui/toolbar.h Fri Nov 10 17:17:14 2017 +0100 @@ -1,7 +1,7 @@ /* * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. * - * Copyright 2014 Olaf Wintermann. All rights reserved. + * Copyright 2017 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:
--- a/ui/ui/toolkit.h Tue Jan 24 18:46:47 2017 +0100 +++ b/ui/ui/toolkit.h Fri Nov 10 17:17:14 2017 +0100 @@ -1,7 +1,7 @@ /* * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. * - * Copyright 2014 Olaf Wintermann. All rights reserved. + * Copyright 2017 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: @@ -97,23 +97,16 @@ typedef struct UiList UiList; typedef struct UiRange UiRange; -/* private types */ +/* begin opaque types */ typedef struct UiContext UiContext; typedef struct UiContainer UiContainer; +/* end opaque types */ typedef struct UiTabbedPane UiTabbedPane; enum UiMouseEventType { UI_PRESS = 0, UI_PRESS2 }; -#define ui_getval(val) (val).get(&(val)) -#define ui_setval(val, v) (val).set(&(val), v) -#define ui_getsubstr(text, begin, end) (text).getsubstr(&(text), begin, end) -#define ui_insert(text, begin, str) (text).insert(&(text), begin, str) -#define ui_length(text) (text).length(&(text)) -#define ui_selection(text, begin, end) (text).selection(&(text), begin, end) -#define ui_position(text) (text).position(&(text)) -#define ui_remove(text, begin, end) (text).remove(&(text), begin, end) typedef void(*ui_callback)(UiEvent*, void*); /* event, user data */ @@ -133,12 +126,12 @@ void *window; /* - * window context (private) + * window context */ UiContext *ctx; /* - * container interface (private) + * container interface */ UiContainer *container; @@ -189,32 +182,37 @@ struct UiInteger { int (*get)(UiInteger*); void (*set)(UiInteger*, int); + void *obj; + int value; - void *obj; + UiObserver *observers; }; struct UiString { char* (*get)(UiString*); void (*set)(UiString*, char*); + void *obj; + char* value; - void *obj; + UiObserver *observers; }; struct UiText { void (*set)(UiText*, char*); char* (*get)(UiText*); - char* (*getsubstr)(UiText*, int, int); // text, begin, end + char* (*getsubstr)(UiText*, int, int); /* text, begin, end */ void (*insert)(UiText*, int, char*); void (*setposition)(UiText*,int); int (*position)(UiText*); - void (*selection)(UiText*, int*, int*); // text, begin, end + void (*selection)(UiText*, int*, int*); /* text, begin, end */ int (*length)(UiText*); - void (*remove)(UiText*, int, int); // text, begin, end + void (*remove)(UiText*, int, int); /* text, begin, end */ char *value; int pos; void *obj; void *undomgr; - // TODO: replace, ... + // TODO: replacefunc, ... + UiObserver *observers; }; /* @@ -229,13 +227,18 @@ void*(*get)(UiList *list, int i); /* get the number of elements */ int(*count)(UiList *list); - /* list of observers */ - UiObserver *observers; /* iterator changes after first() next() and get() */ void *iter; /* private - implementation dependent */ void *data; + /* binding function */ + void (*update)(UiList *list, int i); + /* binding object */ + void *obj; + + /* list of observers */ + UiObserver *observers; }; struct UiRange { @@ -248,15 +251,14 @@ double max; double extent; void *obj; + /* list of observers */ + UiObserver *observers; }; void ui_init(char *appname, int argc, char **argv); char* ui_appname(); -void ui_exitfunc(ui_callback f, void *userdata); // deprecated -void ui_openfilefunc(ui_callback f, void *userdata); // deprecated - void ui_context_closefunc(UiContext *ctx, ui_callback fnc, void *udata); void ui_onstartup(ui_callback f, void *userdata); @@ -269,74 +271,18 @@ void ui_job(UiObject *obj, ui_threadfunc tf, void *td, ui_callback f, void *fd); -void ui_set_enabled(UIWIDGET widget, int enabled); -void ui_set_show_all(UIWIDGET widget, int value); -void ui_set_visible(UIWIDGET widget, int visible); - -UIWIDGET ui_vbox(UiObject *obj); -UIWIDGET ui_hbox(UiObject *obj); -UIWIDGET ui_vbox_sp(UiObject *obj, int margin, int spacing); -UIWIDGET ui_hbox_sp(UiObject *obj, int margin, int spacing); - -UIWIDGET ui_grid(UiObject *obj); -UIWIDGET ui_grid_sp(UiObject *obj, int margin, int columnspacing, int rowspacing); - -UIWIDGET ui_scrolledwindow(UiObject *obj); - -UIWIDGET ui_sidebar(UiObject *obj); -void ui_end(UiObject *obj); - -UIWIDGET ui_tabview(UiObject *obj); -void ui_tab(UiObject *obj, char *title); -void ui_select_tab(UIWIDGET tabview, int tab); - -// box container layout functions -void ui_layout_fill(UiObject *obj, UiBool fill); -// grid container layout functions -void ui_layout_hexpand(UiObject *obj, UiBool expand); -void ui_layout_vexpand(UiObject *obj, UiBool expand); -void ui_layout_gridwidth(UiObject *obj, int width); -void ui_newline(UiObject *obj); - - -UiTabbedPane* ui_tabbed_document_view(UiObject *obj); - -UiObject* ui_document_tab(UiTabbedPane *view); - - - +void* ui_document_new(size_t size); +void ui_document_destroy(void *doc); void ui_set_document(UiObject *obj, void *document); -void ui_detach_document(UiObject *obj, void *document); +void ui_detach_document(UiObject *obj); void* ui_get_document(UiObject *obj); void ui_set_subdocument(void *document, void *sub); void ui_detach_subdocument(void *document, void *sub); void* ui_get_subdocument(void *document); -void* ui_document_new(size_t size); -void ui_document_destroy(void *doc); - UiContext* ui_document_context(void *doc); -// TODO: remove -void* ui_document_malloc(void *doc, size_t size); -void* ui_document_calloc(void *doc, size_t nelem, size_t elsize); -void ui_document_free(void *doc, void *ptr); -void* ui_document_realloc(void *doc, void *ptr, size_t size); - -// TODO: remove (or not) -void ui_document_addint(void *doc, char *name); -void ui_document_regint(void *doc, char *name, UiInteger *i); -void ui_document_setint(void *doc, char *name, int val); -int ui_document_getint(void *doc, char *name); - -void ui_document_regtext(void *doc, char *name, UiText *text); -void ui_document_reglist(void *doc, char *name, UiList *list); - -// new: -int ui_getint(UiObject *obj, char *name); -char *ui_getstr(UiObject *obj, char *name); -char* ui_gettext(UiObject *obj, char *name); void ui_set_group(UiContext *ctx, int group); @@ -349,6 +295,11 @@ void* ui_realloc(UiContext *ctx, void *ptr, size_t size); // types + +UiInteger* ui_int_new(UiContext *ctx, char *name); +UiString* ui_string_new(UiContext *ctx, char *name); +UiText* ui_text_new(UiContext *ctx, char *name); + UiObserver* ui_observer_new(ui_callback f, void *data); UiObserver* ui_obsvlist_add(UiObserver *list, UiObserver *observer); UiObserver* ui_add_observer(UiObserver *list, ui_callback f, void *data); @@ -371,6 +322,12 @@ void ui_add_image(char *imgname, char *filename); +// general widget functions +void ui_set_enabled(UIWIDGET widget, int enabled); +void ui_set_show_all(UIWIDGET widget, int value); +void ui_set_visible(UIWIDGET widget, int visible); + + // label widgets UIWIDGET ui_label(UiObject *obj, char *label); UIWIDGET ui_llabel(UiObject *obj, char *label);
--- a/ui/ui/tree.h Tue Jan 24 18:46:47 2017 +0100 +++ b/ui/ui/tree.h Fri Nov 10 17:17:14 2017 +0100 @@ -1,7 +1,7 @@ /* * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. * - * Copyright 2014 Olaf Wintermann. All rights reserved. + * Copyright 2017 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:
--- a/ui/ui/ui.h Tue Jan 24 18:46:47 2017 +0100 +++ b/ui/ui/ui.h Fri Nov 10 17:17:14 2017 +0100 @@ -1,7 +1,7 @@ /* * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. * - * Copyright 2014 Olaf Wintermann. All rights reserved. + * Copyright 2017 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: @@ -30,6 +30,7 @@ #define UI_H #include "toolkit.h" +#include "container.h" #include "menu.h" #include "toolbar.h" #include "window.h"
--- a/ui/ui/window.h Tue Jan 24 18:46:47 2017 +0100 +++ b/ui/ui/window.h Fri Nov 10 17:17:14 2017 +0100 @@ -1,7 +1,7 @@ /* * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. * - * Copyright 2014 Olaf Wintermann. All rights reserved. + * Copyright 2017 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: