diff --git a/Cargo.toml b/Cargo.toml index 5a9f0ae59..2761c1002 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -35,6 +35,7 @@ dioxus-hooks = { version = "0.4" } dioxus-core = { version = "0.4" } dioxus-hot-reload = { version = "0.4", features = ["file_watcher"] } dioxus-router = { version = "0.4", default-features = false } +dioxus-std = { version = "0.4", features = ["clipboard"] } skia-safe = { version = "0.67.0", features = ["gl", "textlayout", "svg"] } @@ -66,7 +67,7 @@ freya-node-state = { workspace = true } reqwest = { version = "0.11.22", features = ["json"] } serde = "1.0.189" tracing-subscriber = "0.3.17" -dioxus-std = { version = "0.4", features = ["i18n"] } +dioxus-std = { version = "0.4", features = ["i18n", "clipboard"] } rand = "0.8.5" dioxus-router = { workspace = true } itertools = "0.11.0" diff --git a/crates/hooks/Cargo.toml b/crates/hooks/Cargo.toml index 762167197..2673f916f 100644 --- a/crates/hooks/Cargo.toml +++ b/crates/hooks/Cargo.toml @@ -31,6 +31,7 @@ dioxus-native-core = { workspace = true } dioxus-core-macro = { workspace = true } dioxus-hooks = { workspace = true } dioxus-core = { workspace = true } +dioxus-std = { workspace = true } tokio = { workspace = true } winit = { workspace = true } diff --git a/crates/hooks/src/rope_editor.rs b/crates/hooks/src/rope_editor.rs index 8eec3bc39..13a7144e6 100644 --- a/crates/hooks/src/rope_editor.rs +++ b/crates/hooks/src/rope_editor.rs @@ -1,5 +1,6 @@ use std::{cmp::Ordering, fmt::Display, ops::Range}; +use dioxus_std::clipboard::UseClipboard; use ropey::iter::Lines; pub use ropey::Rope; @@ -14,6 +15,8 @@ pub struct RopeEditor { /// Selected text range selected: Option<(usize, usize)>, + + clipboard: UseClipboard } impl Display for RopeEditor { @@ -24,12 +27,13 @@ impl Display for RopeEditor { impl RopeEditor { // Create a new [`RopeEditor`] - pub fn new(text: String, cursor: TextCursor, mode: EditableMode) -> Self { + pub fn new(text: String, cursor: TextCursor, mode: EditableMode, clipboard: UseClipboard) -> Self { Self { rope: Rope::from_str(&text), cursor, selected: None, mode, + clipboard } } @@ -93,6 +97,10 @@ impl TextEditor for RopeEditor { } } + fn get_clipboard(&self) -> &UseClipboard { + &self.clipboard + } + fn highlights(&self, editor_id: usize) -> Option<(usize, usize)> { let (selected_from, selected_to) = self.selected?; @@ -190,6 +198,12 @@ impl TextEditor for RopeEditor { self.set_cursor_pos(to); } } + + fn get_selected_text(&self) -> Option { + let selected = self.selected?; + + Some(self.rope().get_slice(selected.0..selected.1)?.to_string()) + } } /// Iterator over text lines. diff --git a/crates/hooks/src/text_editor.rs b/crates/hooks/src/text_editor.rs index 03daf6334..c4f8d2853 100644 --- a/crates/hooks/src/text_editor.rs +++ b/crates/hooks/src/text_editor.rs @@ -1,5 +1,6 @@ use std::{borrow::Cow, fmt::Display, ops::Range}; +use dioxus_std::clipboard::UseClipboard; use freya_elements::events::keyboard::{Code, Key, Modifiers}; pub use ropey::Rope; @@ -179,6 +180,8 @@ pub trait TextEditor: Sized + Clone + Display { fn move_highlight_to_cursor(&mut self); + fn get_clipboard(&self) -> &UseClipboard; + // Process a Keyboard event fn process_key(&mut self, key: &Key, code: &Code, modifiers: &Modifiers) -> TextEvent { let mut event = TextEvent::None; @@ -358,12 +361,16 @@ pub trait TextEditor: Sized + Clone + Display { event = TextEvent::TextChanged } + Code::KeyC if modifiers.contains(Modifiers::CONTROL) => { + let selected = self.get_selected_text(); + println!("copying: >{selected:?}<"); + } _ => { if let Ok(ch) = character.parse::() { if !ch.is_ascii_control() { // Adds a new character let char_idx = - self.line_to_char(self.cursor_row()) + self.cursor_col(); + self.line_to_char(self.cursor_row()) + self.cursor_col(); self.insert(character, char_idx); self.cursor_right(); @@ -382,4 +389,6 @@ pub trait TextEditor: Sized + Clone + Display { event } + + fn get_selected_text(&self) -> Option; } diff --git a/crates/hooks/src/use_editable.rs b/crates/hooks/src/use_editable.rs index e54eb19fc..5c1db8fea 100644 --- a/crates/hooks/src/use_editable.rs +++ b/crates/hooks/src/use_editable.rs @@ -5,6 +5,7 @@ use std::{ use dioxus_core::{AttributeValue, Scope, ScopeState}; use dioxus_hooks::{use_effect, use_ref, use_state, UseRef, UseState}; +use dioxus_std::clipboard::use_clipboard; use freya_common::{CursorLayoutResponse, EventMessage}; use freya_elements::events::{KeyboardData, MouseData}; use freya_node_state::{CursorReference, CustomAttributeValues}; @@ -157,11 +158,12 @@ pub fn use_editable( ) -> UseEditable { let id = cx.use_hook(Uuid::new_v4); let platform = use_platform(cx); + let clipboard = use_clipboard(cx); // Hold the text editor let text_editor = use_state(cx, || { let config = initializer(); - RopeEditor::new(config.content, config.cursor, mode) + RopeEditor::new(config.content, config.cursor, mode, clipboard) }); let cursor_channels = cx.use_hook(|| {