]> uap-core.de Git - note.git/commitdiff
implement imageviewer main
authorOlaf Wintermann <olaf.wintermann@gmail.com>
Mon, 27 Jul 2026 19:30:18 +0000 (21:30 +0200)
committerOlaf Wintermann <olaf.wintermann@gmail.com>
Mon, 27 Jul 2026 19:30:18 +0000 (21:30 +0200)
ui-rs/src/ui/ffi.rs
ui-rs/src/ui/image.rs [new file with mode: 0644]
ui-rs/src/ui/label.rs
ui-rs/src/ui/mod.rs
ui-rs/src/ui/toolkit.rs

index b448364a2f889e8cdd27777239c3dc2bf8166f5a..2fc9ab647a8b6ce2fb771059e5a424ad521808fa 100644 (file)
@@ -245,4 +245,9 @@ pub struct UiToolbarContentToggleItemArgs {
 #[repr(C)]
 pub struct UiToolbarMenuArgs {
     _private: [u8; 0],
+}
+
+#[repr(C)]
+pub struct UiImageViewerArgs {
+    _private: [u8; 0],
 }
\ No newline at end of file
diff --git a/ui-rs/src/ui/image.rs b/ui-rs/src/ui/image.rs
new file mode 100644 (file)
index 0000000..eae4e3b
--- /dev/null
@@ -0,0 +1,355 @@
+/*
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
+ *
+ * Copyright 2026 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.
+ */
+
+#![allow(dead_code)]
+
+use std::ffi::{c_char, c_int, c_void, CString};
+use std::path::Path;
+use crate::ui::{ffi, toolkit, UiContext, UiImage};
+use crate::ui::ffi::{UiImageViewerArgs, UiLabelArgs};
+use crate::ui::label::{Label, LabelCreate};
+use crate::ui::widget::Widget;
+
+#[cfg(unix)]
+fn path_to_cstring(path: &Path) -> Result<CString, std::ffi::NulError> {
+    use std::os::unix::ffi::OsStrExt;
+    CString::new(path.as_os_str().as_bytes())
+}
+
+#[cfg(windows)]
+fn path_to_cstring(path: &Path) -> Result<CString, std::ffi::NulError> {
+    CString::new(path.to_string_lossy().as_bytes())
+}
+
+impl UiImage {
+    pub fn init(&mut self, ctx: &UiContext, name: Option<&str>) {
+        let c_string = name.map(|n| CString::new(n).unwrap());
+        let c_str = c_string.as_ref().map_or(std::ptr::null(), |s| s.as_ptr());
+        unsafe {
+            self.ptr = crate::ui::toolkit::ui_generic_new(ctx.ptr, c_str);
+        }
+    }
+
+    pub fn load_image_file(&mut self, path: &Path) -> Result<(), i32> {
+        if self.ptr.is_null() {
+            return Err(-2);
+        }
+
+        let path_str = match path_to_cstring(path) {
+            Ok(s) => s,
+            Err(_) => return Err(-1),
+        };
+        let ret = unsafe {
+            ui_image_load_file(self.ptr, path_str.as_ptr())
+        };
+
+        if ret == 0 {
+            Ok(())
+        } else {
+            Err(ret)
+        }
+    }
+
+    pub fn image_load_data(&mut self, data: &[u8]) -> Result<(), i32> {
+        let ret = unsafe {
+            ui_image_load_data(self.ptr, data.as_ptr().cast(), data.len())
+        };
+
+        if ret == 0 {
+            Ok(())
+        } else {
+            Err(ret)
+        }
+    }
+}
+
+pub struct ImageViewer {
+    ptr: *mut c_void
+}
+
+impl Widget for ImageViewer {
+    fn get_widget(&self) -> *mut c_void {
+        self.ptr
+    }
+}
+
+pub struct ImageViewerBuilder<'a, T> {
+    args: *mut UiImageViewerArgs,
+    obj: &'a mut toolkit::UiObject<T>,
+}
+
+impl<'a, T> Drop for ImageViewerBuilder<'a, T> {
+    fn drop(&mut self) {
+        unsafe {
+            ui_imageviewer_args_free(self.args);
+        }
+    }
+}
+
+impl<'a, T> ImageViewerBuilder<'a, T> {
+    pub fn create(&mut self) -> ImageViewer {
+        ImageViewer { ptr: unsafe { ui_imageviewer_create(self.obj.ptr, self.args) } }
+    }
+
+    pub fn fill(&mut self, fill: bool) -> &mut Self {
+        unsafe {
+            ui_imageviewer_args_set_fill(self.args, fill as c_int);
+        }
+        self
+    }
+
+    pub fn hexpand(&mut self, value: bool) -> &mut Self {
+        unsafe {
+            ui_imageviewer_args_set_hexpand(self.args, value as c_int);
+        }
+        self
+    }
+
+    pub fn vexpand(&mut self, value: bool) -> &mut Self {
+        unsafe {
+            ui_imageviewer_args_set_vexpand(self.args, value as c_int);
+        }
+        self
+    }
+
+    pub fn hfill(&mut self, value: bool) -> &mut Self {
+        unsafe {
+            ui_imageviewer_args_set_hfill(self.args, value as c_int);
+        }
+        self
+    }
+
+    pub fn vfill(&mut self, value: bool) -> &mut Self {
+        unsafe {
+            ui_imageviewer_args_set_vfill(self.args, value as c_int);
+        }
+        self
+    }
+
+    pub fn override_defaults(&mut self, value: bool) -> &mut Self {
+        unsafe {
+            ui_imageviewer_args_set_override_defaults(self.args, value as c_int);
+        }
+        self
+    }
+
+    pub fn margin(&mut self, value: i32) -> &mut Self {
+        unsafe {
+            ui_imageviewer_args_set_margin(self.args, value);
+        }
+        self
+    }
+
+    pub fn margin_left(&mut self, value: i32) -> &mut Self {
+        unsafe {
+            ui_imageviewer_args_set_margin_left(self.args, value);
+        }
+        self
+    }
+
+    pub fn margin_right(&mut self, value: i32) -> &mut Self {
+        unsafe {
+            ui_imageviewer_args_set_margin_right(self.args, value);
+        }
+        self
+    }
+
+    pub fn margin_top(&mut self, value: i32) -> &mut Self {
+        unsafe {
+            ui_imageviewer_args_set_margin_top(self.args, value);
+        }
+        self
+    }
+
+    pub fn margin_bottom(&mut self, value: i32) -> &mut Self {
+        unsafe {
+            ui_imageviewer_args_set_margin_bottom(self.args, value);
+        }
+        self
+    }
+
+    pub fn colspan(&mut self, value: i32) -> &mut Self {
+        unsafe {
+            ui_imageviewer_args_set_colspan(self.args, value);
+        }
+        self
+    }
+
+    pub fn rowspan(&mut self, value: i32) -> &mut Self {
+        unsafe {
+            ui_imageviewer_args_set_rowspan(self.args, value);
+        }
+        self
+    }
+
+    pub fn name(&mut self, value: &str) -> &mut Self {
+        let cstr = CString::new(value).unwrap();
+        unsafe {
+            ui_imageviewer_args_set_name(self.args, cstr.as_ptr());
+        }
+        self
+    }
+
+    pub fn style_class(&mut self, value: &str) -> &mut Self {
+        let cstr = CString::new(value).unwrap();
+        unsafe {
+            ui_imageviewer_args_set_style_class(self.args, cstr.as_ptr());
+        }
+        self
+    }
+
+    pub fn value(&mut self, value: &toolkit::UiImage) -> &mut Self{
+        unsafe {
+            ui_imageviewer_args_set_value(self.args, value.ptr);
+        }
+        self
+    }
+
+    pub fn varname(&mut self, varname: &str) -> &mut Self {
+        let cstr = CString::new(varname).unwrap();
+        unsafe {
+            ui_imageviewer_args_set_varname(self.args, cstr.as_ptr());
+        }
+        self
+    }
+
+    pub fn scrollview(&mut self, enable: bool) -> &mut Self {
+        unsafe {
+            ui_imageviewer_args_set_scrollarea(self.args, enable as c_int);
+        }
+        self
+    }
+
+    pub fn autoscale(&mut self, enable: bool) -> &mut Self {
+        unsafe {
+            ui_imageviewer_args_set_autoscale(self.args, enable as c_int);
+        }
+        self
+    }
+
+    pub fn adjustwidgetsize(&mut self, enable: bool) -> &mut Self {
+        unsafe {
+            ui_imageviewer_args_set_adjustwidgetsize(self.args, enable as c_int);
+        }
+        self
+    }
+
+    pub fn useradjustable(&mut self, enable: bool) -> &mut Self {
+        unsafe {
+            ui_imageviewer_args_set_useradjustable(self.args, enable as c_int);
+        }
+        self
+    }
+
+    pub fn padding(&mut self, value: i32) -> &mut Self {
+        unsafe {
+            ui_imageviewer_args_set_image_padding(self.args, value as c_int);
+        }
+        self
+    }
+
+    pub fn padding_left(&mut self, value: i32) -> &mut Self {
+        unsafe {
+            ui_imageviewer_args_set_image_padding_left(self.args, value as c_int);
+        }
+        self
+    }
+
+    pub fn padding_right(&mut self, value: i32) -> &mut Self {
+        unsafe {
+            ui_imageviewer_args_set_image_padding_right(self.args, value as c_int);
+        }
+        self
+    }
+
+    pub fn padding_top(&mut self, value: i32) -> &mut Self {
+        unsafe {
+            ui_imageviewer_args_set_image_padding_top(self.args, value as c_int);
+        }
+        self
+    }
+
+    pub fn padding_bottom(&mut self, value: i32) -> &mut Self {
+        unsafe {
+            ui_imageviewer_args_set_image_padding_bottom(self.args, value as c_int);
+        }
+        self
+    }
+
+    pub fn visibility_states(&mut self, states: &[i32]) -> &mut Self {
+        unsafe {
+            ui_imageviewer_args_set_visibility_states(self.args, states.as_ptr(), states.len() as c_int);
+        }
+        self
+    }
+}
+
+/* -------------------------------- C functions -------------------------------- */
+
+unsafe extern "C" {
+    fn ui_image_load_file(obj: *mut ffi::UiGeneric, path: *const c_char) -> c_int;
+    fn ui_image_load_data(obj: *mut ffi::UiGeneric, imgdata: *const c_void, size: libc::size_t) -> c_int;
+
+    fn ui_imageviewer_create(obj: *mut ffi::UiObject, args: *const ffi::UiImageViewerArgs) -> *mut c_void;
+
+    fn ui_imageviewer_args_new() -> *mut UiImageViewerArgs;
+    fn ui_imageviewer_args_set_fill(args: *mut UiImageViewerArgs, fill: c_int);
+    fn ui_imageviewer_args_set_hexpand(args: *mut UiImageViewerArgs, value: c_int);
+    fn ui_imageviewer_args_set_vexpand(args: *mut UiImageViewerArgs, value: c_int);
+    fn ui_imageviewer_args_set_hfill(args: *mut UiImageViewerArgs, value: c_int);
+    fn ui_imageviewer_args_set_vfill(args: *mut UiImageViewerArgs, value: c_int);
+    fn ui_imageviewer_args_set_override_defaults(args: *mut UiImageViewerArgs, value: c_int);
+    fn ui_imageviewer_args_set_margin(args: *mut UiImageViewerArgs, value: c_int);
+    fn ui_imageviewer_args_set_margin_left(args: *mut UiImageViewerArgs, value: c_int);
+    fn ui_imageviewer_args_set_margin_right(args: *mut UiImageViewerArgs, value: c_int);
+    fn ui_imageviewer_args_set_margin_top(args: *mut UiImageViewerArgs, value: c_int);
+    fn ui_imageviewer_args_set_margin_bottom(args: *mut UiImageViewerArgs, value: c_int);
+    fn ui_imageviewer_args_set_colspan(args: *mut UiImageViewerArgs, value: c_int);
+    fn ui_imageviewer_args_set_rowspan(args: *mut UiImageViewerArgs, value: c_int);
+    fn ui_imageviewer_args_set_name(args: *mut UiImageViewerArgs, name: *const c_char);
+    fn ui_imageviewer_args_set_style_class(args: *mut UiImageViewerArgs, classname: *const c_char);
+    fn ui_imageviewer_args_set_style(args: *mut UiImageViewerArgs, style: c_int);
+    fn ui_imageviewer_args_set_value(args: *mut UiImageViewerArgs, value: *mut ffi::UiGeneric);
+    fn ui_imageviewer_args_set_varname(args: *mut UiImageViewerArgs, varname: *const c_char);
+    fn ui_imageviewer_args_set_scrollarea(args: *mut UiImageViewerArgs, fill: c_int);
+    fn ui_imageviewer_args_set_autoscale(args: *mut UiImageViewerArgs, fill: c_int);
+    fn ui_imageviewer_args_set_adjustwidgetsize(args: *mut UiImageViewerArgs, fill: c_int);
+    fn ui_imageviewer_args_set_useradjustable(args: *mut UiImageViewerArgs, fill: c_int);
+    fn ui_imageviewer_args_set_image_padding(args: *mut UiImageViewerArgs, value: c_int);
+    fn ui_imageviewer_args_set_image_padding_left(args: *mut UiImageViewerArgs, value: c_int);
+    fn ui_imageviewer_args_set_image_padding_right(args: *mut UiImageViewerArgs, value: c_int);
+    fn ui_imageviewer_args_set_image_padding_top(args: *mut UiImageViewerArgs, value: c_int);
+    fn ui_imageviewer_args_set_image_padding_bottom(args: *mut UiImageViewerArgs, value: c_int);
+    fn ui_imageviewer_args_set_visibility_states(args: *mut UiImageViewerArgs, states: *const c_int, numstates: c_int);
+    fn ui_imageviewer_args_free(args: *mut UiImageViewerArgs);
+
+    fn ui_imageviewer_reset(widget: *mut c_void);
+    fn ui_imageviewer_set_autoscale(widget: *mut c_void, set: c_int);
+    fn ui_imageviewer_set_adjustwidgetsize(widget: *mut c_void, set: c_int);
+    fn ui_imageviewer_set_useradjustable(widget: *mut c_void, set: c_int);
+}
\ No newline at end of file
index 094345ccf6f135b4474a8d8ff524b53c15d31ca4..14de16aab1a923b740311801ba619a9bb7ed52db 100644 (file)
@@ -1,3 +1,31 @@
+/*
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
+ *
+ * Copyright 2026 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.
+ */
+
 use std::ffi::{c_char, c_int, c_void, CString};
 use crate::ui::{ffi, toolkit, Button, ButtonBuilder};
 use crate::ui::ffi::{UiButtonArgs, UiLabelArgs, UiObject, UiString, UiToggleArgs};
index dd968c40ae76a129091fe3539275dc33d881d7cb..338d46377288ffe9effdeb82654f09db945ae56b 100644 (file)
@@ -40,6 +40,7 @@ mod menu;
 mod toolbar;
 mod label;
 mod icon;
+mod image;
 
 pub use toolkit::*;
 pub use event::*;
@@ -52,3 +53,4 @@ pub use list::*;
 pub use toolbar::*;
 pub use menu::*;
 pub use icon::*;
+pub use image::*;
index 001dd9be05a783dab8c49fe3f4c64822a0586e2b..3e494db0865f8029f6e78c4f6733fa72a5095c9f 100644 (file)
@@ -34,6 +34,7 @@ use crate::ui::{action_event_wrapper, event, ffi, simple_event_wrapper, ui_objec
 
 use std::marker::PhantomData;
 use std::mem;
+use std::path::Path;
 use std::ptr::null_mut;
 use std::slice::{Iter, IterMut};
 use std::sync::{Arc, Mutex};
@@ -727,6 +728,10 @@ pub struct UiSourceList<T> {
     sublists: Vec<SubList<T>>
 }
 
+pub struct UiImage {
+    pub ptr: *mut ffi::UiGeneric
+}
+
 /* -------------------------------- Default implementation -------------------------------- */
 
 macro_rules! value_default_impl {
@@ -752,6 +757,7 @@ macro_rules! value_default_impl2 {
 value_default_impl!(UiInteger);
 value_default_impl!(UiDouble);
 value_default_impl!(UiString);
+value_default_impl!(UiImage);
 value_default_impl2!(UiText);
 
 impl<T> Default for UiList<T> {
@@ -1469,6 +1475,8 @@ unsafe extern "C" {
     fn ui_string_set(value: *const ffi::UiString, str: *const c_char);
     fn ui_int_get(value: *const ffi::UiInteger) -> i64;
     fn ui_int_set(value: *const ffi::UiInteger, i: i64);
+
+    pub fn ui_generic_new(ctx: *mut ffi::UiContext, name: *const c_char) -> *mut ffi::UiGeneric;
 }
 
 type UiListInitFunc = extern "C" fn(*mut ffi::UiContext, *mut ffi::UiList, *mut c_void);