use ui_rs::ui::*;
use crate::App;
use entity::collection::{Model as Collection, Node};
-use crate::backend::{BackendHandle, BroadcastMessage};
+use crate::backend::{BackendHandle, BroadcastMessage, NoteId};
use crate::newnotebook::new_notebook_dialog;
use crate::notebook::{notelist_getvalue, NoteItem, Notebook, NotebookItem};
pub broadcast_rx: tokio::sync::broadcast::Receiver<BroadcastMessage>,
+ navigation: Navigation,
+
selected_notebook: Option<UiDoc<Notebook>>,
groups: Vec<Collection>,
obj: UiObjRef::default(),
backend: app.backend.clone(),
broadcast_rx: app.backend.btx.subscribe(),
+ navigation: Navigation::default(),
selected_notebook: None,
groups: Vec::new(),
notebooks: UiSourceList::default()
#[action]
pub fn new_note(&mut self, _event: &ActionEvent) {
+ let Some(mut obj) = self.obj.get_object() else {
+ return;
+ };
+
// The new_note action is handled by Notebook and MainWindow
// When a notebook is attached, the notebook receives this action, but in case
// no notebook is selected, the action is handled in the main window
// Select the first notebook
// TODO: maybe select a configured default notebook
- if let Some(group) = self.notebooks.get(0) {
- if let Some(notebook) = group.data().get(0) {
- self.select_notebook(notebook.data.collection_id);
- // self.selected_notebook has a value after select_notebook()
- if let Some(doc) = &self.selected_notebook {
- // Now that a notebook is selected, we can open the new note UI there
- doc.ctx.call_action("new_note");
+ if let Some(group) = self.notebooks.get_mut(0) {
+ if let Some(notebook) = group.data_mut().get_mut(0) {
+ let doc = notebook.get_doc(&self.backend);
+ if let Some(current) = &self.selected_notebook {
+ obj.ctx.detach(current);
}
+ obj.ctx.attach(&doc);
+ // Now that a notebook is selected, we can open the new note UI there
+ // TODO: this does not work correctly, the backend loading can override the list after new_ntoe
+ doc.ctx.call_action("new_note");
+
+ self.selected_notebook = Some(doc);
}
}
}
- pub fn select_notebook(&mut self, collection_id: i32) {
- let Some(mut obj) = self.obj.get_object() else {
- return;
- };
+ pub fn do_nav(&mut self, direction: NavDirection) -> Option<()> {
+ let nav = match direction {
+ NavDirection::Forward => self.navigation.go_forward(),
+ NavDirection::Backward => self.navigation.go_back()
+ }?;
+ let mut obj = self.obj.get_object()?;
+ let (sl, i) = find_notebook(&self.notebooks, nav.collection_id)?;
+ let mut sublist = self.notebooks.get_mut(sl)?;
+
+ sublist.list().set_selected_index(i as i32);
+ let notebook = sublist.data_mut().get_mut(i)?;
+ // detach current notebook
if let Some(current) = &self.selected_notebook {
obj.ctx.detach(current);
}
- let notebook = Notebook::new(collection_id, &self.backend);
- let doc = UiDoc::new2(notebook, |notebook, doc| {
- notebook.doc_ref = doc.doc_ref();
- });
- let proxy = doc.doc_proxy();
- self.backend.get_notes(collection_id, |result|{
- proxy.call_mainthread(|_, nb| {
- match result {
- Ok(notes) => {
- nb.set_notes(notes);
- },
- Err(err) => {
- eprintln!("get_notes failed: {}", err);
- }
- }
- });
- });
+ let notebook_doc = notebook.get_doc(&self.backend);
+ obj.ctx.attach(¬ebook_doc);
+ self.selected_notebook = Some(notebook_doc);
- obj.ctx.attach(&doc);
- self.selected_notebook = Some(doc);
+ Some(())
}
#[action]
pub fn go_back(&mut self, _event: &ActionEvent) {
-
+ self.do_nav(NavDirection::Backward);
}
#[action]
pub fn go_forward(&mut self, _event: &ActionEvent) {
-
+ self.do_nav(NavDirection::Forward);
}
- #[action(String)]
- pub fn navigation(&mut self, _event: &ActionEvent, arg: &String) {
- println!("navigation: {}", arg);
+ #[action(NavigationItem)]
+ pub fn navigation(&mut self, _event: &ActionEvent, arg: &NavigationItem) {
+ self.navigation.push(arg.clone());
}
#[action]
b.onactivate(|e|{
if let EventType::SubList(sl) = &e.event_type {
if let Some(nb) = sl.get_mut_from(&mut e.data.notebooks) {
+ let nav = NavigationItem { collection_id: nb.data.collection_id, note_id: None };
// detach current notebook
if let Some(current) = &e.data.selected_notebook {
e.obj.ctx.detach(current);
}
- let notebook_doc = if let Some(doc) = &nb.model {
- doc.clone()
- } else {
- let doc = nb.load_notebook(&e.data.backend);
- doc
- };
-
+ let notebook_doc = nb.get_doc(&e.data.backend);
e.obj.ctx.attach(¬ebook_doc);
e.data.selected_notebook = Some(notebook_doc);
+
+ e.data.navigation.push(nav);
}
}
});
window.update_notebook_structure(&data.notebooks);
}
+fn find_notebook(sourcelist: &UiSourceList<NotebookItem>, collection_id: i32) -> Option<(usize, usize)> {
+ for (s, sl) in sourcelist.data().iter().enumerate() {
+ for (i, nb) in sl.data().iter().enumerate() {
+ if nb.data.collection_id == collection_id {
+ return Some((s, i))
+ }
+ }
+ }
+ None
+}
+
pub enum NoteTypeTabView {
_Empty = 0,
TextArea = 1
+}
+
+#[derive(Default)]
+pub struct Navigation {
+ history: Vec<NavigationItem>,
+ current: usize,
+}
+
+impl Navigation {
+ pub fn push(&mut self, page: NavigationItem) {
+ // If we are not at the end, truncate forward history
+ self.history.truncate(self.current + 1);
+
+ self.history.push(page);
+ self.current += 1;
+ }
+
+ pub fn go_back(&mut self) -> Option<&NavigationItem> {
+ if self.current > 1 {
+ self.current -= 1;
+ self.history.get(self.current-1)
+ } else {
+ None
+ }
+ }
+
+ pub fn go_forward(&mut self) -> Option<&NavigationItem> {
+ if self.current < self.history.len() {
+ self.current += 1;
+ self.history.get(self.current-1)
+ } else {
+ None
+ }
+ }
+}
+
+#[derive(Default, Clone)]
+pub struct NavigationItem {
+ pub collection_id: i32,
+ pub note_id: Option<NoteId>
+}
+
+enum NavDirection {
+ Forward,
+ Backward
}
\ No newline at end of file