* 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");
});
});
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,
#[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) {
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);
}
})
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]
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);
}
}
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);