|
69 | 69 | * FIX: Memleak on STRG+C
|
70 | 70 | * ADD: Cleanup STRG+C / STRG+V Code
|
71 | 71 | * 0.10 - ADD: Feature Request #7 Add Background Image (via double right click)
|
| 72 | + * ADD: improve UI for Select subimage |
72 | 73 | *
|
73 | 74 | * Known Bugs:
|
74 | 75 | * - Ellipsen kleiner 4x4 Pixel werden nicht erzeugt
|
|
243 | 244 | Function getChanged: Boolean;
|
244 | 245 |
|
245 | 246 | Procedure LoadColorDialogColor(Sender: TObject);
|
246 |
| - Function CursorToPixel(x, y: integer): TPoint; |
| 247 | + Function CursorToPixel(x, y: integer; ClampToImage: Boolean): TPoint; |
247 | 248 | Function CursorIsInImageWindow: Boolean;
|
248 | 249 | Procedure SetLeftColor(Const c: TOpenGL_ColorBox);
|
249 | 250 | Procedure SetRightColor(Const c: TRGBA);
|
|
655 | 656 | If fCriticalError <> '' Then exit;
|
656 | 657 | If ColorPicDialog.Visible Then exit; // ColorPicDialog Modal emulieren ;)
|
657 | 658 | fScrollInfo.ScrollPos := point(x, y);
|
658 |
| - fCursor.Compact.PixelPos := CursorToPixel(x, y); |
| 659 | + fCursor.Compact.PixelPos := CursorToPixel(x, y, true); |
659 | 660 | fCursor.LastMovePos := fCursor.Compact.PixelPos;
|
660 | 661 | fCursor.Pos := point(x, y);
|
661 | 662 | fCursor.PixelDownPos := fCursor.Compact.PixelPos;
|
|
746 | 747 | Begin
|
747 | 748 | If fCriticalError <> '' Then exit;
|
748 | 749 | If ColorPicDialog.Visible Then exit; // ColorPicDialog Modal emulieren ;)
|
749 |
| - fCursor.Compact.PixelPos := CursorToPixel(x, y); |
| 750 | + fCursor.Compact.PixelPos := CursorToPixel(x, y, true); |
| 751 | + fCursor.UnClampedMousePos := CursorToPixel(x, y, false); |
750 | 752 | fCursor.Pos := point(x, y);
|
751 | 753 | If ssLeft In shift Then Begin
|
752 | 754 | If (CursorIsInImageWindow()) And (Not ColorPicDialog.Visible) Then Begin
|
|
798 | 800 | ColorPicDialog.Visible := false;
|
799 | 801 | exit;
|
800 | 802 | End;
|
801 |
| - fCursor.Compact.PixelPos := CursorToPixel(x, y); |
| 803 | + fCursor.Compact.PixelPos := CursorToPixel(x, y, true); |
802 | 804 | fCursor.Pos := Point(x, y);
|
803 |
| - If (button = mbLeft) And (CursorIsInImageWindow()) And (Not ColorPicDialog.Visible) Then Begin |
| 805 | + If (button = mbLeft) And (Not ColorPicDialog.Visible) Then Begin |
804 | 806 | Case fCursor.Tool Of
|
805 | 807 | tEraser, tPen, tMirror,
|
806 | 808 | tLine, tEllipse, tBucket,
|
807 | 809 | tRectangle: Begin
|
808 |
| - fImage.BeginUpdate; |
809 |
| - CursorToPixelOperation(@SetImagePixelByCursor); |
810 |
| - fImage.EndUpdate; |
811 |
| - fundo.PushRecording; |
| 810 | + If (CursorIsInImageWindow()) Then Begin |
| 811 | + fImage.BeginUpdate; |
| 812 | + CursorToPixelOperation(@SetImagePixelByCursor); |
| 813 | + fImage.EndUpdate; |
| 814 | + fundo.PushRecording; |
| 815 | + End; |
812 | 816 | End;
|
813 |
| - tPipette: UnselectPipette; |
| 817 | + tPipette: If (CursorIsInImageWindow()) Then UnselectPipette; |
814 | 818 | TSelect: Begin
|
815 | 819 | If Not fCursor.Select.aSet Then Begin
|
816 | 820 | If fCursor.LeftMouseButton Then Begin
|
817 |
| - fCursor.Select.tl.x := min(fCursor.PixelDownPos.X, fCursor.Compact.PixelPos.X); |
818 |
| - fCursor.Select.tl.Y := min(fCursor.PixelDownPos.Y, fCursor.Compact.PixelPos.Y); |
819 |
| - fCursor.Select.br.x := max(fCursor.PixelDownPos.X, fCursor.Compact.PixelPos.X); |
820 |
| - fCursor.Select.br.Y := max(fCursor.PixelDownPos.Y, fCursor.Compact.PixelPos.Y); |
| 821 | + fCursor.Select.tl.x := max(0, min(fCursor.PixelDownPos.X, fCursor.UnClampedMousePos.X)); |
| 822 | + fCursor.Select.tl.Y := max(0, min(fCursor.PixelDownPos.Y, fCursor.UnClampedMousePos.Y)); |
| 823 | + fCursor.Select.br.x := min(fImage.Width - 1, max(fCursor.PixelDownPos.X, fCursor.UnClampedMousePos.X)); |
| 824 | + fCursor.Select.br.Y := min(fImage.Height - 1, max(fCursor.PixelDownPos.Y, fCursor.UnClampedMousePos.Y)); |
821 | 825 | // Wenn der User nur auf einen Pixel Klickt, dann passiert nix
|
822 | 826 | If Not (((fCursor.Select.br.x - fCursor.Select.tl.X) = 0)
|
823 | 827 | And ((fCursor.Select.br.Y - fCursor.Select.tl.Y) = 0)) Then Begin
|
|
1575 | 1579 | valid := false;
|
1576 | 1580 | If (fCursor.LeftMouseButton) Then Begin
|
1577 | 1581 | // Der Auswahl Rahmen wird gerade gezogen
|
1578 |
| - tl.x := min(fCursor.PixelDownPos.X, fCursor.Compact.PixelPos.X); |
1579 |
| - tl.Y := min(fCursor.PixelDownPos.Y, fCursor.Compact.PixelPos.Y); |
1580 |
| - br.x := max(fCursor.PixelDownPos.X, fCursor.Compact.PixelPos.X); |
1581 |
| - br.Y := max(fCursor.PixelDownPos.Y, fCursor.Compact.PixelPos.Y); |
| 1582 | + tl.x := max(0, min(fCursor.PixelDownPos.X, fCursor.UnClampedMousePos.X)); |
| 1583 | + tl.Y := max(0, min(fCursor.PixelDownPos.Y, fCursor.UnClampedMousePos.Y)); |
| 1584 | + br.x := min(fImage.Width - 1, max(fCursor.PixelDownPos.X, fCursor.UnClampedMousePos.X)); |
| 1585 | + br.Y := min(fImage.Height - 1, max(fCursor.PixelDownPos.Y, fCursor.UnClampedMousePos.Y)); |
1582 | 1586 | valid := (tl.x <> -1);
|
1583 | 1587 | End;
|
1584 | 1588 | If fCursor.Select.aSet Then Begin
|
|
1679 | 1683 | p1, p2: TPoint;
|
1680 | 1684 | Begin
|
1681 | 1685 | // Store the old position
|
1682 |
| - p1 := CursorToPixel(fCursor.Pos.X, fCursor.Pos.Y); |
| 1686 | + p1 := CursorToPixel(fCursor.Pos.X, fCursor.Pos.Y, true); |
1683 | 1687 | // Do the Zoom
|
1684 | 1688 | If ZoomIn Then Begin
|
1685 | 1689 | For i := 0 To high(ZoomLevels) Do Begin
|
|
1698 | 1702 | End;
|
1699 | 1703 | End;
|
1700 | 1704 | // Calc the new "wrong" position
|
1701 |
| - p2 := CursorToPixel(fCursor.Pos.X, fCursor.Pos.y); |
| 1705 | + p2 := CursorToPixel(fCursor.Pos.X, fCursor.Pos.y, true); |
1702 | 1706 | // "Scroll" so that the new position is the old one ;)
|
1703 | 1707 | fScrollInfo.GlobalXOffset := fScrollInfo.GlobalXOffset + (p1.x - p2.x) * fZoom Div 100 * ScreenWidth Div FOwner.Width;
|
1704 | 1708 | fScrollInfo.GlobalyOffset := fScrollInfo.GlobalyOffset + (p1.Y - p2.Y) * fZoom Div 100 * ScreenHeight Div FOwner.Height;
|
1705 | 1709 | // Let the scrollbars do their constraint thing
|
1706 | 1710 | // Nachziehen des Cursors sonst springt der beim Zoomen
|
1707 |
| - fCursor.compact.PixelPos := CursorToPixel(fCursor.Pos.x, fCursor.Pos.y); |
| 1711 | + fCursor.compact.PixelPos := CursorToPixel(fCursor.Pos.x, fCursor.Pos.y, true); |
1708 | 1712 | CheckScrollBorders();
|
1709 | 1713 | UpdateInfoLabel;
|
1710 | 1714 | End;
|
1711 | 1715 |
|
1712 |
| -Function TPixelEditor.CursorToPixel(x, y: integer): TPoint; |
| 1716 | +Function TPixelEditor.CursorToPixel(x, y: integer; ClampToImage: Boolean): TPoint; |
1713 | 1717 | Var
|
1714 | 1718 | rx, ry: Single;
|
1715 | 1719 | riy, rix: Integer;
|
|
1732 | 1736 | // 5. Limitieren auf die Image Größe
|
1733 | 1737 | rix := round(rx);
|
1734 | 1738 | riy := round(ry);
|
1735 |
| - If (rix >= 0) And (rix < fImage.Width) And |
1736 |
| - (riy >= 0) And (riy < fImage.Height) Then Begin |
| 1739 | + If ClampToImage Then Begin |
| 1740 | + If (rix >= 0) And (rix < fImage.Width) And |
| 1741 | + (riy >= 0) And (riy < fImage.Height) Then Begin |
| 1742 | + result := point(rix, riy); |
| 1743 | + End; |
| 1744 | + End |
| 1745 | + Else Begin |
1737 | 1746 | result := point(rix, riy);
|
1738 | 1747 | End;
|
1739 | 1748 | End;
|
|
0 commit comments