Subversion Repositories Kolibri OS

Rev

Rev 7253 | Go to most recent revision | Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
7204 leency 1
// Actions history
2
 
3
#define MAX_ACTIONS_COUNT 10
4
 
5
struct _ActionsHistory {
6
	dword stack[MAX_ACTIONS_COUNT];
7
	dword head;
8
	dword tail;
9
	dword currentIndex;
10
 
11
	void init();
12
	bool isEmpty();
13
 
14
	void saveCurrentState();
15
	void restoreState(dword index);
16
 
17
	void undoLastAction();
18
	void redoLastAction();
19
};
20
 
21
void _ActionsHistory::init() {
22
	dword i;
23
 
24
	head = tail = 0;
25
	currentIndex = -1;
26
 
27
	for (i = 0; i < MAX_ACTIONS_COUNT; i++)
28
		stack[i] = malloc(image.columns * image.rows);
29
 
30
	saveCurrentState();
31
}
32
 
33
bool _ActionsHistory::isEmpty() {
34
	if (head == tail)
35
		return true;
36
	else
37
		return false;
38
}
39
 
40
void _ActionsHistory::saveCurrentState() {
41
	dword addr, offset;
42
	int r, c;
43
 
44
	tail = currentIndex + 1;
45
 
46
	if (tail >= MAX_ACTIONS_COUNT)
47
		tail = tail % MAX_ACTIONS_COUNT;
48
 
49
	addr = stack[tail];
50
 
51
	for (r = 0; r < image.rows; r++)
52
	{
53
		for (c = 0; c < image.columns; c++)
54
		{
55
			offset = calc(image.columns * r + c) * 4;
56
 
57
			ESDWORD[addr + offset] = image.get_pixel(r, c);
58
		}
59
	}
60
 
61
	currentIndex = tail;
62
	tail = calc(tail + 1) % 10;
63
 
64
	if (tail == head)
65
		head = calc(head + 1) % 10;
66
}
67
 
68
void _ActionsHistory::restoreState(dword index) {
69
	dword addr, offset;
70
	int r, c;
71
 
72
	addr = stack[index];
73
 
74
	for (r = 0; r < image.rows; r++)
75
	{
76
		for (c = 0; c < image.columns; c++)
77
		{
78
			offset = calc(image.columns * r + c) * 4;
79
			image.set_pixel(r, c, ESDWORD[addr + offset]);
80
		}
81
	}
82
}
83
 
84
void _ActionsHistory::undoLastAction() {
85
	dword previousAction;
86
 
87
	// Если вышли за левую границу, перемещаемся в конец массива
88
	if (currentIndex == 0) {
89
		previousAction = MAX_ACTIONS_COUNT - 1;
90
	}
91
	else {
92
		previousAction = currentIndex - 1;
93
	}
94
 
95
	if (isEmpty())
96
		return;
97
	else {
98
		if (currentIndex != head) {
99
			restoreState(previousAction);
100
			DrawCanvas();
101
		}
102
 
103
		if (currentIndex != head)
104
			currentIndex = previousAction;
105
	}
106
}
107
 
108
void _ActionsHistory::redoLastAction() {
109
	dword nextAction = calc(currentIndex + 1);
110
 
111
	// Если вышли за левую границу, возвращаемся в начало
112
	if (nextAction >= MAX_ACTIONS_COUNT)
113
		nextAction = nextAction % MAX_ACTIONS_COUNT;
114
 
115
	if (isEmpty())
116
		return;
117
	else {
118
		if (nextAction != tail) {
119
			restoreState(nextAction);
120
			DrawCanvas();
121
		}
122
 
123
		if (nextAction != tail)
124
			currentIndex = nextAction;
125
	}
126
}