--- a/ui/motif/label.c Sun May 23 09:44:43 2021 +0200 +++ b/ui/motif/label.c Sat Jan 04 16:38:48 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: @@ -33,38 +33,154 @@ #include "container.h" #include "../common/context.h" #include "../common/object.h" -#include <ucx/mempool.h> + +#include "Grid.h" -UIWIDGET ui_label(UiObject *obj, char *label) { - UiContainer *ct = uic_get_current_container(obj); - XmString str = XmStringCreateLocalized(label); - +static UIWIDGET label_create(UiObject *obj, UiLabelArgs args, int align) { + Arg xargs[16]; int n = 0; - Arg args[16]; - XtSetArg(args[n], XmNlabelString, str); - n++; + + 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); - Widget parent = ct->prepare(ct, args, &n, FALSE); - Widget widget = XmCreateLabel(parent, "label", args, n); - ct->add(ct, widget); - XtManageChild(widget); + 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 ------------------------------ */ + +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); + } - return widget; + 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_space(UiObject *obj) { - UiContainer *ct = uic_get_current_container(obj); - XmString str = XmStringCreateLocalized(""); - +UIWIDGET ui_progressbar_create(UiObject *obj, UiProgressbarArgs args) { + Arg xargs[16]; int n = 0; - Arg args[16]; - XtSetArg(args[n], XmNlabelString, str); - n++; + + 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); - Widget parent = ct->prepare(ct, args, &n, TRUE); - Widget widget = XmCreateLabel(parent, "space_label", args, n); - ct->add(ct, widget); - XtManageChild(widget); + 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; + } - return widget; + 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); +}