Make the Select tool avoid updating hints just when clicking but not dragging (#2248)

* make Fsm update_hints function borrow tool_data and update individual tool implementations accordingly, use tool_data in select_tool update_hints function as well as add a UpdateHints response when the pointer moves after the change from  DragStart to Dragging state

* Also add for selection box drawing

* Code review

---------

Co-authored-by: Keavon Chambers <keavon@keavon.com>
This commit is contained in:
Utsav Singh 2025-02-05 10:15:57 +05:30 committed by GitHub
parent 0cda8e2bb4
commit 0f03762cff
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
18 changed files with 29 additions and 25 deletions

View File

@ -559,7 +559,7 @@ impl Fsm for ArtboardToolFsmState {
} }
} }
fn update_hints(&self, responses: &mut VecDeque<Message>) { fn update_hints(&self, responses: &mut VecDeque<Message>, _tool_data: &Self::ToolData) {
let hint_data = match self { let hint_data = match self {
ArtboardToolFsmState::Ready { .. } => HintData(vec![ ArtboardToolFsmState::Ready { .. } => HintData(vec![
HintGroup(vec![HintInfo::mouse(MouseMotion::LmbDrag, "Draw Artboard")]), HintGroup(vec![HintInfo::mouse(MouseMotion::LmbDrag, "Draw Artboard")]),

View File

@ -425,7 +425,7 @@ impl Fsm for BrushToolFsmState {
} }
} }
fn update_hints(&self, responses: &mut VecDeque<Message>) { fn update_hints(&self, responses: &mut VecDeque<Message>, _tool_data: &Self::ToolData) {
let hint_data = match self { let hint_data = match self {
BrushToolFsmState::Ready => HintData(vec![ BrushToolFsmState::Ready => HintData(vec![
HintGroup(vec![HintInfo::mouse(MouseMotion::LmbDrag, "Draw")]), HintGroup(vec![HintInfo::mouse(MouseMotion::LmbDrag, "Draw")]),

View File

@ -282,7 +282,7 @@ impl Fsm for EllipseToolFsmState {
} }
} }
fn update_hints(&self, responses: &mut VecDeque<Message>) { fn update_hints(&self, responses: &mut VecDeque<Message>, _tool_data: &Self::ToolData) {
let hint_data = match self { let hint_data = match self {
EllipseToolFsmState::Ready => HintData(vec![HintGroup(vec![ EllipseToolFsmState::Ready => HintData(vec![HintGroup(vec![
HintInfo::mouse(MouseMotion::LmbDrag, "Draw Ellipse"), HintInfo::mouse(MouseMotion::LmbDrag, "Draw Ellipse"),

View File

@ -123,7 +123,7 @@ impl Fsm for EyedropperToolFsmState {
} }
} }
fn update_hints(&self, responses: &mut VecDeque<Message>) { fn update_hints(&self, responses: &mut VecDeque<Message>, _tool_data: &Self::ToolData) {
let hint_data = match self { let hint_data = match self {
EyedropperToolFsmState::Ready => HintData(vec![HintGroup(vec![ EyedropperToolFsmState::Ready => HintData(vec![HintGroup(vec![
HintInfo::mouse(MouseMotion::Lmb, "Sample to Primary"), HintInfo::mouse(MouseMotion::Lmb, "Sample to Primary"),

View File

@ -108,7 +108,7 @@ impl Fsm for FillToolFsmState {
} }
} }
fn update_hints(&self, responses: &mut VecDeque<Message>) { fn update_hints(&self, responses: &mut VecDeque<Message>, _tool_data: &Self::ToolData) {
let hint_data = match self { let hint_data = match self {
FillToolFsmState::Ready => HintData(vec![HintGroup(vec![ FillToolFsmState::Ready => HintData(vec![HintGroup(vec![
HintInfo::mouse(MouseMotion::Lmb, "Fill with Primary"), HintInfo::mouse(MouseMotion::Lmb, "Fill with Primary"),

View File

@ -292,7 +292,7 @@ impl Fsm for FreehandToolFsmState {
} }
} }
fn update_hints(&self, responses: &mut VecDeque<Message>) { fn update_hints(&self, responses: &mut VecDeque<Message>, _tool_data: &Self::ToolData) {
let hint_data = match self { let hint_data = match self {
FreehandToolFsmState::Ready => HintData(vec![HintGroup(vec![ FreehandToolFsmState::Ready => HintData(vec![HintGroup(vec![
HintInfo::mouse(MouseMotion::LmbDrag, "Draw Polyline"), HintInfo::mouse(MouseMotion::LmbDrag, "Draw Polyline"),

View File

@ -492,7 +492,7 @@ impl Fsm for GradientToolFsmState {
} }
} }
fn update_hints(&self, responses: &mut VecDeque<Message>) { fn update_hints(&self, responses: &mut VecDeque<Message>, _tool_data: &Self::ToolData) {
let hint_data = match self { let hint_data = match self {
GradientToolFsmState::Ready => HintData(vec![HintGroup(vec![ GradientToolFsmState::Ready => HintData(vec![HintGroup(vec![
HintInfo::mouse(MouseMotion::LmbDrag, "Draw Gradient"), HintInfo::mouse(MouseMotion::LmbDrag, "Draw Gradient"),

View File

@ -165,7 +165,7 @@ impl Fsm for ImaginateToolFsmState {
} }
} }
fn update_hints(&self, responses: &mut VecDeque<Message>) { fn update_hints(&self, responses: &mut VecDeque<Message>, _tool_data: &Self::ToolData) {
let hint_data = match self { let hint_data = match self {
ImaginateToolFsmState::Ready => HintData(vec![HintGroup(vec![ ImaginateToolFsmState::Ready => HintData(vec![HintGroup(vec![
HintInfo::mouse(MouseMotion::LmbDrag, "Draw Repaint Frame"), HintInfo::mouse(MouseMotion::LmbDrag, "Draw Repaint Frame"),

View File

@ -261,7 +261,7 @@ impl Fsm for LineToolFsmState {
} }
} }
fn update_hints(&self, responses: &mut VecDeque<Message>) { fn update_hints(&self, responses: &mut VecDeque<Message>, _tool_data: &Self::ToolData) {
let hint_data = match self { let hint_data = match self {
LineToolFsmState::Ready => HintData(vec![HintGroup(vec![ LineToolFsmState::Ready => HintData(vec![HintGroup(vec![
HintInfo::mouse(MouseMotion::LmbDrag, "Draw Line"), HintInfo::mouse(MouseMotion::LmbDrag, "Draw Line"),

View File

@ -144,7 +144,7 @@ impl Fsm for NavigateToolFsmState {
} }
} }
fn update_hints(&self, responses: &mut VecDeque<Message>) { fn update_hints(&self, responses: &mut VecDeque<Message>, _tool_data: &Self::ToolData) {
let hint_data = match self { let hint_data = match self {
NavigateToolFsmState::Ready | NavigateToolFsmState::ZoomOrClickZooming => HintData(vec![ NavigateToolFsmState::Ready | NavigateToolFsmState::ZoomOrClickZooming => HintData(vec![
HintGroup(vec![ HintGroup(vec![

View File

@ -1158,7 +1158,7 @@ impl Fsm for PathToolFsmState {
} }
} }
fn update_hints(&self, responses: &mut VecDeque<Message>) { fn update_hints(&self, responses: &mut VecDeque<Message>, _tool_data: &Self::ToolData) {
let hint_data = match self { let hint_data = match self {
PathToolFsmState::Ready => HintData(vec![ PathToolFsmState::Ready => HintData(vec![
HintGroup(vec![HintInfo::mouse(MouseMotion::Lmb, "Select Point"), HintInfo::keys([Key::Shift], "Extend Selection").prepend_plus()]), HintGroup(vec![HintInfo::mouse(MouseMotion::Lmb, "Select Point"), HintInfo::keys([Key::Shift], "Extend Selection").prepend_plus()]),

View File

@ -1126,7 +1126,7 @@ impl Fsm for PenToolFsmState {
} }
} }
fn update_hints(&self, responses: &mut VecDeque<Message>) { fn update_hints(&self, responses: &mut VecDeque<Message>, _tool_data: &Self::ToolData) {
let hint_data = match self { let hint_data = match self {
PenToolFsmState::Ready | PenToolFsmState::GRSHandle => HintData(vec![HintGroup(vec![ PenToolFsmState::Ready | PenToolFsmState::GRSHandle => HintData(vec![HintGroup(vec![
HintInfo::mouse(MouseMotion::Lmb, "Draw Path"), HintInfo::mouse(MouseMotion::Lmb, "Draw Path"),

View File

@ -345,7 +345,7 @@ impl Fsm for PolygonToolFsmState {
} }
} }
fn update_hints(&self, responses: &mut VecDeque<Message>) { fn update_hints(&self, responses: &mut VecDeque<Message>, _tool_data: &Self::ToolData) {
let hint_data = match self { let hint_data = match self {
PolygonToolFsmState::Ready => HintData(vec![HintGroup(vec![ PolygonToolFsmState::Ready => HintData(vec![HintGroup(vec![
HintInfo::mouse(MouseMotion::LmbDrag, "Draw Polygon"), HintInfo::mouse(MouseMotion::LmbDrag, "Draw Polygon"),

View File

@ -288,7 +288,7 @@ impl Fsm for RectangleToolFsmState {
} }
} }
fn update_hints(&self, responses: &mut VecDeque<Message>) { fn update_hints(&self, responses: &mut VecDeque<Message>, _tool_data: &Self::ToolData) {
let hint_data = match self { let hint_data = match self {
RectangleToolFsmState::Ready => HintData(vec![HintGroup(vec![ RectangleToolFsmState::Ready => HintData(vec![HintGroup(vec![
HintInfo::mouse(MouseMotion::LmbDrag, "Draw Rectangle"), HintInfo::mouse(MouseMotion::LmbDrag, "Draw Rectangle"),

View File

@ -227,6 +227,10 @@ impl<'a> MessageHandler<ToolMessage, &mut ToolActionHandlerData<'a>> for SelectT
responses.add(ToolMessage::UpdateHints); responses.add(ToolMessage::UpdateHints);
} }
if matches!(message, ToolMessage::Select(SelectToolMessage::PointerMove(_))) && !self.tool_data.has_dragged {
responses.add(ToolMessage::UpdateHints);
}
self.fsm_state.process_event(message, &mut self.tool_data, tool_data, &(), responses, false); self.fsm_state.process_event(message, &mut self.tool_data, tool_data, &(), responses, false);
if self.tool_data.pivot.should_refresh_pivot_position() || self.tool_data.selected_layers_changed { if self.tool_data.pivot.should_refresh_pivot_position() || self.tool_data.selected_layers_changed {
@ -1234,11 +1238,11 @@ impl Fsm for SelectToolFsmState {
} }
} }
fn standard_tool_messages(&self, message: &ToolMessage, responses: &mut VecDeque<Message>, _tool_data: &mut Self::ToolData) -> bool { fn standard_tool_messages(&self, message: &ToolMessage, responses: &mut VecDeque<Message>, tool_data: &mut Self::ToolData) -> bool {
// Check for standard hits or cursor events // Check for standard hits or cursor events
match message { match message {
ToolMessage::UpdateHints => { ToolMessage::UpdateHints => {
self.update_hints(responses); self.update_hints(responses, tool_data);
true true
} }
ToolMessage::UpdateCursor => { ToolMessage::UpdateCursor => {
@ -1249,7 +1253,7 @@ impl Fsm for SelectToolFsmState {
} }
} }
fn update_hints(&self, responses: &mut VecDeque<Message>) { fn update_hints(&self, responses: &mut VecDeque<Message>, tool_data: &Self::ToolData) {
match self { match self {
SelectToolFsmState::Ready { selection } => { SelectToolFsmState::Ready { selection } => {
let hint_data = HintData(vec![ let hint_data = HintData(vec![
@ -1281,7 +1285,7 @@ impl Fsm for SelectToolFsmState {
]); ]);
responses.add(FrontendMessage::UpdateInputHints { hint_data }); responses.add(FrontendMessage::UpdateInputHints { hint_data });
} }
SelectToolFsmState::Dragging => { SelectToolFsmState::Dragging if tool_data.has_dragged => {
let hint_data = HintData(vec![ let hint_data = HintData(vec![
HintGroup(vec![HintInfo::mouse(MouseMotion::Rmb, ""), HintInfo::keys([Key::Escape], "Cancel").prepend_slash()]), HintGroup(vec![HintInfo::mouse(MouseMotion::Rmb, ""), HintInfo::keys([Key::Escape], "Cancel").prepend_slash()]),
HintGroup(vec![HintInfo::keys([Key::Shift], "Constrain to Axis")]), HintGroup(vec![HintInfo::keys([Key::Shift], "Constrain to Axis")]),
@ -1292,7 +1296,7 @@ impl Fsm for SelectToolFsmState {
]); ]);
responses.add(FrontendMessage::UpdateInputHints { hint_data }); responses.add(FrontendMessage::UpdateInputHints { hint_data });
} }
SelectToolFsmState::Drawing { .. } => { SelectToolFsmState::Drawing { .. } if tool_data.drag_start != tool_data.drag_current => {
let hint_data = HintData(vec![ let hint_data = HintData(vec![
HintGroup(vec![HintInfo::mouse(MouseMotion::Rmb, ""), HintInfo::keys([Key::Escape], "Cancel").prepend_slash()]), HintGroup(vec![HintInfo::mouse(MouseMotion::Rmb, ""), HintInfo::keys([Key::Escape], "Cancel").prepend_slash()]),
HintGroup(vec![HintInfo::keys([Key::Shift], "Extend"), HintInfo::keys([Key::Alt], "Subtract")]), HintGroup(vec![HintInfo::keys([Key::Shift], "Extend"), HintInfo::keys([Key::Alt], "Subtract")]),

View File

@ -381,7 +381,7 @@ impl Fsm for SplineToolFsmState {
} }
} }
fn update_hints(&self, responses: &mut VecDeque<Message>) { fn update_hints(&self, responses: &mut VecDeque<Message>, _tool_data: &Self::ToolData) {
let hint_data = match self { let hint_data = match self {
SplineToolFsmState::Ready => HintData(vec![HintGroup(vec![ SplineToolFsmState::Ready => HintData(vec![HintGroup(vec![
HintInfo::mouse(MouseMotion::Lmb, "Draw Spline"), HintInfo::mouse(MouseMotion::Lmb, "Draw Spline"),

View File

@ -615,7 +615,7 @@ impl Fsm for TextToolFsmState {
} }
} }
fn update_hints(&self, responses: &mut VecDeque<Message>) { fn update_hints(&self, responses: &mut VecDeque<Message>, _tool_data: &Self::ToolData) {
let hint_data = match self { let hint_data = match self {
TextToolFsmState::Ready => HintData(vec![ TextToolFsmState::Ready => HintData(vec![
HintGroup(vec![HintInfo::mouse(MouseMotion::Lmb, "Place Text")]), HintGroup(vec![HintInfo::mouse(MouseMotion::Lmb, "Place Text")]),

View File

@ -56,16 +56,16 @@ pub trait Fsm {
fn transition(self, message: ToolMessage, tool_data: &mut Self::ToolData, transition_data: &mut ToolActionHandlerData, options: &Self::ToolOptions, responses: &mut VecDeque<Message>) -> Self; fn transition(self, message: ToolMessage, tool_data: &mut Self::ToolData, transition_data: &mut ToolActionHandlerData, options: &Self::ToolOptions, responses: &mut VecDeque<Message>) -> Self;
/// Implementing this trait function lets a specific tool provide a list of hints (user input actions presently available) to draw in the footer bar. /// Implementing this trait function lets a specific tool provide a list of hints (user input actions presently available) to draw in the footer bar.
fn update_hints(&self, responses: &mut VecDeque<Message>); fn update_hints(&self, responses: &mut VecDeque<Message>, tool_data: &Self::ToolData);
/// Implementing this trait function lets a specific tool set the current mouse cursor icon. /// Implementing this trait function lets a specific tool set the current mouse cursor icon.
fn update_cursor(&self, responses: &mut VecDeque<Message>); fn update_cursor(&self, responses: &mut VecDeque<Message>);
/// If this message is a standard tool message, process it and return true. Standard tool messages are those which are common across every tool. /// If this message is a standard tool message, process it and return true. Standard tool messages are those which are common across every tool.
fn standard_tool_messages(&self, message: &ToolMessage, responses: &mut VecDeque<Message>, _tool_data: &mut Self::ToolData) -> bool { fn standard_tool_messages(&self, message: &ToolMessage, responses: &mut VecDeque<Message>, tool_data: &mut Self::ToolData) -> bool {
// Check for standard hits or cursor events // Check for standard hits or cursor events
match message { match message {
ToolMessage::UpdateHints => { ToolMessage::UpdateHints => {
self.update_hints(responses); self.update_hints(responses, tool_data);
true true
} }
ToolMessage::UpdateCursor => { ToolMessage::UpdateCursor => {
@ -100,7 +100,7 @@ pub trait Fsm {
// Update state // Update state
if *self != new_state { if *self != new_state {
*self = new_state; *self = new_state;
self.update_hints(responses); self.update_hints(responses, tool_data);
if update_cursor_on_transition { if update_cursor_on_transition {
self.update_cursor(responses); self.update_cursor(responses);
} }