--- a/ui/motif/container.c Sat Feb 01 09:56:01 2025 +0100 +++ b/ui/motif/container.c Sat Feb 01 12:22:47 2025 +0100 @@ -34,6 +34,8 @@ #include "../common/context.h" #include "../common/object.h" +#include <cx/array_list.h> + #include "Grid.h" @@ -219,6 +221,204 @@ } +/* -------------------------- TabView Container -------------------------- */ + +static void ui_tabbar_resize(Widget widget, XtPointer udata, XtPointer cdata) { + printf("ui_tabbar_resize\n"); + + UiMotifTabView *tabview = udata; + + int width = 0; + int height = 0; + XtVaGetValues(widget, XmNwidth, &width, XmNheight, &height, NULL); + int button_width = width / 4; + int x = 0; + + printf("width: %d\n", (int)width); + + CxIterator i = cxListIterator(tabview->tabs); + cx_foreach(UiTab *, tab, i) { + XtVaSetValues( + tab->tab_button, + XmNx, x, + XmNy, 0, + XmNwidth, + button_width, + + NULL); + x += button_width; + } + + if(height <= tabview->height) { + XtVaSetValues(widget, XmNheight, tabview->height + 4, NULL); + } +} + +static void ui_tabbar_expose(Widget widget, XtPointer udata, XtPointer cdata) { + printf("ui_tabbar_expose\n"); + + UiMotifTabView *tabview = udata; + CxIterator i = cxListIterator(tabview->tabs); + cx_foreach(UiTab *, tab, i) { + printf("y: %d\n", (int)tab->tab_button->core.y); + } + + XmDrawingAreaCallbackStruct *cbs = (XmDrawingAreaCallbackStruct *)cdata; + XEvent *event = cbs->event; + Display *dpy = XtDisplay(widget); + + printf("width: %d\n", (int)widget->core.width); +} + +UIWIDGET ui_tabview_create(UiObject *obj, UiTabViewArgs args) { + Arg xargs[16]; + int n = 0; + + UiContainerPrivate *ctn = ui_obj_container(obj); + UI_APPLY_LAYOUT(ctn->layout, args); + + // create widgets + // form + // - tabbar (Drawing Area) + // - content (Frame) + UiMotifTabView *tabview = malloc(sizeof(UiMotifTabView)); + memset(tabview, 0, sizeof(UiMotifTabView)); + char *name = args.name ? (char*)args.name : "tabview"; + XtSetArg(xargs[n], XmNuserData, tabview); n++; + Widget parent = ctn->prepare(ctn, xargs, &n); + Widget form = XmCreateForm(parent, name, xargs, n); + XtManageChild(form); + + n = 0; + XtSetArg(xargs[n], XmNleftAttachment, XmATTACH_FORM); n++; + XtSetArg(xargs[n], XmNrightAttachment, XmATTACH_FORM); n++; + XtSetArg(xargs[n], XmNtopAttachment, XmATTACH_FORM); n++; + XtSetArg(xargs[n], XmNorientation, XmHORIZONTAL); n++; + XtSetArg(xargs[n], XmNpacking, XmPACK_TIGHT); n++; + XtSetArg(xargs[n], XmNspacing, 1); n++; + XtSetArg(xargs[n], XmNmarginWidth, 0); n++; + XtSetArg(xargs[n], XmNmarginHeight, 0); n++; + Widget tabbar = XmCreateDrawingArea(form, "ui_test", xargs, n); + XtManageChild(tabbar); + XtAddCallback(tabbar, XmNresizeCallback , ui_tabbar_resize, tabview); + XtAddCallback(tabbar, XmNexposeCallback, ui_tabbar_expose, tabview); + + n = 0; + XtSetArg(xargs[n], XmNleftAttachment, XmATTACH_FORM); n++; + XtSetArg(xargs[n], XmNrightAttachment, XmATTACH_FORM); n++; + XtSetArg(xargs[n], XmNbottomAttachment, XmATTACH_FORM); n++; + XtSetArg(xargs[n], XmNtopAttachment, XmATTACH_WIDGET); n++; + XtSetArg(xargs[n], XmNtopWidget, tabbar); n++; + Widget content = XmCreateFrame(form, "tabviewcontent", xargs, n); + + // setup tabview object, that holds all relevant objects + tabview->form = form; + tabview->tabbar = tabbar; + tabview->content = content; + tabview->tabview = args.tabview; + tabview->subcontainer = args.subcontainer; + tabview->select = ui_motif_tabview_select; + tabview->add = ui_motif_tabview_add_tab; + tabview->remove = ui_motif_tabview_remove; + tabview->tabs = cxArrayListCreateSimple(sizeof(UiTab), 8); + + UiTabViewContainer *ct = ui_malloc(obj->ctx, sizeof(UiTabViewContainer)); + ct->container.widget = form; + ct->container.type = UI_CONTAINER_TABVIEW; + ct->container.prepare = ui_tabview_container_prepare; + ct->container.add = ui_tabview_container_add; + ct->tabview = tabview; + + uic_object_push_container(obj, (UiContainerX*)ct); + + return form; +} + +void ui_tab_create(UiObject *obj, const char* title) { + UiContainerPrivate *ctn = ui_obj_container(obj); + if(ctn->type != UI_CONTAINER_TABVIEW) { + fprintf(stderr, "UI Error: container is not a tabview\n"); + return; + } + + UiMotifTabView *tabview = NULL; + XtVaGetValues(ctn->widget, XmNuserData, &tabview, NULL); + if(!tabview) { + fprintf(stderr, "UI Error: no tabview\n"); + return; + } + + + Widget child = ui_vbox_create(obj, (UiContainerArgs) { 0 }); + if(tabview->current) { + XtUnmanageChild(child); + } else { + tabview->current = child; + } + + tabview->add(tabview, -1, title, child); +} + +void ui_motif_tabview_select(UiMotifTabView *tabview, int tab) { + +} + +void ui_motif_tabview_add_tab(UiMotifTabView *tabview, int index, const char *name, Widget child) { + UiTab tab; + + Arg args[16]; + int n = 0; + + XmString label = XmStringCreateLocalized((char*)name); + XtSetArg(args[n], XmNlabelString, label); n++; + XtSetArg(args[n], XmNshadowThickness, 0); n++; + XtSetArg(args[n], XmNhighlightThickness, 0); n++; + + Widget button = XmCreatePushButton(tabview->tabbar, "tab_button", args, 3); + XtManageChild(button); + + if(tabview->height == 0) { + Dimension h; + XtVaGetValues( + button, + XmNarmColor, + &tabview->bg1, + XmNbackground, + &tabview->bg2, + XmNheight, + &h, + NULL); + tabview->height = h + 2; // border + } + + tab.tab_button = button; + tab.child = child; + cxListAdd(tabview->tabs, &tab); +} + +void ui_motif_tabview_remove(UiMotifTabView *tabview, int index) { + +} + +Widget ui_tabview_container_prepare(UiContainerPrivate *ctn, Arg *args, int *n) { + UiTabViewContainer *ct = (UiTabViewContainer*)ctn; + UiMotifTabView *tabview = ct->tabview; + int a = *n; + XtSetArg(args[a], XmNleftAttachment, XmATTACH_FORM); a++; + XtSetArg(args[a], XmNrightAttachment, XmATTACH_FORM); a++; + XtSetArg(args[a], XmNbottomAttachment, XmATTACH_FORM); a++; + XtSetArg(args[a], XmNtopAttachment, XmATTACH_WIDGET); a++; + XtSetArg(args[a], XmNtopWidget, tabview->tabbar); a++; + *n = a; + return tabview->form; +} + +void ui_tabview_container_add(UiContainerPrivate *ctn, Widget widget) { + ui_reset_layout(ctn->layout); +} + + + /* -------------------- Container Helper Functions -------------------- */ void ui_container_begin_close(UiObject *obj) {