implement progressbar (Motif) newapi

Sat, 04 Jan 2025 16:22:14 +0100

author
Olaf Wintermann <olaf.wintermann@gmail.com>
date
Sat, 04 Jan 2025 16:22:14 +0100
branch
newapi
changeset 429
0921f8a5d535
parent 428
c7dcd2ab2d3d
child 430
ea949c0109d8

implement progressbar (Motif)

application/main.c file | annotate | diff | comparison | revisions
ui/motif/Grid.c file | annotate | diff | comparison | revisions
ui/motif/label.c file | annotate | diff | comparison | revisions
ui/motif/label.h file | annotate | diff | comparison | revisions
ui/ui/display.h file | annotate | diff | comparison | revisions
--- a/application/main.c	Sat Jan 04 15:16:51 2025 +0100
+++ b/application/main.c	Sat Jan 04 16:22:14 2025 +0100
@@ -596,6 +596,7 @@
     
     ui_button(obj, .label = "Add Menu Item", .onclick = action_button, .name = "mybutton1");
     ui_button(obj, .label = "Add List Item", .onclick = action_button2);
+    ui_progressbar(obj, .name = "pb");
     ui_listview(obj, .list = wdata->list, .fill = UI_ON, .multiselection = TRUE,
             .onactivate = action_listevent, .onactivatedata = "activate",
             .onselection = action_listevent, .onselectiondata = "selection");
--- a/ui/motif/Grid.c	Sat Jan 04 15:16:51 2025 +0100
+++ b/ui/motif/Grid.c	Sat Jan 04 16:22:14 2025 +0100
@@ -409,6 +409,12 @@
         for(int i=0;i<w->composite.num_children;i++) {
             Widget child = w->composite.children[i];
             GridConstraintRec *constraints = child->core.constraints;
+            if(constraints->grid.pref_width == 0) {
+                constraints->grid.pref_width = child->core.width;
+            }
+            if(constraints->grid.pref_height == 0) {
+                constraints->grid.pref_height = child->core.height;
+            }
             
             if(constraints->grid.colspan > span_max || constraints->grid.rowspan > span_max) {
                 continue;
@@ -618,7 +624,9 @@
             }
         }
         
-        XtConfigureWidget(child, x, y, width, height, child->core.border_width);
+        if(width > 0 && height > 0) {
+            XtConfigureWidget(child, x, y, width, height, child->core.border_width);
+        }
         //printf("child %d %d - %d %d\n", (int)child->core.x, (int)child->core.y, (int)child->core.width, (int)child->core.height);
     }
     
--- a/ui/motif/label.c	Sat Jan 04 15:16:51 2025 +0100
+++ b/ui/motif/label.c	Sat Jan 04 16:22:14 2025 +0100
@@ -34,6 +34,8 @@
 #include "../common/context.h"
 #include "../common/object.h"
 
+#include "Grid.h"
+
 static UIWIDGET label_create(UiObject *obj, UiLabelArgs args, int align) {
     Arg xargs[16];
     int n = 0;
@@ -70,3 +72,107 @@
 UIWIDGET ui_rlabel_create(UiObject* obj, UiLabelArgs args) {
     return label_create(obj, args, XmALIGNMENT_END);
 }
+
+
+/* ------------------------------ progressbar ------------------------------ */
+
+static void ui_destroy_progressbar(Widget w, UiProgressBar *pb, XtPointer d) {
+    // TODO: free other stuff
+    free(pb);
+}
+
+static void ui_progressbar_expose(Widget widget, UiProgressBar *pb, XtPointer c) {
+    Display *dp = XtDisplay(widget);
+    Window w = XtWindow(widget);
+    if(!pb->gc) {
+        XGCValues gcvals;
+        gcvals.foreground = pb->color;
+        pb->gc = XCreateGC(dp, w, (GCForeground), &gcvals);
+    }
+    
+    Dimension width = widget->core.width;
+    Dimension height = widget->core.height;
+    
+    double value = (pb->value - pb->min) / (pb->max - pb->min);
+    Dimension valueW = (double)width * value;
+    
+    XClearArea(dp, w, 0, 0, width, height, False);
+    XFillRectangle(dp, w, pb->gc, 0, 0, valueW, widget->core.height);
+}
+
+UIWIDGET ui_progressbar_create(UiObject *obj, UiProgressbarArgs args) {
+    Arg xargs[16];
+    int n = 0;
+    
+    UiContainerPrivate *ctn = ui_obj_container(obj);
+    UI_APPLY_LAYOUT(ctn->layout, args);
+    
+    Widget parent = ctn->prepare(ctn, xargs, &n);
+    
+    char *name = args.name ? (char*)args.name : "progressbar";
+    Widget frame = XmCreateFrame(parent, name, xargs, n);
+    
+    // create a button and get some informations about the height, shadow, highlight, ....
+    // we want the frame to have the same dimensions as a normal button
+    Widget test = XmCreatePushButton(frame, "button", NULL, 0);
+    XtManageChild(test);
+    Dimension h, highlightThickness, shadowThickness;
+    Pixel highlightColor;
+    XtVaGetValues(test, XmNheight, &h, XmNhighlightThickness, &highlightThickness,
+            XmNshadowThickness, &shadowThickness, XmNhighlightColor, &highlightColor, NULL);
+    XtDestroyWidget(test);
+    
+    // adjust frame
+    XtVaSetValues(frame, XmNshadowThickness, shadowThickness, gridMarginLeft, highlightThickness,
+            gridMarginRight, highlightThickness, gridMarginTop, highlightThickness,
+            gridMarginBottom, highlightThickness, NULL);
+    
+    // create drawing area
+    Dimension da_height = h - 2*highlightThickness - 2*shadowThickness;
+    n = 0;
+    XtSetArg(xargs[n], XmNheight, da_height); n++;
+    Widget drawingArea = XmCreateDrawingArea(frame, "progressbar_drawingarea", xargs, n);
+    XtManageChild(drawingArea);
+    
+    UiVar* var = uic_widget_var(obj->ctx, obj->ctx, args.value, args.varname, UI_VAR_DOUBLE);
+    
+    UiProgressBar *progressbarData = malloc(sizeof(UiProgressBar));
+    progressbarData->widget = drawingArea;
+    progressbarData->min = args.min;
+    progressbarData->max = args.max == 0 ? 100 : args.max;
+    progressbarData->value = 50;
+    progressbarData->var = var;
+    progressbarData->color = highlightColor;
+    progressbarData->gc = NULL; // initialize on first expose
+    
+    if(var) {
+        UiDouble *d = var->value;
+        progressbarData->value = d->value;
+        d->obj = progressbarData;
+        d->get = ui_progressbar_get;
+        d->set = ui_progressbar_set;
+    }
+    
+    XtAddCallback(
+            drawingArea,
+            XmNexposeCallback,
+            (XtCallbackProc)ui_progressbar_expose,
+            progressbarData);
+    
+    
+    XtManageChild(frame);
+    return frame;
+}
+
+double ui_progressbar_get(UiDouble *d) {
+    UiProgressBar *pb = d->obj;
+    d->value = pb->value;
+    return d->value;
+}
+
+void ui_progressbar_set(UiDouble *d, double value) {
+    UiProgressBar *pb = d->obj;
+    d->value = value;
+    pb->value = value;
+    ui_progressbar_expose(pb->widget, pb, NULL);
+}
--- a/ui/motif/label.h	Sat Jan 04 15:16:51 2025 +0100
+++ b/ui/motif/label.h	Sat Jan 04 16:22:14 2025 +0100
@@ -30,13 +30,25 @@
 #define	LABEL_H
 
 #include "../ui/display.h"
+#include "../common/context.h"
 
 #ifdef	__cplusplus
 extern "C" {
 #endif
 
+typedef struct UiProgressBar {
+    Widget widget;
+    GC gc;
+    UiVar *var;
+    double min;
+    double max;
+    double value;
+    Pixel color;
+} UiProgressBar;
 
 
+double ui_progressbar_get(UiDouble *d);
+void ui_progressbar_set(UiDouble *d, double value);
 
 #ifdef	__cplusplus
 }
--- a/ui/ui/display.h	Sat Jan 04 15:16:51 2025 +0100
+++ b/ui/ui/display.h	Sat Jan 04 16:22:14 2025 +0100
@@ -84,6 +84,8 @@
     int colspan;
     int rowspan;
     int width;
+    const char *name;
+    const char *style_class;
 
     double min;
     double max;

mercurial