Subversion Repositories Kolibri OS

Rev

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

Rev Author Line No. Line
7254 leency 1
enum {
2
	TOOL_NONE = -1,
3
	TOOL_PENCIL,
4
	TOOL_PIPETTE,
5
	TOOL_FILL,
6
	TOOL_LINE,
7
	TOOL_RECT,
8
	TOOL_SELECT
9
};
10
 
11
struct Tool {
12
	int id;
13
 
14
	void (*activate)();
15
	void (*deactivate)();
16
	void (*onMouseEvent)(int x, int y, int lkm, int pkm);
17
	void (*onKeyEvent)(dword keycode);
18
	void (*onCanvasDraw)();
19
};
20
 
21
int currentTool = -1;
22
Tool tools[6];
23
 
24
 
25
void resetCurrentTool() {
26
	if ((currentTool != TOOL_NONE) && (tools[currentTool].deactivate != 0)) {
27
		tools[currentTool].deactivate();
28
	}
29
 
30
	currentTool = TOOL_NONE;
31
}
32
 
33
void setCurrentTool(int index) {
34
	resetCurrentTool();
35
 
36
	currentTool = index;
37
 
38
	if ((index != TOOL_NONE) && (tools[index].activate != 0))
39
		tools[index].activate();
40
 
41
	DrawLeftPanel();
42
	DrawCanvas();
43
}
44
 
45
//===================================================//
46
//                                                   //
47
//                    FUNTIONS                       //
48
//                                                   //
49
//===================================================//
50
 
51
void FillTool_onMouseEvent(int mouseX, int mouseY, int lkm, int pkm) {
52
	if (canvas.hovered()) && (currentTool==TOOL_FILL) && (mouse.up)
53
	{
54
		image.fill(mouseY-canvas.y/zoom.value,
55
				mouseX-canvas.x/zoom.value, tool_color);
56
		actionsHistory.saveCurrentState();
57
		DrawCanvas();
58
	}
59
}
60
 
61
void PipetteTool_activate() {
62
	SetEventMask(EVM_REDRAW+EVM_KEY+EVM_BUTTON+EVM_MOUSE);
63
}
64
 
65
void PipetteTool_onMouseEvent(int mouseX, int mouseY, int lkm, int pkm) {
66
	tool_color = GetPixelUnderMouse();
67
	DrawBar(Form.cwidth-30, 5, 20, 20, tool_color);
68
 
69
	if (mouse.down) {
70
		SetEventMask(EVM_REDRAW+EVM_KEY+EVM_BUTTON+EVM_MOUSE+EVM_MOUSE_FILTER);
71
		if (mouse.key&MOUSE_LEFT) EventSetActiveColor(1, tool_color);
72
		if (mouse.key&MOUSE_RIGHT) EventSetActiveColor(2, tool_color);
73
 
74
		setCurrentTool(TOOL_PENCIL);
75
	}
76
}
77
 
78
bool PencilTool_Drawing = false;
79
 
80
void PencilTool_onMouseEvent(int mouseX, int mouseY, int lkm, int pkm) {
81
	if (canvas.hovered())
82
	{
83
		if ((PencilTool_Drawing == true) && (!mouse.key)) {
84
			actionsHistory.saveCurrentState();
85
			PencilTool_Drawing = false;
86
		}
87
 
88
		if (mouse.key) {
89
			image.set_pixel(mouseY-canvas.y/zoom.value,
90
				mouseX-canvas.x/zoom.value, tool_color);
91
			PencilTool_Drawing = true;
92
		}
93
		DrawCanvas();
94
	}
95
}
96
 
97
void PencilTool_reset() {
98
	PencilTool_Drawing = false;
99
}
100
 
101
// Line tool
102
struct SimpleFigureTool_State {
103
	int startX, startY;
104
	int lastTempPosX, lastTempPosY;
105
};
106
 
107
enum {
108
	TOOL_LINE_STATE,
109
	TOOL_RECT_STATE
110
};
111
 
112
dword currentFigToolState = -1;
113
SimpleFigureTool_State figTool_States[2];
114
 
115
void SimpleFigureTool_Reset() {
116
	if (currentTool == TOOL_LINE)
117
		currentFigToolState = TOOL_LINE_STATE;
118
	else if (currentTool == TOOL_RECT)
119
		currentFigToolState = TOOL_RECT_STATE;
120
 
121
	figTool_States[currentFigToolState].startX = -1;
122
	figTool_States[currentFigToolState].startY = -1;
123
	figTool_States[currentFigToolState].lastTempPosX = -1;
124
	figTool_States[currentFigToolState].lastTempPosY = -1;
125
}
126
 
127
int mouseX_last;
128
int mouseY_last;
129
bool first_click_in_canvas = false;
130
 
131
void SimpleFigureTool_onMouseEvent(int mouseX, int mouseY, int lkm, int pkm) {
132
	if (mouse.down) && (canvas.hovered()) first_click_in_canvas = true;
133
	if (first_click_in_canvas)
134
	{
135
		if (mouseX>canvas.x+canvas.w-zoom.value) mouseX = canvas.x+canvas.w-zoom.value;
136
		if (mouseY>canvas.y+canvas.h-zoom.value) mouseY = canvas.y+canvas.h-zoom.value;
137
		if (mouseX
138
		if (mouseY
139
 
140
		if (mouse.key) {
141
			if ((figTool_States[currentFigToolState].startX < 0)
142
			|| (figTool_States[currentFigToolState].startY < 0)) {
143
				figTool_States[currentFigToolState].startX = mouseX;
144
				figTool_States[currentFigToolState].startY = mouseY;
145
			}
146
			else {
147
				if ((calc(mouseX - canvas.x/zoom.value) != figTool_States[currentFigToolState].lastTempPosX)
148
					|| (calc(mouseY - canvas.y/zoom.value) != figTool_States[currentFigToolState].lastTempPosY))
149
				{
150
					DrawCanvas();
151
				}
152
			}
153
			mouseX_last = mouseX;
154
			mouseY_last = mouseY;
155
		}
156
		if (mouse.up) {
157
			if ((figTool_States[currentFigToolState].startX >= 0)
158
			&& (figTool_States[currentFigToolState].startY >= 0)) {
159
				// Draw line from start position to current position
160
				if (currentTool == TOOL_LINE) {
161
					DrawLine(figTool_States[currentFigToolState].startX - canvas.x/zoom.value,
162
						figTool_States[currentFigToolState].startY - canvas.y/zoom.value,
163
						mouseX - canvas.x/zoom.value,
164
						mouseY - canvas.y/zoom.value,
165
						tool_color,
166
						1);
167
				}
168
				else if (currentTool == TOOL_RECT) {
169
					DrawRectangleInCanvas(figTool_States[currentFigToolState].startX - canvas.x/zoom.value,
170
						figTool_States[currentFigToolState].startY - canvas.y/zoom.value,
171
						mouseX - canvas.x/zoom.value,
172
						mouseY - canvas.y/zoom.value, tool_color, 1);
173
				}
174
 
175
				DrawCanvas();
176
 
177
				actionsHistory.saveCurrentState();
178
 
179
				// Reset start position
180
				figTool_States[currentFigToolState].startX = -1;
181
				figTool_States[currentFigToolState].startY = -1;
182
 
183
				first_click_in_canvas = false;
184
			}
185
		}
186
	}
187
}
188
 
189
void SimpleFigureTool_onCanvasDraw() {
190
	if ((figTool_States[currentFigToolState].startX >= 0)
191
	&& (figTool_States[currentFigToolState].startY >= 0) && (mouse.key)) {
192
		if (currentTool == TOOL_LINE) {
193
			DrawLine(figTool_States[currentFigToolState].startX - canvas.x/zoom.value,
194
				figTool_States[currentFigToolState].startY - canvas.y/zoom.value,
195
				mouseX_last - canvas.x/zoom.value,
196
				mouseY_last - canvas.y/zoom.value,
197
				tool_color,
198
				2);
199
		}
200
		else if (currentTool == TOOL_RECT) {
201
			DrawRectangleInCanvas(figTool_States[currentFigToolState].startX - canvas.x/zoom.value,
202
				figTool_States[currentFigToolState].startY - canvas.y/zoom.value,
203
				mouseX_last - canvas.x/zoom.value,
204
				mouseY_last - canvas.y/zoom.value,
205
				tool_color,
206
				2);
207
		}
208
 
209
		figTool_States[currentFigToolState].lastTempPosX = mouseX_last - canvas.x/zoom.value;
210
		figTool_States[currentFigToolState].lastTempPosY = mouseY_last - canvas.y/zoom.value;
211
	}
212
}
213
 
214
// Selection
215
int selection_start_x = -1;
216
int selection_start_y = -1;
217
int selection_end_x = -1;
218
int selection_end_y = -1;
219
bool selection_active = false;
220
 
221
dword SelectionTool_buffer = 0;
222
dword SelectionTool_buffer_r = 0;
223
dword SelectionTool_buffer_c = 0;
224
 
225
bool selection_moving_started = false;
226
int selection_pivot_x = -1;
227
int selection_pivot_y = -1;
228
 
229
void SelectTool_normalizeSelection() {
230
	int t;
231
 
232
	// Restructuring of the selection coordinates
233
	if (selection_end_x < selection_start_x) {
234
		t = selection_start_x;
235
		selection_start_x = selection_end_x;
236
		selection_end_x = t;
237
	}
238
 
239
	if (selection_end_y < selection_start_y) {
240
		t = selection_end_y;
241
		selection_end_y = selection_start_y;
242
		selection_start_y = t;
243
	}
244
}
245
 
246
void reset_selection_moving() {
247
	if (selection_moving_started) {
248
		SelectTool_drawBuffer(selection_start_x, selection_start_y, 1);
249
 
250
		selection_pivot_x = -1;
251
		selection_pivot_y = -1;
252
 
253
		selection_moving_started = false;
254
 
255
		actionsHistory.saveCurrentState();
256
		DrawCanvas();
257
	}
258
}
259
 
260
bool is_selection_moving() {
261
	return selection_moving_started;
262
}
263
 
264
void reset_selection() {
265
	reset_selection_moving();
266
 
267
	selection_start_x = -1;
268
	selection_start_y = -1;
269
	selection_end_x = -1;
270
	selection_end_y = -1;
271
}
272
 
273
void SelectTool_activate() {
274
	reset_selection();
275
 
276
	selection_active = false;
277
}
278
 
279
void SelectTool_deactivate() {
280
	reset_selection_moving();
281
}
282
 
283
bool SelectTool_pointInSelection(int x, int y) {
284
	if (x >= selection_start_x) && (x <= selection_end_x) && (y >= selection_start_y) && (y <= selection_end_y)
285
		return true;
286
	else
287
		return false;
288
}
289
 
290
 
291
void SelectTool_copyToBuffer() {
292
	dword offset, r, c;
293
 
294
		if (SelectionTool_buffer != 0)
295
			free(SelectionTool_buffer);
296
 
297
		SelectionTool_buffer_r = selection_end_y - selection_start_y + 1;
298
		SelectionTool_buffer_c = selection_end_x - selection_start_x + 1;
299
		SelectionTool_buffer = malloc(SelectionTool_buffer_r * SelectionTool_buffer_c * 4);
300
 
301
		for (r = selection_start_y; r <= selection_end_y; r++) {
302
			for (c = selection_start_x; c <= selection_end_x; c++) {
303
				offset = calc(SelectionTool_buffer_c * calc(r - selection_start_y) + calc(c - selection_start_x)) * 4;
304
 
305
				ESDWORD[SelectionTool_buffer + offset] = image.get_pixel(r, c);
306
			}
307
		}
308
}
309
 
310
void SelectTool_onMouseEvent(int mouseX, int mouseY, int lkm, int pkm) {
311
	int click_x, click_y, dx, dy, m_x, m_y, r, c, color;
312
	dword pixel;
313
 
314
	m_x = TO_CANVAS_X(mouseX);
315
	m_y = TO_CANVAS_Y(mouseY);
316
 
317
	if (mouse.down) && (canvas.hovered()) && (!selection_active) {
318
		if (selection_start_x != -1) && (SelectTool_pointInSelection(m_x, m_y)) {
319
			if (selection_pivot_x == -1) {
320
				selection_pivot_x = m_x;
321
				selection_pivot_y = m_y;
322
 
323
				GetKeys();
324
 
325
				if (!selection_moving_started) && ( !(key_modifier&KEY_LSHIFT) ) {
326
					for (r = selection_start_y; r <= selection_end_y; r++)
327
						for (c = selection_start_x; c <= selection_end_x; c++) {
328
							image.set_pixel(r, c, color2);
329
						}
330
				}
331
 
332
				selection_moving_started = true;
333
			}
334
		}
335
		else {
336
 
337
			reset_selection();
338
			selection_active = true;
339
		}
340
	}
341
 
342
	if (selection_pivot_x != -1) {
343
		dx = m_x - selection_pivot_x;
344
		dy = m_y - selection_pivot_y;
345
 
346
		if (selection_start_x + dx < 0)
347
			dx = selection_start_x;
348
 
349
		if (selection_end_x + dx >= image.columns)
350
			dx = image.columns-1 - selection_end_x;
351
 
352
		if (selection_start_y + dy < 0)
353
			dy = selection_start_y;
354
 
355
		if (selection_end_y + dy >= image.rows)
356
			dy = image.rows-1 - selection_end_y;
357
 
358
 
359
		selection_start_x += dx;
360
		selection_end_x += dx;
361
 
362
		selection_start_y += dy;
363
		selection_end_y += dy;
364
 
365
		selection_pivot_x += dx;
366
		selection_pivot_y += dy;
367
 
368
		DrawCanvas();
369
	}
370
 
371
	if (selection_active)
372
	{
373
		if (mouseX>canvas.x+canvas.w-zoom.value) mouseX = canvas.x+canvas.w-zoom.value;
374
		if (mouseY>canvas.y+canvas.h-zoom.value) mouseY = canvas.y+canvas.h-zoom.value;
375
 
376
		if (mouseX
377
		if (mouseY
378
 
379
		if (mouse.key) {
380
			selection_end_x = TO_CANVAS_X(mouseX);
381
			selection_end_y = TO_CANVAS_Y(mouseY);
382
 
383
			if ((selection_start_x < 0) || (selection_start_y < 0)) {
384
				selection_start_x = TO_CANVAS_X(mouseX);
385
				selection_start_y = TO_CANVAS_Y(mouseY);
386
			}
387
			else {
388
				DrawCanvas();
389
 
390
				/**if ((calc(TO_CANVAS_X(mouseX)) != selection_end_x)
391
					|| (calc(TO_CANVAS_Y(mouseY)) != selection_end_y))
392
				{
393
					DrawCanvas();
394
				}*/
395
			}
396
 
397
		}
398
 
399
		if (mouse.up) {
400
			selection_active = false;
401
 
402
			SelectTool_normalizeSelection();
403
			SelectTool_copyToBuffer();
404
		}
405
	}
406
 
407
	if (mouse.up) {
408
		if (selection_pivot_x != -1) {
409
			selection_pivot_x = -1;
410
			selection_pivot_y = -1;
411
		}
412
	}
413
}
414
 
415
void SelectTool_onCanvasDraw() {
416
	if (selection_moving_started)
417
		SelectTool_drawBuffer(selection_start_x, selection_start_y, 2);
418
 
419
	if ((selection_start_x >= 0) && (selection_start_y >= 0) && (selection_end_x >= 0) && (selection_end_y >= 0)) {
420
		DrawSelection(selection_start_x, selection_start_y, selection_end_x, selection_end_y);
421
	}
422
}
423
 
424
void SelectTool_drawBuffer(int insert_x, int insert_y, int target) {
425
	dword color;
426
	dword offset, r, c;
427
	dword insert_to_x, insert_to_y;
428
 
429
	if (SelectionTool_buffer != 0) {
430
		insert_to_x = insert_x + SelectionTool_buffer_c - 1;
431
 
432
		if (insert_to_x >= image.columns)
433
			insert_to_x = image.columns-1;
434
 
435
		insert_to_y = insert_y + SelectionTool_buffer_r - 1;
436
 
437
		if (insert_to_y >= image.rows)
438
			insert_to_y = image.rows-1;
439
 
440
		for (r = insert_y; r <= insert_to_y; r++) {
441
			for (c = insert_x; c <= insert_to_x; c++) {
442
					offset = calc(SelectionTool_buffer_c * calc(r - insert_y) + calc(c - insert_x)) * 4;
443
 
444
					color = ESDWORD[SelectionTool_buffer + offset];
445
 
446
					if (target == 1)
447
						image.set_pixel(r, c, color);
448
					else
449
						DrawBar(c*zoom.value + canvas.x, r*zoom.value + canvas.y,
450
							zoom.value, zoom.value, color);
451
			}
452
		}
453
	}
454
}
455
 
456
void SelectTool_onKeyEvent(dword keycode) {
457
	dword offset, r, c;
458
	dword insert_x, insert_y, insert_to_x, insert_to_y;
459
 
460
	if (keycode == SCAN_CODE_KEY_V) {
461
		if (SelectionTool_buffer != 0) {
462
			reset_selection();
463
 
464
			selection_moving_started = true;
465
			selection_start_x = 0;
466
			selection_end_x = SelectionTool_buffer_c - 1;
467
 
468
			selection_start_y = 0;
469
			selection_end_y = SelectionTool_buffer_r - 1;
470
 
471
			DrawCanvas();
472
 
473
		}
474
	}
475
}
476
 
477
 
478
//===================================================//
479
//                                                   //
480
//                      DRAWs                        //
481
//                                                   //
482
//===================================================//
483
 
484
 
485
 
486
// target - image (1) or canvas (2)
487
void DrawLine(int x1, int y1, int x2, int y2, dword color, int target) {
488
	int dx, dy, signX, signY, error, error2;
489
 
490
	if (1==target) {
491
		image.draw_line(x1, y1, x2, y2, color);
492
		return;
493
	}
494
 
495
	dx = x2 - x1;
496
 
497
	if (dx < 0)
498
		dx = -dx;
499
 
500
	dy = y2 - y1;
501
 
502
	if (dy < 0)
503
		dy = -dy;
504
 
505
	if (x1 < x2)
506
		signX = 1;
507
	else
508
		signX = -1;
509
 
510
	if (y1 < y2)
511
		signY = 1;
512
	else
513
		signY = -1;
514
 
515
	error = dx - dy;
516
 
517
	DrawBar(x2*zoom.value + canvas.x, y2*zoom.value + canvas.y,
518
			zoom.value, zoom.value, color);
519
 
520
	while((x1 != x2) || (y1 != y2))
521
	{
522
		DrawBar(x1*zoom.value + canvas.x, y1*zoom.value + canvas.y,
523
			zoom.value, zoom.value, color);
524
 
525
	   error2 = error * 2;
526
 
527
       if(error2 > calc(-dy))
528
       {
529
           error -= dy;
530
           x1 += signX;
531
       }
532
 
533
       if(error2 < dx)
534
       {
535
           error += dx;
536
           y1 += signY;
537
       }
538
	}
539
}
540
 
541
void DrawRectangleInCanvas(int x1, int y1, int x2, int y2, dword color, int target) {
542
	DrawLine(x1, y1, x2, y1, color, target);
543
	DrawLine(x2, y1, x2, y2, color, target);
544
	DrawLine(x2, y2, x1, y2, color, target);
545
	DrawLine(x1, y2, x1, y1, color, target);
546
}
547
 
548
#define SELECTION_COLOR 0xAAE5EF
549
 
550
void DrawSelection(int x1, int y1, int x2, int y2) {
551
	int p1x, p1y, p2x, p2y, r, c, old_color, new_color;
552
	dword offset;
553
 
554
	if (x1 <= x2) {
555
		p1x = x1;
556
		p2x = x2;
557
	}
558
	else {
559
		p1x = x2;
560
		p2x = x1;
561
	}
562
 
563
	if (y1 <= y2) {
564
		p2y = y1;
565
		p1y = y2;
566
	}
567
	else {
568
		p2y = y2;
569
		p1y = y1;
570
	}
571
 
572
	for (r = p1y; r >= p2y; r--) {
573
		for (c = p1x; c <= p2x; c++) {
574
 
575
			if (selection_moving_started) && (SelectTool_pointInSelection(c, r)) {
576
				offset = calc(SelectionTool_buffer_c * calc(r - selection_start_y) + calc(c - selection_start_x)) * 4;
577
				old_color = ESDWORD[SelectionTool_buffer + offset];
578
			}
579
			else {
580
				old_color = image.get_pixel(r, c);
581
			}
582
 
583
			new_color = MixColors(old_color, SELECTION_COLOR, 64);
584
 
585
			DrawBar(c*zoom.value + canvas.x, r*zoom.value + canvas.y,
586
				zoom.value, zoom.value, new_color);
587
 
588
		}
589
	}
590
}