Commit a371c87

Nick committed on
Add drag 'n drop in the tracker grid, closes #16
commit a371c87e55414b3407eff116f2b522a5a605670c parent c707ea9
2 changed files +103−34
Modifiedtracker.pas +1−1
@@ -1274,8 +1274,8 @@ begin
1274 1274
1275 // Get the emulator ready to make sound... 1275 // Get the emulator ready to make sound...
1276 EnableSound; 1276 EnableSound;
1277 StartPlayback;
1278 HaltPlayback; 1277 HaltPlayback;
1278 StartPlayback;
1279 1279
1280 // Start the Oscilloscope repaint timer 1280 // Start the Oscilloscope repaint timer
1281 OscilloscopeUpdateTimer.Enabled := ScopesOn; 1281 OscilloscopeUpdateTimer.Enabled := ScopesOn;
Modifiedtrackergrid.pas +102−33
@@ -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);