Edit selected text layer by hitting Enter (#1000)

* Allow text editing when pressing Enter on a single selected text layer

* Updated LayerDataType import

* Extract the logic to set the edit layer into a function

---------

Co-authored-by: Keavon Chambers <keavon@keavon.com>
This commit is contained in:
Shouvik Ghosh 2023-01-31 22:49:50 +05:30 committed by Keavon Chambers
parent a328e7d3ef
commit 316df70571
3 changed files with 62 additions and 18 deletions

View File

@ -52,7 +52,7 @@ pub fn default_mapping() -> Mapping {
entry!(PointerMove; refresh_keys=[Control, Shift, Alt], action_dispatch=SelectToolMessage::PointerMove { axis_align: Shift, snap_angle: Control, center: Alt, duplicate: Alt }),
entry!(KeyDown(Lmb); action_dispatch=SelectToolMessage::DragStart { add_to_selection: Shift }),
entry!(KeyUp(Lmb); action_dispatch=SelectToolMessage::DragStop),
entry!(KeyDown(Enter); action_dispatch=SelectToolMessage::DragStop),
entry!(KeyDown(Enter); action_dispatch=SelectToolMessage::Enter),
entry!(DoubleClick; action_dispatch=SelectToolMessage::EditLayer),
entry!(KeyDown(Rmb); action_dispatch=SelectToolMessage::Abort),
entry!(KeyDown(Escape); action_dispatch=SelectToolMessage::Abort),

View File

@ -56,6 +56,7 @@ pub enum SelectToolMessage {
},
DragStop,
EditLayer,
Enter,
FlipHorizontal,
FlipVertical,
PointerMove {
@ -215,12 +216,14 @@ impl<'a> MessageHandler<ToolMessage, ToolActionHandlerData<'a>> for SelectTool {
PointerMove,
Abort,
EditLayer,
Enter,
),
_ => actions!(SelectToolMessageDiscriminant;
DragStop,
PointerMove,
Abort,
EditLayer,
Enter,
),
}
}
@ -587,7 +590,7 @@ impl Fsm for SelectToolFsmState {
Ready
}
(Dragging, DragStop) => {
(Dragging, DragStop | Enter) => {
let response = match input.mouse.position.distance(tool_data.drag_start) < 10. * f64::EPSILON {
true => DocumentMessage::Undo,
false => DocumentMessage::CommitTransaction,
@ -596,7 +599,7 @@ impl Fsm for SelectToolFsmState {
responses.push_front(response.into());
Ready
}
(ResizingBounds, DragStop) => {
(ResizingBounds, DragStop | Enter) => {
let response = match input.mouse.position.distance(tool_data.drag_start) < 10. * f64::EPSILON {
true => DocumentMessage::Undo,
false => DocumentMessage::CommitTransaction,
@ -611,7 +614,7 @@ impl Fsm for SelectToolFsmState {
Ready
}
(RotatingBounds, DragStop) => {
(RotatingBounds, DragStop | Enter) => {
let response = match input.mouse.position.distance(tool_data.drag_start) < 10. * f64::EPSILON {
true => DocumentMessage::Undo,
false => DocumentMessage::CommitTransaction,
@ -624,7 +627,7 @@ impl Fsm for SelectToolFsmState {
Ready
}
(DraggingPivot, DragStop) => {
(DraggingPivot, DragStop | Enter) => {
let response = match input.mouse.position.distance(tool_data.drag_start) < 10. * f64::EPSILON {
true => DocumentMessage::Undo,
false => DocumentMessage::CommitTransaction,
@ -635,7 +638,7 @@ impl Fsm for SelectToolFsmState {
Ready
}
(DrawingBox, DragStop) => {
(DrawingBox, DragStop | Enter) => {
let quad = tool_data.selection_quad();
responses.push_front(
DocumentMessage::AddSelectedLayers {
@ -654,6 +657,23 @@ impl Fsm for SelectToolFsmState {
);
Ready
}
(Ready, Enter) => {
let mut selected_layers = document.selected_layers();
if let Some(layer_path) = selected_layers.next() {
// Check that only one layer is selected
if selected_layers.next().is_none() {
if let Ok(layer) = document.document_legacy.layer(layer_path) {
if let LayerDataType::Text(_) = layer.data {
responses.push_front(ToolMessage::ActivateTool { tool_type: ToolType::Text }.into());
responses.push_back(TextToolMessage::EditSelected.into());
}
}
}
}
Ready
}
(Dragging, Abort) => {
tool_data.snap_manager.cleanup(responses);
responses.push_back(DocumentMessage::Undo.into());

View File

@ -10,6 +10,7 @@ use crate::messages::tool::utility_types::{EventToMessageMap, Fsm, ToolActionHan
use crate::messages::tool::utility_types::{HintData, HintGroup, HintInfo};
use document_legacy::intersection::Quad;
use document_legacy::layers::layer_info::LayerDataType;
use document_legacy::layers::style::{self, Fill, RenderData, Stroke};
use document_legacy::LayerId;
use document_legacy::Operation;
@ -53,6 +54,7 @@ pub enum TextToolMessage {
// Tool-specific messages
CommitText,
EditSelected,
Interact,
TextChange {
new_text: String,
@ -241,6 +243,21 @@ fn update_overlays(document: &DocumentMessageHandler, tool_data: &mut TextToolDa
resize_overlays(&mut tool_data.overlays, responses, new_len);
}
fn set_edit_layer(layer_path: &[LayerId], tool_state: TextToolFsmState, tool_data: &mut TextToolData, responses: &mut VecDeque<Message>) {
if tool_state == TextToolFsmState::Editing {
tool_data.set_editing(false, responses);
}
tool_data.layer_path = layer_path.into();
responses.push_back(DocumentMessage::StartTransaction.into());
tool_data.set_editing(true, responses);
let replacement_selected_layers = vec![tool_data.layer_path.clone()];
responses.push_back(DocumentMessage::SetSelectedLayers { replacement_selected_layers }.into());
}
impl Fsm for TextToolFsmState {
type ToolData = TextToolData;
type ToolOptions = TextOptions;
@ -275,18 +292,7 @@ impl Fsm for TextToolFsmState {
.last()
.filter(|l| document.document_legacy.layer(l).map(|l| l.as_text().is_ok()).unwrap_or(false))
{
if state == TextToolFsmState::Editing {
tool_data.set_editing(false, responses);
}
tool_data.layer_path = clicked_text_layer_path.clone();
responses.push_back(DocumentMessage::StartTransaction.into());
tool_data.set_editing(true, responses);
let replacement_selected_layers = vec![tool_data.layer_path.clone()];
responses.push_back(DocumentMessage::SetSelectedLayers { replacement_selected_layers }.into());
set_edit_layer(clicked_text_layer_path, state, tool_data, responses);
Editing
}
@ -339,6 +345,24 @@ impl Fsm for TextToolFsmState {
new_state
}
(state, EditSelected) => {
let mut selected_layers = document.selected_layers();
if let Some(layer_path) = selected_layers.next() {
// Check that only one layer is selected
if selected_layers.next().is_none() {
if let Ok(layer) = document.document_legacy.layer(layer_path) {
if let LayerDataType::Text(_) = layer.data {
set_edit_layer(layer_path, state, tool_data, responses);
return Editing;
}
}
}
}
state
}
(state, Abort) => {
if state == TextToolFsmState::Editing {
tool_data.set_editing(false, responses);