1use std::ops::Mul;
2
3use freya_core::{
4 elements::paragraph::ParagraphHolderInner,
5 prelude::*,
6};
7use keyboard_types::NamedKey;
8use torin::prelude::CursorPoint;
9
10use crate::{
11 EditableConfig,
12 EditorLine,
13 TextSelection,
14 rope_editor::RopeEditor,
15 text_editor::{
16 TextEditor,
17 TextEvent,
18 },
19};
20
21pub enum EditableEvent<'a> {
22 Release,
23 Move {
24 location: CursorPoint,
25 editor_line: EditorLine,
26 holder: &'a ParagraphHolder,
27 },
28 Down {
29 location: CursorPoint,
30 editor_line: EditorLine,
31 holder: &'a ParagraphHolder,
32 },
33 KeyDown {
34 key: &'a Key,
35 modifiers: Modifiers,
36 },
37 KeyUp {
38 key: &'a Key,
39 },
40}
41
42impl EditableEvent<'_> {
43 pub fn process<'a, 'b>(
44 self,
45 mut editor: impl MutView<'b, RopeEditor>,
46 mut dragging: impl MutView<'b, TextDragging>,
47 config: &'_ EditableConfig,
48 ) {
49 match self {
50 EditableEvent::Down {
51 location,
52 editor_line,
53 holder,
54 } => {
55 let holder = holder.0.borrow();
56 let ParagraphHolderInner {
57 paragraph,
58 scale_factor,
59 } = holder.as_ref().unwrap();
60
61 let mut text_editor = editor.write();
62
63 if dragging.peek().shift || dragging.peek().clicked {
64 text_editor.selection_mut().set_as_range();
65 } else {
66 text_editor.clear_selection();
67 }
68
69 dragging.write().clicked = true;
70
71 match EventsCombos::pressed(location) {
72 PressEventType::Triple => {
73 let current_selection = text_editor.selection().clone();
74
75 let char_position = paragraph.get_glyph_position_at_coordinate(
76 location.mul(*scale_factor).to_i32().to_tuple(),
77 );
78 let press_selection = text_editor
79 .measure_selection(char_position.position as usize, editor_line);
80
81 let line = text_editor.rope().char_to_line(press_selection.pos());
83 let line_char = text_editor.rope().line_to_char(line);
84 let line_len = text_editor.rope().line(line).len_utf16_cu();
85 let new_selection =
86 TextSelection::new_range((line_char, line_char + line_len));
87
88 if current_selection != new_selection {
90 *text_editor.selection_mut() = new_selection;
91 }
92 }
93 PressEventType::Double => {
94 let current_selection = text_editor.selection().clone();
95
96 let char_position = paragraph.get_glyph_position_at_coordinate(
97 location.mul(*scale_factor).to_i32().to_tuple(),
98 );
99 let press_selection = text_editor
100 .measure_selection(char_position.position as usize, editor_line);
101
102 let range = text_editor.find_word_boundaries(press_selection.pos());
104 let new_selection = TextSelection::new_range(range);
105
106 if current_selection != new_selection {
108 *text_editor.selection_mut() = new_selection;
109 }
110 }
111 PressEventType::Single => {
112 let current_selection = text_editor.selection().clone();
113
114 let char_position = paragraph.get_glyph_position_at_coordinate(
115 location.mul(*scale_factor).to_i32().to_tuple(),
116 );
117 let new_selection = text_editor
118 .measure_selection(char_position.position as usize, editor_line);
119
120 if current_selection != new_selection {
122 *text_editor.selection_mut() = new_selection;
123 }
124 }
125 }
126 }
127 EditableEvent::Move {
128 location,
129 editor_line,
130 holder,
131 } => {
132 if dragging.peek().clicked {
133 let paragraph = holder.0.borrow();
134 let ParagraphHolderInner {
135 paragraph,
136 scale_factor,
137 } = paragraph.as_ref().unwrap();
138
139 let dist_position = location.mul(*scale_factor);
140
141 let dist_char = paragraph
143 .get_glyph_position_at_coordinate(dist_position.to_i32().to_tuple());
144 let to = dist_char.position as usize;
145
146 if !editor.peek().selection.is_range() {
147 editor.write().selection_mut().set_as_range();
148 }
149
150 let current_selection = editor.peek().selection().clone();
151
152 let new_selection = editor.peek().measure_selection(to, editor_line);
153
154 if current_selection != new_selection {
156 let mut text_editor = editor.write();
157 *text_editor.selection_mut() = new_selection;
158 }
159 }
160 }
161 EditableEvent::Release => {
162 dragging.write().clicked = false;
163 }
164 EditableEvent::KeyDown { key, modifiers } => {
165 match key {
166 Key::Named(NamedKey::Shift) => {
168 dragging.write().shift = true;
169 }
170 _ => {
172 editor.write_if(|mut editor| {
173 let event = editor.process_key(
174 key,
175 &modifiers,
176 config.allow_tabs,
177 config.allow_changes,
178 config.allow_clipboard,
179 );
180 if event.contains(TextEvent::TEXT_CHANGED) {
181 *dragging.write() = TextDragging::default();
182 }
183 !event.is_empty()
184 });
185 }
186 }
187 }
188 EditableEvent::KeyUp { key, .. } => {
189 if *key == Key::Named(NamedKey::Shift) {
190 dragging.write().shift = false;
191 }
192 }
193 };
194 }
195}
196
197#[derive(Debug, PartialEq, Clone, Default)]
198pub struct TextDragging {
199 pub shift: bool,
200 pub clicked: bool,
201}