# HG changeset patch # User Olaf Wintermann # Date 1406015477 -7200 # Node ID 25e5390cce418edad053d9fc3758c6b17b18cd0e # Parent 42506e19eb6b8fcdd87826dd174b21067413487f added document tabview (GTK, Motif) diff -r 42506e19eb6b -r 25e5390cce41 application/main.c --- a/application/main.c Fri Jun 13 10:39:54 2014 +0200 +++ b/application/main.c Tue Jul 22 09:51:17 2014 +0200 @@ -39,6 +39,10 @@ char *mail; } Person; +typedef struct Document { + UiText text; +} Document; + void action_close(UiEvent *event, void *data) { ui_close(event->obj); } @@ -67,6 +71,8 @@ void action_button(UiEvent *event, void *data) { printf("button: %d\n", event->intval); + char *s = ui_gettext(event->obj, "text"); + printf("{%s}\n", s); } int main(int argc, char** argv) { @@ -81,7 +87,7 @@ ui_menuitem_st(UI_STOCK_CLOSE, action_close, NULL); ui_checkitem("Check", action_button, NULL); - ui_toolitem_toggle_st("button", UI_STOCK_GO_BACK, action_button, NULL); + ui_toolitem_st("button", UI_STOCK_GO_BACK, action_button, NULL); ui_toolbar_add_default("button"); printf("create window\n"); @@ -109,10 +115,26 @@ ui_list_append(list, p3); ui_list_append(list, p4); - ui_sidebar(window); - ui_table(window, list, model); - ui_end(window); - ui_textarea(window, NULL); + //ui_sidebar(window); + //ui_table(window, list, model); + //ui_end(window); + + UiTabbedPane *view = ui_tabbed_document_view(window); + + UiObject *tab1 = ui_document_tab(view); + Document *doc1 = ui_document_new(1024); + UiContext *ctx1 = ui_document_context(doc1); + ui_document_regtext(doc1, "text", &doc1->text); + ui_textarea_nv(tab1, "text"); + ui_set_document(tab1, doc1); + + + UiObject *tab2 = ui_document_tab(view); + Document *doc2 = ui_document_new(1024); + UiContext *ctx2 = ui_document_context(doc2); + ui_document_regtext(doc2, "text", &doc2->text); + ui_textarea_nv(tab2, "text"); + ui_set_document(tab2, doc2); ui_show(window); ui_main(); diff -r 42506e19eb6b -r 25e5390cce41 ui/common/context.c --- a/ui/common/context.c Fri Jun 13 10:39:54 2014 +0200 +++ b/ui/common/context.c Tue Jul 22 09:51:17 2014 +0200 @@ -38,21 +38,104 @@ UiContext* uic_context(UiObject *toplevel, UcxMempool *mp) { UiContext *ctx = ucx_mempool_malloc(mp, sizeof(UiContext)); + ctx->parent = NULL; ctx->mempool = mp; - + ctx->document = NULL; ctx->obj = toplevel; ctx->vars = ucx_map_new_a(mp->allocator, 16); ctx->groups = NULL; ctx->group_widgets = NULL; + ctx->set_document = uic_context_set_document; + ctx->detach_document = uic_context_detach_document; + #ifdef UI_GTK - ctx->accel_group = gtk_accel_group_new(); - gtk_window_add_accel_group(GTK_WINDOW(toplevel->widget), ctx->accel_group); + if(toplevel->widget) { + ctx->accel_group = gtk_accel_group_new(); + gtk_window_add_accel_group(GTK_WINDOW(toplevel->widget), ctx->accel_group); + } #endif return ctx; } +void uic_context_set_document(UiContext *ctx, void *document) { + UiContext *docctx = ui_document_context(document); + if(!docctx) { + return; + } + docctx->obj = ctx->obj; + + if(ctx->document) { + uic_context_detach_document(ctx, ctx->document); + } + //obj->document = document; + ctx->document = document; + + UcxMapIterator i = ucx_map_iterator(docctx->vars); + UiVar *var; + UCX_MAP_FOREACH(key, var, i) { + UiVar *v = ucx_map_get(ctx->vars, 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, 1); + var->from = v->from; + + // TODO: free var struct + ucx_map_remove(ctx->vars, key); + } + } +} + +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"); + return; + } + + 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! + } + } + + docctx->obj->ctx->document = NULL; + + docctx->obj = NULL; +} + UiVar* uic_get_var(UiContext *ctx, char *name) { // check document variables first UiVar *var = NULL; @@ -133,7 +216,7 @@ UiText *t = to->value; char *tvalue = t->value; memcpy(t, f, sizeof(UiText)); - if(set) { + if(set && tvalue) { t->set(t, tvalue); } else { f->value = f->get(f); @@ -269,6 +352,55 @@ 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 an string.\n", + name); + } + } else { + fprintf(stderr, "UI Error: unkown variable %s.\n", name); + } + return NULL; +} diff -r 42506e19eb6b -r 25e5390cce41 ui/common/context.h --- a/ui/common/context.h Fri Jun 13 10:39:54 2014 +0200 +++ b/ui/common/context.h Tue Jul 22 09:51:17 2014 +0200 @@ -44,6 +44,7 @@ typedef struct UiGroupWidget UiGroupWidget; struct UiContext { + UiContext *parent; UiObject *obj; UcxMempool *mempool; UcxMap *vars; // key: char* value: UiVar* @@ -51,6 +52,9 @@ UcxList *groups; // int list UcxList *group_widgets; // UiGroupWidget* list + void (*set_document)(UiContext *ctx, void *document); + void (*detach_document)(UiContext *ctx, void *document); + #ifdef UI_GTK GtkAccelGroup *accel_group; #endif @@ -85,6 +89,10 @@ }; UiContext* uic_context(UiObject *toplevel, UcxMempool *mp); + +void uic_context_set_document(UiContext *ctx, void *document); +void uic_context_detach_document(UiContext *ctx, void *document); + 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, int set); @@ -101,6 +109,7 @@ void uic_check_group_widgets(UiContext *ctx); void uic_add_group_widget(UiContext *ctx, void *widget, UcxList *groups); + #ifdef __cplusplus } #endif diff -r 42506e19eb6b -r 25e5390cce41 ui/common/document.c --- a/ui/common/document.c Fri Jun 13 10:39:54 2014 +0200 +++ b/ui/common/document.c Tue Jul 22 09:51:17 2014 +0200 @@ -39,91 +39,48 @@ } void ui_set_document(UiObject *obj, void *document) { - UiContext *ctx = ucx_map_get(documents, ucx_key(&document, sizeof(void*))); - if(!ctx) { - return; - } - ctx->obj = obj; - - if(obj->document) { - ui_detach_document(obj, obj->document); - } - obj->document = document; - obj->ctx->document = document; - - UcxMapIterator i = ucx_map_iterator(ctx->vars); - UiVar *var; - UCX_MAP_FOREACH(key, var, i) { - UiVar *v = ucx_map_get(obj->ctx->vars, 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, 1); - var->from = v->from; - - // TODO: free var struct - ucx_map_remove(obj->ctx->vars, key); - } - } - + obj->ctx->set_document(obj->ctx, document); } void ui_detach_document(UiObject *obj, void *document) { - UiContext *ctx = ucx_map_get(documents, ucx_key(&document, sizeof(void*))); + obj->ctx->detach_document(obj->ctx, document); +} + +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, - "UiError: ui_detach_document: document is not registered\n"); - return; - } - if(obj->document != document) { - fprintf(stderr, "UiError: ui_detach_document: wrong document\n"); - return; + fprintf(stderr, "UI Error: pointer is not a document\n"); } - - UcxMapIterator i = ucx_map_iterator(ctx->vars); - UiVar *var; - UCX_MAP_FOREACH(key, var, i) { - if(var->from && var->from != ctx->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! - } + uic_context_set_document(ctx, sub); +} + +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"); } - - ctx->obj->document = NULL; - ctx->obj->ctx->document = NULL; - - ctx->obj = NULL; + uic_context_detach_document(ctx, sub); +} + +void* ui_get_subdocument(void *document) { + UiContext *ctx = ui_document_context(document); + if(!ctx) { + fprintf(stderr, "UI Error: pointer is not a document\n"); + } + return ctx->document; } void* ui_document_new(size_t size) { UcxMempool *mp = ucx_mempool_new(256); - UiContext *ctx = ucx_mempool_malloc(mp, sizeof(UiContext)); - ctx->obj = NULL; + UiContext *ctx = ucx_mempool_calloc(mp, 1, sizeof(UiContext)); + ctx->set_document = uic_context_set_document; + ctx->detach_document = uic_context_detach_document; ctx->mempool = mp; ctx->vars = ucx_map_new_a(mp->allocator, 16); - //uidoc->subdocument = NULL; void *document = ucx_mempool_calloc(mp, 1, size); ucx_map_put(documents, ucx_key(&document, sizeof(void*)), ctx); @@ -192,7 +149,7 @@ void ui_document_regtext(void *doc, char *name, UiText *text) { UiContext *ctx = ui_document_context(doc); if(ctx) { - uic_reg_var(doc, name, UI_VAR_TEXT, sizeof(UiText), text); + uic_reg_var(ctx, name, UI_VAR_TEXT, sizeof(UiText), text); } } @@ -203,6 +160,6 @@ UiListPtr *lp = ui_document_malloc(doc, sizeof(UiListPtr)); lv->listptr = lp; lp->list = list; - uic_reg_var(doc, name, UI_VAR_LIST, sizeof(UiListPtr), lv); + uic_reg_var(ctx, name, UI_VAR_LIST, sizeof(UiListPtr), lv); } } diff -r 42506e19eb6b -r 25e5390cce41 ui/common/document.h --- a/ui/common/document.h Fri Jun 13 10:39:54 2014 +0200 +++ b/ui/common/document.h Tue Jul 22 09:51:17 2014 +0200 @@ -40,7 +40,6 @@ void uic_document_addvar(void *doc, char *name, int type, size_t vs); - #ifdef __cplusplus } #endif diff -r 42506e19eb6b -r 25e5390cce41 ui/common/object.c --- a/ui/common/object.c Fri Jun 13 10:39:54 2014 +0200 +++ b/ui/common/object.c Tue Jul 22 09:51:17 2014 +0200 @@ -66,6 +66,9 @@ } UiObject* uic_current_obj(UiObject *toplevel) { + if(!toplevel) { + return NULL; + } UiObject *obj = toplevel; while(obj->next) { obj = obj->next; diff -r 42506e19eb6b -r 25e5390cce41 ui/gtk/button.c --- a/ui/gtk/button.c Fri Jun 13 10:39:54 2014 +0200 +++ b/ui/gtk/button.c Tue Jul 22 09:51:17 2014 +0200 @@ -70,7 +70,7 @@ UiEvent e; e.obj = event->obj; e.window = event->obj->window; - e.document = event->obj->document; + e.document = event->obj->ctx->document; e.eventdata = NULL; e.intval = event->value; event->callback(&e, event->userdata); @@ -80,7 +80,7 @@ UiEvent e; e.obj = event->obj; e.window = event->obj->window; - e.document = event->obj->document; + e.document = event->obj->ctx->document; e.eventdata = NULL; e.intval = gtk_toggle_tool_button_get_active(widget); event->callback(&e, event->userdata); diff -r 42506e19eb6b -r 25e5390cce41 ui/gtk/container.c --- a/ui/gtk/container.c Fri Jun 13 10:39:54 2014 +0200 +++ b/ui/gtk/container.c Tue Jul 22 09:51:17 2014 +0200 @@ -101,3 +101,74 @@ void ui_box_add(UiContainer *ct, GtkWidget *widget) { gtk_box_pack_start(GTK_BOX(ct->widget), widget, TRUE, TRUE, 0); } + + + + +static void page_change(GtkNotebook *notebook, GtkWidget *page, guint page_num, gpointer data) { + GQuark q = g_quark_from_static_string("ui.tab.object"); + UiObject *tab = g_object_get_qdata(G_OBJECT(page), q); + if(!tab) { + return; + } + + printf("page_change: %d\n", page_num); + UiContext *ctx = tab->ctx; + ctx->parent->set_document(ctx->parent, ctx->document); +} + +UiTabbedPane* ui_tabbed_document_view(UiObject *obj) { + GtkWidget *tabview = gtk_notebook_new(); + gtk_notebook_set_show_border(GTK_NOTEBOOK(tabview), FALSE); + + g_signal_connect( + tabview, + "switch-page", + G_CALLBACK(page_change), + NULL); + + UiContainer *ct = uic_get_current_container(obj); + ct->add(ct, tabview); + + UiTabbedPane *tabbedpane = ui_malloc(obj->ctx, sizeof(UiTabbedPane)); + tabbedpane->ctx = uic_current_obj(obj)->ctx; + tabbedpane->widget = tabview; + tabbedpane->document = NULL; + + return tabbedpane; +} + +UiObject* ui_document_tab(UiTabbedPane *view) { + GtkWidget *frame = gtk_alignment_new(0.5, 0.5, 1, 1); + // TODO: label + gtk_notebook_append_page(GTK_NOTEBOOK(view->widget), frame, NULL); + + UiObject *tab = ui_malloc(view->ctx, sizeof(UiObject)); + tab->widget = NULL; // initialization for uic_context() + tab->ctx = uic_context(tab, view->ctx->mempool); + tab->ctx->parent = view->ctx; + tab->ctx->set_document = ui_tab_set_document; + tab->ctx->detach_document = ui_tab_detach_document; + tab->widget = frame; + tab->window = view->ctx->obj->window; + tab->container = ui_frame_container(tab, frame); + tab->next = NULL; + + GQuark q = g_quark_from_static_string("ui.tab.object"); + g_object_set_qdata(G_OBJECT(frame), q, tab); + + return tab; +} + +void ui_tab_set_document(UiContext *ctx, void *document) { + if(ctx->parent->document) { + //ctx->parent->detach_document(ctx->parent, ctx->parent->document); + } + uic_context_set_document(ctx, document); + //uic_context_set_document(ctx->parent, document); + //ctx->parent->document = document; +} + +void ui_tab_detach_document(UiContext *ctx, void *document) { + uic_context_detach_document(ctx->parent, document); +} diff -r 42506e19eb6b -r 25e5390cce41 ui/gtk/container.h --- a/ui/gtk/container.h Fri Jun 13 10:39:54 2014 +0200 +++ b/ui/gtk/container.h Tue Jul 22 09:51:17 2014 +0200 @@ -37,6 +37,8 @@ typedef void (*ui_container_add_f)(UiContainer*, GtkWidget*); +typedef struct UiDocumentView UiDocumentView; + struct UiContainer { GtkWidget *widget; void (*add)(UiContainer*, GtkWidget*); @@ -50,6 +52,11 @@ void ui_box_add(UiContainer *ct, GtkWidget *widget); + +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); + #ifdef __cplusplus } #endif diff -r 42506e19eb6b -r 25e5390cce41 ui/gtk/menu.c --- a/ui/gtk/menu.c Fri Jun 13 10:39:54 2014 +0200 +++ b/ui/gtk/menu.c Tue Jul 22 09:51:17 2014 +0200 @@ -440,7 +440,7 @@ UiEvent evt; evt.obj = event->obj; evt.window = event->obj->window; - evt.document = event->obj->document; + evt.document = event->obj->ctx->document; evt.eventdata = NULL; evt.intval = event->value; event->callback(&evt, event->userdata); @@ -450,7 +450,7 @@ UiEvent evt; evt.obj = event->obj; evt.window = event->obj->window; - evt.document = event->obj->document; + evt.document = event->obj->ctx->document; evt.eventdata = NULL; evt.intval = gtk_check_menu_item_get_active(ci); event->callback(&evt, event->userdata); diff -r 42506e19eb6b -r 25e5390cce41 ui/gtk/toolkit.c --- a/ui/gtk/toolkit.c Fri Jun 13 10:39:54 2014 +0200 +++ b/ui/gtk/toolkit.c Tue Jul 22 09:51:17 2014 +0200 @@ -98,7 +98,7 @@ UiEvent event; event.obj = job->obj; event.window = job->obj->window; - event.document = job->obj->document; + event.document = job->obj->ctx->document; event.intval = 0; event.eventdata = NULL; diff -r 42506e19eb6b -r 25e5390cce41 ui/gtk/tree.c --- a/ui/gtk/tree.c Fri Jun 13 10:39:54 2014 +0200 +++ b/ui/gtk/tree.c Tue Jul 22 09:51:17 2014 +0200 @@ -239,7 +239,7 @@ UiEvent e; e.obj = event->obj; e.window = event->obj->window; - e.document = event->obj->document; + e.document = event->obj->ctx->document; e.eventdata = selection; e.intval = selection->count > 0 ? selection->rows[0] : -1; event->activate(&e, event->userdata); @@ -256,7 +256,7 @@ UiEvent e; e.obj = event->obj; e.window = event->obj->window; - e.document = event->obj->document; + e.document = event->obj->ctx->document; e.eventdata = selection; e.intval = selection->count > 0 ? selection->rows[0] : -1; event->selection(&e, event->userdata); diff -r 42506e19eb6b -r 25e5390cce41 ui/motif/button.c --- a/ui/motif/button.c Fri Jun 13 10:39:54 2014 +0200 +++ b/ui/motif/button.c Tue Jul 22 09:51:17 2014 +0200 @@ -99,7 +99,7 @@ UiEvent e; e.obj = event->obj; e.window = event->obj->window; - e.document = event->obj->document; + e.document = event->obj->ctx->document; e.intval = event->value; event->callback(&e, event->user_data); } diff -r 42506e19eb6b -r 25e5390cce41 ui/motif/container.c --- a/ui/motif/container.c Fri Jun 13 10:39:54 2014 +0200 +++ b/ui/motif/container.c Tue Jul 22 09:51:17 2014 +0200 @@ -81,3 +81,143 @@ return sidebar; } + +UiTabbedPane* ui_tabbed_document_view(UiObject *obj) { + int n = 0; + Arg args[16]; + + UiContainer *ct = uic_get_current_container(obj); + Widget parent = ct->add(ct, args, &n); + + Widget tabview = XmCreateForm(parent, "tabview_form", args, n); + XtManageChild(tabview); + + XtSetArg(args[0], XmNorientation, XmHORIZONTAL); + XtSetArg(args[1], XmNpacking, XmPACK_TIGHT); + XtSetArg(args[2], XmNspacing, 1); + XtSetArg(args[3], XmNleftAttachment, XmATTACH_FORM); + XtSetArg(args[4], XmNrightAttachment, XmATTACH_FORM); + XtSetArg(args[5], XmNtopAttachment, XmATTACH_FORM); + Widget tabbar = XmCreateRowColumn(tabview, "toolbar", args, 6); + XtManageChild(tabbar); + + XtSetArg(args[0], XmNleftAttachment, XmATTACH_FORM); + XtSetArg(args[1], XmNrightAttachment, XmATTACH_FORM); + XtSetArg(args[2], XmNtopAttachment, XmATTACH_WIDGET); + XtSetArg(args[3], XmNtopWidget, tabbar); + XtSetArg(args[4], XmNbottomAttachment, XmATTACH_FORM); + XtSetArg(args[5], XmNshadowThickness, 0); + Widget tabct = XmCreateForm(tabview, "tabview", args, 6); + XtManageChild(tabct); + + MotifTabbedPane *tabbedpane = ui_malloc(obj->ctx, sizeof(MotifTabbedPane)); + tabbedpane->view.ctx = uic_current_obj(obj)->ctx; + tabbedpane->view.widget = tabct; + tabbedpane->view.document = NULL; + tabbedpane->tabbar = tabbar; + //tabbedpane->form = tabview; + tabbedpane->tabs = NULL; + tabbedpane->current = NULL; + + return &tabbedpane->view; +} + +UiObject* ui_document_tab(UiTabbedPane *view) { + MotifTabbedPane *v = (MotifTabbedPane*)view; + int n = 0; + Arg args[16]; + + // hide the current tab content + if(v->current) { + XtUnmanageChild(v->current->content->widget); + } + + UiTab *tab = ui_malloc(view->ctx, sizeof(UiTab)); + + // create the new tab content + XtSetArg(args[0], XmNshadowThickness, 0); + XtSetArg(args[1], XmNleftAttachment, XmATTACH_FORM); + XtSetArg(args[2], XmNrightAttachment, XmATTACH_FORM); + XtSetArg(args[3], XmNtopAttachment, XmATTACH_FORM); + XtSetArg(args[4], XmNbottomAttachment, XmATTACH_FORM); + XtSetArg(args[5], XmNuserData, tab); + Widget frame = XmCreateFrame(view->widget, "tab", args, 6); + XtManageChild(frame); + + UiObject *content = ui_malloc(view->ctx, sizeof(UiObject)); + content->widget = NULL; // initialization for uic_context() + content->ctx = uic_context(content, view->ctx->mempool); + content->ctx->parent = view->ctx; + content->ctx->set_document = ui_tab_set_document; + content->ctx->detach_document = ui_tab_detach_document; + content->widget = frame; + content->window = view->ctx->obj->window; + content->container = ui_frame_container(content, frame); + content->next = NULL; + + // add tab button + XmString label = XmStringCreateLocalized("tab"); + XtSetArg(args[0], XmNlabelString, label); + XtSetArg(args[1], XmNshadowThickness, 1); + XtSetArg(args[2], XmNtraversalOn, FALSE); + Widget button = XmCreatePushButton(v->tabbar, "tab_button", args, 3); + XtManageChild(button); + XtAddCallback( + button, + XmNactivateCallback, + (XtCallbackProc)ui_tab_button_callback, + tab); + + tab->tabbedpane = v; + tab->content = content; + tab->tab_button = button; + + v->tabs = ucx_list_append_a(view->ctx->mempool->allocator, v->tabs, tab); + v->current = tab; + ui_change_tab(v, tab); + + return content; +} + +void ui_tab_button_callback(Widget widget, UiTab *tab, XtPointer d) { + MotifTabbedPane *t = tab->tabbedpane; + if(t->current) { + XtUnmanageChild(t->current->content->widget); + } + XtManageChild(tab->content->widget); + + t->current = tab; + ui_change_tab(t, tab); +} + +void ui_change_tab(MotifTabbedPane *pane, UiTab *tab) { + UiContext *ctx = tab->content->ctx; + ctx->parent->set_document(ctx->parent, ctx->document); +} + +void ui_tab_set_document(UiContext *ctx, void *document) { + if(ctx->parent->document) { + //ctx->parent->detach_document(ctx->parent, ctx->parent->document); + } + uic_context_set_document(ctx, document); + //uic_context_set_document(ctx->parent, document); + //ctx->parent->document = document; + + UiTab *tab = NULL; + XtVaGetValues( + ctx->obj->widget, + XmNuserData, + &tab, + NULL); + if(tab) { + if(tab->tabbedpane->current == tab) { + ctx->parent->set_document(ctx->parent, ctx->document); + } + } else { + fprintf(stderr, "UiError: ui_bar_set_document: Cannot set document"); + } +} + +void ui_tab_detach_document(UiContext *ctx, void *document) { + uic_context_detach_document(ctx->parent, document); +} diff -r 42506e19eb6b -r 25e5390cce41 ui/motif/container.h --- a/ui/motif/container.h Fri Jun 13 10:39:54 2014 +0200 +++ b/ui/motif/container.h Tue Jul 22 09:51:17 2014 +0200 @@ -30,22 +30,43 @@ #define CONTAINER_H #include "../ui/toolkit.h" +#include #ifdef __cplusplus extern "C" { #endif +typedef struct MotifTabbedPane MotifTabbedPane; +typedef struct UiTab UiTab; + typedef Widget (*ui_container_add_f)(UiContainer*, Arg*, int*); struct UiContainer { Widget widget; Widget (*add)(UiContainer*, Arg *, int*); }; + +struct MotifTabbedPane { + UiTabbedPane view; + Widget tabbar; + UcxList *tabs; + UiTab *current; +}; + +struct UiTab { + MotifTabbedPane *tabbedpane; + UiObject *content; + Widget tab_button; +}; UiContainer* ui_frame_container(UiObject *obj, Widget frame); Widget ui_frame_container_add(UiContainer *ct, Arg *args, int *n); +void ui_tab_button_callback(Widget widget, UiTab *tab, XtPointer d); +void ui_change_tab(MotifTabbedPane *pane, UiTab *tab); +void ui_tab_set_document(UiContext *ctx, void *document); +void ui_tab_detach_document(UiContext *ctx, void *document); #ifdef __cplusplus diff -r 42506e19eb6b -r 25e5390cce41 ui/motif/list.c --- a/ui/motif/list.c Fri Jun 13 10:39:54 2014 +0200 +++ b/ui/motif/list.c Tue Jul 22 09:51:17 2014 +0200 @@ -154,7 +154,7 @@ UiEvent e; e.obj = event->event.obj; e.window = event->event.obj->window; - e.document = event->event.obj->document; + e.document = event->event.obj->ctx->document; e.eventdata = event->list->list->get(event->list->list, cbs->item_position - 1); e.intval = cbs->item_position - 1; event->event.callback(&e, event->event.user_data); diff -r 42506e19eb6b -r 25e5390cce41 ui/motif/menu.c --- a/ui/motif/menu.c Fri Jun 13 10:39:54 2014 +0200 +++ b/ui/motif/menu.c Tue Jul 22 09:51:17 2014 +0200 @@ -521,7 +521,7 @@ UiEvent e; e.obj = event->obj; e.window = event->obj->window; - e.document = event->obj->document; + e.document = event->obj->ctx->document; e.intval = 0; event->callback(&e, event->user_data); } diff -r 42506e19eb6b -r 25e5390cce41 ui/motif/toolkit.c --- a/ui/motif/toolkit.c Fri Jun 13 10:39:54 2014 +0200 +++ b/ui/motif/toolkit.c Tue Jul 22 09:51:17 2014 +0200 @@ -180,7 +180,7 @@ UiEvent event; event.obj = job->obj; event.window = job->obj->window; - event.document = job->obj->document; + event.document = job->obj->ctx->document; event.intval = 0; event.eventdata = NULL; diff -r 42506e19eb6b -r 25e5390cce41 ui/motif/tree.c --- a/ui/motif/tree.c Fri Jun 13 10:39:54 2014 +0200 +++ b/ui/motif/tree.c Tue Jul 22 09:51:17 2014 +0200 @@ -35,6 +35,7 @@ #include "container.h" #include "../common/object.h" +#include "../common/context.h" #include "../../ucx/utils.h" UIWIDGET ui_table(UiObject *obj, UiList *model, UiModelInfo *modelinfo) { @@ -218,7 +219,7 @@ UiEvent e; e.obj = event->obj; e.window = event->obj->window; - e.document = event->obj->document; + e.document = event->obj->ctx->document; e.eventdata = selection; e.intval = selection->count > 0 ? selection->rows[0] : -1; event->activate(&e, event->userdata); @@ -238,7 +239,7 @@ UiEvent e; e.obj = event->obj; e.window = event->obj->window; - e.document = event->obj->document; + e.document = event->obj->ctx->document; e.eventdata = selection; e.intval = selection->count > 0 ? selection->rows[0] : -1; event->selection(&e, event->userdata); diff -r 42506e19eb6b -r 25e5390cce41 ui/ui/toolkit.h --- a/ui/ui/toolkit.h Fri Jun 13 10:39:54 2014 +0200 +++ b/ui/ui/toolkit.h Tue Jul 22 09:51:17 2014 +0200 @@ -80,6 +80,8 @@ typedef struct UiContext UiContext; typedef struct UiContainer UiContainer; +typedef struct UiTabbedPane UiTabbedPane; + #define ui_getval(val) (val).get(&(val)) #define ui_setval(val, v) (val).set(&(val), v) @@ -110,7 +112,7 @@ /* * current document */ - void *document; + //void *document; /* * window context (private) @@ -128,6 +130,23 @@ UiObject *next; }; +struct UiTabbedPane { + /* + * native widget + */ + UIWIDGET widget; + + /* + * current document + */ + void *document; + + /* + * parent context + */ + UiContext *ctx; +}; + struct UiEvent { UiObject *obj; void *document; @@ -212,8 +231,22 @@ UIWIDGET ui_sidebar(UiObject *obj); void ui_end(UiObject *obj); + + + +UiTabbedPane* ui_tabbed_document_view(UiObject *obj); + +UiObject* ui_document_tab(UiTabbedPane *view); + + + + void ui_set_document(UiObject *obj, void *document); void ui_detach_document(UiObject *obj, void *document); +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); @@ -237,6 +270,8 @@ // 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);