@@ -67,7 +67,9 @@ type |
| 67 |
procedure DblClick; override; |
67 |
procedure DblClick; override; |
| 68 |
procedure KeyDown(var Key: Word; Shift: TShiftState); override; |
68 |
procedure KeyDown(var Key: Word; Shift: TShiftState); override; |
| 69 |
private |
69 |
private |
| 70 |
procedure PerformPaste(Paste: TSelection); |
70 |
function GetSelection: TSelection; |
|
|
71 |
procedure PerformPaste(Paste: TSelection); overload; |
|
|
72 |
procedure PerformPaste(Paste: TSelection; Where: TSelectionPos); overload; |
| 71 |
procedure PerformCopy; |
73 |
procedure PerformCopy; |
| 72 |
procedure DoPaste(var Msg: TLMessage); message LM_PASTE; |
74 |
procedure DoPaste(var Msg: TLMessage); message LM_PASTE; |
| 73 |
procedure DoCopy(var Msg: TLMessage); message LM_COPY; |
75 |
procedure DoCopy(var Msg: TLMessage); message LM_COPY; |
@@ -108,6 +110,10 @@ type |
| 108 |
|
110 |
|
| 109 |
MouseButtonDown: Boolean; |
111 |
MouseButtonDown: Boolean; |
| 110 |
Selecting: Boolean; |
112 |
Selecting: Boolean; |
|
|
113 |
DraggingSelection: Boolean; |
|
|
114 |
MouseMoveHappened: Boolean; |
|
|
115 |
DragSelCursor, DragSelOther: TSelectionPos; |
|
|
116 |
DragOffsetY: Integer; |
| 111 |
|
117 |
|
| 112 |
Performed: TUndoDeque; |
118 |
Performed: TUndoDeque; |
| 113 |
Recall: TRedoStack; |
119 |
Recall: TRedoStack; |
@@ -284,6 +290,8 @@ begin |
| 284 |
Canvas.Rectangle(R); |
290 |
Canvas.Rectangle(R); |
| 285 |
|
291 |
|
| 286 |
RenderSelectedArea; |
292 |
RenderSelectedArea; |
|
|
293 |
if DraggingSelection then |
|
|
294 |
Canvas.DrawFocusRect(SelectionsToRect(DragSelCursor, DragSelOther)); |
| 287 |
end; |
295 |
end; |
| 288 |
|
296 |
|
| 289 |
procedure TTrackerGrid.MouseDown(Button: TMouseButton; Shift: TShiftState; X, |
297 |
procedure TTrackerGrid.MouseDown(Button: TMouseButton; Shift: TShiftState; X, |
@@ -292,7 +300,8 @@ var |
| 292 |
Clicked: TSelectionPos; |
300 |
Clicked: TSelectionPos; |
| 293 |
begin |
301 |
begin |
| 294 |
inherited MouseDown(Button, Shift, X, Y); |
302 |
inherited MouseDown(Button, Shift, X, Y); |
| 295 |
if (Button = mbRight) and Selecting then Exit; |
303 |
|
|
|
304 |
if (Button = mbRight) and (Cursor <> Other) then Exit; |
| 296 |
|
305 |
|
| 297 |
if (Button = mbLeft) and not (ssShift in Shift) then |
306 |
if (Button = mbLeft) and not (ssShift in Shift) then |
| 298 |
MouseButtonDown := True; |
307 |
MouseButtonDown := True; |
@@ -305,38 +314,92 @@ begin |
| 305 |
if ssShift in Shift then |
314 |
if ssShift in Shift then |
| 306 |
Other := Clicked |
315 |
Other := Clicked |
| 307 |
else begin |
316 |
else begin |
| 308 |
Cursor := Clicked; |
317 |
if not SelectionsToRect(Cursor, Other).IntersectsWith(SelectionToRect(Clicked)) then begin |
| 309 |
Other := Cursor; |
318 |
Cursor := Clicked; |
| 310 |
Selecting := False; |
319 |
Other := Cursor; |
|
|
320 |
Selecting := False; |
|
|
321 |
end |
| 311 |
end; |
322 |
end; |
| 312 |
|
323 |
|
| 313 |
NormalizeCursors; |
324 |
MouseMoveHappened := False; |
| 314 |
|
325 |
|
|
|
326 |
NormalizeCursors; |
| 315 |
Invalidate; |
327 |
Invalidate; |
| 316 |
end; |
328 |
end; |
| 317 |
|
329 |
|
| 318 |
procedure TTrackerGrid.MouseMove(Shift: TShiftState; X, Y: Integer); |
330 |
procedure TTrackerGrid.MouseMove(Shift: TShiftState; X, Y: Integer); |
|
|
331 |
var |
|
|
332 |
Click, Drag: TSelectionPos; |
|
|
333 |
SelectionRect: TRect; |
| 319 |
begin |
334 |
begin |
| 320 |
inherited MouseMove(Shift, X, Y); |
335 |
inherited MouseMove(Shift, X, Y); |
| 321 |
|
336 |
|
|
|
337 |
Click := MousePosToSelection(X, Y); |
|
|
338 |
if MouseButtonDown |
|
|
339 |
and ((Cursor <> Other) or (Cursor.Y <> Other.Y)) // <> is overridden |
|
|
340 |
and (not Selecting) |
|
|
341 |
and (not MouseMoveHappened) |
|
|
342 |
and SelectionsToRect(Cursor, Other).IntersectsWith(SelectionToRect(Click)) then begin |
|
|
343 |
DraggingSelection := True; |
|
|
344 |
SelectionRect := SelectionsToRect(Cursor, Other); |
|
|
345 |
DragOffsetY := Y - SelectionRect.Top; |
|
|
346 |
end; |
|
|
347 |
|
| 322 |
if MouseButtonDown then begin |
348 |
if MouseButtonDown then begin |
| 323 |
Selecting := True; |
349 |
if DraggingSelection then begin |
| 324 |
Other := MousePosToSelection(X, Y); |
350 |
Drag := MousePosToSelection(X, Y - DragOffsetY); |
|
|
351 |
DragSelCursor := Cursor; |
|
|
352 |
DragSelOther := Other; |
| 325 |
|
353 |
|
| 326 |
ClampCursors; |
354 |
DragSelCursor.X := Drag.X; |
|
|
355 |
DragSelCursor.Y := Drag.Y; |
| 327 |
|
356 |
|
| 328 |
Invalidate; |
357 |
DragSelOther.X := DragSelCursor.X + (Other.X - Cursor.X); |
|
|
358 |
DragSelOther.Y := DragSelCursor.Y + (Other.Y - Cursor.Y); |
|
|
359 |
|
|
|
360 |
Invalidate; |
|
|
361 |
end |
|
|
362 |
else begin |
|
|
363 |
Selecting := True; |
|
|
364 |
Other := Click; |
|
|
365 |
|
|
|
366 |
ClampCursors; |
|
|
367 |
Invalidate; |
|
|
368 |
end; |
| 329 |
end; |
369 |
end; |
|
|
370 |
|
|
|
371 |
MouseMoveHappened := True; |
| 330 |
end; |
372 |
end; |
| 331 |
|
373 |
|
| 332 |
procedure TTrackerGrid.MouseUp(Button: TMouseButton; Shift: TShiftState; X, |
374 |
procedure TTrackerGrid.MouseUp(Button: TMouseButton; Shift: TShiftState; X, |
| 333 |
Y: Integer); |
375 |
Y: Integer); |
|
|
376 |
var |
|
|
377 |
Selection: TSelection; |
| 334 |
begin |
378 |
begin |
| 335 |
inherited MouseUp(Button, Shift, X, Y); |
379 |
inherited MouseUp(Button, Shift, X, Y); |
| 336 |
|
380 |
|
| 337 |
NormalizeCursors; |
381 |
if (not Selecting) and (not MouseMoveHappened) then begin |
|
|
382 |
Cursor := MousePosToSelection(X, Y); |
|
|
383 |
Other := Cursor; |
|
|
384 |
end; |
| 338 |
|
385 |
|
|
|
386 |
Selecting := False; |
|
|
387 |
MouseMoveHappened := False; |
| 339 |
MouseButtonDown := False; |
388 |
MouseButtonDown := False; |
|
|
389 |
|
|
|
390 |
if DraggingSelection then begin |
|
|
391 |
Selection := GetSelection; |
|
|
392 |
EraseSelection; |
|
|
393 |
PerformPaste(Selection, DragSelCursor); |
|
|
394 |
Cursor := DragSelCursor; |
|
|
395 |
Other := DragSelOther; |
|
|
396 |
|
|
|
397 |
DraggingSelection := False; |
|
|
398 |
SaveUndoState; |
|
|
399 |
end; |
|
|
400 |
|
|
|
401 |
NormalizeCursors; |
|
|
402 |
Invalidate; |
| 340 |
end; |
403 |
end; |
| 341 |
|
404 |
|
| 342 |
procedure TTrackerGrid.DblClick; |
405 |
procedure TTrackerGrid.DblClick; |
@@ -388,13 +451,28 @@ begin |
| 388 |
if not (ssShift in Shift) then |
451 |
if not (ssShift in Shift) then |
| 389 |
Other := Cursor; |
452 |
Other := Cursor; |
| 390 |
|
453 |
|
| 391 |
Selecting := ssShift in Shift; |
|
|
| 392 |
|
|
|
| 393 |
ClampCursors; |
454 |
ClampCursors; |
| 394 |
Invalidate |
455 |
Invalidate |
| 395 |
end; |
456 |
end; |
| 396 |
|
457 |
|
| 397 |
procedure TTrackerGrid.PerformPaste(Paste: TSelection); |
458 |
function TTrackerGrid.GetSelection: TSelection; |
|
|
459 |
var |
|
|
460 |
R: Integer; |
|
|
461 |
Rect: TRect; |
|
|
462 |
SelRow: TSelectionRow; |
|
|
463 |
begin |
|
|
464 |
NormalizeCursors; |
|
|
465 |
|
|
|
466 |
Rect := SelectionGridRect; |
|
|
467 |
SetLength(Result, Rect.Height+1); |
|
|
468 |
R := 0; |
|
|
469 |
for SelRow in TSelectionEnumerator.Create(Patterns, Cursor, Other) do begin |
|
|
470 |
Result[R] := SelRow; |
|
|
471 |
Inc(R) |
|
|
472 |
end; |
|
|
473 |
end; |
|
|
474 |
|
|
|
475 |
procedure TTrackerGrid.PerformPaste(Paste: TSelection; Where: TSelectionPos); |
| 398 |
procedure OverlayCell(var Cell1: TCell; const Cell2: TSelectedCell); |
476 |
procedure OverlayCell(var Cell1: TCell; const Cell2: TSelectedCell); |
| 399 |
begin |
477 |
begin |
| 400 |
if cpNote in Cell2.Parts then Cell1.Note := Cell2.Cell.Note; |
478 |
if cpNote in Cell2.Parts then Cell1.Note := Cell2.Cell.Note; |
@@ -408,12 +486,13 @@ var |
| 408 |
begin |
486 |
begin |
| 409 |
try |
487 |
try |
| 410 |
for Y := 0 to High(Paste) do begin |
488 |
for Y := 0 to High(Paste) do begin |
| 411 |
if Cursor.Y+Y > High(TPattern) then Break; |
489 |
if not InRange(Where.Y+Y, Low(TPattern), High(TPattern)) then Continue; |
| 412 |
for X := 0 to High(Paste[Y]) do begin |
490 |
for X := 0 to High(Paste[Y]) do begin |
| 413 |
if Cursor.X+X > High(Patterns) then Break; |
491 |
if not InRange(Where.X+X, Low(Patterns), High(Patterns)) then Continue; |
| 414 |
OverlayCell(Patterns[Cursor.X + X]^[Cursor.Y + Y], Paste[Y, X]); |
492 |
OverlayCell(Patterns[Where.X + X]^[Where.Y + Y], Paste[Y, X]); |
| 415 |
end; |
493 |
end; |
| 416 |
end; |
494 |
end; |
|
|
495 |
Cursor := Where; |
| 417 |
Other.X := Cursor.X + X; |
496 |
Other.X := Cursor.X + X; |
| 418 |
Other.Y := Cursor.Y + Y; |
497 |
Other.Y := Cursor.Y + Y; |
| 419 |
Cursor.SelectedPart := Low(TCellPart); |
498 |
Cursor.SelectedPart := Low(TCellPart); |
@@ -424,6 +503,11 @@ begin |
| 424 |
end; |
503 |
end; |
| 425 |
end; |
504 |
end; |
| 426 |
|
505 |
|
|
|
506 |
procedure TTrackerGrid.PerformPaste(Paste: TSelection); |
|
|
507 |
begin |
|
|
508 |
PerformPaste(Paste, Cursor); |
|
|
509 |
end; |
|
|
510 |
|
| 427 |
procedure TTrackerGrid.PerformCopy; |
511 |
procedure TTrackerGrid.PerformCopy; |
| 428 |
begin |
512 |
begin |
| 429 |
|
513 |
|
@@ -455,23 +539,8 @@ begin |
| 455 |
end; |
539 |
end; |
| 456 |
|
540 |
|
| 457 |
procedure TTrackerGrid.DoCopy(var Msg: TLMessage); |
541 |
procedure TTrackerGrid.DoCopy(var Msg: TLMessage); |
| 458 |
var |
|
|
| 459 |
Selection: TSelection; |
|
|
| 460 |
R: Integer; |
|
|
| 461 |
Rect: TRect; |
|
|
| 462 |
SelRow: TSelectionRow; |
|
|
| 463 |
begin |
542 |
begin |
| 464 |
NormalizeCursors; |
543 |
CopyCells(GetSelection); |
| 465 |
|
|
|
| 466 |
Rect := SelectionGridRect; |
|
|
| 467 |
SetLength(Selection, Rect.Height+1); |
|
|
| 468 |
R := 0; |
|
|
| 469 |
for SelRow in TSelectionEnumerator.Create(Patterns, Cursor, Other) do begin |
|
|
| 470 |
Selection[R] := SelRow; |
|
|
| 471 |
Inc(R) |
|
|
| 472 |
end; |
|
|
| 473 |
|
|
|
| 474 |
CopyCells(Selection); |
|
|
| 475 |
end; |
544 |
end; |
| 476 |
|
545 |
|
| 477 |
procedure TTrackerGrid.DoCut(var Msg: TLMessage); |
546 |
procedure TTrackerGrid.DoCut(var Msg: TLMessage); |