finish minimal tabview implementation (Motif)

5 weeks ago

author
Olaf Wintermann <olaf.wintermann@gmail.com>
date
Thu, 06 Feb 2025 22:36:29 +0100 (5 weeks ago)
changeset 460
1274d84f44de
parent 459
4ea4bb379273
child 461
b480e133b576

finish minimal tabview implementation (Motif)

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
--- a/application/main.c	Thu Feb 06 22:03:14 2025 +0100
+++ b/application/main.c	Thu Feb 06 22:36:29 2025 +0100
@@ -646,6 +646,10 @@
         ui_tab(obj, "Tab 2") {
             ui_button(obj, .label = "Test Tab 2");
         }
+        
+        ui_tab(obj, "Tab 3") {
+            ui_button(obj, .label = "Test Tab 3");
+        }
     }
     
     
--- a/ui/motif/container.c	Thu Feb 06 22:03:14 2025 +0100
+++ b/ui/motif/container.c	Thu Feb 06 22:36:29 2025 +0100
@@ -224,20 +224,23 @@
 /* -------------------------- 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 numbuttons = cxListSize(tabview->tabs);
+    if(numbuttons == 0) {
+        return;
+    }
+    int button_width = width / numbuttons;
     int x = 0;
     
-    printf("width: %d\n", (int)width);
-    
     CxIterator i = cxListIterator(tabview->tabs);
     cx_foreach(UiTab *, tab, i) {
+        if(i.index + 1 == numbuttons) {
+            button_width = width - x;
+        }
         XtVaSetValues(
                 tab->tab_button,
                 XmNx, x,
@@ -255,19 +258,21 @@
 }
 
 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);
+    if(!tabview->gc_initialized) {
+        XGCValues gcvals;
+        gcvals.foreground = tabview->fg1;
+        tabview->gc = XCreateGC(XtDisplay(tabview->tabbar), XtWindow(tabview->tabbar), (GCForeground), &gcvals);
+    }
+    
+    if(tabview->current_tab) {
+        Widget tab = tabview->current_tab->tab_button;
+        XFillRectangle(dpy, XtWindow(widget), tabview->gc, tab->core.x, tab->core.height, tab->core.width, 4);
+    }
 }
 
 UIWIDGET ui_tabview_create(UiObject *obj, UiTabViewArgs args) {
@@ -363,6 +368,12 @@
     
 }
 
+static void ui_tab_button_callback(Widget widget, UiTab *tab, XtPointer d) {
+    UiMotifTabView *tabview = NULL;
+    XtVaGetValues(widget, XmNuserData, &tabview, NULL);
+    ui_motif_tabview_change_tab(tabview, tab);
+}
+
 void ui_motif_tabview_add_tab(UiMotifTabView *tabview, int index, const char *name, Widget child) {
     UiTab tab;
     
@@ -373,8 +384,9 @@
     XtSetArg(args[n], XmNlabelString, label); n++;
     XtSetArg(args[n], XmNshadowThickness, 0); n++;
     XtSetArg(args[n], XmNhighlightThickness, 0); n++;
+    XtSetArg(args[n], XmNuserData, tabview); n++;
     
-    Widget button = XmCreatePushButton(tabview->tabbar, "tab_button", args, 3);
+    Widget button = XmCreatePushButton(tabview->tabbar, "tab_button", args, n);
     XtManageChild(button);
     
     if(tabview->height == 0) {
@@ -385,21 +397,49 @@
                 &tabview->bg1,
                 XmNbackground,
                 &tabview->bg2,
+                XmNhighlightColor,
+                &tabview->fg1,
                 XmNheight,
                 &h,
                 NULL);
         tabview->height = h + 2; // border
+        
+        XtVaSetValues(tabview->tabbar, XmNbackground, tabview->bg1, NULL);
     }
     
     tab.tab_button = button;
     tab.child = child;
+    size_t newtab_index = cxListSize(tabview->tabs);
     cxListAdd(tabview->tabs, &tab);
+    UiTab *newtab = cxListAt(tabview->tabs, newtab_index);
+    
+    XtAddCallback(
+            button,
+            XmNactivateCallback,
+            (XtCallbackProc)ui_tab_button_callback,
+            newtab);
+    
+    if(newtab_index == 0) {
+        ui_motif_tabview_change_tab(tabview, newtab);
+    } else {
+        XtVaSetValues(button, XmNbackground, tabview->bg1, NULL);
+    }
 }
 
 void ui_motif_tabview_remove(UiMotifTabView *tabview, int index) {
     
 }
 
+void ui_motif_tabview_change_tab(UiMotifTabView *tabview, UiTab *tab) {
+    if(tabview->current_tab) {
+        XtVaSetValues(tabview->current_tab->tab_button, XmNshadowThickness, 0, XmNbackground, tabview->bg1, NULL);
+        XtUnmanageChild(tabview->current_tab->child);
+    }
+    XtVaSetValues(tab->tab_button, XmNshadowThickness, 1, XmNbackground, tabview->bg2, NULL);
+    tabview->current_tab = tab;
+    XtManageChild(tab->child);
+}
+
 Widget ui_tabview_container_prepare(UiContainerPrivate *ctn, Arg *args, int *n) {
     UiTabViewContainer *ct = (UiTabViewContainer*)ctn;
     UiMotifTabView *tabview = ct->tabview;
--- a/ui/motif/container.h	Thu Feb 06 22:03:14 2025 +0100
+++ b/ui/motif/container.h	Thu Feb 06 22:36:29 2025 +0100
@@ -104,15 +104,24 @@
     Dimension y;
 } UiGridContainer;
 
+typedef struct UiTab {
+    Widget tab_button;
+    Widget child;
+} UiTab;
+
 typedef struct UiMotifTabView UiMotifTabView;
 struct UiMotifTabView {
     Widget form;
     Widget tabbar;
     Widget content;
     Widget current;
+    UiTab *current_tab;
     int height;
     Pixel bg1;
     Pixel bg2;
+    Pixel fg1;
+    GC gc;
+    int gc_initialized;
     UiTabViewType tabview;
     UiSubContainerType subcontainer;
     CxList *tabs;
@@ -121,11 +130,6 @@
     void (*remove)(UiMotifTabView *tabview, int index);
 };
 
-typedef struct UiTab {
-    Widget tab_button;
-    Widget child;
-} UiTab;
-
 typedef struct UiTabViewContainer {
     UiContainerPrivate container;
     UiMotifTabView *tabview;
@@ -134,6 +138,7 @@
 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);
+void ui_motif_tabview_change_tab(UiMotifTabView *tabview, UiTab *tab);
 
 Widget ui_tabview_container_prepare(UiContainerPrivate *ctn, Arg *args, int *n);
 void ui_tabview_container_add(UiContainerPrivate *ctn, Widget widget);

mercurial