Mon, 06 Jan 2025 22:22:55 +0100
update ucx, toolkit
/* * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. * * 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: * * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. */ #include <stdio.h> #include <stdlib.h> #include "label.h" #include "container.h" #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; }