From 3716300139c8bfa89e4c37f5a289cd7d19b86ae3 Mon Sep 17 00:00:00 2001 From: Jeremy Soller Date: Mon, 13 Nov 2023 14:47:17 -0700 Subject: [PATCH] Show changed status --- Cargo.lock | 52 ++++++++++++++++++++++++------------------------- src/main.rs | 17 ++++++++++++++-- src/tab.rs | 8 +++++++- src/text_box.rs | 39 ++++++++++++++++++++++++++++++------- 4 files changed, 80 insertions(+), 36 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 0440c45..193b724 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -315,7 +315,7 @@ dependencies = [ "futures-lite 2.0.1", "parking", "polling 3.3.0", - "rustix 0.38.21", + "rustix 0.38.22", "slab", "tracing", "waker-fn", @@ -355,7 +355,7 @@ dependencies = [ "cfg-if", "event-listener 3.1.0", "futures-lite 1.13.0", - "rustix 0.38.21", + "rustix 0.38.22", "windows-sys 0.48.0", ] @@ -382,7 +382,7 @@ dependencies = [ "cfg-if", "futures-core", "futures-io", - "rustix 0.38.21", + "rustix 0.38.22", "signal-hook-registry", "slab", "windows-sys 0.48.0", @@ -429,7 +429,7 @@ version = "0.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f4d45f362125ed144544e57b0ec6de8fd6a296d41a6252fc4a20c0cf12e9ed3a" dependencies = [ - "rustix 0.38.21", + "rustix 0.38.22", "tempfile", "windows-sys 0.48.0", ] @@ -815,7 +815,7 @@ dependencies = [ [[package]] name = "cosmic-config" version = "0.1.0" -source = "git+https://github.com/pop-os/libcosmic?branch=menu#a9818966c368c2f1f8e7b401f172a12770a66ff5" +source = "git+https://github.com/pop-os/libcosmic?branch=menu#bd3f3e9d28e2acd1b39dac673636ea72a313425a" dependencies = [ "atomicwrites", "cosmic-config-derive", @@ -829,7 +829,7 @@ dependencies = [ [[package]] name = "cosmic-config-derive" version = "0.1.0" -source = "git+https://github.com/pop-os/libcosmic?branch=menu#a9818966c368c2f1f8e7b401f172a12770a66ff5" +source = "git+https://github.com/pop-os/libcosmic?branch=menu#bd3f3e9d28e2acd1b39dac673636ea72a313425a" dependencies = [ "quote", "syn 1.0.109", @@ -878,7 +878,7 @@ dependencies = [ [[package]] name = "cosmic-text" version = "0.10.0" -source = "git+https://github.com/pop-os/cosmic-text?branch=vi-editor#5352fdee940ef009ea978837afdfc44c468f7be8" +source = "git+https://github.com/pop-os/cosmic-text?branch=vi-editor#4c85a6be721b729350acddcc8a4396353786b901" dependencies = [ "fontdb 0.15.0", "libm", @@ -901,7 +901,7 @@ dependencies = [ [[package]] name = "cosmic-theme" version = "0.1.0" -source = "git+https://github.com/pop-os/libcosmic?branch=menu#a9818966c368c2f1f8e7b401f172a12770a66ff5" +source = "git+https://github.com/pop-os/libcosmic?branch=menu#bd3f3e9d28e2acd1b39dac673636ea72a313425a" dependencies = [ "almost", "cosmic-config", @@ -2039,7 +2039,7 @@ dependencies = [ [[package]] name = "iced" version = "0.10.0" -source = "git+https://github.com/pop-os/libcosmic?branch=menu#a9818966c368c2f1f8e7b401f172a12770a66ff5" +source = "git+https://github.com/pop-os/libcosmic?branch=menu#bd3f3e9d28e2acd1b39dac673636ea72a313425a" dependencies = [ "iced_accessibility", "iced_core", @@ -2054,7 +2054,7 @@ dependencies = [ [[package]] name = "iced_accessibility" version = "0.1.0" -source = "git+https://github.com/pop-os/libcosmic?branch=menu#a9818966c368c2f1f8e7b401f172a12770a66ff5" +source = "git+https://github.com/pop-os/libcosmic?branch=menu#bd3f3e9d28e2acd1b39dac673636ea72a313425a" dependencies = [ "accesskit", "accesskit_winit", @@ -2063,7 +2063,7 @@ dependencies = [ [[package]] name = "iced_core" version = "0.10.0" -source = "git+https://github.com/pop-os/libcosmic?branch=menu#a9818966c368c2f1f8e7b401f172a12770a66ff5" +source = "git+https://github.com/pop-os/libcosmic?branch=menu#bd3f3e9d28e2acd1b39dac673636ea72a313425a" dependencies = [ "bitflags 1.3.2", "instant", @@ -2077,7 +2077,7 @@ dependencies = [ [[package]] name = "iced_futures" version = "0.7.0" -source = "git+https://github.com/pop-os/libcosmic?branch=menu#a9818966c368c2f1f8e7b401f172a12770a66ff5" +source = "git+https://github.com/pop-os/libcosmic?branch=menu#bd3f3e9d28e2acd1b39dac673636ea72a313425a" dependencies = [ "futures", "iced_core", @@ -2089,7 +2089,7 @@ dependencies = [ [[package]] name = "iced_graphics" version = "0.9.0" -source = "git+https://github.com/pop-os/libcosmic?branch=menu#a9818966c368c2f1f8e7b401f172a12770a66ff5" +source = "git+https://github.com/pop-os/libcosmic?branch=menu#bd3f3e9d28e2acd1b39dac673636ea72a313425a" dependencies = [ "bitflags 1.3.2", "bytemuck", @@ -2107,7 +2107,7 @@ dependencies = [ [[package]] name = "iced_renderer" version = "0.1.0" -source = "git+https://github.com/pop-os/libcosmic?branch=menu#a9818966c368c2f1f8e7b401f172a12770a66ff5" +source = "git+https://github.com/pop-os/libcosmic?branch=menu#bd3f3e9d28e2acd1b39dac673636ea72a313425a" dependencies = [ "iced_graphics", "iced_tiny_skia", @@ -2120,7 +2120,7 @@ dependencies = [ [[package]] name = "iced_runtime" version = "0.1.1" -source = "git+https://github.com/pop-os/libcosmic?branch=menu#a9818966c368c2f1f8e7b401f172a12770a66ff5" +source = "git+https://github.com/pop-os/libcosmic?branch=menu#bd3f3e9d28e2acd1b39dac673636ea72a313425a" dependencies = [ "iced_core", "iced_futures", @@ -2130,7 +2130,7 @@ dependencies = [ [[package]] name = "iced_style" version = "0.9.0" -source = "git+https://github.com/pop-os/libcosmic?branch=menu#a9818966c368c2f1f8e7b401f172a12770a66ff5" +source = "git+https://github.com/pop-os/libcosmic?branch=menu#bd3f3e9d28e2acd1b39dac673636ea72a313425a" dependencies = [ "iced_core", "once_cell", @@ -2140,7 +2140,7 @@ dependencies = [ [[package]] name = "iced_tiny_skia" version = "0.1.0" -source = "git+https://github.com/pop-os/libcosmic?branch=menu#a9818966c368c2f1f8e7b401f172a12770a66ff5" +source = "git+https://github.com/pop-os/libcosmic?branch=menu#bd3f3e9d28e2acd1b39dac673636ea72a313425a" dependencies = [ "bytemuck", "cosmic-text 0.9.0", @@ -2158,7 +2158,7 @@ dependencies = [ [[package]] name = "iced_wgpu" version = "0.11.1" -source = "git+https://github.com/pop-os/libcosmic?branch=menu#a9818966c368c2f1f8e7b401f172a12770a66ff5" +source = "git+https://github.com/pop-os/libcosmic?branch=menu#bd3f3e9d28e2acd1b39dac673636ea72a313425a" dependencies = [ "bitflags 1.3.2", "bytemuck", @@ -2180,7 +2180,7 @@ dependencies = [ [[package]] name = "iced_widget" version = "0.1.3" -source = "git+https://github.com/pop-os/libcosmic?branch=menu#a9818966c368c2f1f8e7b401f172a12770a66ff5" +source = "git+https://github.com/pop-os/libcosmic?branch=menu#bd3f3e9d28e2acd1b39dac673636ea72a313425a" dependencies = [ "iced_renderer", "iced_runtime", @@ -2194,7 +2194,7 @@ dependencies = [ [[package]] name = "iced_winit" version = "0.10.0" -source = "git+https://github.com/pop-os/libcosmic?branch=menu#a9818966c368c2f1f8e7b401f172a12770a66ff5" +source = "git+https://github.com/pop-os/libcosmic?branch=menu#bd3f3e9d28e2acd1b39dac673636ea72a313425a" dependencies = [ "iced_graphics", "iced_runtime", @@ -2338,7 +2338,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "cb0889898416213fab133e1d33a0e5858a48177452750691bde3666d0fdbaf8b" dependencies = [ "hermit-abi", - "rustix 0.38.21", + "rustix 0.38.22", "windows-sys 0.48.0", ] @@ -2442,7 +2442,7 @@ checksum = "89d92a4743f9a61002fae18374ed11e7973f530cb3a3255fb354818118b2203c" [[package]] name = "libcosmic" version = "0.1.0" -source = "git+https://github.com/pop-os/libcosmic?branch=menu#a9818966c368c2f1f8e7b401f172a12770a66ff5" +source = "git+https://github.com/pop-os/libcosmic?branch=menu#bd3f3e9d28e2acd1b39dac673636ea72a313425a" dependencies = [ "apply", "cosmic-config", @@ -3464,7 +3464,7 @@ dependencies = [ "cfg-if", "concurrent-queue", "pin-project-lite", - "rustix 0.38.21", + "rustix 0.38.22", "tracing", "windows-sys 0.48.0", ] @@ -3870,9 +3870,9 @@ dependencies = [ [[package]] name = "rustix" -version = "0.38.21" +version = "0.38.22" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2b426b0506e5d50a7d8dafcf2e81471400deb602392c7dd110815afb4eaf02a3" +checksum = "80109a168d9bc0c7f483083244543a6eb0dba02295d33ca268145e6190d6df0c" dependencies = [ "bitflags 2.4.1", "errno", @@ -4361,7 +4361,7 @@ dependencies = [ "cfg-if", "fastrand 2.0.1", "redox_syscall 0.4.1", - "rustix 0.38.21", + "rustix 0.38.22", "windows-sys 0.48.0", ] diff --git a/src/main.rs b/src/main.rs index fa480b0..ed492c6 100644 --- a/src/main.rs +++ b/src/main.rs @@ -125,6 +125,7 @@ pub enum Message { SelectAll, SyntaxTheme(usize, bool), TabActivate(segmented_button::Entity), + TabChanged(segmented_button::Entity), TabClose(segmented_button::Entity), Todo, ToggleContextPage(ContextPage), @@ -706,8 +707,8 @@ impl Application for App { if tab.path_opt.is_none() { //TODO: use async file dialog tab.path_opt = rfd::FileDialog::new().save_file(); - title_opt = Some(tab.title()); } + title_opt = Some(tab.title()); tab.save(); } None => { @@ -754,6 +755,15 @@ impl Application for App { self.tab_model.activate(entity); return self.update_tab(); } + Message::TabChanged(entity) => match self.tab_model.data::(entity) { + Some(tab) => { + let mut title = tab.title(); + //TODO: better way of adding change indicator + title.push_str(" \u{2022}"); + self.tab_model.text_set(entity, title); + } + None => {} + }, Message::TabClose(entity) => { // Activate closest item if let Some(position) = self.tab_model.position(entity) { @@ -997,7 +1007,10 @@ impl Application for App { } } }; - tab_column = tab_column.push(text_box(&tab.editor, self.config.metrics())); + tab_column = tab_column.push( + text_box(&tab.editor, self.config.metrics()) + .on_changed(Message::TabChanged(self.tab_model.active())), + ); tab_column = tab_column.push(text(status).font(cosmic::font::Font::MONOSPACE)); } None => { diff --git a/src/tab.rs b/src/tab.rs index 66fde17..3555590 100644 --- a/src/tab.rs +++ b/src/tab.rs @@ -77,7 +77,7 @@ impl Tab { pub fn save(&mut self) { if let Some(path) = &self.path_opt { - let editor = self.editor.lock().unwrap(); + let mut editor = self.editor.lock().unwrap(); let mut text = String::new(); for line in editor.buffer().lines.iter() { text.push_str(line.text()); @@ -85,6 +85,7 @@ impl Tab { } match fs::write(path, text) { Ok(()) => { + editor.set_changed(false); log::info!("saved {:?}", path); } Err(err) => { @@ -96,6 +97,11 @@ impl Tab { } } + pub fn changed(&self) -> bool { + let editor = self.editor.lock().unwrap(); + editor.changed() + } + pub fn icon(&self, size: u16) -> Icon { match &self.path_opt { Some(path) => mime_icon(path, size), diff --git a/src/text_box.rs b/src/text_box.rs index 1430e63..d7f0829 100644 --- a/src/text_box.rs +++ b/src/text_box.rs @@ -57,18 +57,23 @@ impl StyleSheet for Theme { } } -pub struct TextBox<'a> { +pub struct TextBox<'a, Message> { editor: &'a Mutex>, metrics: Metrics, padding: Padding, + on_changed: Option, } -impl<'a> TextBox<'a> { +impl<'a, Message> TextBox<'a, Message> +where + Message: Clone, +{ pub fn new(editor: &'a Mutex>, metrics: Metrics) -> Self { Self { editor, metrics, padding: Padding::new(0.0), + on_changed: None, } } @@ -76,9 +81,20 @@ impl<'a> TextBox<'a> { self.padding = padding.into(); self } + + pub fn on_changed(mut self, on_changed: Message) -> Self { + self.on_changed = Some(on_changed); + self + } } -pub fn text_box<'a>(editor: &'a Mutex>, metrics: Metrics) -> TextBox<'a> { +pub fn text_box<'a, Message>( + editor: &'a Mutex>, + metrics: Metrics, +) -> TextBox<'a, Message> +where + Message: Clone, +{ TextBox::new(editor, metrics) } @@ -149,8 +165,9 @@ fn draw_rect( } } -impl<'a, 'editor, Message, Renderer> Widget for TextBox<'a> +impl<'a, 'editor, Message, Renderer> Widget for TextBox<'a, Message> where + Message: Clone, Renderer: renderer::Renderer + image::Renderer, Renderer::Theme: StyleSheet, { @@ -393,7 +410,7 @@ where cursor_position: mouse::Cursor, _renderer: &Renderer, _clipboard: &mut dyn Clipboard, - _shell: &mut Shell<'_, Message>, + shell: &mut Shell<'_, Message>, _viewport: &Rectangle, ) -> Status { let state = tree.state.downcast_mut::(); @@ -401,6 +418,7 @@ where let scrollbar_rect = state.scrollbar_rect.get(); let mut editor = self.editor.lock().unwrap(); let buffer_size = editor.buffer().size(); + let last_changed = editor.changed(); let mut font_system = FONT_SYSTEM.lock().unwrap(); let mut editor = editor.borrow_with(&mut font_system); @@ -567,16 +585,23 @@ where _ => (), } + if editor.changed() != last_changed { + if let Some(on_changed) = &self.on_changed { + shell.publish(on_changed.clone()); + } + } + status } } -impl<'a, 'editor, Message, Renderer> From> for Element<'a, Message, Renderer> +impl<'a, 'editor, Message, Renderer> From> for Element<'a, Message, Renderer> where + Message: Clone + 'a, Renderer: renderer::Renderer + image::Renderer, Renderer::Theme: StyleSheet, { - fn from(text_box: TextBox<'a>) -> Self { + fn from(text_box: TextBox<'a, Message>) -> Self { Self::new(text_box) } }