mirror of
https://github.com/aseprite/aseprite.git
synced 2025-03-30 22:21:12 +00:00
Improve detection of one click when using a stylus
We can interpret a quick mouse down/up events (e.g. less than 250 milliseconds) as a simple click if the mouse doesn't move too much in the middle of both events (e.g. a tiny rectangle of 7x7 pixels). Some discussion about this: https://community.aseprite.org/t/12491/10
This commit is contained in:
parent
87e8b45dc1
commit
f3fd0de3d0
@ -36,6 +36,9 @@
|
||||
#include "app/ui/main_window.h"
|
||||
#include "app/ui/timeline/timeline.h"
|
||||
|
||||
#include <algorithm>
|
||||
#include <cmath>
|
||||
#include <cstdlib>
|
||||
#include <cstring>
|
||||
|
||||
namespace app {
|
||||
@ -104,6 +107,9 @@ void DrawingState::initToolLoop(Editor* editor,
|
||||
|
||||
m_velocity.reset();
|
||||
m_lastPointer = pointer;
|
||||
m_mouseDownPos = msg->position();
|
||||
m_mouseDownTime = base::current_tick();
|
||||
|
||||
m_toolLoopManager->prepareLoop(pointer);
|
||||
m_toolLoopManager->pressButton(pointer);
|
||||
|
||||
@ -193,7 +199,7 @@ bool DrawingState::onMouseUp(Editor* editor, MouseMessage* msg)
|
||||
// one click).
|
||||
if (!m_toolLoop->getInk()->isSelection() ||
|
||||
m_toolLoop->getController()->isOnePoint() ||
|
||||
m_mouseMoveReceived ||
|
||||
!canInterpretMouseMovementAsJustOneClick() ||
|
||||
// In case of double-click (to select tiles) we don't want to
|
||||
// deselect if the mouse is not moved. In this case the tile
|
||||
// will be selected anyway even if the mouse is not moved.
|
||||
@ -253,6 +259,9 @@ bool DrawingState::onMouseMove(Editor* editor, MouseMessage* msg)
|
||||
// (used in the Rectangular Marquee to deselect when we just do a
|
||||
// simple click without moving the mouse).
|
||||
m_mouseMoveReceived = true;
|
||||
gfx::Point delta = (msg->position() - m_mouseDownPos);
|
||||
m_mouseMaxDelta.x = std::max(m_mouseMaxDelta.x, std::abs(delta.x));
|
||||
m_mouseMaxDelta.y = std::max(m_mouseMaxDelta.y, std::abs(delta.y));
|
||||
|
||||
// Use DelayedMouseMove for tools like line, rectangle, etc. (that
|
||||
// use the only the last mouse position) to filter out rapid mouse
|
||||
@ -358,6 +367,18 @@ void DrawingState::handleMouseMovement()
|
||||
m_toolLoopManager->movement(m_lastPointer);
|
||||
}
|
||||
|
||||
bool DrawingState::canInterpretMouseMovementAsJustOneClick()
|
||||
{
|
||||
// If the user clicked (pressed and released the mouse button) in
|
||||
// less than 250 milliseconds in "the same place" (inside a 7 pixels
|
||||
// rectangle actually, to detect stylus shake).
|
||||
return
|
||||
!m_mouseMoveReceived ||
|
||||
(m_mouseMaxDelta.x < 4 &&
|
||||
m_mouseMaxDelta.y < 4 &&
|
||||
(base::current_tick() - m_mouseDownTime < 250));
|
||||
}
|
||||
|
||||
bool DrawingState::canExecuteCommands()
|
||||
{
|
||||
// Returning true here means that the user can trigger commands with
|
||||
|
@ -13,6 +13,7 @@
|
||||
#include "app/tools/velocity.h"
|
||||
#include "app/ui/editor/delayed_mouse_move.h"
|
||||
#include "app/ui/editor/standby_state.h"
|
||||
#include "base/time.h"
|
||||
#include "obs/connection.h"
|
||||
#include <memory>
|
||||
|
||||
@ -58,6 +59,7 @@ namespace app {
|
||||
|
||||
private:
|
||||
void handleMouseMovement();
|
||||
bool canInterpretMouseMovementAsJustOneClick();
|
||||
bool canExecuteCommands();
|
||||
void onBeforeCommandExecution(CommandExecutionEvent& ev);
|
||||
void destroyLoopIfCanceled(Editor* editor);
|
||||
@ -77,10 +79,13 @@ namespace app {
|
||||
// Tool-loop manager
|
||||
std::unique_ptr<tools::ToolLoopManager> m_toolLoopManager;
|
||||
|
||||
// True if at least we've received a onMouseMove(). It's used to
|
||||
// cancel selection tool (deselect) when the user click (press and
|
||||
// release the mouse button in the same location).
|
||||
// These fields are used to detect a selection tool cancelation
|
||||
// (deselect command) when the user just click (press and release
|
||||
// the mouse button in the "same location" approximately).
|
||||
bool m_mouseMoveReceived;
|
||||
gfx::Point m_mouseMaxDelta;
|
||||
gfx::Point m_mouseDownPos;
|
||||
base::tick_t m_mouseDownTime;
|
||||
|
||||
// Stores the last mouse pointer, used to re-use the latest mouse
|
||||
// button when onScrollChange() event is received.
|
||||
|
Loading…
x
Reference in New Issue
Block a user