From: Olaf Wintermann Date: Fri, 4 Sep 2026 19:22:37 +0000 (+0200) Subject: prepare attachments window data loading X-Git-Url: https://uap-core.de/gitweb/?a=commitdiff_plain;h=409ee4f4c33b01a77d0893ec83995ed044240597;p=note.git prepare attachments window data loading --- diff --git a/application/note/src/attachments_window.rs b/application/note/src/attachments_window.rs index 64c0d2f..9352afd 100644 --- a/application/note/src/attachments_window.rs +++ b/application/note/src/attachments_window.rs @@ -25,17 +25,21 @@ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. */ +use backend::backend::BackendHandle; use ui_rs::ui::*; use ui_rs::{action, button, imageviewer, tabview, ui_actions, webview, UiModel}; -pub fn attachments_window_create(note_id: i32, selected_attachment: Option) { - let data = AttachmentsWindow::new(note_id); +pub fn attachments_window_create(backend: BackendHandle, note_id: i32, selected_attachment: Option) { + let mut data = AttachmentsWindow::new(backend, note_id); + data.selection = selected_attachment; let obj = simple_window("Attachments", data, |obj, data|{ + data.obj = obj.obj_ref(); + obj.headerbar().create(|hb|{ hb.start(|obj|{ button!(obj, icon = UiIconSet::GoBack.as_str(), action = "go_back"); - button!(obj, icon = UiIconSet::GoBack.as_str(), action = "go_forward"); + button!(obj, icon = UiIconSet::GoForward.as_str(), action = "go_forward"); }); }); @@ -47,14 +51,24 @@ pub fn attachments_window_create(note_id: i32, selected_attachment: Option) webview!(obj, varname = "webview", fill = true); }); }); + + data.load_attachments(); }); obj.show(); } -#[derive(UiModel, Default)] +#[derive(UiModel)] pub struct AttachmentsWindow { + obj: UiObjRef, + note_id: i32, + backend: BackendHandle, + + attachments: Vec, + content: Vec>, + selection: Option, + selected_index: Option, #[bind("image")] pub image: UiImage, @@ -65,13 +79,68 @@ pub struct AttachmentsWindow { #[ui_actions] impl AttachmentsWindow { - pub fn new(note_id: i32) -> AttachmentsWindow { + pub fn new(backend: BackendHandle, note_id: i32) -> AttachmentsWindow { AttachmentsWindow { + obj: UiObjRef::default(), note_id, - ..Default::default() + backend, + attachments: Vec::new(), + content: Vec::new(), + selection: None, + selected_index: None, + image: Default::default(), + webview: Default::default() } } + pub fn load_attachments(&mut self) { + let Some(obj) = self.obj.get_object() else { + return; + }; + + let proxy = obj.obj_proxy(); + self.backend.get_note_attachments(self.note_id, move|result|{ + proxy.call_mainthread(move |doc, wdata|{ + match result { + Ok(attachments) => { + println!("attachments loaded"); + wdata.attachments = attachments; + wdata.content = vec![None; wdata.attachments.len()]; + + if let Some(selection) = wdata.selection { + wdata.selected_index = wdata.attachments.iter().position(|a| a.attachment_id == selection); + if let Some(index) = wdata.selected_index { + wdata.load_content(index); + } + } else { + wdata.selected_index = None; + } + }, + Err(e) => { + println!("Cannot get note attachments: {}", e); + } + } + }); + }); + } + pub fn load_content(&mut self, index: usize) { + let Some(obj) = self.obj.get_object() else { + return; + }; + if index >= self.content.len() { + return; + } + + let ct = &self.content[index]; + if let Some(content) = ct { + self.image.image_load_data(&content.content); + } else { + let proxy = obj.obj_proxy(); + // TODO: load attachment data + } + } + + #[action] pub fn go_back(&mut self, _event: &ActionEvent) { diff --git a/application/note/src/window.rs b/application/note/src/window.rs index e045148..076595b 100644 --- a/application/note/src/window.rs +++ b/application/note/src/window.rs @@ -293,17 +293,18 @@ pub fn create_window(app: &App, ctx: &AppContext) -> UiObject() .varname("note_attachments") .container(SubContainer::HBox) - .createui(|obj, data, _i|{ - let note_id = data.attachment.note_id; - let attachment_id = data.attachment.attachment_id; + .createui(|obj, wdata, at, _i|{ + let note_id = at.attachment.note_id; + let attachment_id = at.attachment.attachment_id; + let imgviewer = imageviewer!(obj, scrollview = false, autoscale = true, onbuttonpress = move|event|{ - attachments_window_create(note_id, Some(attachment_id)); + attachments_window_create(event.data.backend.clone(), note_id, Some(attachment_id)); }); imgviewer.set_size(100, 80); - if let Some(thumbnail) = &data.attachment.thumbnail { + if let Some(thumbnail) = &at.attachment.thumbnail { imgviewer.load_data(thumbnail); } }) diff --git a/ui-rs/src/ui/container.rs b/ui-rs/src/ui/container.rs index f2b8cb0..b0b5b25 100644 --- a/ui-rs/src/ui/container.rs +++ b/ui-rs/src/ui/container.rs @@ -33,7 +33,7 @@ use std::ffi::{c_char, c_int, c_void}; use std::ffi::CString; use std::marker::PhantomData; use crate::ui::ffi::*; -use crate::ui::{ffi, getvalue_wrapper, toolkit, ui_object_ref, Button, GetValueWrapper, ListValue}; +use crate::ui::{ffi, getvalue_wrapper, toolkit, ui_object_get_windowdata, ui_object_ref, Button, GetValueWrapper, ListValue}; use crate::ui::widget::Widget; #[macro_export] @@ -1568,18 +1568,21 @@ impl toolkit::UiObject { type CreateUiFunc = extern "C" fn(obj: *mut ffi::UiObject, list: *mut ffi::UiList, row: c_int, elm: *mut c_void, userdata: *mut c_void); struct CreateUiWrapper { - callback: Box, &T, i32)> + callback: Box, &D, &T, i32)> } extern "C" fn createui_wrapper(obj_ptr: *mut ffi::UiObject, _list: *mut ffi::UiList, row: c_int, elm_ptr: *mut c_void, userdata: *mut c_void) { let wrapper = unsafe { &*(userdata as *const CreateUiWrapper ) }; let elm = unsafe { &*(elm_ptr as *const T) }; + let wdata_ptr = unsafe { ui_object_get_windowdata(obj_ptr) }; + let wdata = unsafe { &mut *(wdata_ptr as *mut D) }; + unsafe { ui_object_ref(obj_ptr); } let mut obj: toolkit::UiObject = toolkit::UiObject::from_ptr(obj_ptr); - (wrapper.callback)(&mut obj, elm, row); + (wrapper.callback)(&mut obj, wdata, elm, row); } @@ -1720,7 +1723,7 @@ impl<'a, T, C> ItemListContainerBuilder<'a, T, C> { } pub fn createui(&mut self, f: F) -> &mut Self - where F: Fn(&mut toolkit::UiObject, &C, i32) + 'static { + where F: Fn(&mut toolkit::UiObject, &T, &C, i32) + 'static { unsafe { let wrapper = Box::new(CreateUiWrapper { callback: Box::new(f) }); let ptr = self.obj.ctx.reg_box(wrapper);