]> uap-core.de Git - note.git/commitdiff
prepare attachments window data loading main
authorOlaf Wintermann <olaf.wintermann@gmail.com>
Fri, 4 Sep 2026 19:22:37 +0000 (21:22 +0200)
committerOlaf Wintermann <olaf.wintermann@gmail.com>
Fri, 4 Sep 2026 19:22:37 +0000 (21:22 +0200)
application/note/src/attachments_window.rs
application/note/src/window.rs
ui-rs/src/ui/container.rs

index 64c0d2fee755b29c010a1834b9205cd032403340..9352afdd7439074babbbdbeed974ea0f0bcd7938 100644 (file)
  * 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<i32>) {
-    let data = AttachmentsWindow::new(note_id);
+pub fn attachments_window_create(backend: BackendHandle, note_id: i32, selected_attachment: Option<i32>) {
+    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<i32>)
                 webview!(obj, varname = "webview", fill = true);
             });
         });
+
+        data.load_attachments();
     });
     obj.show();
 }
 
 
-#[derive(UiModel, Default)]
+#[derive(UiModel)]
 pub struct AttachmentsWindow {
+    obj: UiObjRef<AttachmentsWindow>,
+
     note_id: i32,
+    backend: BackendHandle,
+
+    attachments: Vec<entity::attachment::Model>,
+    content: Vec<Option<entity::attachmentcontent::Model>>,
+    selection: Option<i32>,
+    selected_index: Option<usize>,
 
     #[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) {
 
index e0451483076f27b2036c49f9575540ffc316898c..076595bad7fe4533b619dacfa7fa6e4335d8c28e 100644 (file)
@@ -293,17 +293,18 @@ pub fn create_window(app: &App, ctx: &AppContext<MainWindow>) -> UiObject<MainWi
                             obj.itemlist::<Attachment>()
                                 .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);
                                     }
                                 })
index f2b8cb07a6c803b360434cb3c1f776b109787047..b0b5b252c429985172e1d5cba690568de90653e1 100644 (file)
@@ -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<T> toolkit::UiObject<T> {
 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<D, T> {
-    callback: Box<dyn Fn(&mut toolkit::UiObject<D>, &T, i32)>
+    callback: Box<dyn Fn(&mut toolkit::UiObject<D>, &D, &T, i32)>
 }
 
 extern "C" fn createui_wrapper<D, T>(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<D, T> ) };
     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<D> = 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<F>(&mut self, f: F) -> &mut Self
-    where F: Fn(&mut toolkit::UiObject<T>, &C, i32) + 'static {
+    where F: Fn(&mut toolkit::UiObject<T>, &T, &C, i32) + 'static {
         unsafe {
             let wrapper = Box::new(CreateUiWrapper { callback: Box::new(f) });
             let ptr = self.obj.ctx.reg_box(wrapper);