From: Olaf Wintermann Date: Tue, 15 Apr 2025 19:37:13 +0000 (+0200) Subject: create UI models for loaded attachments X-Git-Url: https://uap-core.de/gitweb/?a=commitdiff_plain;h=0bc59ed6b2fca33d453a30ec215256442b908c2b;p=note.git create UI models for loaded attachments --- diff --git a/application/note.c b/application/note.c index b97267f..3d3c946 100644 --- a/application/note.c +++ b/application/note.c @@ -130,6 +130,17 @@ static void note_content_loaded(UiEvent *event, cxmutstr result, void *userdata) 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); } diff --git a/ui/cocoa/button.h b/ui/cocoa/button.h index 8c9311b..7489591 100644 --- a/ui/cocoa/button.h +++ b/ui/cocoa/button.h @@ -30,6 +30,17 @@ #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); diff --git a/ui/cocoa/button.m b/ui/cocoa/button.m index 5ac939b..cd2f245 100644 --- a/ui/cocoa/button.m +++ b/ui/cocoa/button.m @@ -174,17 +174,45 @@ void ui_switch_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; @@ -220,9 +248,28 @@ UIWIDGET ui_radiobutton_create(UiObject* obj, UiToggleArgs args) { } 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; } diff --git a/ui/gtk/image.c b/ui/gtk/image.c index 6a49665..db060f1 100644 --- a/ui/gtk/image.c +++ b/ui/gtk/image.c @@ -341,6 +341,27 @@ int ui_image_load_file(UiGeneric *obj, const char *path) { 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); } diff --git a/ui/qt/button.cpp b/ui/qt/button.cpp index 1ca6f4e..827279c 100644 --- a/ui/qt/button.cpp +++ b/ui/qt/button.cpp @@ -1,7 +1,7 @@ /* * 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: @@ -167,9 +167,9 @@ void ui_checkbox_set(UiInteger *value, int64_t i) { 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); } } diff --git a/ui/qt/button.h b/ui/qt/button.h index b848ec6..862ad49 100644 --- a/ui/qt/button.h +++ b/ui/qt/button.h @@ -1,7 +1,7 @@ /* * 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: diff --git a/ui/qt/entry.cpp b/ui/qt/entry.cpp new file mode 100644 index 0000000..2dee2e7 --- /dev/null +++ b/ui/qt/entry.cpp @@ -0,0 +1,180 @@ +/* + * 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 +#include + + + +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; +} diff --git a/ui/qt/entry.h b/ui/qt/entry.h new file mode 100644 index 0000000..5feefac --- /dev/null +++ b/ui/qt/entry.h @@ -0,0 +1,55 @@ +/* + * 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 */ + diff --git a/ui/qt/qt5.pro b/ui/qt/qt5.pro index 43d9637..5971c32 100644 --- a/ui/qt/qt5.pro +++ b/ui/qt/qt5.pro @@ -50,6 +50,7 @@ SOURCES += button.cpp SOURCES += label.cpp SOURCES += graphics.cpp SOURCES += widget.cpp +SOURCES += entry.cpp HEADERS += toolkit.h HEADERS += window.h @@ -64,4 +65,5 @@ HEADERS += button.h HEADERS += label.h HEADERS += graphics.h HEADERS += widget.h +HEADERS += entry.h diff --git a/ui/ui/image.h b/ui/ui/image.h index 0d53d8f..7217caa 100644 --- a/ui/ui/image.h +++ b/ui/ui/image.h @@ -85,6 +85,7 @@ UIEXPORT UIWIDGET ui_imageviewer_set_adjustwidgetsize(UIWIDGET w, UiBool set); 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);