From 9121096235813436cfeb1cbb4d504934acb5f147 Mon Sep 17 00:00:00 2001 From: ask Date: Sun, 23 Jun 2013 19:50:36 +0000 Subject: [PATCH] TAChart: Initial implementation of diagram decorators git-svn-id: trunk@41857 - --- components/tachart/tadiagram.pas | 104 ++++++++++++++++++++++++ components/tachart/tadiagramdrawing.pas | 34 +++++++- 2 files changed, 134 insertions(+), 4 deletions(-) diff --git a/components/tachart/tadiagram.pas b/components/tachart/tadiagram.pas index e274ff3b17..bf4732fd84 100644 --- a/components/tachart/tadiagram.pas +++ b/components/tachart/tadiagram.pas @@ -47,6 +47,40 @@ type TDiaElement = class; + TDiaDecoratorList = class; + + TDiaDecorator = class(TDiaObject) + private + FOwner: TDiaObject; + public + constructor Create(AOwner: TDiaDecoratorList); + property Owner: TDiaObject read FOwner; + end; + + TDiaDecoratorEnumerator = class; + + TDiaDecoratorList = class(TDiaObject) + private + FDecorators: array of TDiaDecorator; + FOwner: TDiaObject; + procedure Add(ADecorator: TDiaDecorator); + public + constructor Create(AOwner: TDiaObject); + destructor Destroy; override; + property Owner: TDiaObject read FOwner; + function GetEnumerator: TDiaDecoratorEnumerator; + end; + + TDiaDecoratorEnumerator = class + FList: TDiaDecoratorList; + FPosition: Integer; + public + constructor Create(AList: TDiaDecoratorList); + function GetCurrent: TDiaDecorator; + function MoveNext: Boolean; + property Current: TDiaDecorator read GetCurrent; + end; + TDiagram = class(TDiaObject) strict private FBounds: array [TDiaBoxSide] of TDiaCoordinate; @@ -74,13 +108,17 @@ type FConnectors: array of TDiaConnector; FOwner: TDiagram; private + FDecorators: TDiaDecoratorList; procedure SetOwner(AValue: TDiagram); public + constructor Create; + destructor Destroy; override; procedure Add(AConnector: TDiaConnector); procedure Changed(ASender: TDiaObject); override; procedure Draw; virtual; procedure Notify(ASender: TDiaObject); override; property Owner: TDiagram read FOwner; + property Decorators: TDiaDecoratorList read FDecorators; end; TDiaPosition = class(TDiaObject) @@ -218,6 +256,61 @@ begin Result.Y := WeightedAverage(AP1.Y, AP2.Y, ACoeff); end; +{ TDiaDecoratorEnumerator } + +constructor TDiaDecoratorEnumerator.Create(AList: TDiaDecoratorList); +begin + FList := AList; + FPosition := -1; +end; + +function TDiaDecoratorEnumerator.GetCurrent: TDiaDecorator; +begin + Result := FList.FDecorators[FPosition]; +end; + +function TDiaDecoratorEnumerator.MoveNext: Boolean; +begin + FPosition += 1; + Result := FPosition < Length(FList.FDecorators); +end; + +{ TDiaDecoratorList } + +procedure TDiaDecoratorList.Add(ADecorator: TDiaDecorator); +begin + SetLength(FDecorators, Length(FDecorators) + 1); + FDecorators[High(FDecorators)] := ADecorator; + //Notify(ADecorator); +end; + +constructor TDiaDecoratorList.Create(AOwner: TDiaObject); +begin + FOwner := AOwner; +end; + +destructor TDiaDecoratorList.Destroy; +var + d: TDiaDecorator; +begin + for d in FDecorators do + d.Free; + inherited; +end; + +function TDiaDecoratorList.GetEnumerator: TDiaDecoratorEnumerator; +begin + Result := TDiaDecoratorEnumerator.Create(Self); +end; + +{ TDiaDecorator } + +constructor TDiaDecorator.Create(AOwner: TDiaDecoratorList); +begin + if AOwner <> nil then + AOwner.Add(Self); +end; + { TDiaLink } procedure TDiaLink.Draw; @@ -540,6 +633,17 @@ begin c.Changed(ASender); end; +constructor TDiaElement.Create; +begin + FDecorators := TDiaDecoratorList.Create(Self); +end; + +destructor TDiaElement.Destroy; +begin + FreeAndNil(FDecorators); + inherited; +end; + procedure TDiaElement.Draw; begin // diff --git a/components/tachart/tadiagramdrawing.pas b/components/tachart/tadiagramdrawing.pas index 44e93516b2..a1bb4b8e35 100644 --- a/components/tachart/tadiagramdrawing.pas +++ b/components/tachart/tadiagramdrawing.pas @@ -25,10 +25,19 @@ type property Drawer: IChartDrawer read FDrawer write FDrawer; end; + TDiaPenDecorator = class(TDiaDecorator) + private + FPen: TFPCustomPen; + public + constructor Create(AOwner: TDiaDecoratorList); + destructor Destroy; override; + property Pen: TFPCustomPen read FPen; + end; + implementation uses - Math, Types, + Math, Types, SysUtils, TAGeometry; function ToImage(const AP: TDiaPoint): TPoint; inline; @@ -62,18 +71,20 @@ var Length: Integer = 20; startPos, endPos: TPoint; AAngle: float; + d: TDiaDecorator; begin if (ASelf.Start = nil) or (ASelf.Finish = nil) then exit; id := (ASelf.Owner.Context as TDiaContextDrawer).Drawer; id.PrepareSimplePen($000000); - if ASelf.Dashes then - id.SetPenParams(psDash, $000000); - id.SetBrushColor($FFFFFF); + for d in ASelf.Decorators do + if d is TDiaPenDecorator then + id.Pen := (d as TDiaPenDecorator).Pen; startPos := ToImage(ASelf.Start.ActualPos); endPos := ToImage(ASelf.Finish.ActualPos); id.Line(startPos, endPos); if not ASelf.Arrow then exit; id.SetPenParams(psSolid, $000000); + id.SetBrushColor($FFFFFF); da := ArcTan2(Width, Length); endPos := ToImage(ASelf.Finish.ActualPos); @@ -84,6 +95,21 @@ begin id.Polygon([pt1, endPos, pt2], 0, 3); end; +{ TDiaPenDecorator } + +constructor TDiaPenDecorator.Create(AOwner: TDiaDecoratorList); +begin + inherited Create(AOwner); + FPen := TFPCustomPen.Create; + FPen.Mode := pmCopy; +end; + +destructor TDiaPenDecorator.Destroy; +begin + FreeAndNil(FPen); + inherited; +end; + initialization TDiaBox.FInternalDraw := @DrawDiaBox; TDiaLink.FInternalDraw := @DrawDiaLink;