Sat, 04 Jan 2025 16:22:14 +0100
implement progressbar (Motif)
application/main.c | file | annotate | diff | comparison | revisions | |
ui/motif/Grid.c | file | annotate | diff | comparison | revisions | |
ui/motif/label.c | file | annotate | diff | comparison | revisions | |
ui/motif/label.h | file | annotate | diff | comparison | revisions | |
ui/ui/display.h | file | annotate | diff | comparison | revisions |
--- a/application/main.c Sat Jan 04 15:16:51 2025 +0100 +++ b/application/main.c Sat Jan 04 16:22:14 2025 +0100 @@ -596,6 +596,7 @@ ui_button(obj, .label = "Add Menu Item", .onclick = action_button, .name = "mybutton1"); ui_button(obj, .label = "Add List Item", .onclick = action_button2); + ui_progressbar(obj, .name = "pb"); ui_listview(obj, .list = wdata->list, .fill = UI_ON, .multiselection = TRUE, .onactivate = action_listevent, .onactivatedata = "activate", .onselection = action_listevent, .onselectiondata = "selection");
--- a/ui/motif/Grid.c Sat Jan 04 15:16:51 2025 +0100 +++ b/ui/motif/Grid.c Sat Jan 04 16:22:14 2025 +0100 @@ -409,6 +409,12 @@ for(int i=0;i<w->composite.num_children;i++) { Widget child = w->composite.children[i]; GridConstraintRec *constraints = child->core.constraints; + if(constraints->grid.pref_width == 0) { + constraints->grid.pref_width = child->core.width; + } + if(constraints->grid.pref_height == 0) { + constraints->grid.pref_height = child->core.height; + } if(constraints->grid.colspan > span_max || constraints->grid.rowspan > span_max) { continue; @@ -618,7 +624,9 @@ } } - XtConfigureWidget(child, x, y, width, height, child->core.border_width); + if(width > 0 && height > 0) { + XtConfigureWidget(child, x, y, width, height, child->core.border_width); + } //printf("child %d %d - %d %d\n", (int)child->core.x, (int)child->core.y, (int)child->core.width, (int)child->core.height); }
--- 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); +}
--- a/ui/motif/label.h Sat Jan 04 15:16:51 2025 +0100 +++ b/ui/motif/label.h Sat Jan 04 16:22:14 2025 +0100 @@ -30,13 +30,25 @@ #define LABEL_H #include "../ui/display.h" +#include "../common/context.h" #ifdef __cplusplus extern "C" { #endif +typedef struct UiProgressBar { + Widget widget; + GC gc; + UiVar *var; + double min; + double max; + double value; + Pixel color; +} UiProgressBar; +double ui_progressbar_get(UiDouble *d); +void ui_progressbar_set(UiDouble *d, double value); #ifdef __cplusplus }