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 #include "precomp.h"
9 
10 ToolsModel toolsModel;
11 
12 /* FUNCTIONS ********************************************************/
13 
ToolsModel()14 ToolsModel::ToolsModel()
15 {
16     m_lineWidth = m_penWidth = 1;
17     m_brushWidth = 4;
18     m_shapeStyle = 0;
19     m_brushStyle = BrushStyleRound;
20     m_oldActiveTool = m_activeTool = TOOL_PEN;
21     m_airBrushRadius = 5;
22     m_rubberRadius = 4;
23     m_transpBg = FALSE;
24     m_zoom = 1000;
25     m_pToolObject = GetOrCreateTool(m_activeTool);
26 }
27 
~ToolsModel()28 ToolsModel::~ToolsModel()
29 {
30     delete m_pToolObject;
31     m_pToolObject = NULL;
32 }
33 
GetOrCreateTool(TOOLTYPE nTool)34 ToolBase *ToolsModel::GetOrCreateTool(TOOLTYPE nTool)
35 {
36     delete m_pToolObject;
37     m_pToolObject = ToolBase::createToolObject(nTool);
38     return m_pToolObject;
39 }
40 
IsSelection() const41 BOOL ToolsModel::IsSelection() const
42 {
43     return (GetActiveTool() == TOOL_RECTSEL || GetActiveTool() == TOOL_FREESEL);
44 }
45 
GetLineWidth() const46 int ToolsModel::GetLineWidth() const
47 {
48     return m_lineWidth;
49 }
50 
SetLineWidth(int nLineWidth)51 void ToolsModel::SetLineWidth(int nLineWidth)
52 {
53     m_lineWidth = nLineWidth;
54     NotifyToolSettingsChanged();
55     imageModel.NotifyImageChanged();
56 }
57 
GetPenWidth() const58 INT ToolsModel::GetPenWidth() const
59 {
60     return m_penWidth;
61 }
62 
SetPenWidth(INT nPenWidth)63 void ToolsModel::SetPenWidth(INT nPenWidth)
64 {
65     m_penWidth = nPenWidth;
66     NotifyToolSettingsChanged();
67     imageModel.NotifyImageChanged();
68 }
69 
GetBrushWidth() const70 INT ToolsModel::GetBrushWidth() const
71 {
72     return m_brushWidth;
73 }
74 
SetBrushWidth(INT nBrushWidth)75 void ToolsModel::SetBrushWidth(INT nBrushWidth)
76 {
77     m_brushWidth = nBrushWidth;
78     NotifyToolSettingsChanged();
79     imageModel.NotifyImageChanged();
80 }
81 
MakeLineThickerOrThinner(BOOL bThinner)82 void ToolsModel::MakeLineThickerOrThinner(BOOL bThinner)
83 {
84     INT thickness = GetLineWidth();
85     SetLineWidth(bThinner ? max(1, thickness - 1) : (thickness + 1));
86 }
87 
MakePenThickerOrThinner(BOOL bThinner)88 void ToolsModel::MakePenThickerOrThinner(BOOL bThinner)
89 {
90     INT thickness = GetPenWidth();
91     SetPenWidth(bThinner ? max(1, thickness - 1) : (thickness + 1));
92 }
93 
MakeBrushThickerOrThinner(BOOL bThinner)94 void ToolsModel::MakeBrushThickerOrThinner(BOOL bThinner)
95 {
96     INT thickness = GetBrushWidth();
97     SetBrushWidth(bThinner ? max(1, thickness - 1) : (thickness + 1));
98 }
99 
MakeAirBrushThickerOrThinner(BOOL bThinner)100 void ToolsModel::MakeAirBrushThickerOrThinner(BOOL bThinner)
101 {
102     INT thickness = GetAirBrushRadius();
103     SetAirBrushRadius(bThinner ? max(1, thickness - 1) : (thickness + 1));
104 }
105 
MakeRubberThickerOrThinner(BOOL bThinner)106 void ToolsModel::MakeRubberThickerOrThinner(BOOL bThinner)
107 {
108     INT thickness = GetRubberRadius();
109     SetRubberRadius(bThinner ? max(1, thickness - 1) : (thickness + 1));
110 }
111 
GetShapeStyle() const112 int ToolsModel::GetShapeStyle() const
113 {
114     return m_shapeStyle;
115 }
116 
SetShapeStyle(int nShapeStyle)117 void ToolsModel::SetShapeStyle(int nShapeStyle)
118 {
119     m_shapeStyle = nShapeStyle;
120     NotifyToolSettingsChanged();
121 }
122 
GetBrushStyle() const123 BrushStyle ToolsModel::GetBrushStyle() const
124 {
125     return m_brushStyle;
126 }
127 
SetBrushStyle(BrushStyle nBrushStyle)128 void ToolsModel::SetBrushStyle(BrushStyle nBrushStyle)
129 {
130     m_brushStyle = nBrushStyle;
131     NotifyToolSettingsChanged();
132 }
133 
GetActiveTool() const134 TOOLTYPE ToolsModel::GetActiveTool() const
135 {
136     return m_activeTool;
137 }
138 
GetOldActiveTool() const139 TOOLTYPE ToolsModel::GetOldActiveTool() const
140 {
141     return m_oldActiveTool;
142 }
143 
SetActiveTool(TOOLTYPE nActiveTool)144 void ToolsModel::SetActiveTool(TOOLTYPE nActiveTool)
145 {
146     OnEndDraw(FALSE);
147 
148     selectionModel.Landing();
149 
150     m_activeTool = nActiveTool;
151 
152     switch (m_activeTool)
153     {
154         case TOOL_FREESEL:
155         case TOOL_RECTSEL:
156         case TOOL_COLOR:
157         case TOOL_ZOOM:
158         case TOOL_TEXT:
159             // The active tool is not an actually drawing tool
160             break;
161 
162         case TOOL_LINE:
163         case TOOL_BEZIER:
164         case TOOL_RECT:
165         case TOOL_SHAPE:
166         case TOOL_ELLIPSE:
167         case TOOL_FILL:
168         case TOOL_AIRBRUSH:
169         case TOOL_RRECT:
170         case TOOL_RUBBER:
171         case TOOL_BRUSH:
172         case TOOL_PEN:
173             // The active tool is an actually drawing tool. Save it for TOOL_COLOR to restore
174             m_oldActiveTool = nActiveTool;
175             break;
176     }
177 
178     m_pToolObject = GetOrCreateTool(m_activeTool);
179 
180     NotifyToolChanged();
181 }
182 
GetAirBrushRadius() const183 INT ToolsModel::GetAirBrushRadius() const
184 {
185     return m_airBrushRadius;
186 }
187 
SetAirBrushRadius(INT nAirBrushRadius)188 void ToolsModel::SetAirBrushRadius(INT nAirBrushRadius)
189 {
190     m_airBrushRadius = nAirBrushRadius;
191     NotifyToolSettingsChanged();
192 }
193 
GetRubberRadius() const194 int ToolsModel::GetRubberRadius() const
195 {
196     return m_rubberRadius;
197 }
198 
SetRubberRadius(int nRubberRadius)199 void ToolsModel::SetRubberRadius(int nRubberRadius)
200 {
201     m_rubberRadius = nRubberRadius;
202     NotifyToolSettingsChanged();
203 }
204 
GetToolSize() const205 SIZE ToolsModel::GetToolSize() const
206 {
207     SIZE size;
208     switch (m_activeTool)
209     {
210         case TOOL_FREESEL:
211         case TOOL_RECTSEL:
212             size.cx = selectionModel.m_rc.Width();
213             size.cy = selectionModel.m_rc.Height();
214             break;
215         case TOOL_COLOR:
216         case TOOL_ZOOM:
217         case TOOL_TEXT:
218         case TOOL_FILL:
219             size.cx = size.cy = 1;
220             break;
221         case TOOL_LINE:
222         case TOOL_BEZIER:
223         case TOOL_RECT:
224         case TOOL_RRECT:
225         case TOOL_SHAPE:
226         case TOOL_ELLIPSE:
227             size.cx = size.cy = GetLineWidth();
228             break;
229         case TOOL_AIRBRUSH:
230             size.cx = size.cy = GetAirBrushRadius() * 2;
231             break;
232         case TOOL_RUBBER:
233             size.cx = size.cy = GetRubberRadius() * 2;
234             break;
235         case TOOL_BRUSH:
236             size.cx = size.cy = GetBrushWidth();
237             break;
238         case TOOL_PEN:
239             size.cx = size.cy = GetPenWidth();
240             break;
241     }
242     if (size.cx < 1)
243         size.cx = 1;
244     if (size.cy < 1)
245         size.cy = 1;
246     return size;
247 }
248 
IsBackgroundTransparent() const249 BOOL ToolsModel::IsBackgroundTransparent() const
250 {
251     return m_transpBg;
252 }
253 
SetBackgroundTransparent(BOOL bTransparent)254 void ToolsModel::SetBackgroundTransparent(BOOL bTransparent)
255 {
256     m_transpBg = bTransparent;
257     NotifyToolSettingsChanged();
258     imageModel.NotifyImageChanged();
259 }
260 
GetZoom() const261 int ToolsModel::GetZoom() const
262 {
263     return m_zoom;
264 }
265 
SetZoom(int nZoom)266 void ToolsModel::SetZoom(int nZoom)
267 {
268     m_zoom = nZoom;
269     NotifyZoomChanged();
270 }
271 
NotifyToolChanged()272 void ToolsModel::NotifyToolChanged()
273 {
274     if (toolBoxContainer.IsWindow())
275         toolBoxContainer.SendMessage(WM_TOOLSMODELTOOLCHANGED, m_activeTool);
276     if (toolSettingsWindow.IsWindow())
277         toolSettingsWindow.SendMessage(WM_TOOLSMODELTOOLCHANGED, m_activeTool);
278     if (fontsDialog.IsWindow())
279         fontsDialog.SendMessage(WM_TOOLSMODELTOOLCHANGED, m_activeTool);
280     if (textEditWindow.IsWindow())
281         textEditWindow.SendMessage(WM_TOOLSMODELTOOLCHANGED, m_activeTool);
282 }
283 
NotifyToolSettingsChanged()284 void ToolsModel::NotifyToolSettingsChanged()
285 {
286     if (toolSettingsWindow.IsWindow())
287         toolSettingsWindow.SendMessage(WM_TOOLSMODELSETTINGSCHANGED);
288     if (textEditWindow.IsWindow())
289         textEditWindow.SendMessage(WM_TOOLSMODELSETTINGSCHANGED);
290 }
291 
NotifyZoomChanged()292 void ToolsModel::NotifyZoomChanged()
293 {
294     if (toolSettingsWindow.IsWindow())
295         toolSettingsWindow.SendMessage(WM_TOOLSMODELZOOMCHANGED);
296     if (textEditWindow.IsWindow())
297         textEditWindow.SendMessage(WM_TOOLSMODELZOOMCHANGED);
298     if (canvasWindow.IsWindow())
299         canvasWindow.SendMessage(WM_TOOLSMODELZOOMCHANGED);
300 }
301 
resetTool()302 void ToolsModel::resetTool()
303 {
304     m_pToolObject->reset();
305 }
306 
selectAll()307 void ToolsModel::selectAll()
308 {
309     SetActiveTool(TOOL_RECTSEL);
310     OnButtonDown(TRUE, 0, 0, FALSE);
311     OnMouseMove(TRUE, imageModel.GetWidth(), imageModel.GetHeight());
312     OnButtonUp(TRUE, imageModel.GetWidth(), imageModel.GetHeight());
313 }
314