1 | // Aseprite |
2 | // Copyright (C) 2022 Igara Studio S.A. |
3 | // |
4 | // This program is distributed under the terms of |
5 | // the End-User License Agreement for Aseprite. |
6 | |
7 | #ifndef APP_UI_EDITOR_DELAYED_MOUSE_MOVE_STATE_H_INCLUDED |
8 | #define APP_UI_EDITOR_DELAYED_MOUSE_MOVE_STATE_H_INCLUDED |
9 | #pragma once |
10 | |
11 | #include "app/ui/editor/standby_state.h" |
12 | #include "ui/timer.h" |
13 | |
14 | #include <limits> |
15 | |
16 | namespace ui { |
17 | class MouseMessage; |
18 | } |
19 | |
20 | namespace app { |
21 | class Editor; |
22 | |
23 | class DelayedMouseMoveDelegate { |
24 | public: |
25 | virtual ~DelayedMouseMoveDelegate() { } |
26 | virtual void onCommitMouseMove(Editor* editor, |
27 | const gfx::PointF& spritePos) = 0; |
28 | }; |
29 | |
30 | // Helper class to group several onMouseMove() calls into one |
31 | // onCommitMouseMove(). Useful in Linux as mouse movement messages |
32 | // are queued a high speed (so we can group several mouse messages |
33 | // for tools that use only the last position and have a heavy |
34 | // calculation per mouse position, e.g. pixel transformations, |
35 | // drawing with Line, Rectangle, etc.). |
36 | class DelayedMouseMove { |
37 | public: |
38 | // The "interval" is given in milliseconds, and can be zero if we |
39 | // want to disable the delay between onMouseMove() -> onCommitMouseMove() |
40 | DelayedMouseMove(DelayedMouseMoveDelegate* delegate, |
41 | Editor* editor, |
42 | const int interval); |
43 | |
44 | // In case the event wasn't started with onMouseDown() we can |
45 | // initialize the sprite position directly (e.g. starting a line |
46 | // from last painted point with Shift+click with Pencil tool). |
47 | void initSpritePos(const gfx::PointF& pos); |
48 | |
49 | void onMouseDown(const ui::MouseMessage* msg); |
50 | bool onMouseMove(const ui::MouseMessage* msg); |
51 | void onMouseUp(const ui::MouseMessage* msg); |
52 | |
53 | // Forces stopping the timer so we don't receive a Tick event in |
54 | // case that we've just removed/delete some structure that is |
55 | // needed in onCommitMouseMove(). |
56 | void stopTimer(); |
57 | |
58 | const gfx::PointF& spritePos() const; |
59 | |
60 | private: |
61 | void commitMouseMove(); |
62 | bool updateSpritePos(const ui::MouseMessage* msg); |
63 | |
64 | DelayedMouseMoveDelegate* m_delegate; |
65 | Editor* m_editor; |
66 | ui::Timer m_timer; |
67 | |
68 | // Position of the mouse in the canvas to avoid redrawing when the |
69 | // mouse position changes (only we redraw when the canvas position |
70 | // changes). |
71 | gfx::PointF m_spritePos; |
72 | }; |
73 | |
74 | } // namespace app |
75 | |
76 | #endif // APP_UI_EDITOR_DELAYED_MOUSE_MOVE_STATE_H_INCLUDED |
77 | |