]> uap-core.de Git - note.git/commitdiff
hide note list on activate events main
authorOlaf Wintermann <olaf.wintermann@gmail.com>
Sat, 13 Jun 2026 13:04:50 +0000 (15:04 +0200)
committerOlaf Wintermann <olaf.wintermann@gmail.com>
Sat, 13 Jun 2026 13:04:50 +0000 (15:04 +0200)
application/src/main.rs
application/src/notebook.rs
application/src/window.rs
ui-rs-derive/src/lib.rs
ui/gtk/headerbar.c
ui/gtk/headerbar.h
ui/gtk/list.c
ui/gtk/toolkit.c
ui/gtk/window.c

index 4882d1db1143c151efdd32f152e0668528877d8b..abd842d35167c98aed1a9df020174412318cabd0 100644 (file)
@@ -151,6 +151,10 @@ fn create_toolbar(app: &AppContext<MainWindow>) {
     app.toolbar_item("go_forward").icon(UiIconSet::GoForward.as_str()).action("go_forward").create();
     app.toolbar_item("new_note").icon(UiIconSet::Add.as_str()).action("new_note").states(&[AppStates::NoteEnableNew as i32]).create();
 
+    app.toolbar_item("go_back2").icon(UiIconSet::GoBack.as_str()).action("go_back").create();
+    app.toolbar_item("go_forward2").icon(UiIconSet::GoForward.as_str()).action("go_forward").create();
+    app.toolbar_item("new_note2").icon(UiIconSet::Add.as_str()).action("new_note").states(&[AppStates::NoteEnableNew as i32]).create();
+
     app.toolbar_add_default("new_notebook", ToolbarItemPosition::SidebarLeft);
     app.toolbar_add_default("go_back", ToolbarItemPosition::Left);
     app.toolbar_add_default("go_forward", ToolbarItemPosition::Left);
@@ -165,7 +169,8 @@ fn create_toolbar(app: &AppContext<MainWindow>) {
 #[repr(i32)]
 pub enum AppStates {
     Null = 0,
-    NoteEnableNew
+    NoteEnableNew,
+    NoteMaximized
 }
 
 fn username() -> String {
index 16aded1537c1c78ee933ee7ed7ef422b59648049..7173693d3301d63a3f17bb960bbcfd0f9b0c4603 100644 (file)
@@ -16,8 +16,7 @@ pub struct Notebook {
     pub broadcast_rx: tokio::sync::broadcast::Receiver<BroadcastMessage>,
     pub collection_id: i32,
 
-    pub selected_note: Option<UiDoc<crate::note::Note>>,
-    pub selected_index: Option<usize>,
+    pub selected_note: Option<NoteSelection>,
 
     #[bind("notes")]
     pub notes: UiList<NoteItem>
@@ -32,7 +31,6 @@ impl Notebook {
             broadcast_rx: backend.btx.subscribe(),
             collection_id: id,
             selected_note: None,
-            selected_index: None,
             notes: Default::default()
         }
     }
@@ -55,13 +53,13 @@ impl Notebook {
             // doc_ref.get_doc() should never fail here
             if let Some(mut doc) = self.doc_ref.get_doc() {
                 // save the note
-                let note_proxy = current.doc_proxy();
+                let note_proxy = current.doc.doc_proxy();
                 note_proxy.call_mainthread(move |_doc, note|{
                     note.save_note();
                 });
 
                 // detach the note
-                doc.ctx.detach(current);
+                doc.ctx.detach(&current.doc);
                 self.selected_note = None;
             }
         }
@@ -76,15 +74,29 @@ impl Notebook {
         None
     }
 
-    pub fn select_note_from(&mut self, from: NoteSelectFrom) -> Option<()> {
+    pub fn get_note_id(&self, index: usize) -> NoteId {
+        if let Some(note) = self.notes.data().get(index) {
+            note.id.clone()
+        } else {
+            NoteId::TmpId(0) // placeholder id
+        }
+    }
+
+    pub fn is_current_selection(&self, note: &NoteId) -> bool{
+        if let Some(current) = &self.selected_note {
+            return current.id == *note
+        } else {
+            false
+        }
+    }
+
+    pub fn select_note_from(&mut self, from: NoteSelectFrom, maximized: bool) -> Option<()> {
         let mut add_to_nav = false;
         let (selected_index, note) = match from {
             NoteSelectFrom::ListSelection(s) => {
                 let index = s.selected_index()?;
-                if let Some(current_selection) = self.selected_index {
-                    if current_selection == index {
-                        return None
-                    }
+                if self.is_current_selection(&self.get_note_id(index)) {
+                    return None
                 }
                 self.detach_current_note();
                 let note = s.selected_element_mut(self.notes.data_mut())?;
@@ -93,10 +105,8 @@ impl Notebook {
             },
             NoteSelectFrom::NavigationItem(nav) => {
                 let index = self.find_note(&nav.note_id?)?;
-                if let Some(current_selection) = self.selected_index {
-                    if current_selection == index {
-                        return None
-                    }
+                if self.is_current_selection(&self.get_note_id(index)) {
+                    return None
                 }
                 self.detach_current_note();
                 self.notes.select_with_event(index as i32, false);
@@ -104,11 +114,11 @@ impl Notebook {
                 (index, note)
             }
         };
-        
-        self.selected_index = Some(selected_index);
+
         let is_new = note.is_new();
 
-        let nav = NavigationItem { collection_id: self.collection_id, note_id: Some(note.id.clone()) };
+        let id = note.id.clone();
+        let nav = NavigationItem { collection_id: self.collection_id, note_id: Some(note.id.clone()), note_maximized: maximized };
         let doc = if let Some(doc) = &note.model {
             doc.clone()
         } else {
@@ -132,7 +142,7 @@ impl Notebook {
             if is_new {
                 nb.ctx.call_action("textarea_focus");
             }
-            self.selected_note = Some(doc);
+            self.selected_note = Some(NoteSelection { doc: doc, id: id, index: selected_index });
 
             if add_to_nav {
                 let arg: Box<dyn Any> = Box::new(nav);
@@ -146,18 +156,33 @@ impl Notebook {
     #[action]
     pub fn note_selected(&mut self, event: &ActionEvent) {
         if let EventType::ListSelection(s) = event.event_type {
-            self.select_note_from(NoteSelectFrom::ListSelection(s));
+            self.select_note_from(NoteSelectFrom::ListSelection(s), false);
         }
     }
 
     #[action]
-    pub fn note_activated(&mut self, event: &mut ActionEvent) {
+    pub fn note_activated(&mut self, event: &mut ActionEvent) -> Option<()> {
+        let obj = &mut event.obj.as_mut()?;
+
         if let EventType::ListSelection(s) = event.event_type {
-            self.select_note_from(NoteSelectFrom::ListSelection(s));
-            if let Some(obj) = &mut event.obj {
-                obj.splitview_set_visible(0, false);
+            let result = self.select_note_from(NoteSelectFrom::ListSelection(s), true);
+            obj.splitview_set_visible(0, false);
+            // in case select_note_from didn't return a result, the note was already selected
+            // and no new navigation item was added
+            if result.is_none() {
+                let current = &self.selected_note.as_ref()?;
+                let nav = NavigationItem {
+                    collection_id: self.collection_id,
+                    note_id: Some(current.id.clone()),
+                    note_maximized: true
+                };
+
+                let arg: Box<dyn Any> = Box::new(nav);
+                obj.ctx.call_action_with_parameter("navigation", arg);
             }
         }
+
+        Some(())
     }
 
     #[action]
@@ -171,14 +196,19 @@ impl Notebook {
     }
 
     #[action(NavigationItem)]
-    pub fn navigate_to_note(&mut self, _event: &ActionEvent, nav: &NavigationItem) {
-        println!("navigate to note");
+    pub fn navigate_to_note(&mut self, event: &mut ActionEvent, nav: &NavigationItem) {
+        let Some(obj) = &mut event.obj else {
+            return;
+        };
+
+        //println!("navigate to note");
         if nav.collection_id != self.collection_id {
             println!("invalid navigation event: notebook collection_id {} != {}", self.collection_id, nav.collection_id);
             return;
         }
 
-        self.select_note_from(NoteSelectFrom::NavigationItem(nav.clone()));
+        self.select_note_from(NoteSelectFrom::NavigationItem(nav.clone()), false);
+        obj.splitview_set_visible(0, !nav.note_maximized);
     }
 
     pub fn update_note_title(&mut self, update: &NoteTitleUpdate) {
@@ -186,11 +216,11 @@ impl Notebook {
         // Find the note in the list (or add it if it doesn't exist yet)
         // Start with the currently selected note
         let mut update_row: Option<usize> = None;
-        if let Some(index) = self.selected_index {
-            if let Some(item) = self.notes.data_mut().get_mut(index) {
+        if let Some(current) = &self.selected_note {
+            if let Some(item) = self.notes.data_mut().get_mut(current.index) {
                 if item.id == update.note_id {
                     item.data.title = update.title.clone();
-                    update_row = Some(index);
+                    update_row = Some(current.index);
                 }
             }
         }
@@ -323,6 +353,7 @@ impl NotebookItem {
     }
 }
 
+
 /// ListView item
 pub struct NoteItem {
     id: NoteId,
@@ -357,4 +388,10 @@ impl NoteItem {
     pub fn is_new(&self) -> bool {
         return matches!(self.id, NoteId::TmpId(_))
     }
+}
+
+pub struct NoteSelection {
+    pub id: NoteId,
+    pub doc: UiDoc<crate::note::Note>,
+    pub index: usize
 }
\ No newline at end of file
index 25512fb52c5a314705a656d1179ed5fef87ba417..02592549587394a09ff940e485a2912edb14c44d 100644 (file)
@@ -201,7 +201,7 @@ pub fn create_window(app: &App, ctx: &AppContext<MainWindow>) -> UiObject<MainWi
                 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 };
+                            let nav = NavigationItem { collection_id: nb.data.collection_id, ..Default::default() };
                             // detach current notebook
                             if let Some(current) = &e.data.selected_notebook {
                                 current.ctx.call_action("save");
@@ -339,7 +339,8 @@ impl Navigation {
 #[derive(Default, Clone)]
 pub struct NavigationItem {
     pub collection_id: i32,
-    pub note_id: Option<NoteId>
+    pub note_id: Option<NoteId>,
+    pub note_maximized: bool
 }
 
 pub enum NavDirection {
index 83d550550b2e814fa013f4d21883d55c44f4589a..d764776b6b28d89df908d3f3150cb1a3e8503a88 100644 (file)
@@ -176,7 +176,8 @@ pub fn ui_actions(_attr: TokenStream, item: TokenStream) -> TokenStream {
             ctx.add_action(
                 stringify!(#name),
                 |target: &mut Self, event| {
-                    if let EventType::TypedObject(obj) = &event.event_type {
+                    let event_type = std::mem::replace(&mut event.event_type, EventType::Null);
+                    if let EventType::TypedObject(obj) = event_type {
                         if let Some(arg) = obj.downcast_ref::<#ty>() {
                             target.#name(event, arg);
                         }
index d2554a0c56434e4f09e02d323bbd72c2952cc080..ac435aae0f5eeba29b3537d635c3e760c3839e46 100644 (file)
@@ -30,6 +30,9 @@
 
 #include "button.h"
 #include "menu.h"
+#include "../ui/widget.h"
+
+#include <cx/array_list.h>
 
 #include "../ui/properties.h"
 
@@ -66,53 +69,63 @@ void ui_fill_headerbar(UiObject *obj, GtkWidget *sidebar_headerbar, GtkWidget *m
     }
     
     // main toolbar
-    ui_headerbar_add_items(obj, main_headerbar, left_defaults, UI_TOOLBAR_LEFT);
-    ui_headerbar_add_items(obj, main_headerbar, center_defaults, UI_TOOLBAR_CENTER);
+    ui_headerbar_add_items(obj, main_headerbar, left_defaults, UI_TOOLBAR_LEFT, NULL);
+    ui_headerbar_add_items(obj, main_headerbar, center_defaults, UI_TOOLBAR_CENTER, NULL);
     
     if(appmenu && appmenu_pos == UI_TOOLBAR_RIGHT) {
         ui_add_headerbar_menu(main_headerbar, NULL, appmenu, obj, UI_TOOLBAR_RIGHT);
     }
-    ui_headerbar_add_items(obj, main_headerbar, right_defaults, UI_TOOLBAR_RIGHT);
+    ui_headerbar_add_items(obj, main_headerbar, right_defaults, UI_TOOLBAR_RIGHT, NULL);
     
     // sidebar
     if(sidebar_headerbar) {
         // ui_headerbar_add_items pos parameter uses only UI_TOOLBAR_LEFT, UI_TOOLBAR_CENTER, UI_TOOLBAR_RIGHT
-        ui_headerbar_add_items(obj, sidebar_headerbar, sidebar_left_defaults, UI_TOOLBAR_LEFT);
+        ui_headerbar_add_items(obj, sidebar_headerbar, sidebar_left_defaults, UI_TOOLBAR_LEFT, NULL);
 
         if(appmenu && appmenu_pos == UI_TOOLBAR_SIDEBAR_RIGHT) {
             ui_add_headerbar_menu(sidebar_headerbar, NULL, appmenu, obj, UI_TOOLBAR_RIGHT);
         }
-        ui_headerbar_add_items(obj, sidebar_headerbar, sidebar_right_defaults, UI_TOOLBAR_RIGHT);
+        ui_headerbar_add_items(obj, sidebar_headerbar, sidebar_right_defaults, UI_TOOLBAR_RIGHT, NULL);
     }
     
     // right panel
     if(right_headerbar) {
-        ui_headerbar_add_items(obj, right_headerbar, rightpanel_left_defaults, UI_TOOLBAR_LEFT);
-        ui_headerbar_add_items(obj, right_headerbar, rightpanel_center_defaults, UI_TOOLBAR_CENTER);
+        // also add central toolbar items, in case the central pane is hidden
+        CxList *backup_toolbar_widgets = cxArrayListCreate(obj->ctx->allocator, CX_STORE_POINTERS, 16);
+        ui_headerbar_add_items(obj, right_headerbar, left_defaults, UI_TOOLBAR_LEFT, backup_toolbar_widgets);
+        ui_headerbar_add_items(obj, right_headerbar, center_defaults, UI_TOOLBAR_LEFT, backup_toolbar_widgets);
+        ui_headerbar_add_items(obj, right_headerbar, right_defaults, UI_TOOLBAR_LEFT, backup_toolbar_widgets);
+        CxIterator i = cxListIterator(backup_toolbar_widgets);
+        cx_foreach(GtkWidget *, w, i) {
+            ui_set_visible(w, FALSE);
+        }
+        g_object_set_data(G_OBJECT(obj->widget), "ui_toolbar_center_backup", backup_toolbar_widgets);
+        
+        // main items for the right panel
+        ui_headerbar_add_items(obj, right_headerbar, rightpanel_left_defaults, UI_TOOLBAR_LEFT, NULL);
+        ui_headerbar_add_items(obj, right_headerbar, rightpanel_center_defaults, UI_TOOLBAR_CENTER, NULL);
 
         if(appmenu && appmenu_pos == UI_TOOLBAR_RIGHTPANEL_RIGHT) {
             ui_add_headerbar_menu(right_headerbar, NULL, appmenu, obj, UI_TOOLBAR_RIGHT);
         }
-        ui_headerbar_add_items(obj, right_headerbar, rightpanel_right_defaults, UI_TOOLBAR_RIGHT);
+        ui_headerbar_add_items(obj, right_headerbar, rightpanel_right_defaults, UI_TOOLBAR_RIGHT, NULL);
     }
 }
 
-static void create_item(UiObject *obj, GtkWidget *headerbar, GtkWidget *box, UiToolbarItemI *i, enum UiToolbarPos pos) {
+static GtkWidget* create_item(UiObject *obj, GtkWidget *headerbar, GtkWidget *box, UiToolbarItemI *i, enum UiToolbarPos pos) {
     switch(i->type) {
         case UI_TOOLBAR_ITEM: {
-            ui_add_headerbar_item(headerbar, box, (UiToolbarItem*)i, obj, pos);
-            break;
+            return ui_add_headerbar_item(headerbar, box, (UiToolbarItem*)i, obj, pos);
         }
         case UI_TOOLBAR_TOGGLEITEM: {
-            ui_add_headerbar_toggleitem(headerbar, box, (UiToolbarToggleItem*)i, obj, pos);
-            break;
+            return ui_add_headerbar_toggleitem(headerbar, box, (UiToolbarToggleItem*)i, obj, pos);
         }
         case UI_TOOLBAR_MENU: {
-            ui_add_headerbar_menu(headerbar, box, (UiToolbarMenuItem*)i, obj, pos);
-            break;
+            return ui_add_headerbar_menu(headerbar, box, (UiToolbarMenuItem*)i, obj, pos);
         }
         default: fprintf(stderr, "toolbar item type unimplemented: %d\n", (int)i->type);
     }
+    return NULL;
 }
 
 static void headerbar_add(GtkWidget *headerbar, GtkWidget *box, GtkWidget *item, enum UiToolbarPos pos) {
@@ -137,12 +150,15 @@ static void headerbar_add(GtkWidget *headerbar, GtkWidget *box, GtkWidget *item,
     }
 }
 
-void ui_headerbar_add_items(UiObject *obj, GtkWidget *headerbar, CxList *items, enum UiToolbarPos pos) {
+void ui_headerbar_add_items(UiObject *obj, GtkWidget *headerbar, CxList *items, enum UiToolbarPos pos, CxList *out_items) {
     GtkWidget *box = NULL;
     
     if(pos == UI_TOOLBAR_CENTER && cxListSize(items) > 0) {
         box = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 6);
         UI_HEADERBAR_SET_TITLE_WIDGET(headerbar, box);
+        if(out_items) {
+            cxListAdd(out_items, box);
+        }
     }
     
     CxIterator i = pos == UI_TOOLBAR_RIGHT ? cxListBackwardsIterator(items) : cxListIterator(items);
@@ -152,11 +168,14 @@ void ui_headerbar_add_items(UiObject *obj, GtkWidget *headerbar, CxList *items,
             fprintf(stderr, "unknown toolbar item: %s\n", def);
             continue;
         }
-        create_item(obj, headerbar, box, item, pos);
+        GtkWidget *item_widget = create_item(obj, headerbar, box, item, pos);
+        if(out_items && !box) {
+            cxListAdd(out_items, item_widget);
+        }
     }
 }
 
-void ui_add_headerbar_item(
+GtkWidget* ui_add_headerbar_item(
         GtkWidget *headerbar,
         GtkWidget *box,
         UiToolbarItem *item,
@@ -168,9 +187,10 @@ void ui_add_headerbar_item(
     ui_set_widget_visibility_states(obj->ctx, button, item->args.visibility_states);
     WIDGET_ADD_CSS_CLASS(button, "flat");
     headerbar_add(headerbar, box, button, pos);
+    return button;
 }
 
-void ui_add_headerbar_toggleitem(
+GtkWidget* ui_add_headerbar_toggleitem(
         GtkWidget *headerbar,
         GtkWidget *box,
         UiToolbarToggleItem *item,
@@ -183,9 +203,10 @@ void ui_add_headerbar_toggleitem(
     WIDGET_ADD_CSS_CLASS(button, "flat");
     ui_setup_togglebutton(obj, button, item->args.label, item->args.icon, item->args.tooltip, item->args.varname, NULL, item->args.onchange, item->args.onchangedata, item->args.action, 0);
     headerbar_add(headerbar, box, button, pos);
+    return button;
 }
 
-void ui_add_headerbar_menu(
+GtkWidget* ui_add_headerbar_menu(
         GtkWidget *headerbar,
         GtkWidget *box,
         UiToolbarMenuItem *item,
@@ -222,6 +243,8 @@ void ui_add_headerbar_menu(
 #endif
     
     headerbar_add(headerbar, box, menubutton, pos);
+    
+    return menubutton;
 }
     
 #endif // GTK_CHECK_VERSION(3, 10, 0)
index d3786c8cd15972664980a1eff2c84acc84d7b6c0..e957c6c4bbf189d2b7b0c2b3ea135786406d0b57 100644 (file)
@@ -65,23 +65,23 @@ extern "C" {
     
 void ui_fill_headerbar(UiObject *obj, GtkWidget *sidebar_headerbar, GtkWidget *main_headerbar, GtkWidget *right_headerbar);
 
-void ui_headerbar_add_items(UiObject *obj, GtkWidget *headerbar, CxList *items, enum UiToolbarPos pos);
+void ui_headerbar_add_items(UiObject *obj, GtkWidget *headerbar, CxList *items, enum UiToolbarPos pos, CxList *out_items);
 
-void ui_add_headerbar_item(
+GtkWidget* ui_add_headerbar_item(
         GtkWidget *headerbar,
         GtkWidget *box,
         UiToolbarItem *item,
         UiObject *obj,
         enum UiToolbarPos pos);
 
-void ui_add_headerbar_toggleitem(
+GtkWidget* ui_add_headerbar_toggleitem(
         GtkWidget *headerbar,
         GtkWidget *box,
         UiToolbarToggleItem *item,
         UiObject *obj,
         enum UiToolbarPos pos);
 
-void ui_add_headerbar_menu(
+GtkWidget* ui_add_headerbar_menu(
         GtkWidget *headerbar,
         GtkWidget *box,
         UiToolbarMenuItem *item,
index d1d08e5c7dcf3ebf96bfecc9e63cdc9d8b5b43bb..14f8aecf3fafab57ec6b360c9013eceb804c8bad 100644 (file)
@@ -515,9 +515,7 @@ UIWIDGET ui_listview_create(UiObject *obj, UiListArgs *args) {
     }
     
     // event handling
-    printf("test\n");
     if(args->onactivate || args->onactivate_action) {
-        printf("signal connect activate\n");
         // columnview and listview can use the same callback function, because
         // the first parameter (which is technically a different pointer type)
         // is ignored
@@ -877,7 +875,6 @@ void ui_dropdown_notify(GtkWidget *dropdown, GObject *pspec, gpointer userdata)
     
     
 void ui_columnview_activate(void *ignore, guint position, gpointer userdata) {
-    printf("columnview activate\n");
     UiListView *view = userdata;
     if(view->selection.count == 0) {
         listview_update_selection(view);
index db9bbada633cd6a63edb2247338d9b054ad21d63..dbdde0a91164fbdcc36a09352bc3ce1380478a29 100644 (file)
@@ -259,7 +259,7 @@ void ui_set_show_all(UIWIDGET widget, int value) {
 #endif
 }
 
-void ui_set_visible(UIWIDGET widget, UiBool visible) {
+void ui_set_visible(UIWIDGET widget, int visible) {
 #if GTK_MAJOR_VERSION >= 4
     gtk_widget_set_visible(widget, visible);
 #else
index f19eb0b42528195788b16769a4ac8fb5e92562fa..009d432cac07cd802c7be67fa485ef4147ecb470 100644 (file)
@@ -45,6 +45,7 @@
 #include "headerbar.h"
 #include "button.h"
 #include "window.h"
+#include "widget.h"
 
 static int nwindows = 0;
 
@@ -289,26 +290,26 @@ static UiObject* create_window(const char *title, UiBool sidebar, UiBool splitvi
         g_object_set_data(G_OBJECT(obj->widget), "ui_left_panel_top", toolbar_view);
         g_object_set_data(G_OBJECT(obj->widget), "ui_right_panel_top", right_panel);
     }
-
+    
     GtkWidget *content_box = vbox;
-
+    
     if(sidebar) {
         GtkWidget *splitview = adw_overlay_split_view_new();
         adw_application_window_set_content(ADW_APPLICATION_WINDOW(obj->widget), splitview);
-
+        
         GtkWidget *sidebar_toolbar_view = adw_toolbar_view_new();
         adw_overlay_split_view_set_sidebar(ADW_OVERLAY_SPLIT_VIEW(splitview), sidebar_toolbar_view);
         headerbar_sidebar = adw_header_bar_new();
         adw_header_bar_set_show_title(ADW_HEADER_BAR(headerbar_sidebar), FALSE);
         adw_toolbar_view_add_top_bar(ADW_TOOLBAR_VIEW(sidebar_toolbar_view), headerbar_sidebar);
-
+        
         adw_overlay_split_view_set_content(ADW_OVERLAY_SPLIT_VIEW(splitview), content);
-
+        
         g_object_set_data(G_OBJECT(obj->widget), "ui_sidebar", sidebar_toolbar_view);
     } else {
         adw_application_window_set_content(ADW_APPLICATION_WINDOW(obj->widget), content);
     }
-
+    
     const char *show_title = ui_get_property("ui.gtk.window.showtitle");
     if(show_title) {
         if(!strcmp(show_title, "main") && sidebar) {
@@ -335,10 +336,10 @@ static UiObject* create_window(const char *title, UiBool sidebar, UiBool splitvi
             adw_header_bar_set_show_title(ADW_HEADER_BAR(headerbar_sidebar), TRUE);
         }
     }
-
+    
     adw_toolbar_view_add_top_bar(ADW_TOOLBAR_VIEW(toolbar_view), headerbar_main);
     g_object_set_data(G_OBJECT(obj->widget), "ui_headerbar", headerbar_main);
-
+    
     if(!simple) {
         ui_fill_headerbar(obj, headerbar_sidebar, headerbar_main, headerbar_right);
     }
@@ -366,7 +367,7 @@ static UiObject* create_window(const char *title, UiBool sidebar, UiBool splitvi
         //GtkWidget *hb = ui_create_headerbar(obj);
         //gtk_window_set_titlebar(GTK_WINDOW(obj->widget), hb);
     }
-
+    
     GtkWidget *content_box = ui_gtk_vbox_new(0);
     WINDOW_SET_CONTENT(obj->widget, vbox);
     if(sidebar || splitview) {
@@ -377,16 +378,16 @@ static UiObject* create_window(const char *title, UiBool sidebar, UiBool splitvi
             g_object_set_data(G_OBJECT(obj->widget), "ui_sidebar", sidebar_vbox);
             gtk_paned_set_position(GTK_PANED(paned), 200);
         }
-
+        
         if(splitview) {
             GtkWidget *content_paned = gtk_paned_new(GTK_ORIENTATION_HORIZONTAL);
             gtk_paned_set_position(GTK_PANED(content_paned), splitview_pos);
             PANED_SET_CHILD2(paned, content_paned);
-
+            
             GtkWidget *right_content_box = ui_gtk_vbox_new(0);
             PANED_SET_CHILD1(content_paned, content_box);
             PANED_SET_CHILD2(content_paned, right_content_box);
-
+            
             g_object_set_data(G_OBJECT(obj->widget), "ui_window_splitview", content_paned);
             g_object_set_data(G_OBJECT(obj->widget), "ui_left_panel", content_box);
             g_object_set_data(G_OBJECT(obj->widget), "ui_right_panel", right_content_box);
@@ -395,14 +396,14 @@ static UiObject* create_window(const char *title, UiBool sidebar, UiBool splitvi
         } else {
             PANED_SET_CHILD2(paned, content_box);
         }
-
+        
         BOX_ADD_EXPAND(GTK_BOX(vbox), paned);
     } else {
         BOX_ADD_EXPAND(GTK_BOX(vbox), content_box);
     }
-
+    
 #endif
-
+    
     // window content
     // the content has a (TODO: not yet) configurable frame
     // TODO: really? why
@@ -410,7 +411,7 @@ static UiObject* create_window(const char *title, UiBool sidebar, UiBool splitvi
     GtkWidget *frame = gtk_frame_new(NULL);
     gtk_frame_set_shadow_type(GTK_FRAME(frame), GTK_SHADOW_NONE);
     gtk_box_pack_start(GTK_BOX(vbox), frame, TRUE, TRUE, 0);
-
+    
     // content vbox
     GtkWidget *content_box = ui_gtk_vbox_new(0);
     gtk_container_add(GTK_CONTAINER(frame), content_box);
@@ -418,7 +419,7 @@ static UiObject* create_window(const char *title, UiBool sidebar, UiBool splitvi
     */
     UiContainer *container = ui_box_container(obj, content_box, UI_CONTAINER_VBOX);
     uic_object_push_container(obj, container);
-
+    
     nwindows++;
     return obj;
 }
@@ -481,10 +482,13 @@ void ui_splitview_window_use_property(UiBool enable) {
 
 UIEXPORT void ui_splitview_window_set_visible(UiObject *obj, int pane, UiBool visible) {
     GtkWidget *panel = NULL;
+    CxList *backup_items = NULL;
     if(pane == 0) {
         panel = g_object_get_data(G_OBJECT(obj->widget), "ui_left_panel_top");
+        backup_items = g_object_get_data(G_OBJECT(obj->widget), "ui_toolbar_center_backup");
     } else if(pane == 1) {
         panel = g_object_get_data(G_OBJECT(obj->widget), "ui_right_panel_top");
+        // TODO: backup toolbar items
     }
     
     if(panel == NULL) {
@@ -493,6 +497,13 @@ UIEXPORT void ui_splitview_window_set_visible(UiObject *obj, int pane, UiBool vi
     }
     
     gtk_widget_set_visible(panel, visible);
+    
+    if(backup_items) {
+        CxIterator i = cxListIterator(backup_items);
+        cx_foreach(GtkWidget*, w, i) {
+            ui_set_visible(w, !visible);
+        }
+    }
 }
 
 #ifdef UI_LIBADWAITA