* Sync to trunk HEAD (r53318).
[reactos.git] / base / applications / mspaint / history.c
1 /*
2 * PROJECT: PAINT for ReactOS
3 * LICENSE: LGPL
4 * FILE: base/applications/paint/history.c
5 * PURPOSE: Undo and redo functionality
6 * PROGRAMMERS: Benedikt Freisen
7 */
8
9 /* INCLUDES *********************************************************/
10
11 #include "precomp.h"
12
13 /* FUNCTIONS ********************************************************/
14
15 extern void updateCanvasAndScrollbars(void);
16
17 void
18 setImgXYRes(int x, int y)
19 {
20 if ((imgXRes != x) || (imgYRes != y))
21 {
22 imgXRes = x;
23 imgYRes = y;
24 updateCanvasAndScrollbars();
25 }
26 }
27
28 void
29 newReversible()
30 {
31 DeleteObject(hBms[(currInd + 1) % HISTORYSIZE]);
32 hBms[(currInd + 1) % HISTORYSIZE] = CopyImage(hBms[currInd], IMAGE_BITMAP, 0, 0, LR_COPYRETURNORG);
33 currInd = (currInd + 1) % HISTORYSIZE;
34 if (undoSteps < HISTORYSIZE - 1)
35 undoSteps++;
36 redoSteps = 0;
37 SelectObject(hDrawingDC, hBms[currInd]);
38 imgXRes = GetDIBWidth(hBms[currInd]);
39 imgYRes = GetDIBHeight(hBms[currInd]);
40 imageSaved = FALSE;
41 }
42
43 void
44 undo()
45 {
46 if (undoSteps > 0)
47 {
48 ShowWindow(hSelection, SW_HIDE);
49 currInd = (currInd + HISTORYSIZE - 1) % HISTORYSIZE;
50 SelectObject(hDrawingDC, hBms[currInd]);
51 undoSteps--;
52 if (redoSteps < HISTORYSIZE - 1)
53 redoSteps++;
54 setImgXYRes(GetDIBWidth(hBms[currInd]), GetDIBHeight(hBms[currInd]));
55 }
56 }
57
58 void
59 redo()
60 {
61 if (redoSteps > 0)
62 {
63 ShowWindow(hSelection, SW_HIDE);
64 currInd = (currInd + 1) % HISTORYSIZE;
65 SelectObject(hDrawingDC, hBms[currInd]);
66 redoSteps--;
67 if (undoSteps < HISTORYSIZE - 1)
68 undoSteps++;
69 setImgXYRes(GetDIBWidth(hBms[currInd]), GetDIBHeight(hBms[currInd]));
70 }
71 }
72
73 void
74 resetToU1()
75 {
76 DeleteObject(hBms[currInd]);
77 hBms[currInd] =
78 CopyImage(hBms[(currInd + HISTORYSIZE - 1) % HISTORYSIZE], IMAGE_BITMAP, 0, 0, LR_COPYRETURNORG);
79 SelectObject(hDrawingDC, hBms[currInd]);
80 imgXRes = GetDIBWidth(hBms[currInd]);
81 imgYRes = GetDIBHeight(hBms[currInd]);
82 }
83
84 void
85 clearHistory()
86 {
87 undoSteps = 0;
88 redoSteps = 0;
89 }
90
91 void
92 insertReversible(HBITMAP hbm)
93 {
94 DeleteObject(hBms[(currInd + 1) % HISTORYSIZE]);
95 hBms[(currInd + 1) % HISTORYSIZE] = hbm;
96 currInd = (currInd + 1) % HISTORYSIZE;
97 if (undoSteps < HISTORYSIZE - 1)
98 undoSteps++;
99 redoSteps = 0;
100 SelectObject(hDrawingDC, hBms[currInd]);
101 setImgXYRes(GetDIBWidth(hBms[currInd]), GetDIBHeight(hBms[currInd]));
102 }
103
104 void
105 cropReversible(int width, int height, int xOffset, int yOffset)
106 {
107 HDC hdc;
108 HPEN oldPen;
109 HBRUSH oldBrush;
110
111 SelectObject(hDrawingDC, hBms[currInd]);
112 DeleteObject(hBms[(currInd + 1) % HISTORYSIZE]);
113 hBms[(currInd + 1) % HISTORYSIZE] = CreateDIBWithProperties(width, height);
114 currInd = (currInd + 1) % HISTORYSIZE;
115 if (undoSteps < HISTORYSIZE - 1)
116 undoSteps++;
117 redoSteps = 0;
118
119 hdc = CreateCompatibleDC(hDrawingDC);
120 SelectObject(hdc, hBms[currInd]);
121
122 oldPen = SelectObject(hdc, CreatePen(PS_SOLID, 1, bgColor));
123 oldBrush = SelectObject(hdc, CreateSolidBrush(bgColor));
124 Rectangle(hdc, 0, 0, width, height);
125 BitBlt(hdc, -xOffset, -yOffset, imgXRes, imgYRes, hDrawingDC, 0, 0, SRCCOPY);
126 DeleteObject(SelectObject(hdc, oldBrush));
127 DeleteObject(SelectObject(hdc, oldPen));
128 DeleteDC(hdc);
129 SelectObject(hDrawingDC, hBms[currInd]);
130
131 setImgXYRes(width, height);
132 }