ui/motif/label.c

changeset 101
7b3a3130be44
parent 100
d2bd73d28ff1
--- a/ui/motif/label.c	Thu Dec 12 20:01:43 2024 +0100
+++ b/ui/motif/label.c	Mon Jan 06 22:22:55 2025 +0100
@@ -1,7 +1,7 @@
 /*
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
  *
- * Copyright 2014 Olaf Wintermann. All rights reserved.
+ * Copyright 2024 Olaf Wintermann. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions are met:
@@ -34,3 +34,209 @@
 #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;
+    
+    UiContainerPrivate *ctn = ui_obj_container(obj);
+    UI_APPLY_LAYOUT(ctn->layout, args);
+    
+    Widget parent = ctn->prepare(ctn, xargs, &n);
+    
+    XtSetArg(xargs[n], XmNalignment, align); n++;
+    XmString label = NULL;
+    if(args.label) {
+        label = XmStringCreateLocalized((char*)args.label);
+        XtSetArg(xargs[n], XmNlabelString, label); n++;
+    }
+    
+    char *name = args.name ? (char*)args.name : "label";
+    Widget w = XmCreateLabel(parent, name, xargs, n);
+    XtManageChild(w);
+    ctn->add(ctn, w);
+      
+    XmStringFree(label);
+    return w;
+} 
+
+UIWIDGET ui_label_create(UiObject* obj, UiLabelArgs args) {
+    return label_create(obj, args, XmALIGNMENT_CENTER);
+}
+
+UIWIDGET ui_llabel_create(UiObject* obj, UiLabelArgs args) {
+    return label_create(obj, args, XmALIGNMENT_BEGINNING);
+}
+
+UIWIDGET ui_rlabel_create(UiObject* obj, UiLabelArgs args) {
+    return label_create(obj, args, XmALIGNMENT_END);
+}
+
+
+/* -------------------------- progressbar/spiner -------------------------- */
+
+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(w == 0) {
+        return;
+    }
+    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);
+    XtAddCallback(
+            drawingArea,
+            XmNresizeCallback,
+            (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);
+}
+
+
+UIWIDGET ui_progressspinner_create(UiObject* obj, UiProgressbarSpinnerArgs 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);
+     
+    XmString label = XmStringCreateSimple("");
+    XtSetArg(xargs[n], XmNlabelString, label); n++;
+    XtSetArg(xargs[n], XmNalignment, XmALIGNMENT_END); n++;
+    XtSetArg(xargs[n], gridMinWidth, 40); n++;
+    
+    char *name = args.name ? (char*)args.name : "progresss_spinner";
+    Widget w = XmCreateLabel(parent, name, xargs, n);
+    XtManageChild(w);
+    ctn->add(ctn, w);
+    
+    UiVar* var = uic_widget_var(obj->ctx, obj->ctx, args.value, args.varname, UI_VAR_INTEGER);
+    if(var) {
+        UiInteger *value = var->value;
+        value->obj = w;
+        value->get = ui_progressspinner_get;
+        value->set = ui_progressspinner_set;
+        
+        if(value->value) {
+            ui_progressspinner_set(value, 1);
+        }
+    }
+    
+      
+    XmStringFree(label);
+    return w;
+}
+
+int64_t ui_progressspinner_get(UiInteger *i) {
+    return i->value;
+}
+
+void ui_progressspinner_set(UiInteger *i, int64_t value) {
+    Widget w = i->obj;
+    XmString label;
+    if(value) {
+        char str[4];
+        snprintf(str, 4, "%c", 150);
+        label = XmStringCreateSimple(str);
+    } else {
+        label = XmStringCreateSimple("");
+    }
+    XtVaSetValues(w, XmNlabelString, label, NULL);
+    XmStringFree(label);
+    i->value = value;
+}

mercurial