Subversion Repositories Kolibri OS

Rev

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