1 /*
2  * PROJECT:    PAINT for ReactOS
3  * LICENSE:    LGPL-2.0-or-later (https://spdx.org/licenses/LGPL-2.0-or-later)
4  * PURPOSE:    Keep track of tool parameters, notify listeners
5  * COPYRIGHT:  Copyright 2015 Benedikt Freisen <b.freisen@gmx.net>
6  */
7 
8 #pragma once
9 
10 enum TOOLTYPE
11 {
12     TOOL_FREESEL  =  1,
13     TOOL_RECTSEL  =  2,
14     TOOL_RUBBER   =  3,
15     TOOL_FILL     =  4,
16     TOOL_COLOR    =  5,
17     TOOL_ZOOM     =  6,
18     TOOL_PEN      =  7,
19     TOOL_BRUSH    =  8,
20     TOOL_AIRBRUSH =  9,
21     TOOL_TEXT     = 10,
22     TOOL_LINE     = 11,
23     TOOL_BEZIER   = 12,
24     TOOL_RECT     = 13,
25     TOOL_SHAPE    = 14,
26     TOOL_ELLIPSE  = 15,
27     TOOL_RRECT    = 16,
28     TOOL_MAX = TOOL_RRECT,
29 };
30 
31 /* CLASSES **********************************************************/
32 
33 struct ToolBase
34 {
35     TOOLTYPE m_tool;
36     HDC m_hdc;
37     COLORREF m_fg, m_bg;
38     static INT s_pointSP;
39     static POINT s_pointStack[256];
40 
41     ToolBase(TOOLTYPE tool) : m_tool(tool), m_hdc(NULL) { }
42     virtual ~ToolBase() { }
43 
44     virtual void OnButtonDown(BOOL bLeftButton, LONG x, LONG y, BOOL bDoubleClick) { }
45     virtual void OnMouseMove(BOOL bLeftButton, LONG x, LONG y) { }
46     virtual void OnButtonUp(BOOL bLeftButton, LONG x, LONG y) { }
47 
48     virtual void OnCancelDraw();
49     virtual void OnFinishDraw();
50 
51     virtual void OnDrawOverlayOnImage(HDC hdc) { }
52     virtual void OnDrawOverlayOnCanvas(HDC hdc) { }
53 
54     void beginEvent();
55     void endEvent();
56     void reset();
57 
58     static ToolBase* createToolObject(TOOLTYPE type);
59 
60 protected:
61     void OnDrawSelectionOnCanvas(HDC hdc);
62 };
63 
64 class ToolsModel
65 {
66 private:
67     int m_lineWidth;
68     int m_shapeStyle;
69     int m_brushStyle;
70     TOOLTYPE m_activeTool;
71     TOOLTYPE m_oldActiveTool;
72     int m_airBrushWidth;
73     int m_rubberRadius;
74     BOOL m_transpBg;
75     int m_zoom;
76     ToolBase* m_tools[TOOL_MAX + 1];
77     ToolBase *m_pToolObject;
78 
79     ToolBase *GetOrCreateTool(TOOLTYPE nTool);
80 
81 public:
82     ToolsModel();
83     ~ToolsModel();
84 
85     BOOL IsSelection() const;
86     int GetLineWidth() const;
87     void SetLineWidth(int nLineWidth);
88     int GetShapeStyle() const;
89     void SetShapeStyle(int nShapeStyle);
90     int GetBrushStyle() const;
91     void SetBrushStyle(int nBrushStyle);
92     TOOLTYPE GetActiveTool() const;
93     TOOLTYPE GetOldActiveTool() const;
94     void SetActiveTool(TOOLTYPE nActiveTool);
95     int GetAirBrushWidth() const;
96     void SetAirBrushWidth(int nAirBrushWidth);
97     int GetRubberRadius() const;
98     void SetRubberRadius(int nRubberRadius);
99     BOOL IsBackgroundTransparent() const;
100     void SetBackgroundTransparent(BOOL bTransparent);
101     int GetZoom() const;
102     void SetZoom(int nZoom);
103 
104     void OnButtonDown(BOOL bLeftButton, LONG x, LONG y, BOOL bDoubleClick);
105     void OnMouseMove(BOOL bLeftButton, LONG x, LONG y);
106     void OnButtonUp(BOOL bLeftButton, LONG x, LONG y);
107     void OnCancelDraw();
108     void OnFinishDraw();
109     void OnDrawOverlayOnImage(HDC hdc);
110     void OnDrawOverlayOnCanvas(HDC hdc);
111 
112     void resetTool();
113     void selectAll();
114 
115     void NotifyToolChanged();
116     void NotifyToolSettingsChanged();
117     void NotifyZoomChanged();
118 };
119 
120 extern ToolsModel toolsModel;
121 
122 static inline int Zoomed(int xy)
123 {
124     return xy * toolsModel.GetZoom() / 1000;
125 }
126 
127 static inline int UnZoomed(int xy)
128 {
129     return xy * 1000 / toolsModel.GetZoom();
130 }
131 
132 static inline void Zoomed(POINT& pt)
133 {
134     pt.x = Zoomed(pt.x);
135     pt.y = Zoomed(pt.y);
136 }
137 
138 static inline void Zoomed(RECT& rc)
139 {
140     rc.left = Zoomed(rc.left);
141     rc.top = Zoomed(rc.top);
142     rc.right = Zoomed(rc.right);
143     rc.bottom = Zoomed(rc.bottom);
144 }
145 
146 static inline void UnZoomed(POINT& pt)
147 {
148     pt.x = UnZoomed(pt.x);
149     pt.y = UnZoomed(pt.y);
150 }
151 
152 static inline void UnZoomed(RECT& rc)
153 {
154     rc.left = UnZoomed(rc.left);
155     rc.top = UnZoomed(rc.top);
156     rc.right = UnZoomed(rc.right);
157     rc.bottom = UnZoomed(rc.bottom);
158 }
159