From a4fb8cc245d48451c0df2f7cb17c1b6774f63d60 Mon Sep 17 00:00:00 2001 From: ask Date: Sun, 13 Feb 2011 15:49:51 +0000 Subject: [PATCH] TAChart: Use IChartDrawer to draw chart title and footer git-svn-id: trunk@29528 - --- components/tachart/tadrawutils.pas | 107 ++++++++++++++++++++++++++--- components/tachart/tagraph.pas | 24 ++----- components/tachart/talegend.pas | 3 +- components/tachart/tatypes.pas | 28 ++++---- 4 files changed, 119 insertions(+), 43 deletions(-) diff --git a/components/tachart/tadrawutils.pas b/components/tachart/tadrawutils.pas index 62c4d0e538..8bd22a86b5 100644 --- a/components/tachart/tadrawutils.pas +++ b/components/tachart/tadrawutils.pas @@ -50,6 +50,8 @@ type procedure Recall; end; + TChartTextOut = class; + { IChartDrawer } IChartDrawer = interface @@ -66,7 +68,8 @@ type procedure SetFont(AValue: TFPCustomFont); procedure SetPen(APen: TFPCustomPen); function TextExtent(const AText: String): TPoint; - procedure TextOut(AX, AY: Integer; const AText: String); + function TextExtent(AText: TStrings): TPoint; + function TextOut: TChartTextOut; property Brush: TFPCustomBrush write SetBrush; property Canvas: TCanvas read GetCanvas; @@ -74,6 +77,27 @@ type property Pen: TFPCustomPen write SetPen; end; + { TChartTextOut } + + TChartTextOut = class + FAlignment: TAlignment; + FDrawer: IChartDrawer; + FPos: TPoint; + FText1: String; + FText2: TStrings; + FWidth: Integer; + public + constructor Create(ADrawer: IChartDrawer); + public + function Alignment(AAlignment: TAlignment): TChartTextOut; + procedure Done; + function Pos(AX, AY: Integer): TChartTextOut; + function Pos(const APos: TPoint): TChartTextOut; + function Text(const AText: String): TChartTextOut; + function Text(const AText: TStrings): TChartTextOut; + function Width(AWidth: Integer): TChartTextOut; + end; + { TCanvasDrawer } TCanvasDrawer = class(TInterfacedObject, IChartDrawer) @@ -95,7 +119,8 @@ type procedure Rectangle(const ARect: TRect); procedure SetBrushParams(AStyle: TBrushStyle; AColor: TChartColor); function TextExtent(const AText: String): TPoint; - procedure TextOut(AX, AY: Integer; const AText: String); + function TextExtent(AText: TStrings): TPoint; + function TextOut: TChartTextOut; end; procedure DrawLineDepth(ACanvas: TCanvas; AX1, AY1, AX2, AY2, ADepth: Integer); @@ -103,10 +128,12 @@ procedure DrawLineDepth(ACanvas: TCanvas; const AP1, AP2: TPoint; ADepth: Intege function MultiLineTextExtent(ACanvas: TCanvas; const AText: String): TPoint; function MultiLineTextExtent(ACanvas: TCanvas; AText: TStrings): TPoint; -procedure MultiLineTextOut(ACanvas: TCanvas; APos: TPoint; const AText: String); procedure MultiLineTextOut( - ACanvas: TCanvas; APos: TPoint; AText: TStrings; AAlignment: TAlignment; - AWidth: Integer); + ACanvas: TCanvas; APos: TPoint; const AText: String; + AAlignment: TAlignment; AWidth: Integer); +procedure MultiLineTextOut( + ACanvas: TCanvas; APos: TPoint; AText: TStrings; + AAlignment: TAlignment; AWidth: Integer); procedure PrepareSimplePen(ACanvas: TCanvas; AColor: TColor); procedure PrepareXorPen(ACanvas: TCanvas); @@ -162,7 +189,9 @@ begin end; end; -procedure MultiLineTextOut(ACanvas: TCanvas; APos: TPoint; const AText: String); +procedure MultiLineTextOut( + ACanvas: TCanvas; APos: TPoint; const AText: String; AAlignment: TAlignment; + AWidth: Integer); var sl: TStrings; begin @@ -173,7 +202,7 @@ begin sl := TStringList.Create; try sl.Text := AText; - MultiLineTextOut(ACanvas, APos, sl, taLeftJustify, 0); + MultiLineTextOut(ACanvas, APos, sl, AAlignment, AWidth); finally sl.Free; end; @@ -228,6 +257,59 @@ begin Result := ACanvas.TextHeight(TYPICAL_TEXT); end; +{ TChartTextOut } + +function TChartTextOut.Alignment(AAlignment: TAlignment): TChartTextOut; +begin + FAlignment := AAlignment; + Result := Self; +end; + +constructor TChartTextOut.Create(ADrawer: IChartDrawer); +begin + FDrawer := ADrawer; + FAlignment := taLeftJustify; +end; + +procedure TChartTextOut.Done; +begin + if FText2 = nil then + MultiLineTextOut(FDrawer.Canvas, FPos, FText1, FAlignment, FWidth) + else + MultiLineTextOut(FDrawer.Canvas, FPos, FText2, FAlignment, FWidth); + Free; +end; + +function TChartTextOut.Pos(AX, AY: Integer): TChartTextOut; +begin + FPos := Point(AX, AY); + Result := Self; +end; + +function TChartTextOut.Pos(const APos: TPoint): TChartTextOut; +begin + FPos := APos; + Result := Self; +end; + +function TChartTextOut.Text(const AText: String): TChartTextOut; +begin + FText1 := AText; + Result := Self; +end; + +function TChartTextOut.Text(const AText: TStrings): TChartTextOut; +begin + FText2 := AText; + Result := Self; +end; + +function TChartTextOut.Width(AWidth: Integer): TChartTextOut; +begin + FWidth := AWidth; + Result := Self; +end; + { TCanvasDrawer } constructor TCanvasDrawer.Create(ACanvas: TCanvas); @@ -292,12 +374,17 @@ end; function TCanvasDrawer.TextExtent(const AText: String): TPoint; begin - Result := FCanvas.TextExtent(AText); + Result := MultiLineTextExtent(FCanvas, AText); end; -procedure TCanvasDrawer.TextOut(AX, AY: Integer; const AText: String); +function TCanvasDrawer.TextExtent(AText: TStrings): TPoint; begin - FCanvas.TextOut(AX, AY, AText); + Result := MultiLineTextExtent(FCanvas, AText); +end; + +function TCanvasDrawer.TextOut: TChartTextOut; +begin + Result := TChartTextOut.Create(Self); end; { TPenBrushFontRecall } diff --git a/components/tachart/tagraph.pas b/components/tachart/tagraph.pas index 92edf776ea..8b52788a1d 100644 --- a/components/tachart/tagraph.pas +++ b/components/tachart/tagraph.pas @@ -218,7 +218,6 @@ type procedure Clear(ADrawer: IChartDrawer; const ARect: TRect); procedure DisplaySeries(ADrawer: IChartDrawer); procedure DrawBackWall(ACanvas: TCanvas); - procedure DrawTitleFoot(ACanvas: TCanvas); procedure MouseDown( Button: TMouseButton; Shift: TShiftState; X, Y: Integer); override; procedure MouseMove(Shift: TShiftState; X, Y: Integer); override; @@ -629,7 +628,7 @@ end; procedure TChart.Draw(ADrawer: IChartDrawer; const ARect: TRect); var - i: Integer; + i, c: Integer; legendItems: TChartLegendItems = nil; legendRect: TRect; begin @@ -648,7 +647,11 @@ begin if not FIsZoomed then FLogicalExtent := GetFullExtent; FCurrentExtent := FLogicalExtent; - DrawTitleFoot(ADrawer.Canvas); + + c := (FClipRect.Left + FClipRect.Right) div 2; + FTitle.Draw(ADrawer, 1, c, FClipRect.Top); + FFoot.Draw(ADrawer, -1, c, FClipRect.Bottom); + if Legend.Visible then PrepareLegend(ADrawer, legendItems, FClipRect, legendRect); try @@ -734,21 +737,6 @@ begin DrawLineHoriz(ACanvas, FReticulePos.Y); end; -procedure TChart.DrawTitleFoot(ACanvas: TCanvas); -var - c: Integer; - pbf: TPenBrushFontRecall; -begin - pbf := TPenBrushFontRecall.Create(ACanvas, [pbfBrush, pbfFont]); - try - c := (FClipRect.Left + FClipRect.Right) div 2; - FTitle.Draw(ACanvas, 1, c, FClipRect.Top); - FFoot.Draw(ACanvas, -1, c, FClipRect.Bottom); - finally - pbf.Free; - end; -end; - procedure TChart.EraseBackground(DC: HDC); begin // do not erase, since we will paint over it anyway diff --git a/components/tachart/talegend.pas b/components/tachart/talegend.pas index 5806d3b500..fd4802a534 100644 --- a/components/tachart/talegend.pas +++ b/components/tachart/talegend.pas @@ -204,7 +204,8 @@ end; procedure TLegendItem.Draw(ADrawer: IChartDrawer; const ARect: TRect); begin - ADrawer.TextOut(ARect.Right + SYMBOL_TEXT_SPACING, ARect.Top, FText); + ADrawer.TextOut. + Pos(ARect.Right + SYMBOL_TEXT_SPACING, ARect.Top).Text(FText).Done; end; { TLegendItemUserDrawn } diff --git a/components/tachart/tatypes.pas b/components/tachart/tatypes.pas index afb7310b38..e2902b539b 100644 --- a/components/tachart/tatypes.pas +++ b/components/tachart/tatypes.pas @@ -29,7 +29,7 @@ interface uses Classes, SysUtils, Graphics, Controls, FPCanvas, Types, - TAChartUtils; + TAChartUtils, TADrawUtils; const MARKS_MARGIN_X = 4; @@ -103,8 +103,8 @@ type constructor Create(AOwner: TCustomChart); destructor Destroy; override; public - procedure Assign(Source: TPersistent); override; - procedure Draw(ACanvas: TCanvas; ADir, AX: Integer; var AY: Integer); + procedure Assign(ASource: TPersistent); override; + procedure Draw(ADrawer: IChartDrawer; ADir, AX: Integer; var AY: Integer); published property Alignment: TAlignment read FAlignment write SetAlignment default taCenter; @@ -311,7 +311,7 @@ type implementation uses - TACustomSource, TADrawUtils; + TACustomSource; { TChartPen } @@ -383,10 +383,10 @@ end; { TChartTitle } -procedure TChartTitle.Assign(Source: TPersistent); +procedure TChartTitle.Assign(ASource: TPersistent); begin - if Source is TChartTitle then - with TChartTitle(Source) do begin + if ASource is TChartTitle then + with TChartTitle(ASource) do begin Self.FAlignment := Alignment; Self.FBrush.Assign(Brush); Self.FFont.Assign(Font); @@ -394,7 +394,7 @@ begin Self.FText.Assign(Text); end; - inherited Assign(Source); + inherited Assign(ASource); end; constructor TChartTitle.Create(AOwner: TCustomChart); @@ -423,22 +423,22 @@ begin end; procedure TChartTitle.Draw( - ACanvas: TCanvas; ADir, AX: Integer; var AY: Integer); + ADrawer: IChartDrawer; ADir, AX: Integer; var AY: Integer); var ptSize, textOrigin: TPoint; a: Double; w: Integer; begin if not Visible or (Text.Count = 0) then exit; - ACanvas.Brush.Assign(Brush); - ACanvas.Font.Assign(Font); + ADrawer.Brush := Brush; + ADrawer.Font := Font; a := -OrientToRad(Font.Orientation); - ptSize := MultiLineTextExtent(ACanvas, Text); + ptSize := ADrawer.TextExtent(Text); textOrigin := RotatePoint(-ptSize div 2, a); w := ptSize.X; ptSize := MeasureRotatedRect(ptSize, a); textOrigin += Point(AX, AY + ptSize.Y div 2 * ADir); - MultiLineTextOut(ACanvas, textOrigin, Text, Alignment, w); + ADrawer.TextOut.Pos(textOrigin).Text(Text).Alignment(Alignment).Width(w).Done; AY += ADir * (ptSize.Y + Margin); end; @@ -567,7 +567,7 @@ begin end; ptText := RotatePoint(-ptText div 2, LabelAngle) + ALabelCenter; - MultiLineTextOut(ACanvas, ptText, AText); + MultiLineTextOut(ACanvas, ptText, AText, taLeftJustify, 0); if wasClipping then ACanvas.Clipping := true; end;