mirror of
https://github.com/GraphiteEditor/Graphite.git
synced 2026-10-04 05:58:12 +08:00
Fix text layer getting deselected after clicking out of Text tool interactive editing (#2144)
* properties panel remains active when user edits text layer * Keep text layers selected after editing * Update editor/src/messages/portfolio/document/document_message_handler.rs * Delete Empty Text Layer on Escape or Right Click * Fix: delete empty text layer on right click --------- Co-authored-by: Keavon Chambers <keavon@keavon.com>
This commit is contained in:
co-authored by
Keavon Chambers
parent
39a7b76ade
commit
f225756655
@@ -56,7 +56,7 @@ pub enum TextToolMessage {
|
|||||||
CommitText,
|
CommitText,
|
||||||
EditSelected,
|
EditSelected,
|
||||||
Interact,
|
Interact,
|
||||||
TextChange { new_text: String },
|
TextChange { new_text: String, is_right_click: bool },
|
||||||
UpdateBounds { new_text: String },
|
UpdateBounds { new_text: String },
|
||||||
UpdateOptions(TextOptionsUpdate),
|
UpdateOptions(TextOptionsUpdate),
|
||||||
}
|
}
|
||||||
@@ -241,6 +241,19 @@ struct TextToolData {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl TextToolData {
|
impl TextToolData {
|
||||||
|
fn delete_empty_layer(&mut self, font_cache: &FontCache, responses: &mut VecDeque<Message>) -> TextToolFsmState {
|
||||||
|
// Remove the editable textbox UI first
|
||||||
|
self.set_editing(false, font_cache, responses);
|
||||||
|
|
||||||
|
// Delete the empty text layer and update the graph
|
||||||
|
responses.add(NodeGraphMessage::DeleteNodes {
|
||||||
|
node_ids: vec![self.layer.to_node()],
|
||||||
|
delete_children: true,
|
||||||
|
});
|
||||||
|
responses.add(NodeGraphMessage::RunDocumentGraph);
|
||||||
|
|
||||||
|
TextToolFsmState::Ready
|
||||||
|
}
|
||||||
/// Set the editing state of the currently modifying layer
|
/// Set the editing state of the currently modifying layer
|
||||||
fn set_editing(&self, editable: bool, font_cache: &FontCache, responses: &mut VecDeque<Message>) {
|
fn set_editing(&self, editable: bool, font_cache: &FontCache, responses: &mut VecDeque<Message>) {
|
||||||
if let Some(editing_text) = self.editing_text.as_ref().filter(|_| editable) {
|
if let Some(editing_text) = self.editing_text.as_ref().filter(|_| editable) {
|
||||||
@@ -253,9 +266,13 @@ impl TextToolData {
|
|||||||
transform: editing_text.transform.to_cols_array(),
|
transform: editing_text.transform.to_cols_array(),
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
|
// Check if DisplayRemoveEditableTextbox is already in the responses queue
|
||||||
|
let has_remove_textbox = responses.iter().any(|msg| matches!(msg, Message::Frontend(FrontendMessage::DisplayRemoveEditableTextbox)));
|
||||||
responses.add(FrontendMessage::DisplayRemoveEditableTextbox);
|
responses.add(FrontendMessage::DisplayRemoveEditableTextbox);
|
||||||
// Clear all selected nodes when no longer editing
|
|
||||||
responses.add(NodeGraphMessage::SelectedNodesSet { nodes: Vec::new() });
|
if has_remove_textbox {
|
||||||
|
responses.add(NodeGraphMessage::SelectedNodesSet { nodes: Vec::new() });
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -474,20 +491,34 @@ impl Fsm for TextToolFsmState {
|
|||||||
TextToolFsmState::Ready
|
TextToolFsmState::Ready
|
||||||
}
|
}
|
||||||
(TextToolFsmState::Editing, TextToolMessage::CommitText) => {
|
(TextToolFsmState::Editing, TextToolMessage::CommitText) => {
|
||||||
responses.add(FrontendMessage::TriggerTextCommit);
|
if tool_data.new_text.is_empty() {
|
||||||
|
return tool_data.delete_empty_layer(font_cache, responses);
|
||||||
|
}
|
||||||
|
|
||||||
|
responses.add(FrontendMessage::TriggerTextCommit);
|
||||||
TextToolFsmState::Editing
|
TextToolFsmState::Editing
|
||||||
}
|
}
|
||||||
(TextToolFsmState::Editing, TextToolMessage::TextChange { new_text }) => {
|
(TextToolFsmState::Editing, TextToolMessage::TextChange { new_text, is_right_click }) => {
|
||||||
tool_data.set_editing(false, font_cache, responses);
|
tool_data.new_text = new_text;
|
||||||
|
|
||||||
responses.add(NodeGraphMessage::SetInput {
|
if !is_right_click {
|
||||||
input_connector: InputConnector::node(graph_modification_utils::get_text_id(tool_data.layer, &document.network_interface).unwrap(), 1),
|
tool_data.set_editing(false, font_cache, responses);
|
||||||
input: NodeInput::value(TaggedValue::String(new_text), false),
|
|
||||||
});
|
|
||||||
responses.add(NodeGraphMessage::RunDocumentGraph);
|
|
||||||
|
|
||||||
TextToolFsmState::Ready
|
responses.add(NodeGraphMessage::SetInput {
|
||||||
|
input_connector: InputConnector::node(graph_modification_utils::get_text_id(tool_data.layer, &document.network_interface).unwrap(), 1),
|
||||||
|
input: NodeInput::value(TaggedValue::String(tool_data.new_text.clone()), false),
|
||||||
|
});
|
||||||
|
responses.add(NodeGraphMessage::RunDocumentGraph);
|
||||||
|
|
||||||
|
TextToolFsmState::Ready
|
||||||
|
} else {
|
||||||
|
if tool_data.new_text.is_empty() {
|
||||||
|
return tool_data.delete_empty_layer(font_cache, responses);
|
||||||
|
}
|
||||||
|
|
||||||
|
responses.add(FrontendMessage::TriggerTextCommit);
|
||||||
|
TextToolFsmState::Editing
|
||||||
|
}
|
||||||
}
|
}
|
||||||
(TextToolFsmState::Editing, TextToolMessage::UpdateBounds { new_text }) => {
|
(TextToolFsmState::Editing, TextToolMessage::UpdateBounds { new_text }) => {
|
||||||
tool_data.new_text = new_text;
|
tool_data.new_text = new_text;
|
||||||
|
|||||||
@@ -300,7 +300,7 @@
|
|||||||
export function triggerTextCommit() {
|
export function triggerTextCommit() {
|
||||||
if (!textInput) return;
|
if (!textInput) return;
|
||||||
const textCleaned = textInputCleanup(textInput.innerText);
|
const textCleaned = textInputCleanup(textInput.innerText);
|
||||||
editor.handle.onChangeText(textCleaned);
|
editor.handle.onChangeText(textCleaned, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function displayEditableTextbox(displayEditableTextbox: DisplayEditableTextbox) {
|
export async function displayEditableTextbox(displayEditableTextbox: DisplayEditableTextbox) {
|
||||||
|
|||||||
@@ -172,7 +172,8 @@ export function createInputManager(editor: Editor, dialog: DialogState, portfoli
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (!inTextInput && !inContextMenu) {
|
if (!inTextInput && !inContextMenu) {
|
||||||
if (textToolInteractiveInputElement) editor.handle.onChangeText(textInputCleanup(textToolInteractiveInputElement.innerText));
|
const isRightClick = e.button === 2;
|
||||||
|
if (textToolInteractiveInputElement) editor.handle.onChangeText(textInputCleanup(textToolInteractiveInputElement.innerText), isRightClick);
|
||||||
else viewportPointerInteractionOngoing = isTargetingCanvas instanceof Element;
|
else viewportPointerInteractionOngoing = isTargetingCanvas instanceof Element;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -433,8 +433,8 @@ impl EditorHandle {
|
|||||||
|
|
||||||
/// A text box was committed
|
/// A text box was committed
|
||||||
#[wasm_bindgen(js_name = onChangeText)]
|
#[wasm_bindgen(js_name = onChangeText)]
|
||||||
pub fn on_change_text(&self, new_text: String) -> Result<(), JsValue> {
|
pub fn on_change_text(&self, new_text: String, is_right_click: bool) -> Result<(), JsValue> {
|
||||||
let message = TextToolMessage::TextChange { new_text };
|
let message = TextToolMessage::TextChange { new_text, is_right_click };
|
||||||
self.dispatch(message);
|
self.dispatch(message);
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
|
|||||||
Reference in New Issue
Block a user