Thu, 01 Jan 2015 14:13:37 +0100
added vbox container (Motif)
/* * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. * * Copyright 2014 Olaf Wintermann. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: * * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. */ #include <stdio.h> #include <stdlib.h> #include "container.h" #include "../common/context.h" #include "../common/object.h" static UiBool ui_lb2bool(UiLayoutBool b) { return b == UI_LAYOUT_TRUE ? TRUE : FALSE; } static UiLayoutBool ui_bool2lb(UiBool b) { return b ? UI_LAYOUT_TRUE : UI_LAYOUT_FALSE; } UiContainer* ui_frame_container(UiObject *obj, Widget frame) { UiContainer *ct = ucx_mempool_calloc( obj->ctx->mempool, 1, sizeof(UiContainer)); ct->widget = frame; ct->prepare = ui_frame_container_prepare; ct->add = ui_frame_container_add; return ct; } Widget ui_frame_container_prepare(UiContainer *ct, Arg *args, int *n, UiBool fill) { ui_reset_layout(ct->layout); return ct->widget; } void ui_frame_container_add(UiContainer *ct, Widget widget) { } UiContainer* ui_vbox_container(UiObject *obj, Widget box) { UiContainer *ct = ucx_mempool_calloc( obj->ctx->mempool, 1, sizeof(UiBoxContainer)); ct->widget = box; ct->prepare = ui_vbox_container_prepare; ct->add = ui_vbox_container_add; return ct; } Widget ui_vbox_container_prepare(UiContainer *ct, Arg *args, int *n, UiBool fill) { UiBoxContainer *bc = (UiBoxContainer*)ct; if(ct->layout.fill != UI_LAYOUT_UNDEFINED) { fill = ui_lb2bool(ct->layout.fill); } if(bc->has_fill && fill) { fprintf(stderr, "UiError: container has 2 filled widgets"); fill = FALSE; } if(fill) { bc->has_fill = TRUE; } //UiBool expand = fill; int a = *n; XtSetArg(args[a], XmNleftAttachment, XmATTACH_FORM); a++; XtSetArg(args[a], XmNrightAttachment, XmATTACH_FORM); a++; if(fill) { XtSetArg(args[a], XmNbottomAttachment, XmATTACH_FORM); a++; bc->cur_fill = TRUE; } if(bc->prev_widget) { XtSetArg(args[a], XmNtopAttachment, XmATTACH_WIDGET); a++; XtSetArg(args[a], XmNtopWidget, bc->prev_widget); a++; } else { XtSetArg(args[a], XmNtopAttachment, XmATTACH_FORM); a++; } *n += a; return ct->widget; } void ui_vbox_container_add(UiContainer *ct, Widget widget) { UiBoxContainer *bc = (UiBoxContainer*)ct; if(bc->prev_widget) { int v = 0; XtVaGetValues(bc->prev_widget, XmNbottomAttachment, &v, 0); if(v == XmATTACH_FORM) { XtVaSetValues( bc->prev_widget, XmNbottomAttachment, XmATTACH_WIDGET, XmNbottomWidget, widget, 0); XtVaSetValues( widget, XmNtopAttachment, XmATTACH_NONE, XmNbottomAttachment, XmATTACH_FORM, 0); } } bc->prev_widget = widget; if(bc->cur_fill) { bc->filled_widget = widget; } } UIWIDGET ui_sidebar(UiObject *obj) { UiContainer *ct = uic_get_current_container(obj); Arg args[8]; int n = 0; XtSetArg(args[n], XmNorientation, XmHORIZONTAL); n++; Widget parent = ct->prepare(ct, args, &n, TRUE); Widget pane = XmCreatePanedWindow(parent, "pane", args, n); XtManageChild(pane); // add sidebar widget XtSetArg(args[0], XmNshadowType, XmSHADOW_ETCHED_OUT); XtSetArg(args[1], XmNshadowThickness, 0); Widget sidebar = XmCreateFrame(pane, "sidebar", args, 2); XtManageChild(sidebar); UiObject *left = uic_object_new(obj, sidebar); left->container = ui_frame_container(left, sidebar); // add content widget XtSetArg (args[2], XmNpaneMaximum, 8000); Widget content = XmCreateFrame(pane, "content_area", args, 3); XtManageChild(content); UiObject *right = uic_object_new(obj, content); right->container = ui_frame_container(right, content); uic_obj_add(obj, right); uic_obj_add(obj, left); 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->prepare(ct, args, &n, TRUE); 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 = XmCreateForm(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 v->tabs = ucx_list_append_a(view->ctx->mempool->allocator, v->tabs, tab); XmString label = XmStringCreateLocalized("tab"); XtSetArg(args[0], XmNlabelString, label); XtSetArg(args[1], XmNshadowThickness, 1); XtSetArg(args[2], XmNtraversalOn, FALSE); XtSetArg(args[3], XmNtopAttachment, XmATTACH_FORM); XtSetArg(args[4], XmNbottomAttachment, XmATTACH_FORM); XtSetArg(args[5], XmNhighlightThickness, 0); XtSetArg(args[6], XmNindicatorOn, XmINDICATOR_NONE); XtSetArg(args[7], XmNfillOnSelect, TRUE); XtSetArg(args[8], XmNtopShadowColor, 1); Widget button = XmCreateToggleButton(v->tabbar, "tab_button", args, 8); tab->tabbedpane = v; tab->content = content; tab->tab_button = button; // layout int is_first = 1; size_t count = ucx_list_size(v->tabs); int part = 100 / count; int pos = 0; int i = 0; UCX_FOREACH(elm, v->tabs) { UiTab *tt = elm->data; if(is_first) { XtVaSetValues( tt->tab_button, XmNleftAttachment, XmATTACH_FORM, XmNrightAttachment, XmATTACH_POSITION, XmNrightPosition, pos + part, XmNset, FALSE, NULL); is_first = FALSE; } else if(i < count - 1) { XtVaSetValues( tt->tab_button, XmNleftAttachment, XmATTACH_POSITION, XmNleftPosition, pos, XmNrightAttachment, XmATTACH_POSITION, XmNrightPosition, pos + part, XmNset, FALSE, NULL); } else { XtVaSetValues( tt->tab_button, XmNleftAttachment, XmATTACH_POSITION, XmNleftPosition, pos, XmNrightAttachment, XmATTACH_FORM, XmNset, FALSE, NULL); } pos += part; i++; } XtManageChild(button); XtVaSetValues(button, XmNset, TRUE, NULL); XtAddCallback( button, XmNvalueChangedCallback, (XtCallbackProc)ui_tab_button_callback, 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); XtVaSetValues(t->current->tab_button, XmNset, 0, NULL); } 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); }