Ver Fonte

refactor layer access, allow multiple layers

Johann há 6 anos atrás
pai
commit
5870fb6fcb
1 ficheiros alterados com 159 adições e 105 exclusões
  1. 159 105
      vectoredit/umain.pas

+ 159 - 105
vectoredit/umain.pas

@@ -212,6 +212,7 @@ type
     function GetPenStyle: TBGRAPenStyle;
     function GetPenWidth: single;
     function GetSplineStyle: TSplineStyle;
+    function GetVectorOriginal: TVectorOriginal;
     function GetVectorTransform: TAffineMatrix;
     function GetZoomFactor: single;
     procedure ImageChange(ARectF: TRectF);
@@ -236,6 +237,7 @@ type
     procedure SetPenWidth(AValue: single);
     procedure SetPhongShapeKind(AValue: TPhongShapeKind);
     procedure SetSplineStyle(AValue: TSplineStyle);
+    procedure SetVectorLayerIndex(AValue: integer);
     procedure SetZoomFactor(AValue: single);
     procedure SplineToolbarClick(Sender: TObject);
     procedure TextPenPhongClick(Sender: TObject);
@@ -279,17 +281,18 @@ type
     procedure TextFontTextBoxChange(Sender: TObject);
     procedure TextFontTextBoxEnter(Sender: TObject);
     procedure TextFontTextBoxExit(Sender: TObject);
+    procedure NewImage(AWidth,AHeight: integer);
+    procedure SetImage(AImage: TBGRALazPaintImage);
   public
     { public declarations }
     img: TBGRALazPaintImage;
+    FVectorLayerIndex: Integer;
     filename: string;
-    vectorOriginal: TVectorOriginal;
     zoom: TAffineMatrix;
     newShape: TVectorShape;
     justDown, shapeAdded: boolean;
     newStartPoint: TPointF;
     newButton: TMouseButton;
-    vectorLayer: Integer;
     mouseState: TShiftState;
     baseCaption: string;
     procedure DoCopy;
@@ -305,6 +308,8 @@ type
     property joinStyle: TPenJoinStyle read FPenJoinStyle write SetPenJoinStyle;
     property phongShapeKind: TPhongShapeKind read FPhongShapeKind write SetPhongShapeKind;
     property zoomFactor: single read GetZoomFactor write SetZoomFactor;
+    property vectorOriginal: TVectorOriginal read GetVectorOriginal;
+    property vectorLayerIndex: integer read FVectorLayerIndex write SetVectorLayerIndex;
   end;
 
 var
@@ -380,16 +385,7 @@ begin
     with (ActionList.Actions[i] as TAction) do
       if Hint = '' then Hint := Caption;
 
-  img := TBGRALazPaintImage.Create(640,480);
-  filename := '';
-  vectorOriginal := TVectorOriginal.Create;
-  vectorLayer := img.AddLayerFromOwnedOriginal(vectorOriginal);
-  img.LayerOriginalMatrix[vectorLayer] := AffineMatrixScale(1,1);
-  vectorOriginal.OnSelectShape:= @OnSelectShape;
-  img.OnOriginalEditingChange:= @OnEditingChange;
-  img.EditorFocused:= BGRAVirtualScreen1.Focused;
-  img.OnEditorFocusChanged:=@OnEditorFocusChange;
-  img.OnOriginalChange:= @OnOriginalChange;
+  NewImage(640,480);
 
   zoom := AffineMatrixScale(1,1);
   FPenStyleMenu := TPopupMenu.Create(nil);
@@ -482,7 +478,10 @@ begin
   if FFlattened = nil then
     UpdateFlattenedImage(rect(0,0,img.Width,img.Height), false);
   Bitmap.StretchPutImage(zoomBounds, FFlattened, dmLinearBlend);
-  FLastEditorBounds := img.DrawEditor(Bitmap, vectorLayer, zoom, EditorPointSize);
+  if vectorLayerIndex <> -1 then
+    FLastEditorBounds := img.DrawEditor(Bitmap, vectorLayerIndex, zoom, EditorPointSize)
+  else
+    FLastEditorBounds := EmptyRect;
 end;
 
 procedure TForm1.BGRAVirtualScreen1MouseDown(Sender: TObject;
@@ -612,30 +611,25 @@ end;
 procedure TForm1.FileOpenExecute(Sender: TObject);
 var
   openedImg: TBGRALazPaintImage;
-  openedLayer: Integer;
-  openedLayerOriginal: TBGRALayerCustomOriginal;
+  openedLayer, i: Integer;
 begin
   if OpenDialog1.Execute then
   begin
     openedImg := TBGRALazPaintImage.Create;
     try
       openedImg.LoadFromFile(OpenDialog1.FileName);
-      if openedImg.NbLayers <> 1 then raise exception.Create('Expecting one layer only');
-      openedLayer := 0;
-      openedLayerOriginal := openedImg.LayerOriginal[openedLayer];
-      if (openedLayerOriginal = nil) or not (openedLayerOriginal is TVectorOriginal) then
-        raise exception.Create('Not a vectorial image');
-
-      img.Free;
-      img := openedImg;
+      openedLayer := -1;
+      for i := 0 to openedImg.NbLayers-1 do
+        if openedImg.LayerOriginalClass[i] = TVectorOriginal then
+        begin
+          openedLayer:= i;
+          break;
+        end;
+      if openedLayer= -1 then raise exception.Create('Cannot find any vector layer');
+
+      SetImage(openedImg);
       openedImg := nil;
-      vectorLayer:= openedLayer;
-      vectorOriginal := TVectorOriginal(openedLayerOriginal);
-      vectorOriginal.OnSelectShape:= @OnSelectShape;
-      img.OnOriginalEditingChange:= @OnEditingChange;
-      img.OnOriginalChange:= @OnOriginalChange;
-      img.EditorFocused := BGRAVirtualScreen1.Focused;
-      img.OnEditorFocusChanged:=@OnEditorFocusChange;
+      vectorLayerIndex:= openedLayer;
       filename:= OpenDialog1.FileName;
       UpdateTitleBar;
       ImageChangesCompletely;
@@ -752,49 +746,52 @@ begin
   if handled then UpdateTextAlignment;
   UpdateViewCursor(cur);
 
-  ptF := ImgCoordToOriginalCoord(imgPtF);
-  if justDown and not Assigned(newShape) and IsCreateShapeTool(currentTool) and
-    (VectLen(ptF-newStartPoint) >= EditorPointSize) then
-  begin
-    vectorOriginal.DeselectShape;
-    newShape := CreateShape(newStartPoint,ptF);
-    shapeAdded := false;
-    rF := newShape.GetRenderBounds(InfiniteRect, vectorTransform);
-    ImageChange(rF);
-    justDown := false;
-    if IsEmptyRectF(rF) and newShape.CreateEmpty then
-    begin
-      vectorOriginal.DeselectShape;
-      vectorOriginal.AddShape(newShape);
-      vectorOriginal.SelectShape(newShape);
-      currentTool:= ptHand;
-      shapeAdded := true;
-    end;
-  end else
-  if Assigned(newShape) then
+  if Assigned(vectorOriginal) then
   begin
-    prevRF := newShape.GetRenderBounds(InfiniteRect, vectorTransform);
-    newShape.QuickDefine(newStartPoint,ptF);
-    if (vsfBackFill in newShape.Fields) and (newShape.BackFill.FillType in [vftGradient, vftTexture]) then
+    ptF := ImgCoordToOriginalCoord(imgPtF);
+    if justDown and not Assigned(newShape) and IsCreateShapeTool(currentTool) and
+      (VectLen(ptF-newStartPoint) >= EditorPointSize) then
     begin
-      vectorFill := BackFillControl.CreateShapeFill(newShape);
-      newShape.BackFill := vectorFill;
-      vectorFill.Free;
-    end;
-    if (vsfPenFill in newShape.Fields) and (newShape.PenFill.FillType in [vftGradient, vftTexture]) then
-    begin
-      vectorFill := PenFillControl.CreateShapeFill(newShape);
-      newShape.PenFill := vectorFill;
-      vectorFill.Free;
-    end;
-    if (vsfOutlineFill in newShape.Fields) and (newShape.OutlineFill.FillType in [vftGradient, vftTexture]) then
+      vectorOriginal.DeselectShape;
+      newShape := CreateShape(newStartPoint,ptF);
+      shapeAdded := false;
+      rF := newShape.GetRenderBounds(InfiniteRect, vectorTransform);
+      ImageChange(rF);
+      justDown := false;
+      if IsEmptyRectF(rF) and newShape.CreateEmpty then
+      begin
+        vectorOriginal.DeselectShape;
+        vectorOriginal.AddShape(newShape);
+        vectorOriginal.SelectShape(newShape);
+        currentTool:= ptHand;
+        shapeAdded := true;
+      end;
+    end else
+    if Assigned(newShape) then
     begin
-      vectorFill := OutlineFillControl.CreateShapeFill(newShape);
-      newShape.OutlineFill := vectorFill;
-      vectorFill.Free;
+      prevRF := newShape.GetRenderBounds(InfiniteRect, vectorTransform);
+      newShape.QuickDefine(newStartPoint,ptF);
+      if (vsfBackFill in newShape.Fields) and (newShape.BackFill.FillType in [vftGradient, vftTexture]) then
+      begin
+        vectorFill := BackFillControl.CreateShapeFill(newShape);
+        newShape.BackFill := vectorFill;
+        vectorFill.Free;
+      end;
+      if (vsfPenFill in newShape.Fields) and (newShape.PenFill.FillType in [vftGradient, vftTexture]) then
+      begin
+        vectorFill := PenFillControl.CreateShapeFill(newShape);
+        newShape.PenFill := vectorFill;
+        vectorFill.Free;
+      end;
+      if (vsfOutlineFill in newShape.Fields) and (newShape.OutlineFill.FillType in [vftGradient, vftTexture]) then
+      begin
+        vectorFill := OutlineFillControl.CreateShapeFill(newShape);
+        newShape.OutlineFill := vectorFill;
+        vectorFill.Free;
+      end;
+      rF := newShape.GetRenderBounds(InfiniteRect, vectorTransform);
+      ImageChange(rF.Union(prevRF, true));
     end;
-    rF := newShape.GetRenderBounds(InfiniteRect, vectorTransform);
-    ImageChange(rF.Union(prevRF, true));
   end;
 end;
 
@@ -818,41 +815,44 @@ begin
   end;
   UpdateViewCursor(cur);
 
-  if justDown and (Button = newButton) then
-  begin
-    if IsCreateShapeTool(currentTool) and (vsuCreate in PaintToolClass[currentTool].Usermodes) then
-    begin
-      vectorOriginal.DeselectShape;
-      vectorOriginal.AddShape(CreateShape(newStartPoint,newStartPoint), vsuCreate);
-    end else
-    if IsCreateShapeTool(currentTool) and PaintToolClass[currentTool].CreateEmpty then
-    begin
-      vectorOriginal.DeselectShape;
-      addedShape := CreateShape(newStartPoint,newStartPoint);
-      vectorOriginal.AddShape(addedShape);
-      vectorOriginal.SelectShape(addedShape);
-      currentTool:= ptHand;
-    end else
-      vectorOriginal.MouseClick(newStartPoint);
-    justDown:= false;
-  end
-  else if Assigned(newShape) and (Button = newButton) then
+  if Assigned(vectorOriginal) then
   begin
-    if shapeAdded then
-      newShape := nil
-    else
+    if justDown and (Button = newButton) then
     begin
-      rF := newShape.GetRenderBounds(InfiniteRect, vectorTransform);
-      if not IsEmptyRectF(rF) or (vsuCreate in newShape.Usermodes) then
+      if IsCreateShapeTool(currentTool) and (vsuCreate in PaintToolClass[currentTool].Usermodes) then
       begin
-        addedShape := newShape;
-        newShape := nil;
-        vectorOriginal.AddShape(addedShape, vsuCreate);
-      end
+        vectorOriginal.DeselectShape;
+        vectorOriginal.AddShape(CreateShape(newStartPoint,newStartPoint), vsuCreate);
+      end else
+      if IsCreateShapeTool(currentTool) and PaintToolClass[currentTool].CreateEmpty then
+      begin
+        vectorOriginal.DeselectShape;
+        addedShape := CreateShape(newStartPoint,newStartPoint);
+        vectorOriginal.AddShape(addedShape);
+        vectorOriginal.SelectShape(addedShape);
+        currentTool:= ptHand;
+      end else
+        vectorOriginal.MouseClick(newStartPoint);
+      justDown:= false;
+    end
+    else if Assigned(newShape) and (Button = newButton) then
+    begin
+      if shapeAdded then
+        newShape := nil
       else
       begin
-        FreeAndNil(newShape);
-        ShowMessage('Shape is empty and was not added');
+        rF := newShape.GetRenderBounds(InfiniteRect, vectorTransform);
+        if not IsEmptyRectF(rF) or (vsuCreate in newShape.Usermodes) then
+        begin
+          addedShape := newShape;
+          newShape := nil;
+          vectorOriginal.AddShape(addedShape, vsuCreate);
+        end
+        else
+        begin
+          FreeAndNil(newShape);
+          ShowMessage('Shape is empty and was not added');
+        end;
       end;
     end;
   end;
@@ -1059,10 +1059,19 @@ begin
   result := FSplineStyle;
 end;
 
+function TForm1.GetVectorOriginal: TVectorOriginal;
+begin
+  if Assigned(img) and (vectorLayerIndex >= 0) and (vectorLayerIndex < img.NbLayers) and
+     (img.LayerOriginalClass[vectorLayerIndex] = TVectorOriginal) then
+   result := img.LayerOriginal[vectorLayerIndex] as TVectorOriginal
+  else
+    result := nil
+end;
+
 function TForm1.GetVectorTransform: TAffineMatrix;
 begin
-  if vectorLayer<>-1 then
-    result:= img.LayerOriginalMatrix[vectorLayer]
+  if Assigned(img) and (vectorLayerIndex<>-1) then
+    result:= img.LayerOriginalMatrix[vectorLayerIndex]
   else
     result:= AffineMatrixIdentity;
 end;
@@ -1333,6 +1342,22 @@ begin
     TCurveShape(vectorOriginal.SelectedShape).SplineStyle := FSplineStyle;
 end;
 
+procedure TForm1.SetVectorLayerIndex(AValue: integer);
+var
+  prevOrig: TVectorOriginal;
+begin
+  if FVectorLayerIndex=AValue then Exit;
+  prevOrig := vectorOriginal;
+  if Assigned(prevOrig) then prevOrig.OnSelectShape:= nil;
+  if Assigned(img) and (AValue >= 0) and (AValue < img.NbLayers) and
+    (img.LayerOriginalClass[AValue] = TVectorOriginal) then
+  begin
+    FVectorLayerIndex:= AValue;
+    vectorOriginal.OnSelectShape:= @OnSelectShape;
+  end else
+    FVectorLayerIndex:= -1;
+end;
+
 procedure TForm1.SetZoomFactor(AValue: single);
 begin
   zoom := AffineMatrixScale(AValue,AValue);
@@ -1426,6 +1451,31 @@ begin
   tb.Text := FTextFontName;
 end;
 
+procedure TForm1.NewImage(AWidth, AHeight: integer);
+var
+  orig: TVectorOriginal;
+  newImg: TBGRALazPaintImage;
+  layerIndex: Integer;
+begin
+  newImg := TBGRALazPaintImage.Create(640,480);
+  orig := TVectorOriginal.Create;
+  layerIndex := newImg.AddLayerFromOwnedOriginal(orig);
+  SetImage(newImg);
+  filename := '';
+  vectorLayerIndex := layerIndex;
+end;
+
+procedure TForm1.SetImage(AImage: TBGRALazPaintImage);
+begin
+  FreeAndNil(img);
+  img := AImage;
+  img.OnOriginalEditingChange:= @OnEditingChange;
+  img.EditorFocused:= BGRAVirtualScreen1.Focused;
+  img.OnEditorFocusChanged:=@OnEditorFocusChange;
+  img.OnOriginalChange:= @OnOriginalChange;
+  FVectorLayerIndex:= -1;
+end;
+
 procedure TForm1.TextStyleClick(Sender: TObject);
 var
   btn: TToolButton;
@@ -1527,6 +1577,7 @@ var
   shapeRectF: TRectF;
   shapeRect: TRect;
 begin
+  img.FreezeExceptOneLayer(vectorLayerIndex);
   if FFlattened = nil then
     FFlattened := img.ComputeFlatImage
   else
@@ -1579,11 +1630,14 @@ begin
   end;
   if Assigned(img) then
   begin
-    newEditorBounds := img.GetEditorBounds(vectorLayer, zoom, EditorPointSize);
-    if not IsRectEmpty(newEditorBounds) then
+    if vectorLayerIndex<>-1 then
     begin
-      if IsRectEmpty(viewRect) then viewRect := newEditorBounds else
-        UnionRect(viewRect,viewRect,newEditorBounds);
+      newEditorBounds := img.GetEditorBounds(vectorLayerIndex, zoom, EditorPointSize);
+      if not IsRectEmpty(newEditorBounds) then
+      begin
+        if IsRectEmpty(viewRect) then viewRect := newEditorBounds else
+          UnionRect(viewRect,viewRect,newEditorBounds);
+      end;
     end;
   end;