--- 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; +}