static void note_attachments_loaded(UiEvent *event, int error, void *userdata) {
LoadNoteContent *op = userdata;
op->attachments = TRUE;
+
+ if(op->note->attachments) {
+ CxIterator i = cxListIterator(op->note->attachments);
+ cx_foreach(Attachment *, attachment, i) {
+ attachment_create_ui_model(op->note->model->ctx, attachment, op->note);
+ if(attachment->bin_content.length > 0) {
+ printf("attachment content loaded\n");
+ }
+ }
+ }
+
if(op->content) {
note_loading_completed(op);
}
#import "../ui/button.h"
+@interface UiRadioButton : NSButton
+
+@property UiVar *var;
+@property Boolean direct_state;
+
+- (UiRadioButton*)init;
+- (void)setState:(NSControlStateValue)state;
+
+@end
+
+
int64_t ui_togglebutton_get(UiInteger *i);
void ui_togglebutton_set(UiInteger *i, int64_t value);
button.state = state;
}
+
+@implementation UiRadioButton
+
+- (UiRadioButton*)init {
+ self = [super init];
+ _direct_state = NO;
+ [self setButtonType:NSButtonTypeRadio];
+ return self;
+}
+
+- (void)setState:(NSControlStateValue)state {
+ // NOOP
+}
+
+@end
+
static void radiobutton_eventdata(id button, UiVar *var, void **eventdata, int *value) {
if(var) {
- printf("switch radiobutton\n");
+ UiInteger *value = var->value;
+ NSMutableArray *buttons = (__bridge NSMutableArray*)value->obj;
+ for(UiRadioButton *b in buttons) {
+ if(b != button) {
+ b.direct_state = YES;
+ [[b cell] setState:0];
+ b.direct_state = NO;
+ }
+ }
}
}
UIWIDGET ui_radiobutton_create(UiObject* obj, UiToggleArgs args) {
- NSButton *button = [[NSButton alloc] init];
- [button setButtonType:NSButtonTypeRadio];
+ UiRadioButton *button = [[UiRadioButton alloc] init];
+
+ if(args.label) {
+ button.title = [[NSString alloc] initWithUTF8String:args.label];
+ }
UiVar* var = uic_widget_var(obj->ctx, obj->ctx, args.value, args.varname, UI_VAR_INTEGER);
+ button.var = var;
NSMutableArray *buttons = nil;
if(var) {
UiInteger *i = var->value;
}
int64_t ui_radiobuttons_get(UiInteger *i) {
- return 0;
+ NSMutableArray *buttons = (__bridge NSMutableArray*)i->obj;
+ int64_t index = 0;
+ for(UiRadioButton *b in buttons) {
+ if([b cell].state != 0) {
+ i->value = index;
+ break;
+ }
+ index++;
+ }
+ return index;
}
void ui_radiobuttons_set(UiInteger *i, int64_t value) {
-
+ NSMutableArray *buttons = (__bridge NSMutableArray*)i->obj;
+ int64_t index = 0;
+ for(UiRadioButton *b in buttons) {
+ if(index == value) {
+ [b cell].state = NSControlStateValueOn;
+ } else {
+ [b cell].state = NSControlStateValueOff;
+ }
+ index++;
+ }
+ return index;
}
return 0;
}
+UIEXPORT int ui_image_load_data(UiGeneric *obj, const void *imgdata, size_t size) {
+ GBytes *bytes = g_bytes_new_static(imgdata, size);
+ GInputStream *in = g_memory_input_stream_new_from_bytes(bytes);
+ GError *error = NULL;
+ GdkPixbuf *pixbuf = gdk_pixbuf_new_from_stream(in, NULL, &error);
+ g_object_unref(bytes);
+ g_object_unref(in);
+ if(!pixbuf) {
+ return 1;
+ }
+
+ if(obj->set) {
+ obj->set(obj, pixbuf, UI_IMAGE_OBJECT_TYPE);
+ g_object_unref(pixbuf);
+ } else {
+ obj->value = pixbuf;
+ }
+
+ return 0;
+}
+
void ui_image_ref(UIIMAGE img) {
g_object_ref(img);
}
/*
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
*
- * Copyright 2015 Olaf Wintermann. All rights reserved.
+ * Copyright 2025 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:
static void radiobutton_event(UiEvent *event, UiEventWrapper *wrapper) {
if(wrapper->var) {
- UiInteger *value = wrapper->var->value;
+ UiInteger *value = (UiInteger*)wrapper->var->value;
event->eventdata = value;
- event->intval = ui_get(value);
+ event->intval = value->get(value);
}
}
/*
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
*
- * Copyright 2015 Olaf Wintermann. All rights reserved.
+ * Copyright 2025 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:
--- /dev/null
+/*
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
+ *
+ * Copyright 2025 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 "entry.h"
+
+#include "container.h"
+#include "../common/context.h"
+
+#include <QDoubleSpinBox>
+#include <QSpinBox>
+
+
+
+UIWIDGET ui_spinner_create(UiObject *obj, UiSpinnerArgs args) {
+ UiContainerPrivate *ctn = ui_obj_container(obj);
+ UI_APPLY_LAYOUT(ctn->layout, args);
+
+ bool use_double = false;
+ UiVar *var = NULL;
+ if(args.varname) {
+ var = uic_get_var(obj->ctx, args.varname);
+ if(var->type == UI_VAR_DOUBLE) {
+ use_double = true;
+ } else if(var->type == UI_VAR_RANGE) {
+ use_double = true;
+ } else if(var->type != UI_VAR_INTEGER) {
+ var = NULL;
+ fprintf(stderr, "UI Error: var '%s' has wrong type (must be int/double/range)\n", args.varname);
+ }
+ }
+
+ if(!var) {
+ if(args.intvalue) {
+ var = uic_widget_var(obj->ctx, obj->ctx, args.intvalue, NULL, UI_VAR_INTEGER);
+ } else if(args.doublevalue) {
+ var = uic_widget_var(obj->ctx, obj->ctx, args.doublevalue, NULL, UI_VAR_DOUBLE);
+ use_double = true;
+ } else if(args.rangevalue) {
+ var = uic_widget_var(obj->ctx, obj->ctx, args.rangevalue, NULL, UI_VAR_RANGE);
+ use_double = true;
+ } else {
+ if(args.digits > 0) {
+ use_double = true;
+ }
+ }
+ }
+
+ QAbstractSpinBox *widget = nullptr;
+ if(use_double) {
+ QDoubleSpinBox *spinbox = new QDoubleSpinBox();
+ spinbox->setDecimals(args.digits);
+ if(args.step != 0) {
+ spinbox->setSingleStep(args.step);
+ }
+ widget = spinbox;
+ } else {
+ QSpinBox *spinbox = new QSpinBox();
+ if(args.step != 0) {
+ spinbox->setSingleStep(args.step);
+ }
+ widget = spinbox;
+ }
+
+ if(var) {
+ if(var->type == UI_VAR_INTEGER) {
+ UiInteger *value = (UiInteger*)var->value;
+ value->obj = widget;
+ if(value->value != 0) {
+ QSpinBox *spinbox = (QSpinBox*)widget;
+ spinbox->setValue(value->value);
+ }
+ value->get = ui_spinbox_int_get;
+ value->set = ui_spinbox_int_set;
+ } else if(var->type == UI_VAR_DOUBLE) {
+ UiDouble *value = (UiDouble*)var->value;
+ value->obj = widget;
+ if(value->value != 0) {
+ QDoubleSpinBox *spinbox = (QDoubleSpinBox*)widget;
+ spinbox->setValue(value->value);
+ }
+ value->get = ui_spinbox_double_get;
+ value->set = ui_spinbox_double_set;
+ } else if(var->type == UI_VAR_RANGE) {
+ UiRange *value = (UiRange*)var->value;
+ value->obj = widget;
+ QDoubleSpinBox *spinbox = (QDoubleSpinBox*)widget;
+ if(value->value != 0) {
+ spinbox->setValue(value->value);
+ }
+ if(value->min != value->max) {
+ spinbox->setRange(value->min, value->max);
+ }
+ if(value->extent != 0) {
+ spinbox->setSingleStep(value->extent);
+ }
+ value->get = ui_spinbox_range_get;
+ value->set = ui_spinbox_range_set;
+ value->setrange = ui_spinbox_range_setrange;
+ value->setextent = ui_spinbox_range_setextent;
+ }
+ }
+
+
+ ctn->add(widget, false);
+ return widget;
+}
+
+int64_t ui_spinbox_int_get(UiInteger *i) {
+ QSpinBox *spinbox = (QSpinBox*)i->obj;
+ i->value = spinbox->value();
+ return i->value;
+}
+
+void ui_spinbox_int_set(UiInteger *i, int64_t value) {
+ QSpinBox *spinbox = (QSpinBox*)i->obj;
+ spinbox->setValue(value);
+ i->value = spinbox->value();
+}
+
+double ui_spinbox_double_get(UiDouble *d) {
+ QDoubleSpinBox *spinbox = (QDoubleSpinBox*)d->obj;
+ d->value = spinbox->value();
+ return d->value;
+}
+
+void ui_spinbox_double_set(UiDouble *d, double value) {
+ QDoubleSpinBox *spinbox = (QDoubleSpinBox*)d->obj;
+ spinbox->setValue(value);
+ d->value = spinbox->value();
+}
+
+double ui_spinbox_range_get(UiRange *range) {
+ QDoubleSpinBox *spinbox = (QDoubleSpinBox*)range->obj;
+ range->value = spinbox->value();
+ return range->value;
+}
+
+void ui_spinbox_range_set(UiRange *range, double value) {
+ QDoubleSpinBox *spinbox = (QDoubleSpinBox*)range->obj;
+ spinbox->setValue(value);
+ range->value = spinbox->value();
+}
+
+void ui_spinbox_range_setrange(UiRange *range, double min, double max) {
+ QDoubleSpinBox *spinbox = (QDoubleSpinBox*)range->obj;
+ spinbox->setRange(min, max);
+ range->min = min;
+ range->max = max;
+}
+
+void ui_spinbox_range_setextent(UiRange *range, double extent) {
+ QDoubleSpinBox *spinbox = (QDoubleSpinBox*)range->obj;
+ spinbox->setSingleStep(extent);
+ range->extent = extent;
+}
--- /dev/null
+/*
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
+ *
+ * Copyright 2025 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.
+ */
+
+#ifndef ENTRY_H
+#define ENTRY_H
+
+#include "../ui/entry.h"
+#include "toolkit.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+int64_t ui_spinbox_int_get(UiInteger *i);
+void ui_spinbox_int_set(UiInteger *i, int64_t value);
+
+double ui_spinbox_double_get(UiDouble *d);
+void ui_spinbox_double_set(UiDouble *d, double value);
+
+double ui_spinbox_range_get(UiRange *range);
+void ui_spinbox_range_set(UiRange *range, double value);
+void ui_spinbox_range_setrange(UiRange *range, double min, double max);
+void ui_spinbox_range_setextent(UiRange *range, double extent);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* ENTRY_H */
+
SOURCES += label.cpp
SOURCES += graphics.cpp
SOURCES += widget.cpp
+SOURCES += entry.cpp
HEADERS += toolkit.h
HEADERS += window.h
HEADERS += label.h
HEADERS += graphics.h
HEADERS += widget.h
+HEADERS += entry.h
UIEXPORT UIWIDGET ui_imageviewer_set_useradjustable(UIWIDGET w, UiBool set);
UIEXPORT int ui_image_load_file(UiGeneric *obj, const char *path);
+UIEXPORT int ui_image_load_data(UiGeneric *obj, const void *imgdata, size_t size);
UIEXPORT void ui_image_ref(UIIMAGE img);
UIEXPORT void ui_image_unref(UIIMAGE img);