kas_widgets/edit/mod.rs
1// Licensed under the Apache License, Version 2.0 (the "License");
2// you may not use this file except in compliance with the License.
3// You may obtain a copy of the License in the LICENSE-APACHE file or at:
4// https://www.apache.org/licenses/LICENSE-2.0
5
6//! The [`EditField`] and [`EditBox`] widgets, plus supporting items
7
8mod edit_box;
9mod edit_field;
10mod editor;
11mod guard;
12
13pub use edit_box::EditBox;
14pub use edit_field::EditField;
15pub use editor::Editor;
16pub use guard::*;
17
18use std::fmt::Debug;
19use std::ops::Range;
20
21/// Describes the change source of a history (undo) state
22#[derive(Clone, Copy, Debug, PartialEq, Eq)]
23enum EditOp {
24 /// Initial state
25 Initial,
26 /// Cursor movement or selection adjustment
27 Cursor,
28 /// Keyboard
29 KeyInput,
30 /// Input Method Editor
31 Ime,
32 /// Deletion due to key press
33 Delete,
34 /// Cut to or paste from clipboard
35 Clipboard,
36 /// Programmatic edit
37 Synthetic,
38}
39
40impl EditOp {
41 /// An edit may be merged with a previous one if both are equal and this method returns `true`
42 fn try_merge(self, last_op: &mut Option<Self>) -> bool {
43 match (self, last_op) {
44 (EditOp::Cursor, Some(last)) => {
45 *last = self;
46 true
47 }
48 (EditOp::KeyInput | EditOp::Delete, Some(last)) if self == *last => true,
49 _ => false,
50 }
51 }
52}
53
54enum CmdAction {
55 /// Key not used, no action
56 Unused,
57 /// Key used, no action
58 Used,
59 /// Cursor and/or selection changed
60 Cursor,
61 /// Enter key in single-line editor
62 Activate,
63 /// Text was edited by key command
64 Edit,
65}
66
67/// Used to track ongoing incompatible actions
68#[derive(Clone, Debug, Default, PartialEq, Eq)]
69enum CurrentAction {
70 /// No current action
71 #[default]
72 None,
73 /// IME is enabled but no input has yet been given. This is special in that
74 /// a selection may exist (which would get replaced by the pre-edit text).
75 ImeStart,
76 /// We have some pre-edit text within the given range (if non-empty).
77 ///
78 /// This text should be deleted if IME is cancelled.
79 ImePreedit {
80 /// Range of the pre-edit text
81 edit_range: Range<u32>,
82 },
83 Selection,
84}
85
86impl CurrentAction {
87 fn is_none(&self) -> bool {
88 *self == CurrentAction::None
89 }
90
91 /// Check whether IME is enabled
92 ///
93 /// This does not imply a pre-edit (or any IME input).
94 fn is_ime_enabled(&self) -> bool {
95 matches!(
96 self,
97 CurrentAction::ImeStart | CurrentAction::ImePreedit { .. }
98 )
99 }
100}