ui/motif/label.c

branch
newapi
changeset 429
0921f8a5d535
parent 428
c7dcd2ab2d3d
child 430
ea949c0109d8
--- 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);
+}

mercurial