|
@@ -8,6 +8,19 @@ uses
|
|
Classes, SysUtils, Types, LCVectorOriginal, BGRABitmapTypes, BGRALayerOriginal,
|
|
Classes, SysUtils, Types, LCVectorOriginal, BGRABitmapTypes, BGRALayerOriginal,
|
|
BGRABitmap, BGRATransform, BGRAGradients;
|
|
BGRABitmap, BGRATransform, BGRAGradients;
|
|
|
|
|
|
|
|
+type
|
|
|
|
+ TArrowKind = (akNone, akTail, akTip, akNormal, akCut, akFlipped, akFlippedCut,
|
|
|
|
+ akTriangle, akTriangleBack1, akTriangleBack2,
|
|
|
|
+ akHollowTriangle, akHollowTriangleBack1, akHollowTriangleBack2);
|
|
|
|
+
|
|
|
|
+const
|
|
|
|
+ ArrowKindToStr: array[TArrowKind] of string =
|
|
|
|
+ ('none', 'tail', 'tip', 'normal', 'cut', 'flipped', 'flipped-cut',
|
|
|
|
+ 'triangle', 'triangle-back1', 'triangle-back2',
|
|
|
|
+ 'hollow-triangle', 'hollow-triangle-back1', 'hollow-triangle-back2');
|
|
|
|
+
|
|
|
|
+function StrToArrowKind(AStr: string): TArrowKind;
|
|
|
|
+
|
|
type
|
|
type
|
|
{ TCustomPolypointShape }
|
|
{ TCustomPolypointShape }
|
|
|
|
|
|
@@ -16,6 +29,9 @@ type
|
|
FClosed: boolean;
|
|
FClosed: boolean;
|
|
function GetPoint(AIndex: integer): TPointF;
|
|
function GetPoint(AIndex: integer): TPointF;
|
|
function GetPointCount: integer;
|
|
function GetPointCount: integer;
|
|
|
|
+ procedure SetArrowEndKind(AValue: TArrowKind);
|
|
|
|
+ procedure SetArrowSize(AValue: TPointF);
|
|
|
|
+ procedure SetArrowStartKind(AValue: TArrowKind);
|
|
procedure SetPoint(AIndex: integer; AValue: TPointF);
|
|
procedure SetPoint(AIndex: integer; AValue: TPointF);
|
|
protected
|
|
protected
|
|
FPoints: array of record
|
|
FPoints: array of record
|
|
@@ -29,6 +45,8 @@ type
|
|
FAddingPoint: boolean;
|
|
FAddingPoint: boolean;
|
|
FMousePos: TPointF;
|
|
FMousePos: TPointF;
|
|
FHoverPoint: integer;
|
|
FHoverPoint: integer;
|
|
|
|
+ FArrowStartKind,FArrowEndKind: TArrowKind;
|
|
|
|
+ FArrowSize: TPointF;
|
|
procedure OnMovePoint({%H-}ASender: TObject; {%H-}APrevCoord, ANewCoord: TPointF; {%H-}AShift: TShiftState);
|
|
procedure OnMovePoint({%H-}ASender: TObject; {%H-}APrevCoord, ANewCoord: TPointF; {%H-}AShift: TShiftState);
|
|
procedure OnMoveCenterPoint({%H-}ASender: TObject; {%H-}APrevCoord, ANewCoord: TPointF; {%H-}AShift: TShiftState);
|
|
procedure OnMoveCenterPoint({%H-}ASender: TObject; {%H-}APrevCoord, ANewCoord: TPointF; {%H-}AShift: TShiftState);
|
|
procedure OnStartMove({%H-}ASender: TObject; APointIndex: integer; {%H-}AShift: TShiftState);
|
|
procedure OnStartMove({%H-}ASender: TObject; APointIndex: integer; {%H-}AShift: TShiftState);
|
|
@@ -42,11 +60,13 @@ type
|
|
procedure DoClickPoint({%H-}APointIndex: integer; {%H-}AShift: TShiftState); virtual;
|
|
procedure DoClickPoint({%H-}APointIndex: integer; {%H-}AShift: TShiftState); virtual;
|
|
function CanMovePoints: boolean; virtual;
|
|
function CanMovePoints: boolean; virtual;
|
|
procedure InsertPointAuto;
|
|
procedure InsertPointAuto;
|
|
|
|
+ function ComputeStroke(APoints: ArrayOfTPointF; AClosed: boolean;
|
|
|
|
+ AStrokeMatrix: TAffineMatrix): ArrayOfTPointF; override;
|
|
public
|
|
public
|
|
constructor Create(AContainer: TVectorOriginal); override;
|
|
constructor Create(AContainer: TVectorOriginal); override;
|
|
procedure Clear;
|
|
procedure Clear;
|
|
destructor Destroy; override;
|
|
destructor Destroy; override;
|
|
- function AddPoint(const APoint: TPointF): integer;
|
|
|
|
|
|
+ function AddPoint(const APoint: TPointF): integer; virtual;
|
|
function RemovePoint(AIndex: integer): boolean;
|
|
function RemovePoint(AIndex: integer): boolean;
|
|
procedure RemovePointRange(AFromIndex, AToIndexPlus1: integer);
|
|
procedure RemovePointRange(AFromIndex, AToIndexPlus1: integer);
|
|
procedure InsertPoint(AIndex: integer; APoint: TPointF);
|
|
procedure InsertPoint(AIndex: integer; APoint: TPointF);
|
|
@@ -59,10 +79,14 @@ type
|
|
procedure ConfigureCustomEditor(AEditor: TBGRAOriginalEditor); override;
|
|
procedure ConfigureCustomEditor(AEditor: TBGRAOriginalEditor); override;
|
|
procedure Transform(AMatrix: TAffineMatrix); override;
|
|
procedure Transform(AMatrix: TAffineMatrix); override;
|
|
class function Usermodes: TVectorShapeUsermodes; override;
|
|
class function Usermodes: TVectorShapeUsermodes; override;
|
|
|
|
+ class function DefaultArrowSize: TPointF;
|
|
property Points[AIndex:integer]: TPointF read GetPoint write SetPoint;
|
|
property Points[AIndex:integer]: TPointF read GetPoint write SetPoint;
|
|
property PointCount: integer read GetPointCount;
|
|
property PointCount: integer read GetPointCount;
|
|
property Closed: boolean read GetClosed write SetClosed;
|
|
property Closed: boolean read GetClosed write SetClosed;
|
|
property HoverPoint: integer read FHoverPoint;
|
|
property HoverPoint: integer read FHoverPoint;
|
|
|
|
+ property ArrowStartKind: TArrowKind read FArrowStartKind write SetArrowStartKind;
|
|
|
|
+ property ArrowEndKind: TArrowKind read FArrowEndKind write SetArrowEndKind;
|
|
|
|
+ property ArrowSize: TPointF read FArrowSize write SetArrowSize;
|
|
end;
|
|
end;
|
|
|
|
|
|
{ TPolylineShape }
|
|
{ TPolylineShape }
|
|
@@ -84,8 +108,10 @@ type
|
|
|
|
|
|
TCurveShape = class(TPolylineShape)
|
|
TCurveShape = class(TPolylineShape)
|
|
private
|
|
private
|
|
|
|
+ FCosineAngle: single;
|
|
FSplineStyle: TSplineStyle;
|
|
FSplineStyle: TSplineStyle;
|
|
function GetCurveMode(AIndex: integer): TEasyBezierCurveMode;
|
|
function GetCurveMode(AIndex: integer): TEasyBezierCurveMode;
|
|
|
|
+ procedure SetCosineAngle(AValue: single);
|
|
procedure SetCurveMode(AIndex: integer; AValue: TEasyBezierCurveMode);
|
|
procedure SetCurveMode(AIndex: integer; AValue: TEasyBezierCurveMode);
|
|
procedure SetSplineStyle(AValue: TSplineStyle);
|
|
procedure SetSplineStyle(AValue: TSplineStyle);
|
|
protected
|
|
protected
|
|
@@ -95,17 +121,55 @@ type
|
|
public
|
|
public
|
|
class function Usermodes: TVectorShapeUsermodes; override;
|
|
class function Usermodes: TVectorShapeUsermodes; override;
|
|
constructor Create(AContainer: TVectorOriginal); override;
|
|
constructor Create(AContainer: TVectorOriginal); override;
|
|
|
|
+ function AddPoint(const APoint: TPointF): integer; override;
|
|
procedure KeyPress(UTF8Key: string; var AHandled: boolean); override;
|
|
procedure KeyPress(UTF8Key: string; var AHandled: boolean); override;
|
|
procedure LoadFromStorage(AStorage: TBGRACustomOriginalStorage); override;
|
|
procedure LoadFromStorage(AStorage: TBGRACustomOriginalStorage); override;
|
|
procedure SaveToStorage(AStorage: TBGRACustomOriginalStorage); override;
|
|
procedure SaveToStorage(AStorage: TBGRACustomOriginalStorage); override;
|
|
class function StorageClassName: RawByteString; override;
|
|
class function StorageClassName: RawByteString; override;
|
|
property SplineStyle: TSplineStyle read FSplineStyle write SetSplineStyle;
|
|
property SplineStyle: TSplineStyle read FSplineStyle write SetSplineStyle;
|
|
property CurveMode[AIndex: integer]: TEasyBezierCurveMode read GetCurveMode write SetCurveMode;
|
|
property CurveMode[AIndex: integer]: TEasyBezierCurveMode read GetCurveMode write SetCurveMode;
|
|
|
|
+ property CosineAngle: single read FCosineAngle write SetCosineAngle;
|
|
end;
|
|
end;
|
|
|
|
|
|
|
|
+procedure ApplyArrowStyle(AArrow: TBGRACustomArrow; AStart: boolean; AKind: TArrowKind; ASize: TPointF);
|
|
|
|
+
|
|
implementation
|
|
implementation
|
|
|
|
|
|
-uses BGRAPen, BGRAGraphics, BGRAFillInfo, BGRAPath, math, LCVectorialFill;
|
|
|
|
|
|
+uses BGRAPen, BGRAGraphics, BGRAFillInfo, BGRAPath, math, LCVectorialFill,
|
|
|
|
+ BGRAArrow;
|
|
|
|
+
|
|
|
|
+function StrToArrowKind(AStr: string): TArrowKind;
|
|
|
|
+var
|
|
|
|
+ ak: TArrowKind;
|
|
|
|
+begin
|
|
|
|
+ for ak := low(TArrowKind) to high(TArrowKind) do
|
|
|
|
+ if CompareText(AStr, ArrowKindToStr[ak])=0 then exit(ak);
|
|
|
|
+ result := akNone;
|
|
|
|
+end;
|
|
|
|
+
|
|
|
|
+procedure ApplyArrowStyle(AArrow: TBGRACustomArrow; AStart: boolean; AKind: TArrowKind; ASize: TPointF);
|
|
|
|
+var backOfs: single;
|
|
|
|
+begin
|
|
|
|
+ backOfs := 0;
|
|
|
|
+ if (ASize.x = 0) or (ASize.y = 0) then AKind := akNone;
|
|
|
|
+ if AKind in[akTriangleBack1,akHollowTriangleBack1] then backOfs := 0.25;
|
|
|
|
+ if AKind in[akTriangleBack2,akHollowTriangleBack2] then backOfs := 0.50;
|
|
|
|
+ case AKind of
|
|
|
|
+ akTail: if AStart then AArrow.StartAsTail else AArrow.EndAsTail;
|
|
|
|
+ akTip: if AStart then AArrow.StartAsTriangle else AArrow.EndAsTriangle;
|
|
|
|
+ akNormal,akCut,akFlipped,akFlippedCut:
|
|
|
|
+ if AStart then AArrow.StartAsClassic(AKind in[akFlipped,akFlippedCut], AKind in[akCut,akFlippedCut])
|
|
|
|
+ else AArrow.EndAsClassic(AKind in[akFlipped,akFlippedCut], AKind in[akCut,akFlippedCut]);
|
|
|
|
+ akTriangle,akTriangleBack1,akTriangleBack2:
|
|
|
|
+ if AStart then AArrow.StartAsTriangle(backOfs) else AArrow.EndAsTriangle(backOfs);
|
|
|
|
+ akHollowTriangle,akHollowTriangleBack1,akHollowTriangleBack2:
|
|
|
|
+ if AStart then AArrow.StartAsTriangle(backOfs,False,True) else AArrow.EndAsTriangle(backOfs,False,True);
|
|
|
|
+ else if AStart then AArrow.StartAsNone else AArrow.EndAsNone;
|
|
|
|
+ end;
|
|
|
|
+ if (AKind = akTip) and not ((ASize.x = 0) or (ASize.y = 0)) then
|
|
|
|
+ ASize := ASize*(0.5/ASize.y);
|
|
|
|
+ if AStart then AArrow.StartSize := ASize else AArrow.EndSize := ASize;
|
|
|
|
+end;
|
|
|
|
|
|
procedure IncludePointF(var ARectF: TRectF; APointF: TPointF);
|
|
procedure IncludePointF(var ARectF: TRectF; APointF: TPointF);
|
|
begin
|
|
begin
|
|
@@ -154,6 +218,30 @@ begin
|
|
result:= length(FPoints);
|
|
result:= length(FPoints);
|
|
end;
|
|
end;
|
|
|
|
|
|
|
|
+procedure TCustomPolypointShape.SetArrowEndKind(AValue: TArrowKind);
|
|
|
|
+begin
|
|
|
|
+ if FArrowEndKind=AValue then Exit;
|
|
|
|
+ BeginUpdate;
|
|
|
|
+ FArrowEndKind:=AValue;
|
|
|
|
+ EndUpdate;
|
|
|
|
+end;
|
|
|
|
+
|
|
|
|
+procedure TCustomPolypointShape.SetArrowSize(AValue: TPointF);
|
|
|
|
+begin
|
|
|
|
+ if FArrowSize=AValue then Exit;
|
|
|
|
+ BeginUpdate;
|
|
|
|
+ FArrowSize:=AValue;
|
|
|
|
+ EndUpdate;
|
|
|
|
+end;
|
|
|
|
+
|
|
|
|
+procedure TCustomPolypointShape.SetArrowStartKind(AValue: TArrowKind);
|
|
|
|
+begin
|
|
|
|
+ if FArrowStartKind=AValue then Exit;
|
|
|
|
+ BeginUpdate;
|
|
|
|
+ FArrowStartKind:=AValue;
|
|
|
|
+ EndUpdate;
|
|
|
|
+end;
|
|
|
|
+
|
|
procedure TCustomPolypointShape.SetClosed(AValue: boolean);
|
|
procedure TCustomPolypointShape.SetClosed(AValue: boolean);
|
|
begin
|
|
begin
|
|
if AValue = FClosed then exit;
|
|
if AValue = FClosed then exit;
|
|
@@ -235,6 +323,11 @@ begin
|
|
Result:= inherited Usermodes + [vsuCreate];
|
|
Result:= inherited Usermodes + [vsuCreate];
|
|
end;
|
|
end;
|
|
|
|
|
|
|
|
+class function TCustomPolypointShape.DefaultArrowSize: TPointF;
|
|
|
|
+begin
|
|
|
|
+ result := PointF(2,2);
|
|
|
|
+end;
|
|
|
|
+
|
|
procedure TCustomPolypointShape.SetUsermode(AValue: TVectorShapeUsermode);
|
|
procedure TCustomPolypointShape.SetUsermode(AValue: TVectorShapeUsermode);
|
|
var
|
|
var
|
|
add: Boolean;
|
|
add: Boolean;
|
|
@@ -356,6 +449,17 @@ begin
|
|
end;
|
|
end;
|
|
end;
|
|
end;
|
|
|
|
|
|
|
|
+function TCustomPolypointShape.ComputeStroke(APoints: ArrayOfTPointF;
|
|
|
|
+ AClosed: boolean; AStrokeMatrix: TAffineMatrix): ArrayOfTPointF;
|
|
|
|
+begin
|
|
|
|
+ if Stroker.Arrow = nil then Stroker.Arrow := TBGRAArrow.Create;
|
|
|
|
+ ApplyArrowStyle(Stroker.Arrow, true, ArrowStartKind, ArrowSize);
|
|
|
|
+ ApplyArrowStyle(Stroker.Arrow, false, ArrowEndKind, ArrowSize);
|
|
|
|
+ Result:=inherited ComputeStroke(APoints, AClosed, AStrokeMatrix);
|
|
|
|
+ Stroker.Arrow.StartAsNone;
|
|
|
|
+ Stroker.Arrow.EndAsNone;
|
|
|
|
+end;
|
|
|
|
+
|
|
constructor TCustomPolypointShape.Create(AContainer: TVectorOriginal);
|
|
constructor TCustomPolypointShape.Create(AContainer: TVectorOriginal);
|
|
begin
|
|
begin
|
|
inherited Create(AContainer);
|
|
inherited Create(AContainer);
|
|
@@ -435,7 +539,10 @@ begin
|
|
FMousePos := PointF(X,Y);
|
|
FMousePos := PointF(X,Y);
|
|
if FAddingPoint then
|
|
if FAddingPoint then
|
|
begin
|
|
begin
|
|
- Points[PointCount-1] := FMousePos;
|
|
|
|
|
|
+ if (PointCount = 1) and (FMousePos <> Points[PointCount-1]) then
|
|
|
|
+ Points[PointCount] := FMousePos
|
|
|
|
+ else
|
|
|
|
+ Points[PointCount-1] := FMousePos;
|
|
AHandled:= true;
|
|
AHandled:= true;
|
|
end;
|
|
end;
|
|
end;
|
|
end;
|
|
@@ -514,6 +621,11 @@ begin
|
|
FPoints[i].data := nil;
|
|
FPoints[i].data := nil;
|
|
end;
|
|
end;
|
|
FClosed:= AStorage.Bool['closed'];
|
|
FClosed:= AStorage.Bool['closed'];
|
|
|
|
+ if AStorage.HasAttribute('arrow-size') then
|
|
|
|
+ FArrowSize := AStorage.PointF['arrow-size']
|
|
|
|
+ else FArrowSize := DefaultArrowSize;
|
|
|
|
+ FArrowStartKind:= StrToArrowKind(AStorage.RawString['arrow-start-kind']);
|
|
|
|
+ FArrowEndKind:= StrToArrowKind(AStorage.RawString['arrow-end-kind']);
|
|
EndUpdate;
|
|
EndUpdate;
|
|
end;
|
|
end;
|
|
|
|
|
|
@@ -533,6 +645,12 @@ begin
|
|
AStorage.FloatArray['x'] := x;
|
|
AStorage.FloatArray['x'] := x;
|
|
AStorage.FloatArray['y'] := y;
|
|
AStorage.FloatArray['y'] := y;
|
|
AStorage.Bool['closed'] := Closed;
|
|
AStorage.Bool['closed'] := Closed;
|
|
|
|
+ if ArrowStartKind=akNone then AStorage.RemoveAttribute('arrow-start-kind')
|
|
|
|
+ else AStorage.RawString['arrow-start-kind'] := ArrowKindToStr[ArrowStartKind];
|
|
|
|
+ if ArrowEndKind=akNone then AStorage.RemoveAttribute('arrow-end-kind')
|
|
|
|
+ else AStorage.RawString['arrow-end-kind'] := ArrowKindToStr[ArrowEndKind];
|
|
|
|
+ if (ArrowStartKind=akNone) and (ArrowEndKind=akNone) then AStorage.RemoveAttribute('arrow-size')
|
|
|
|
+ else AStorage.PointF['arrow-size'] := FArrowSize;
|
|
end;
|
|
end;
|
|
|
|
|
|
procedure TCustomPolypointShape.ConfigureCustomEditor(AEditor: TBGRAOriginalEditor);
|
|
procedure TCustomPolypointShape.ConfigureCustomEditor(AEditor: TBGRAOriginalEditor);
|
|
@@ -547,7 +665,7 @@ begin
|
|
for i:= 0 to PointCount-1 do
|
|
for i:= 0 to PointCount-1 do
|
|
if isEmptyPointF(Points[i]) then
|
|
if isEmptyPointF(Points[i]) then
|
|
FPoints[i].editorIndex := -1
|
|
FPoints[i].editorIndex := -1
|
|
- else if (FAddingPoint and ((i = 0) or (i = PointCount-1))) then
|
|
|
|
|
|
+ else if (FAddingPoint and (i = PointCount-1)) then
|
|
begin
|
|
begin
|
|
FPoints[i].editorIndex := -1;
|
|
FPoints[i].editorIndex := -1;
|
|
FCenterPoint += Points[i];
|
|
FCenterPoint += Points[i];
|
|
@@ -660,7 +778,7 @@ begin
|
|
pts := GetCurve(AMatrix);
|
|
pts := GetCurve(AMatrix);
|
|
if PenVisible(rboAssumePenFill in AOptions) then
|
|
if PenVisible(rboAssumePenFill in AOptions) then
|
|
begin
|
|
begin
|
|
- if JoinStyle = pjsRound then
|
|
|
|
|
|
+ if (JoinStyle = pjsRound) and (ArrowStartKind = akNone) and (ArrowEndKind = akNone) then
|
|
begin
|
|
begin
|
|
xMargin := (abs(AMatrix[1,1])+abs(AMatrix[1,2]))*PenWidth*0.5;
|
|
xMargin := (abs(AMatrix[1,1])+abs(AMatrix[1,2]))*PenWidth*0.5;
|
|
yMargin := (abs(AMatrix[2,1])+abs(AMatrix[2,2]))*PenWidth*0.5;
|
|
yMargin := (abs(AMatrix[2,1])+abs(AMatrix[2,2]))*PenWidth*0.5;
|
|
@@ -728,6 +846,14 @@ begin
|
|
result := cmAuto;
|
|
result := cmAuto;
|
|
end;
|
|
end;
|
|
|
|
|
|
|
|
+procedure TCurveShape.SetCosineAngle(AValue: single);
|
|
|
|
+begin
|
|
|
|
+ if FCosineAngle=AValue then Exit;
|
|
|
|
+ BeginUpdate;
|
|
|
|
+ FCosineAngle:=AValue;
|
|
|
|
+ EndUpdate;
|
|
|
|
+end;
|
|
|
|
+
|
|
procedure TCurveShape.SetCurveMode(AIndex: integer; AValue: TEasyBezierCurveMode);
|
|
procedure TCurveShape.SetCurveMode(AIndex: integer; AValue: TEasyBezierCurveMode);
|
|
begin
|
|
begin
|
|
if (AIndex < 0) or (AIndex >= PointCount) then exit;
|
|
if (AIndex < 0) or (AIndex >= PointCount) then exit;
|
|
@@ -751,7 +877,7 @@ begin
|
|
setlength(cm, PointCount);
|
|
setlength(cm, PointCount);
|
|
for i := 0 to PointCount-1 do
|
|
for i := 0 to PointCount-1 do
|
|
cm[i] := CurveMode[i];
|
|
cm[i] := CurveMode[i];
|
|
- eb := EasyBezierCurve(pts, Closed, cm);
|
|
|
|
|
|
+ eb := EasyBezierCurve(pts, Closed, cm, CosineAngle);
|
|
result := eb.ToPoints;
|
|
result := eb.ToPoints;
|
|
end else
|
|
end else
|
|
begin
|
|
begin
|
|
@@ -787,23 +913,43 @@ begin
|
|
FSplineStyle:= ssEasyBezier;
|
|
FSplineStyle:= ssEasyBezier;
|
|
end;
|
|
end;
|
|
|
|
|
|
|
|
+function TCurveShape.AddPoint(const APoint: TPointF): integer;
|
|
|
|
+begin
|
|
|
|
+ if (PointCount > 1) and (APoint = Points[PointCount-1]) then
|
|
|
|
+ begin
|
|
|
|
+ BeginUpdate;
|
|
|
|
+ CurveMode[PointCount-1] := CurveMode[PointCount-2];
|
|
|
|
+ Result:=inherited AddPoint(APoint);
|
|
|
|
+ EndUpdate;
|
|
|
|
+ end
|
|
|
|
+ else Result:=inherited AddPoint(APoint);
|
|
|
|
+end;
|
|
|
|
+
|
|
procedure TCurveShape.KeyPress(UTF8Key: string; var AHandled: boolean);
|
|
procedure TCurveShape.KeyPress(UTF8Key: string; var AHandled: boolean);
|
|
|
|
+var
|
|
|
|
+ targetPoint: Integer;
|
|
begin
|
|
begin
|
|
- if (FHoverPoint >= 0) and (FHoverPoint < PointCount) then
|
|
|
|
|
|
+ if FHoverPoint<>-1 then
|
|
|
|
+ targetPoint := FHoverPoint
|
|
|
|
+ else if FAddingPoint and (PointCount > 1) then
|
|
|
|
+ targetPoint := PointCount-2
|
|
|
|
+ else
|
|
|
|
+ targetPoint := -1;
|
|
|
|
+ if (targetPoint >= 0) and (targetPoint < PointCount) then
|
|
begin
|
|
begin
|
|
if (UTF8Key = 'A') or (UTF8Key = 'a') then
|
|
if (UTF8Key = 'A') or (UTF8Key = 'a') then
|
|
begin
|
|
begin
|
|
- CurveMode[FHoverPoint] := cmAuto;
|
|
|
|
|
|
+ CurveMode[targetPoint] := cmAuto;
|
|
AHandled := true;
|
|
AHandled := true;
|
|
end else
|
|
end else
|
|
if (UTF8Key = 'S') or (UTF8Key = 's') then
|
|
if (UTF8Key = 'S') or (UTF8Key = 's') then
|
|
begin
|
|
begin
|
|
- CurveMode[FHoverPoint] := cmCurve;
|
|
|
|
|
|
+ CurveMode[targetPoint] := cmCurve;
|
|
AHandled:= true;
|
|
AHandled:= true;
|
|
end else
|
|
end else
|
|
if (UTF8Key = 'X') or (UTF8Key = 'x') then
|
|
if (UTF8Key = 'X') or (UTF8Key = 'x') then
|
|
begin
|
|
begin
|
|
- CurveMode[FHoverPoint] := cmAngle;
|
|
|
|
|
|
+ CurveMode[targetPoint] := cmAngle;
|
|
AHandled:= true;
|
|
AHandled:= true;
|
|
end;
|
|
end;
|
|
end;
|
|
end;
|
|
@@ -841,6 +987,7 @@ begin
|
|
for i:= length(cm) to PointCount-1 do
|
|
for i:= length(cm) to PointCount-1 do
|
|
CurveMode[i] := cmCurve;
|
|
CurveMode[i] := cmCurve;
|
|
end;
|
|
end;
|
|
|
|
+ CosineAngle := AStorage.FloatDef['cosine-angle', EasyBezierDefaultMinimumDotProduct];
|
|
EndUpdate;
|
|
EndUpdate;
|
|
end;
|
|
end;
|
|
|
|
|
|
@@ -869,6 +1016,7 @@ begin
|
|
cm[i] := ord(CurveMode[i]);
|
|
cm[i] := ord(CurveMode[i]);
|
|
AStorage.FloatArray['curve-mode'] := cm;
|
|
AStorage.FloatArray['curve-mode'] := cm;
|
|
end;
|
|
end;
|
|
|
|
+ AStorage.Float['cosine-angle'] := CosineAngle;
|
|
end;
|
|
end;
|
|
|
|
|
|
class function TCurveShape.StorageClassName: RawByteString;
|
|
class function TCurveShape.StorageClassName: RawByteString;
|