add first code for motif tabview (incomplete)

6 weeks ago

author
Olaf Wintermann <olaf.wintermann@gmail.com>
date
Sat, 01 Feb 2025 12:22:47 +0100 (6 weeks ago)
changeset 452
a0620cf552a6
parent 451
b3eb3a25fb46
child 453
abe2c7bf2246

add first code for motif tabview (incomplete)

application/main.c file | annotate | diff | comparison | revisions
ui/motif/container.c file | annotate | diff | comparison | revisions
ui/motif/container.h file | annotate | diff | comparison | revisions
ui/motif/text.c file | annotate | diff | comparison | revisions
ui/motif/toolkit.c file | annotate | diff | comparison | revisions
--- a/application/main.c	Sat Feb 01 09:56:01 2025 +0100
+++ b/application/main.c	Sat Feb 01 12:22:47 2025 +0100
@@ -619,6 +619,7 @@
     ui_list_append(wdata->list, "List Item 3");
     ui_list_append(wdata->list, "List Item 4");
     
+    /*
     ui_button(obj, .label = "Add Menu Item", .onclick = action_button, .name = "mybutton1");
     ui_button(obj, .label = "Add List Item", .onclick = action_button2);
     ui_hbox0(obj) {
@@ -628,6 +629,17 @@
     ui_listview(obj, .list = wdata->list, .fill = UI_ON, .multiselection = TRUE,
             .onactivate = action_listevent, .onactivatedata = "activate",
             .onselection = action_listevent, .onselectiondata = "selection");
+    */
+    
+    ui_tabview(obj, .tabview = UI_TABVIEW_NAVIGATION_TOP, .fill = UI_ON) {
+        ui_tab(obj, "Tab 1") {
+            ui_textarea(obj, .varname = "text", .fill = UI_ON);
+        }
+        
+        ui_tab(obj, "Tab 2") {
+            ui_button(obj, .label = "Test Tab 2");
+        }
+    }
     
     
     ui_show(obj);
--- 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) {
--- a/ui/motif/container.h	Sat Feb 01 09:56:01 2025 +0100
+++ b/ui/motif/container.h	Sat Feb 01 12:22:47 2025 +0100
@@ -48,6 +48,12 @@
     layout.rowspan = args.rowspan
     
 typedef enum UiBoxOrientation UiBoxOrientation;
+
+enum UiContainerType {
+    UI_CONTAINER_GENERIC = 0,
+    UI_CONTAINER_TABVIEW
+};
+typedef enum UiContainerType UiContainerType;
     
 #define ui_reset_layout(layout) memset(&(layout), 0, sizeof(UiLayout))
 #define ui_lb2bool(b) ((b) == UI_LAYOUT_TRUE ? TRUE : FALSE)
@@ -79,11 +85,12 @@
 
 
 struct UiContainerPrivate {
-    UiContainerX container;
-    Widget       (*prepare)(UiContainerPrivate*, Arg *, int*);
-    void         (*add)(UiContainerPrivate*, Widget);
-    Widget       widget;
-    UiLayout     layout;
+    UiContainerX    container;
+    Widget          (*prepare)(UiContainerPrivate*, Arg *, int*);
+    void            (*add)(UiContainerPrivate*, Widget);
+    Widget          widget;
+    UiContainerType type;
+    UiLayout        layout;
 };
 
 typedef struct UiBoxContainer {
@@ -97,6 +104,40 @@
     Dimension y;
 } UiGridContainer;
 
+typedef struct UiMotifTabView UiMotifTabView;
+struct UiMotifTabView {
+    Widget form;
+    Widget tabbar;
+    Widget content;
+    Widget current;
+    int height;
+    Pixel bg1;
+    Pixel bg2;
+    UiTabViewType tabview;
+    UiSubContainerType subcontainer;
+    CxList *tabs;
+    void (*select)(UiMotifTabView *tabview, int tab);
+    void (*add)(UiMotifTabView *tabview, int index, const char *name, Widget child);
+    void (*remove)(UiMotifTabView *tabview, int index);
+};
+
+typedef struct UiTab {
+    Widget tab_button;
+    Widget child;
+} UiTab;
+
+typedef struct UiTabViewContainer {
+    UiContainerPrivate container;
+    UiMotifTabView *tabview;
+} UiTabViewContainer;
+
+void ui_motif_tabview_select(UiMotifTabView *tabview, int tab);
+void ui_motif_tabview_add_tab(UiMotifTabView *tabview, int index, const char *name, Widget child);
+void ui_motif_tabview_remove(UiMotifTabView *tabview, int index);
+
+Widget ui_tabview_container_prepare(UiContainerPrivate *ctn, Arg *args, int *n);
+void ui_tabview_container_add(UiContainerPrivate *ctn, Widget widget);
+
 UiContainerX* ui_box_container(UiObject *obj, Widget grid, UiBoxOrientation orientation);
 Widget ui_vbox_prepare(UiContainerPrivate *ctn, Arg *args, int *n);
 Widget ui_hbox_prepare(UiContainerPrivate *ctn, Arg *args, int *n);
--- a/ui/motif/text.c	Sat Feb 01 09:56:01 2025 +0100
+++ b/ui/motif/text.c	Sat Feb 01 12:22:47 2025 +0100
@@ -42,6 +42,8 @@
     Arg xargs[16];
     int n = 0;
     
+    XtSetArg(xargs[n], XmNeditMode, XmMULTI_LINE_EDIT); n++;
+    
     UiContainerPrivate *ctn = ui_obj_container(obj);
     UI_APPLY_LAYOUT(ctn->layout, args);
     
--- a/ui/motif/toolkit.c	Sat Feb 01 09:56:01 2025 +0100
+++ b/ui/motif/toolkit.c	Sat Feb 01 12:22:47 2025 +0100
@@ -78,6 +78,8 @@
         "*window_frame.shadowThickness: 1",
         "*togglebutton.shadowThickness: 1",
         "*togglebutton.highlightThickness: 2",
+        
+        "*ui_test.background: red",
 	NULL
 };
 

mercurial