Преглед на файлове

auto-switch between selection tools

Juliette ELSASS преди 1 година
родител
ревизия
bd57f3cc53
променени са 5 файла, в които са добавени 106 реда и са изтрити 12 реда
  1. 8 1
      lazpaint/lazpaintmainform.pas
  2. 12 4
      lazpaint/tools/utool.pas
  3. 57 3
      lazpaint/tools/utoolbasic.pas
  4. 13 2
      lazpaint/tools/utoollayer.pas
  5. 16 2
      lazpaint/tools/utoolselect.pas

+ 8 - 1
lazpaint/lazpaintmainform.pas

@@ -859,6 +859,7 @@ type
     procedure CallScriptFunction(AParams:TVariableSet); overload;
     procedure ZoomFitIfTooBig;
     function RunToolCommand(AToolCommand: TToolCommand): boolean;
+    procedure UpdateSelectionHighlightMode;
     property Scripting: TScriptContext read GetScriptContext;
     property Image: TLazPaintImage read GetImage;
 
@@ -3111,7 +3112,7 @@ begin
         ToolManager.ToolMove(texMapBounds.Right-0.5, texMapBounds.Bottom-0.5, 1);
         ToolManager.ToolUp;
       end;
-      FLayout.FillSelectionHighlight := ToolManager.DisplayFilledSelection and not FShowSelectionNormal;
+      UpdateSelectionHighlightMode;
     except
       on ex:Exception do
       begin
@@ -4137,6 +4138,7 @@ begin
     UpdateToolImage;
     UpdatePenWidthToolbar;
     UpdateCurveModeToolbar;
+    UpdateSelectionHighlightMode;
   end;
 end;
 
@@ -4167,6 +4169,11 @@ begin
   else result := false;
 end;
 
+procedure TFMain.UpdateSelectionHighlightMode;
+begin
+  FLayout.FillSelectionHighlight := ToolManager.DisplayFilledSelection and not FShowSelectionNormal;
+end;
+
 function TFMain.TryOpenFileUTF8(filenameUTF8: string; AddToRecent: Boolean;
      ALoadedImage: PImageEntry; ASkipDialogIfSingleImage: boolean;
      AAllowDuplicate: boolean; AEntryToLoad: integer): Boolean;

+ 12 - 4
lazpaint/tools/utool.pas

@@ -191,6 +191,7 @@ type
     FConfigProvider: IConfigProvider;
     FOnQueryColorTarget: TOnQueryColorTargetHandler;
     FShouldExitTool: boolean;
+    FSwitchAfterExitTool: TPaintToolType;
     FImage: TLazPaintImage;
     FBlackAndWhite: boolean;
     FScriptContext: TScriptContext;
@@ -509,6 +510,7 @@ type
     function IsBackEditGradTexPoints: boolean;
     function IsOutlineEditGradTexPoints: boolean;
     procedure QueryExitTool;
+    procedure QueryExitTool(ASwitchTo: TPaintToolType);
     procedure QueryColorTarget(ATarget: TVectorialFill);
 
     function RenderTool(formBitmap: TBGRABitmap): TRect;
@@ -1588,10 +1590,7 @@ begin
   if FShouldExitTool then
   begin
     FShouldExitTool:= false;
-    if FCurrentToolType in[ptRect,ptEllipse,ptPolygon,ptSpline,ptText,ptPhong,ptGradient] then
-      SetCurrentToolType(ptEditShape)
-    else
-      SetCurrentToolType(ptHand);
+    SetCurrentToolType(FSwitchAfterExitTool);
     result := true;
   end else
     result := false;
@@ -3891,8 +3890,17 @@ begin
 end;
 
 procedure TToolManager.QueryExitTool;
+begin
+  if FCurrentToolType in[ptRect,ptEllipse,ptPolygon,ptSpline,ptText,ptPhong,ptGradient] then
+    QueryExitTool(ptEditShape)
+  else
+    QueryExitTool(ptHand);
+end;
+
+procedure TToolManager.QueryExitTool(ASwitchTo: TPaintToolType);
 begin
   FShouldExitTool:= true;
+  FSwitchAfterExitTool:= ASwitchTo;
 end;
 
 procedure TToolManager.QueryColorTarget(ATarget: TVectorialFill);

+ 57 - 3
lazpaint/tools/utoolbasic.pas

@@ -15,7 +15,7 @@ type
 
   TToolHand = class(TReadonlyTool)
   protected
-    handMoving: boolean;
+    handMoving, samePosition: boolean;
     handOriginF: TPointF;
     function FixSelectionTransform: boolean; override;
     function FixLayerOffset: boolean; override;
@@ -23,6 +23,7 @@ type
       {%H-}rightBtn: boolean): TRect; override;
     function DoToolMove({%H-}toolDest: TBGRABitmap; {%H-}pt: TPoint; ptF: TPointF): TRect; override;
     function GetStatusText: string; override;
+    procedure TrySelect(ptF: TPointF);
   public
     constructor Create(AManager: TToolManager); override;
     function ToolUp: TRect; override;
@@ -81,7 +82,7 @@ type
 implementation
 
 uses Types, Graphics, ugraph, Controls, LazPaintType,
-  UResourceStrings, BGRAPen, math;
+  UResourceStrings, BGRAPen, math, BGRATransform;
 
 { TToolErase }
 
@@ -505,6 +506,7 @@ begin
   if not handMoving then
   begin
     handMoving := true;
+    samePosition := true;
     handOriginF := ptF;
   end;
 end;
@@ -521,6 +523,7 @@ begin
     if newOfs <> Manager.Image.ImageOffset then
     begin
       Manager.Image.ImageOffset := newOfs;
+      samePosition := false;
       result := OnlyRenderChange;
     end;
   end;
@@ -562,6 +565,50 @@ begin
   end;
 end;
 
+procedure TToolHand.TrySelect(ptF: TPointF);
+var
+  untransformedPtF: TPointF;
+  c: TBGRAPixel;
+  ofs: TPoint;
+  original: TVectorOriginal;
+  i: Integer;
+begin
+  if not Manager.Image.SelectionMaskEmpty and
+    not Manager.Image.SelectionLayerIsEmpty and
+    IsAffineMatrixInversible(Manager.Image.SelectionTransform) then
+  begin
+    untransformedPtF := AffineMatrixInverse(Manager.Image.SelectionTransform) * ptF;
+    c := Manager.Image.SelectionLayerReadonly.GetPixel(untransformedPtF.X,untransformedPtF.Y);
+    if c.alpha <> 0 then
+    begin
+      Manager.QueryExitTool(ptMoveSelection);
+      exit;
+    end;
+  end;
+  if GetCurrentLayerKind = lkVectorial then
+  begin
+    original := Manager.Image.LayerOriginal[Manager.Image.CurrentLayerIndex] as TVectorOriginal;
+    for i := original.ShapeCount-1 downto 0 do
+    begin
+      if original.Shape[i].PointInShape(ptF) then
+      begin
+        original.SelectShape(i);
+        Manager.QueryExitTool(ptEditShape);
+        exit;
+      end;
+    end;
+  end else
+  begin
+    ofs := Manager.Image.LayerOffset[Manager.Image.CurrentLayerIndex];
+    c := Manager.Image.CurrentLayerReadOnly.GetPixel(ptF.X - ofs.X,ptF.Y - ofs.Y);
+    if c.alpha <> 0 then
+    begin
+      Manager.QueryExitTool(ptMoveLayer);
+      exit;
+    end;
+  end;
+end;
+
 constructor TToolHand.Create(AManager: TToolManager);
 begin
   inherited Create(AManager);
@@ -570,7 +617,14 @@ end;
 
 function TToolHand.ToolUp: TRect;
 begin
-  handMoving := false;
+  if handMoving then
+  begin
+    handMoving := false;
+    if samePosition then
+    begin
+      TrySelect(handOriginF);
+    end;
+  end;
   result := EmptyRect;
 end;
 

+ 13 - 2
lazpaint/tools/utoollayer.pas

@@ -16,6 +16,7 @@ type
   TToolMoveLayer = class(TGenericTool)
   protected
     handMoving: boolean;
+    notMovedAtAll: boolean;
     handOriginF: TPointF;
     originalTransformBefore: TAffineMatrix;
     layerOffsetBefore: TPoint;
@@ -152,12 +153,17 @@ end;
 
 function TToolMoveLayer.DoToolDown(toolDest: TBGRABitmap; pt: TPoint;
   ptF: TPointF; rightBtn: boolean): TRect;
+var
+  ofs: TPoint;
 begin
   result := EmptyRect;
   if not handMoving then
   begin
     GetAction;
     handMoving := true;
+    ofs := LayerOffset;
+    notMovedAtAll:= (toolDest = nil) or
+      (toolDest.GetPixel(ptF.X - ofs.X, ptF.Y - ofs.Y).alpha = 0);
     handOriginF := ptF;
     if UseOriginal then Manager.Image.DraftOriginal := true;
     SaveOffsetBefore;
@@ -294,9 +300,14 @@ end;
 
 function TToolMoveLayer.ToolUp: TRect;
 begin
-  handMoving := false;
+  if handMoving then
+  begin
+    handMoving := false;
+    if UseOriginal then Manager.Image.DraftOriginal := false;
+    if notMovedAtAll then
+      Manager.QueryExitTool;
+  end;
   result := EmptyRect;
-  if UseOriginal then Manager.Image.DraftOriginal := false;
 end;
 
 function TToolMoveLayer.DoToolKeyDown(var key: Word): TRect;

+ 16 - 2
lazpaint/tools/utoolselect.pas

@@ -102,7 +102,7 @@ type
 
   TToolMoveSelection = class(TTransformSelectionTool)
   protected
-    handMoving: boolean;
+    handMoving, notMovedAtAll: boolean;
     handOriginF: TPointF;
     selectionTransformBefore: TAffineMatrix;
     function DoToolDown({%H-}toolDest: TBGRABitmap; {%H-}pt: TPoint; ptF: TPointF;
@@ -570,10 +570,19 @@ end;
 
 function TToolMoveSelection.DoToolDown(toolDest: TBGRABitmap; pt: TPoint;
   ptF: TPointF; rightBtn: boolean): TRect;
+var
+  untransformedPtF: TPointF;
 begin
   if not handMoving and not Manager.Image.SelectionMaskEmpty then
   begin
     handMoving := true;
+    notMovedAtAll := true;
+    if IsAffineMatrixInversible(Manager.Image.SelectionTransform) then
+    begin
+      untransformedPtF := AffineMatrixInverse(Manager.Image.SelectionTransform) * ptF;
+      if Manager.Image.SelectionMaskReadonly.GetPixel(untransformedPtF.X, untransformedPtF.Y).green <> 0 then
+        notMovedAtAll:= false;
+    end;
     handOriginF := ptF;
     selectionTransformBefore := Manager.Image.SelectionTransform;
   end;
@@ -599,6 +608,7 @@ begin
     if Manager.Image.SelectionTransform <> newSelTransform then
     begin
       Manager.Image.SelectionTransform := newSelTransform;
+      notMovedAtAll := false;
       result := OnlyRenderChange;
     end;
   end;
@@ -612,7 +622,11 @@ end;
 
 function TToolMoveSelection.ToolUp: TRect;
 begin
-  handMoving := false;
+  if handMoving then
+  begin
+    handMoving := false;
+    if notMovedAtAll then Manager.QueryExitTool;
+  end;
   result := EmptyRect;
 end;