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 {
ArtboardToolFsmState::Ready { .. } => HintData(vec![
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 {
BrushToolFsmState::Ready => HintData(vec![
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 {
EllipseToolFsmState::Ready => HintData(vec![HintGroup(vec![
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 {
EyedropperToolFsmState::Ready => HintData(vec![HintGroup(vec![
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 {
FillToolFsmState::Ready => HintData(vec![HintGroup(vec![
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 {
FreehandToolFsmState::Ready => HintData(vec![HintGroup(vec![
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 {
GradientToolFsmState::Ready => HintData(vec![HintGroup(vec![
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 {
ImaginateToolFsmState::Ready => HintData(vec![HintGroup(vec![
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 {
LineToolFsmState::Ready => HintData(vec![HintGroup(vec![
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 {
NavigateToolFsmState::Ready | NavigateToolFsmState::ZoomOrClickZooming => HintData(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 {
PathToolFsmState::Ready => HintData(vec![
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 {
PenToolFsmState::Ready | PenToolFsmState::GRSHandle => HintData(vec![HintGroup(vec![
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 {
PolygonToolFsmState::Ready => HintData(vec![HintGroup(vec![
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 {
RectangleToolFsmState::Ready => HintData(vec![HintGroup(vec![
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);
}
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);
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
match message {
ToolMessage::UpdateHints => {
self.update_hints(responses);
self.update_hints(responses, tool_data);
true
}
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 {
SelectToolFsmState::Ready { selection } => {
let hint_data = HintData(vec![
@ -1281,7 +1285,7 @@ impl Fsm for SelectToolFsmState {
]);
responses.add(FrontendMessage::UpdateInputHints { hint_data });
}
SelectToolFsmState::Dragging => {
SelectToolFsmState::Dragging if tool_data.has_dragged => {
let hint_data = HintData(vec![
HintGroup(vec![HintInfo::mouse(MouseMotion::Rmb, ""), HintInfo::keys([Key::Escape], "Cancel").prepend_slash()]),
HintGroup(vec![HintInfo::keys([Key::Shift], "Constrain to Axis")]),
@ -1292,7 +1296,7 @@ impl Fsm for SelectToolFsmState {
]);
responses.add(FrontendMessage::UpdateInputHints { hint_data });
}
SelectToolFsmState::Drawing { .. } => {
SelectToolFsmState::Drawing { .. } if tool_data.drag_start != tool_data.drag_current => {
let hint_data = HintData(vec![
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")]),

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 {
SplineToolFsmState::Ready => HintData(vec![HintGroup(vec![
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 {
TextToolFsmState::Ready => HintData(vec![
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;
/// 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.
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.
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
match message {
ToolMessage::UpdateHints => {
self.update_hints(responses);
self.update_hints(responses, tool_data);
true
}
ToolMessage::UpdateCursor => {
@ -100,7 +100,7 @@ pub trait Fsm {
// Update state
if *self != new_state {
*self = new_state;
self.update_hints(responses);
self.update_hints(responses, tool_data);
if update_cursor_on_transition {
self.update_cursor(responses);
}