2 * PROJECT: PAINT for ReactOS
4 * FILE: base/applications/mspaint/history.cpp
5 * PURPOSE: Undo and redo functionality
6 * PROGRAMMERS: Benedikt Freisen
9 /* INCLUDES *********************************************************/
13 /* FUNCTIONS ********************************************************/
15 void ImageModel::NotifyDimensionsChanged()
17 imageArea
.SendMessage(WM_IMAGEMODELDIMENSIONSCHANGED
);
20 void ImageModel::NotifyImageChanged()
22 imageArea
.SendMessage(WM_IMAGEMODELIMAGECHANGED
);
25 ImageModel::ImageModel()
32 // prepare a minimal usable bitmap
36 hDrawingDC
= CreateCompatibleDC(NULL
);
37 SelectObject(hDrawingDC
, CreatePen(PS_SOLID
, 0, paletteModel
.GetFgColor()));
38 SelectObject(hDrawingDC
, CreateSolidBrush(paletteModel
.GetBgColor()));
40 hBms
[0] = CreateDIBWithProperties(imgXRes
, imgYRes
);
41 SelectObject(hDrawingDC
, hBms
[0]);
42 Rectangle(hDrawingDC
, 0 - 1, 0 - 1, imgXRes
+ 1, imgYRes
+ 1);
45 void ImageModel::CopyPrevious()
47 DeleteObject(hBms
[(currInd
+ 1) % HISTORYSIZE
]);
48 hBms
[(currInd
+ 1) % HISTORYSIZE
] = (HBITMAP
) CopyImage(hBms
[currInd
], IMAGE_BITMAP
, 0, 0, LR_COPYRETURNORG
);
49 currInd
= (currInd
+ 1) % HISTORYSIZE
;
50 if (undoSteps
< HISTORYSIZE
- 1)
53 SelectObject(hDrawingDC
, hBms
[currInd
]);
57 void ImageModel::Undo()
61 int oldWidth
= GetWidth();
62 int oldHeight
= GetHeight();
63 selectionWindow
.ShowWindow(SW_HIDE
);
64 currInd
= (currInd
+ HISTORYSIZE
- 1) % HISTORYSIZE
;
65 SelectObject(hDrawingDC
, hBms
[currInd
]);
67 if (redoSteps
< HISTORYSIZE
- 1)
69 if (GetWidth() != oldWidth
|| GetHeight() != oldHeight
)
70 NotifyDimensionsChanged();
75 void ImageModel::Redo()
79 int oldWidth
= GetWidth();
80 int oldHeight
= GetHeight();
81 selectionWindow
.ShowWindow(SW_HIDE
);
82 currInd
= (currInd
+ 1) % HISTORYSIZE
;
83 SelectObject(hDrawingDC
, hBms
[currInd
]);
85 if (undoSteps
< HISTORYSIZE
- 1)
87 if (GetWidth() != oldWidth
|| GetHeight() != oldHeight
)
88 NotifyDimensionsChanged();
93 void ImageModel::ResetToPrevious()
95 DeleteObject(hBms
[currInd
]);
97 (HBITMAP
) CopyImage(hBms
[(currInd
+ HISTORYSIZE
- 1) % HISTORYSIZE
], IMAGE_BITMAP
, 0, 0, LR_COPYRETURNORG
);
98 SelectObject(hDrawingDC
, hBms
[currInd
]);
102 void ImageModel::ClearHistory()
108 void ImageModel::Insert(HBITMAP hbm
)
110 int oldWidth
= GetWidth();
111 int oldHeight
= GetHeight();
112 DeleteObject(hBms
[(currInd
+ 1) % HISTORYSIZE
]);
113 hBms
[(currInd
+ 1) % HISTORYSIZE
] = hbm
;
114 currInd
= (currInd
+ 1) % HISTORYSIZE
;
115 if (undoSteps
< HISTORYSIZE
- 1)
118 SelectObject(hDrawingDC
, hBms
[currInd
]);
119 if (GetWidth() != oldWidth
|| GetHeight() != oldHeight
)
120 NotifyDimensionsChanged();
121 NotifyImageChanged();
124 void ImageModel::Crop(int nWidth
, int nHeight
, int nOffsetX
, int nOffsetY
)
129 int oldWidth
= GetWidth();
130 int oldHeight
= GetHeight();
132 SelectObject(hDrawingDC
, hBms
[currInd
]);
133 DeleteObject(hBms
[(currInd
+ 1) % HISTORYSIZE
]);
134 hBms
[(currInd
+ 1) % HISTORYSIZE
] = CreateDIBWithProperties(nWidth
, nHeight
);
135 currInd
= (currInd
+ 1) % HISTORYSIZE
;
136 if (undoSteps
< HISTORYSIZE
- 1)
140 hdc
= CreateCompatibleDC(hDrawingDC
);
141 SelectObject(hdc
, hBms
[currInd
]);
143 oldPen
= (HPEN
) SelectObject(hdc
, CreatePen(PS_SOLID
, 1, paletteModel
.GetBgColor()));
144 oldBrush
= (HBRUSH
) SelectObject(hdc
, CreateSolidBrush(paletteModel
.GetBgColor()));
145 Rectangle(hdc
, 0, 0, nWidth
, nHeight
);
146 BitBlt(hdc
, -nOffsetX
, -nOffsetY
, GetWidth(), GetHeight(), hDrawingDC
, 0, 0, SRCCOPY
);
147 DeleteObject(SelectObject(hdc
, oldBrush
));
148 DeleteObject(SelectObject(hdc
, oldPen
));
150 SelectObject(hDrawingDC
, hBms
[currInd
]);
152 if (GetWidth() != oldWidth
|| GetHeight() != oldHeight
)
153 NotifyDimensionsChanged();
154 NotifyImageChanged();
157 void ImageModel::SaveImage(LPTSTR lpFileName
)
159 SaveDIBToFile(hBms
[currInd
], lpFileName
, hDrawingDC
, &fileTime
, &fileSize
, fileHPPM
, fileVPPM
);
163 BOOL
ImageModel::IsImageSaved()
168 BOOL
ImageModel::HasUndoSteps()
170 return undoSteps
> 0;
173 BOOL
ImageModel::HasRedoSteps()
175 return redoSteps
> 0;
178 void ImageModel::StretchSkew(int nStretchPercentX
, int nStretchPercentY
, int nSkewDegX
, int nSkewDegY
)
180 int oldWidth
= GetWidth();
181 int oldHeight
= GetHeight();
182 Insert((HBITMAP
) CopyImage(hBms
[currInd
], IMAGE_BITMAP
,
183 GetWidth() * nStretchPercentX
/ 100,
184 GetHeight() * nStretchPercentY
/ 100, 0));
185 if (GetWidth() != oldWidth
|| GetHeight() != oldHeight
)
186 NotifyDimensionsChanged();
187 NotifyImageChanged();
190 int ImageModel::GetWidth()
192 return GetDIBWidth(hBms
[currInd
]);
195 int ImageModel::GetHeight()
197 return GetDIBHeight(hBms
[currInd
]);
200 void ImageModel::InvertColors()
202 RECT rect
= {0, 0, GetWidth(), GetHeight()};
204 InvertRect(hDrawingDC
, &rect
);
205 NotifyImageChanged();
208 void ImageModel::Clear(COLORREF color
)
210 Rectangle(hDrawingDC
, 0 - 1, 0 - 1, GetWidth() + 1, GetHeight() + 1);
211 NotifyImageChanged();
214 HDC
ImageModel::GetDC()
219 void ImageModel::FlipHorizontally()
222 StretchBlt(hDrawingDC
, GetWidth() - 1, 0, -GetWidth(), GetHeight(), GetDC(), 0, 0,
223 GetWidth(), GetHeight(), SRCCOPY
);
224 NotifyImageChanged();
227 void ImageModel::FlipVertically()
230 StretchBlt(hDrawingDC
, 0, GetHeight() - 1, GetWidth(), -GetHeight(), GetDC(), 0, 0,
231 GetWidth(), GetHeight(), SRCCOPY
);
232 NotifyImageChanged();
235 void ImageModel::RotateNTimes90Degrees(int iN
)
240 StretchBlt(hDrawingDC
, GetWidth() - 1, GetHeight() - 1, -GetWidth(), -GetHeight(), GetDC(),
241 0, 0, GetWidth(), GetHeight(), SRCCOPY
);
243 NotifyImageChanged();