ソースを参照

remove ToolMoveAfter, subpixel offset

circular17 6 年 前
コミット
9cabf5149f

+ 0 - 1
lazpaint/lazpaintmainform.pas

@@ -1209,7 +1209,6 @@ begin
   if ToolManager.ToolMove(BmpPos,CurrentPressure) then
   begin
     FImageView.UpdatePicture(PictureCanvasOfs, FLayout.WorkArea, self);
-    ToolManager.ToolMoveAfter(FImageView.FormToBitmap(FormMouseMovePos)); //new BmpPos after repaint
   end else
     updateForVSCursor := true;
   UpdateToolbar;

+ 0 - 38
lazpaint/tools/utool.pas

@@ -71,7 +71,6 @@ type
     function FixLayerOffset: boolean; virtual;
     function DoToolDown(toolDest: TBGRABitmap; pt: TPoint; ptF: TPointF; rightBtn: boolean): TRect; virtual;
     function DoToolMove(toolDest: TBGRABitmap; pt: TPoint; ptF: TPointF): TRect; virtual;
-    procedure DoToolMoveAfter(pt: TPoint; ptF: TPointF); virtual;
     function DoToolUpdate(toolDest: TBGRABitmap): TRect; virtual;
     procedure OnTryStop(sender: TCustomLayerAction); virtual;
     function SelectionMaxPointDistance: single;
@@ -92,7 +91,6 @@ type
     function ToolUpdate: TRect;
     function ToolDown(X,Y: single; rightBtn: boolean): TRect;
     function ToolMove(X,Y: single): TRect;
-    procedure ToolMoveAfter(X,Y: single);
     function ToolKeyDown(var key: Word): TRect; virtual;
     function ToolKeyUp(var key: Word): TRect; virtual;
     function ToolKeyPress(var key: TUTF8Char): TRect; virtual;
@@ -280,10 +278,8 @@ type
 
     function ToolDown(X,Y: single; ARightBtn: boolean; APressure: single): boolean; overload;
     function ToolMove(X,Y: single; APressure: single): boolean; overload;
-    procedure ToolMoveAfter(X,Y: single); overload;
     function ToolDown(ACoord: TPointF; ARightBtn: boolean; APressure: single): boolean; overload;
     function ToolMove(ACoord: TPointF; APressure: single): boolean; overload;
-    procedure ToolMoveAfter(coord: TPointF); overload;
     function ToolKeyDown(var key: Word): boolean;
     function ToolKeyUp(var key: Word): boolean;
     function ToolKeyPress(var key: TUTF8Char): boolean;
@@ -589,14 +585,6 @@ begin
 end;
 {$hints on}
 
-{$hints off}
-procedure TGenericTool.DoToolMoveAfter(pt: TPoint; ptF: TPointF);
-begin
-  //nothing
-end;
-
-{$hints on}
-
 constructor TGenericTool.Create(AManager: TToolManager);
 begin
   inherited Create;
@@ -752,21 +740,6 @@ begin
   result := DoToolMove(toolDest,ptF.Round,ptF);
 end;
 
-procedure TGenericTool.ToolMoveAfter(X, Y: single);
-var
-  pt: TPoint;
-  ptF: TPointF;
-begin
-  if FixLayerOffset then
-  begin
-    x -= LayerOffset.x;
-    y -= LayerOffset.y;
-  end;
-  pt := Point(round(x),round(y));
-  ptF := PointF(x,y);
-  DoToolMoveAfter(pt,ptF);
-end;
-
 {$hints off}
 function TGenericTool.ToolKeyDown(var key: Word): TRect;
 begin
@@ -1714,12 +1687,6 @@ begin
   if result then NotifyImageOrSelectionChanged(currentTool.LastToolDrawingLayer, changed);
 end;
 
-procedure TToolManager.ToolMoveAfter(X, Y: single); overload;
-begin
-  if ToolCanBeUsed then
-    currentTool.ToolMoveAfter(X,Y);
-end;
-
 function TToolManager.ToolKeyDown(var key: Word): boolean;
 var changed: TRect;
 begin
@@ -1886,11 +1853,6 @@ begin
   result := ToolMove(ACoord.x,ACoord.y,APressure)
 end;
 
-procedure TToolManager.ToolMoveAfter(coord: TPointF); overload;
-begin
-  ToolMoveAfter(coord.x,coord.y);
-end;
-
 initialization
   fillchar({%H-}PaintTools,sizeof(PaintTools),0);
 

+ 21 - 16
lazpaint/tools/utoolbasic.pas

@@ -15,12 +15,12 @@ type
   TToolHand = class(TReadonlyTool)
   protected
     handMoving: boolean;
-    handOrigin: TPoint;
+    handOriginF: TPointF;
     function FixSelectionTransform: boolean; override;
+    function FixLayerOffset: boolean; override;
     function DoToolDown({%H-}toolDest: TBGRABitmap; pt: TPoint; {%H-}ptF: TPointF;
       {%H-}rightBtn: boolean): TRect; override;
     function DoToolMove({%H-}toolDest: TBGRABitmap; pt: TPoint; {%H-}ptF: TPointF): TRect; override;
-    procedure DoToolMoveAfter(pt: TPoint; {%H-}ptF: TPointF); override;
     function GetStatusText: string; override;
   public
     constructor Create(AManager: TToolManager); override;
@@ -416,6 +416,11 @@ begin
   Result:= false;
 end;
 
+function TToolHand.FixLayerOffset: boolean;
+begin
+  Result:= false;
+end;
+
 function TToolHand.DoToolDown(toolDest: TBGRABitmap; pt: TPoint; ptF: TPointF;
   rightBtn: boolean): TRect;
 begin
@@ -423,25 +428,25 @@ begin
   if not handMoving then
   begin
     handMoving := true;
-    handOrigin := pt;
+    handOriginF := ptF;
   end;
 end;
 
-function TToolHand.DoToolMove(toolDest: TBGRABitmap; pt: TPoint; ptF: TPointF
-  ): TRect;
+function TToolHand.DoToolMove(toolDest: TBGRABitmap; pt: TPoint; ptF: TPointF): TRect;
+var
+  newOfs: TPoint;
 begin
-  if handMoving and ((handOrigin.X <> pt.X) or (handOrigin.Y <> pt.Y)) then
+  result := EmptyRect;
+  if handMoving then
   begin
-    Manager.Image.ImageOffset := Point(Manager.Image.ImageOffset.X+pt.X-HandOrigin.X,
-                                       Manager.Image.ImageOffset.Y+pt.Y-HandOrigin.Y);
-    result := OnlyRenderChange;
-  end else
-    result := EmptyRect;
-end;
-
-procedure TToolHand.DoToolMoveAfter(pt: TPoint; ptF: TPointF);
-begin
-  if handMoving then handOrigin := pt;
+    newOfs := Point(Manager.Image.ImageOffset.X+round(ptF.X-HandOriginF.X),
+                    Manager.Image.ImageOffset.Y+round(ptF.Y-HandOriginF.Y));
+    if newOfs <> Manager.Image.ImageOffset then
+    begin
+      Manager.Image.ImageOffset := newOfs;
+      result := OnlyRenderChange;
+    end;
+  end;
 end;
 
 function TToolHand.GetStatusText: string;

+ 72 - 21
lazpaint/tools/utoollayer.pas

@@ -15,7 +15,10 @@ type
   TToolMoveLayer = class(TGenericTool)
   protected
     handMoving: boolean;
-    handOrigin: TPoint;
+    handOriginF: TPointF;
+    originalTransformBefore: TAffineMatrix;
+    layerOffsetBefore: TPoint;
+    snapToPixel: boolean;
     FStartLayerOffset: TPoint;
     FStartLayerMatrix: TAffineMatrix;
     FStartLayerOffsetDefined: boolean;
@@ -25,15 +28,17 @@ type
     function DoToolDown({%H-}toolDest: TBGRABitmap; pt: TPoint; {%H-}ptF: TPointF;
       {%H-}rightBtn: boolean): TRect; override;
     function DoToolMove({%H-}toolDest: TBGRABitmap; pt: TPoint; {%H-}ptF: TPointF): TRect; override;
-    procedure DoToolMoveAfter(pt: TPoint; {%H-}ptF: TPointF); override;
     function UseOriginal: boolean;
     procedure NeedLayerBounds;
     function GetAction: TLayerAction; override;
     function DoGetToolDrawingLayer: TBGRABitmap; override;
     procedure OnTryStop({%H-}sender: TCustomLayerAction); override;
+    function FixLayerOffset: boolean; override;
   public
+    constructor Create(AManager: TToolManager); override;
     function ToolUp: TRect; override;
     function ToolKeyDown(var key: Word): TRect; override;
+    function ToolKeyUp(var key: Word): TRect; override;
     function GetContextualToolbars: TContextualToolbars; override;
     function ToolCommand(ACommand: TToolCommand): boolean; override;
     function ToolProvideCommand(ACommand: TToolCommand): boolean; override;
@@ -152,46 +157,62 @@ begin
   if not handMoving then
   begin
     handMoving := true;
-    handOrigin := pt;
+    handOriginF := ptF;
+    idx := Manager.Image.CurrentLayerIndex;
     if not FStartLayerOffsetDefined then
     begin
       FStartLayerOffsetDefined := true;
-      idx := Manager.Image.CurrentLayerIndex;
       NeedLayerBounds;
       FStartLayerOffset := Manager.Image.LayerOffset[idx];
       FStartLayerMatrix := Manager.Image.LayerOriginalMatrix[idx];
     end;
-    if UseOriginal then Manager.Image.DraftOriginal := true;
+    if UseOriginal then
+    begin
+      Manager.Image.DraftOriginal := true;
+      originalTransformBefore := Manager.Image.LayerOriginalMatrix[idx];
+    end else
+      originalTransformBefore := AffineMatrixIdentity;
+    layerOffsetBefore := Manager.Image.LayerOffset[idx];
   end;
 end;
 
 function TToolMoveLayer.DoToolMove(toolDest: TBGRABitmap; pt: TPoint;
   ptF: TPointF): TRect;
 var idx: integer;
-  prev: TPoint;
+  dx, dy: Single;
+  newTransform: TAffineMatrix;
+  newOfs: TPoint;
 begin
-  if handMoving and ((handOrigin.X <> pt.X) or (handOrigin.Y <> pt.Y)) then
+  result := EmptyRect;
+  if handMoving then
   begin
     idx := Manager.Image.CurrentLayerIndex;
+    dx := ptF.X-HandOriginF.X;
+    dy := ptF.Y-HandOriginF.Y;
+    if snapToPixel then
+    begin
+      dx := round(dx);
+      dy := round(dy);
+    end;
     if UseOriginal then
     begin
-      Manager.Image.LayerOriginalMatrix[idx] :=
-          AffineMatrixTranslation(pt.X-HandOrigin.X,pt.Y-HandOrigin.Y)*Manager.Image.LayerOriginalMatrix[idx];
-      result := OnlyRenderChange;
+      newTransform := AffineMatrixTranslation(dx,dy)*originalTransformBefore;
+      if Manager.Image.LayerOriginalMatrix[idx] <> newTransform then
+      begin
+        Manager.Image.LayerOriginalMatrix[idx] := newTransform;
+        result := OnlyRenderChange;
+      end;
     end else
     begin
-      prev := Manager.Image.LayerOffset[idx];
-      Manager.Image.SetLayerOffset(idx, Point(prev.X+pt.X-HandOrigin.X,
-                                         prev.Y+pt.Y-HandOrigin.Y), FLayerBounds);
-      result := OnlyRenderChange;
+      newOfs := Point(layerOffsetBefore.X+round(dx),
+                      layerOffsetBefore.Y+round(dy));
+      if Manager.Image.LayerOffset[idx]<>newOfs then
+      begin
+        Manager.Image.SetLayerOffset(idx, newOfs, FLayerBounds);
+        result := OnlyRenderChange;
+      end;
     end;
-  end else
-    result := EmptyRect;
-end;
-
-procedure TToolMoveLayer.DoToolMoveAfter(pt: TPoint; ptF: TPointF);
-begin
-  if handMoving then handOrigin := pt;
+  end;
 end;
 
 function TToolMoveLayer.UseOriginal: boolean;
@@ -240,6 +261,19 @@ begin
   //nothing
 end;
 
+function TToolMoveLayer.FixLayerOffset: boolean;
+begin
+  Result:= false;
+end;
+
+constructor TToolMoveLayer.Create(AManager: TToolManager);
+begin
+  inherited Create(AManager);
+  handMoving := false;
+  FStartLayerOffsetDefined:= false;
+  snapToPixel:= false;
+end;
+
 function TToolMoveLayer.ToolUp: TRect;
 begin
   handMoving := false;
@@ -256,6 +290,12 @@ begin
     result := EmptyRect;
     Key := 0;
   end
+  else if (key = VK_SNAP) or (key = VK_SNAP2) then
+  begin
+    snapToPixel:= true;
+    result := EmptyRect;
+    key := 0;
+  end
   else if key = VK_ESCAPE then
   begin
     if FStartLayerOffsetDefined then
@@ -274,6 +314,17 @@ begin
     Result:=inherited ToolKeyDown(key);
 end;
 
+function TToolMoveLayer.ToolKeyUp(var key: Word): TRect;
+begin
+  if (key = VK_SNAP) or (key = VK_SNAP2) then
+  begin
+    snapToPixel:= false;
+    result := EmptyRect;
+    key := 0;
+  end
+  else Result:=inherited ToolKeyUp(key);
+end;
+
 function TToolMoveLayer.GetContextualToolbars: TContextualToolbars;
 begin
   Result:= [];

+ 51 - 13
lazpaint/tools/utoolselect.pas

@@ -100,14 +100,17 @@ type
 
   TToolMoveSelection = class(TTransformSelectionTool)
   protected
-    handMoving: boolean;
-    handOrigin: TPoint;
+    handMoving, snapToPixel: boolean;
+    handOriginF: TPointF;
+    selectionTransformBefore: TAffineMatrix;
     function DoToolDown({%H-}toolDest: TBGRABitmap; pt: TPoint; {%H-}ptF: TPointF;
       {%H-}rightBtn: boolean): TRect; override;
     function DoToolMove({%H-}toolDest: TBGRABitmap; pt: TPoint; {%H-}ptF: TPointF): TRect; override;
-    procedure DoToolMoveAfter(pt: TPoint; {%H-}ptF: TPointF); override;
   public
+    constructor Create(AManager: TToolManager); override;
     function ToolUp: TRect; override;
+    function ToolKeyDown(var key: Word): TRect; override;
+    function ToolKeyUp(var key: Word): TRect; override;
     destructor Destroy; override;
   end;
 
@@ -502,31 +505,44 @@ end;
 function TToolMoveSelection.DoToolDown(toolDest: TBGRABitmap; pt: TPoint;
   ptF: TPointF; rightBtn: boolean): TRect;
 begin
-  if not handMoving then
+  if not handMoving and not Manager.Image.SelectionMaskEmpty then
   begin
     handMoving := true;
-    handOrigin := pt;
+    handOriginF := ptF;
+    selectionTransformBefore := Manager.Image.SelectionTransform;
   end;
   result := EmptyRect;
 end;
 
 function TToolMoveSelection.DoToolMove(toolDest: TBGRABitmap; pt: TPoint;
   ptF: TPointF): TRect;
-var dx,dy: integer;
+var dx,dy: single;
+  newSelTransform: TAffineMatrix;
 begin
   result := EmptyRect;
-  if handMoving and ((handOrigin.X <> pt.X) or (handOrigin.Y <> pt.Y)) then
+  if handMoving then
   begin
-    dx := pt.X-HandOrigin.X;
-    dy := pt.Y-HandOrigin.Y;
-    Manager.Image.SelectionTransform := AffineMatrixTranslation(dx,dy) * Manager.Image.SelectionTransform;
-    result := OnlyRenderChange;
+    dx := ptF.X-HandOriginF.X;
+    dy := ptF.Y-HandOriginF.Y;
+    if snapToPixel then
+    begin
+      dx := round(dx);
+      dy := round(dy);
+    end;
+    newSelTransform := AffineMatrixTranslation(dx,dy) * selectionTransformBefore;
+    if Manager.Image.SelectionTransform <> newSelTransform then
+    begin
+      Manager.Image.SelectionTransform := newSelTransform;
+      result := OnlyRenderChange;
+    end;
   end;
 end;
 
-procedure TToolMoveSelection.DoToolMoveAfter(pt: TPoint; ptF: TPointF);
+constructor TToolMoveSelection.Create(AManager: TToolManager);
 begin
-  if handMoving then handOrigin := pt;
+  inherited Create(AManager);
+  handMoving := false;
+  snapToPixel:= false;
 end;
 
 function TToolMoveSelection.ToolUp: TRect;
@@ -535,6 +551,28 @@ begin
   result := EmptyRect;
 end;
 
+function TToolMoveSelection.ToolKeyDown(var key: Word): TRect;
+begin
+  if (Key = VK_SNAP) or (Key = VK_SNAP2) then
+  begin
+    result := EmptyRect;
+    snapToPixel:= true;
+    key := 0;
+  end else
+    Result:=inherited ToolKeyDown(key);
+end;
+
+function TToolMoveSelection.ToolKeyUp(var key: Word): TRect;
+begin
+  if (Key = VK_SNAP) or (Key = VK_SNAP2) then
+  begin
+    result := EmptyRect;
+    snapToPixel:= false;
+    key := 0;
+  end else
+    Result:=inherited ToolKeyUp(key);
+end;
+
 destructor TToolMoveSelection.Destroy;
 begin
   if handMoving then handMoving := false;