1 // Aseprite
2 // Copyright (C) 2001-2018  David Capello
3 //
4 // This program is distributed under the terms of
5 // the End-User License Agreement for Aseprite.
6 
7 #ifndef APP_UI_EDITOR_SELECT_BOX_STATE_H_INCLUDED
8 #define APP_UI_EDITOR_SELECT_BOX_STATE_H_INCLUDED
9 #pragma once
10 
11 #include "app/ui/editor/editor_decorator.h"
12 #include "app/ui/editor/ruler.h"
13 #include "app/ui/editor/standby_state.h"
14 #include "ui/cursor_type.h"
15 #include "ui/mouse_buttons.h"
16 
17 #include <string>
18 #include <vector>
19 
20 namespace app {
21 
22   class SelectBoxDelegate {
23   public:
~SelectBoxDelegate()24     virtual ~SelectBoxDelegate() { }
25 
26     // Called each time the selected box is modified (e.g. rulers are
27     // moved).
onChangeRectangle(const gfx::Rect & rect)28     virtual void onChangeRectangle(const gfx::Rect& rect) { }
29 
30     // Called only in QUICKBOX mode, when the user released the mouse
31     // button.
onQuickboxEnd(Editor * editor,const gfx::Rect & rect,ui::MouseButtons buttons)32     virtual void onQuickboxEnd(Editor* editor, const gfx::Rect& rect, ui::MouseButtons buttons) { }
onQuickboxCancel(Editor * editor)33     virtual void onQuickboxCancel(Editor* editor) { }
34 
35     // Help text to be shown in the ContextBar
onGetContextBarHelp()36     virtual std::string onGetContextBarHelp() { return ""; }
37   };
38 
39   class SelectBoxState : public StandbyState
40                        , public EditorDecorator {
41     enum { H1, H2, V1, V2 };
42 
43   public:
44     enum class Flags {
45       // Draw rulers at each edge of the current box
46       Rulers = 1,
47 
48       // The outside of the current box must be darker (used in "Canvas Size" command)
49       DarkOutside = 2,
50 
51       // Show a horizontal array of boxes starting from the current box
52       HGrid = 4,
53 
54       // Show a vertical array of boxes starting from the current box
55       VGrid = 8,
56 
57       // Show a grid starting from the current box
58       Grid = (HGrid | VGrid),
59 
60       // Select the box as in selection tool, drawing a boxu
61       QuickBox = 16,
62     };
63 
64     SelectBoxState(SelectBoxDelegate* delegate,
65                    const gfx::Rect& rc,
66                    Flags flags);
67     ~SelectBoxState();
68 
69     void setFlags(Flags flags);
70 
71     // Returns the bounding box arranged by the rulers.
72     gfx::Rect getBoxBounds() const;
73     void setBoxBounds(const gfx::Rect& rc);
74 
75     // EditorState overrides
76     virtual void onEnterState(Editor* editor) override;
77     virtual void onBeforePopState(Editor* editor) override;
78     virtual bool onMouseDown(Editor* editor, ui::MouseMessage* msg) override;
79     virtual bool onMouseUp(Editor* editor, ui::MouseMessage* msg) override;
80     virtual bool onMouseMove(Editor* editor, ui::MouseMessage* msg) override;
81     virtual bool onSetCursor(Editor* editor, const gfx::Point& mouseScreenPos) override;
82     virtual bool acceptQuickTool(tools::Tool* tool) override;
83     virtual bool requireBrushPreview() override;
84     virtual tools::Ink* getStateInk() override;
85 
86     // EditorDecorator overrides
87     virtual void postRenderDecorator(EditorPostRender* render) override;
88     virtual void getInvalidDecoratoredRegion(Editor* editor, gfx::Region& region) override;
89 
90   private:
91     typedef std::vector<Ruler> Rulers;
92 
93     void updateContextBar();
94 
95     // This returns a ui align value (e.g. LEFT for the ruler)
96     int hitTestRulers(Editor* editor,
97                       const gfx::Point& mousePos,
98                       const bool updateMovingRulers);
99 
100     // Returns true if the position screen position (x, y) is touching
101     // the given ruler.
102     bool hitTestRuler(Editor* editor, const Ruler& ruler,
103                       const gfx::Point& mousePos);
104 
105     ui::CursorType cursorFromAlign(const int align) const;
106 
107     bool hasFlag(Flags flag) const;
108 
109     SelectBoxDelegate* m_delegate;
110     Rulers m_rulers;
111     Rulers m_startRulers;
112     int m_rulersDragAlign;      // Used to calculate the correct mouse cursor
113     std::vector<int> m_movingRulers;
114     bool m_selectingBox;
115     ui::MouseButtons m_selectingButtons;
116     gfx::Point m_startingPos;
117     Flags m_flags;
118   };
119 
120 } // namespace app
121 
122 #endif  // APP_UI_EDITOR_SELECT_BOX_STATE_H_INCLUDED
123