diff options
Diffstat (limited to 'src/text/rich.rs')
| -rw-r--r-- | src/text/rich.rs | 85 |
1 files changed, 63 insertions, 22 deletions
diff --git a/src/text/rich.rs b/src/text/rich.rs index 2285b4e..b49adbd 100644 --- a/src/text/rich.rs +++ b/src/text/rich.rs @@ -10,6 +10,7 @@ use crate::core::mouse; use crate::core::renderer; use crate::core::text::{Paragraph as _, Span}; use crate::core::touch; +use crate::core::widget::Operation; use crate::core::widget::text::{Alignment, LineHeight, Shaping, Wrapping}; use crate::core::widget::tree::{self, Tree}; use crate::core::{ @@ -44,6 +45,7 @@ pub struct Rich< on_link_click: Option<Box<dyn Fn(Link) -> Message + 'a>>, on_link_hover: Option<Box<dyn Fn(Link) -> Message + 'a>>, on_hover_lost: Option<Box<dyn Fn() -> Message + 'a>>, + independent_selection: bool, } impl<'a, Link, Message, Theme, Renderer> @@ -70,6 +72,7 @@ where on_link_click: None, on_link_hover: None, on_hover_lost: None, + independent_selection: true, } } @@ -184,6 +187,15 @@ where self } + /// Makes this [`Rich`] selection independent of others. + /// + /// Independent texts handle their own selection copy and don't allow being selected from + /// outside its bounds. + pub fn independent(mut self, independent_selection: bool) -> Self { + self.independent_selection = independent_selection; + self + } + /// Sets the default style of the [`Rich`] text. #[must_use] pub fn style(mut self, style: impl Fn(&Theme) -> Style + 'a) -> Self @@ -225,7 +237,6 @@ struct State<Link> { dragging: Option<Dragging>, last_click: Option<mouse::Click>, potential_click: Option<mouse::Click>, - has_cleared_clipboard: bool, keyboard_modifiers: keyboard::Modifiers, visual_lines_bounds: Vec<core::Rectangle>, } @@ -367,7 +378,6 @@ where dragging: None, last_click: None, potential_click: None, - has_cleared_clipboard: false, keyboard_modifiers: keyboard::Modifiers::default(), visual_lines_bounds: Vec::new(), }) @@ -632,7 +642,9 @@ where shell.capture_event(); } else { - if let Some(position) = cursor.land().position() { + if let Some(position) = cursor.land().position() + && !self.independent_selection + { let potential_click = mouse::Click::new( position, mouse::Button::Left, @@ -756,33 +768,20 @@ where state.last_click = Some(potential_click); state.potential_click = None; - - // Clear the clipboard so that we can append to it if the user presses the copy - // shortcut to be able to include all selected texts. - clipboard.write(clipboard::Kind::Standard, String::new()); - state.has_cleared_clipboard = true; } } Event::Keyboard(keyboard::Event::KeyPressed { key, .. }) => { match key.as_ref() { keyboard::Key::Character("c") if state.keyboard_modifiers.command() + && !shell.is_event_captured() + && self.independent_selection && !state.selection.is_empty() => { - let contents = - if state.has_cleared_clipboard { - state.has_cleared_clipboard = false; - clipboard - .read(clipboard::Kind::Standard) - .map(|c| { - if !c.is_empty() { c + "\n" } else { c } - }) - .unwrap_or_default() - + &state.selection.text(&state.paragraph) - } else { - state.selection.text(&state.paragraph) - }; - clipboard.write(clipboard::Kind::Standard, contents); + clipboard.write( + clipboard::Kind::Standard, + state.selection.text(&state.paragraph), + ); shell.capture_event(); } @@ -921,6 +920,48 @@ where } } + fn operate( + &mut self, + state: &mut Tree, + layout: Layout<'_>, + _renderer: &Renderer, + operation: &mut dyn Operation, + ) { + let state = state.state.downcast_ref::<State<Link>>(); + operation.text( + None, + layout.bounds(), + &state.paragraph.buffer().lines.iter().fold( + String::new(), + |mut str, l| { + if !str.is_empty() { + str.push('\n'); + } + str.push_str(l.text()); + str + }, + ), + ); + + if !self.independent_selection { + let selection = state.selection.text(&state.paragraph); + if !selection.is_empty() { + operation.custom( + None, + layout.bounds(), + &mut crate::operation::Selection(selection), + ); + } + } + + // let mut isel = crate::operation::IndependentSelection::new(&mut self.independent_selection); + operation.custom( + None, + layout.bounds(), + &mut self.independent_selection, + ); + } + fn mouse_interaction( &self, tree: &Tree, |
