TAChart: initial implementation of BiDiMode

git-svn-id: trunk@44555 -
This commit is contained in:
wp 2014-03-30 16:23:31 +00:00
parent 759c840e8a
commit 6df6fe5c6e
6 changed files with 124 additions and 10 deletions

View File

@ -154,6 +154,7 @@ type
procedure PrepareHelper( procedure PrepareHelper(
ADrawer: IChartDrawer; const ATransf: ICoordTransformer; ADrawer: IChartDrawer; const ATransf: ICoordTransformer;
AClipRect: PRect; AMaxZPosition: Integer); AClipRect: PRect; AMaxZPosition: Integer);
procedure UpdateBidiMode;
procedure UpdateBounds(var AMin, AMax: Double); procedure UpdateBounds(var AMin, AMax: Double);
property DisplayName: String read GetDisplayName; property DisplayName: String read GetDisplayName;
property Value[AIndex: Integer]: TChartValueText read GetValue; property Value[AIndex: Integer]: TChartValueText read GetValue;
@ -223,6 +224,7 @@ type
procedure Prepare(ARect: TRect); procedure Prepare(ARect: TRect);
procedure PrepareGroups; procedure PrepareGroups;
procedure SetAxisByAlign(AAlign: TChartAxisAlignment; AValue: TChartAxis); procedure SetAxisByAlign(AAlign: TChartAxisAlignment; AValue: TChartAxis);
procedure UpdateBiDiMode;
property Axes[AIndex: Integer]: TChartAxis read GetAxes; default; property Axes[AIndex: Integer]: TChartAxis read GetAxes; default;
property BottomAxis: TChartAxis index calBottom read GetAxisByAlign write SetAxisByAlign; property BottomAxis: TChartAxis index calBottom read GetAxisByAlign write SetAxisByAlign;
@ -900,6 +902,26 @@ begin
end; end;
end; end;
procedure TChartAxis.UpdateBidiMode;
begin
if csLoading in GetChart.ComponentState then
exit;
case GetAlignment of
calLeft:
begin
Alignment := calRight;
Title.Font.Orientation := -Title.Font.Orientation;
end;
calRight:
begin
Alignment := calLeft;
Title.Font.Orientation := -Title.Font.Orientation;
end;
calBottom,
calTop: Inverted := not Inverted;
end;
end;
procedure TChartAxis.UpdateBounds(var AMin, AMax: Double); procedure TChartAxis.UpdateBounds(var AMin, AMax: Double);
begin begin
with Range do begin with Range do begin
@ -1112,6 +1134,14 @@ begin
FChart.Invalidate; FChart.Invalidate;
end; end;
procedure TChartAxisList.UpdateBiDiMode;
var
a: TChartAxis;
begin
for a in self do
a.UpdateBidiMode;
end;
{ TAxisCoeffHelper } { TAxisCoeffHelper }
constructor TAxisCoeffHelper.Init( constructor TAxisCoeffHelper.Init(

View File

@ -422,6 +422,19 @@ end;
procedure TCanvasDrawer.SimpleTextOut(AX, AY: Integer; const AText: String); procedure TCanvasDrawer.SimpleTextOut(AX, AY: Integer; const AText: String);
procedure DrawSimpleText(ACanvas: TCanvas; x, y: Integer; const txt: String);
// add right-to-left mode. Cannot use TextOut since it does not respect TextStyle
var
r: TRect;
ts: TTextStyle;
begin
ts := ACanvas.TextStyle;
ts.RightToLeft := FRightToLeft;
ts.Clipping := false;
r := Bounds(x, y, 1, 1);
ACanvas.TextRect(r, x, y, txt, ts);
end;
procedure DrawXorText; procedure DrawXorText;
var var
bmp: TBitmap; bmp: TBitmap;
@ -439,7 +452,7 @@ procedure TCanvasDrawer.SimpleTextOut(AX, AY: Integer; const AText: String);
bmp.Canvas.Brush.Style := bsClear; bmp.Canvas.Brush.Style := bsClear;
bmp.Canvas.Font := GetCanvas.Font; bmp.Canvas.Font := GetCanvas.Font;
bmp.Canvas.Font.Color := clWhite; bmp.Canvas.Font.Color := clWhite;
bmp.Canvas.TextOut(p.X, p.Y, AText); DrawSimpleText(bmp.Canvas, p.X, p.Y, AText);
bmp.Canvas.Pen.Color := clWhite; bmp.Canvas.Pen.Color := clWhite;
BitBlt( BitBlt(
GetCanvas.Handle, AX - p.X, AY - p.Y, bmpSize.X, bmpSize.Y, GetCanvas.Handle, AX - p.X, AY - p.Y, bmpSize.X, bmpSize.Y,
@ -453,7 +466,7 @@ begin
if FXor then if FXor then
DrawXorText DrawXorText
else else
GetCanvas.TextOut(AX, AY, AText); DrawSimpleText(GetCanvas, AX, AY, AText);
end; end;
initialization initialization

View File

@ -99,6 +99,8 @@ type
procedure SetMonochromeColor(AColor: TChartColor); procedure SetMonochromeColor(AColor: TChartColor);
procedure SetPen(APen: TFPCustomPen); procedure SetPen(APen: TFPCustomPen);
procedure SetPenParams(AStyle: TFPPenStyle; AColor: TChartColor); procedure SetPenParams(AStyle: TFPPenStyle; AColor: TChartColor);
function GetRightToLeft: Boolean;
procedure SetRightToLeft(AValue: Boolean);
procedure SetTransparency(ATransparency: TChartTransparency); procedure SetTransparency(ATransparency: TChartTransparency);
procedure SetXor(AXor: Boolean); procedure SetXor(AXor: Boolean);
function TextExtent(const AText: String): TPoint; function TextExtent(const AText: String): TPoint;
@ -122,6 +124,7 @@ type
FChartColorToFPColorFunc: TChartColorToFPColorFunc; FChartColorToFPColorFunc: TChartColorToFPColorFunc;
FGetFontOrientationFunc: TGetFontOrientationFunc; FGetFontOrientationFunc: TGetFontOrientationFunc;
FMonochromeColor: TChartColor; FMonochromeColor: TChartColor;
FRightToLeft: Boolean;
FTransparency: TChartTransparency; FTransparency: TChartTransparency;
FXor: Boolean; FXor: Boolean;
function ColorOrMono(AColor: TChartColor): TChartColor; inline; function ColorOrMono(AColor: TChartColor): TChartColor; inline;
@ -135,6 +138,7 @@ type
procedure DrawingEnd; virtual; procedure DrawingEnd; virtual;
procedure DrawLineDepth(AX1, AY1, AX2, AY2, ADepth: Integer); procedure DrawLineDepth(AX1, AY1, AX2, AY2, ADepth: Integer);
procedure DrawLineDepth(const AP1, AP2: TPoint; ADepth: Integer); procedure DrawLineDepth(const AP1, AP2: TPoint; ADepth: Integer);
function GetRightToLeft: Boolean;
procedure LineTo(AX, AY: Integer); virtual; abstract; procedure LineTo(AX, AY: Integer); virtual; abstract;
procedure LineTo(const AP: TPoint); procedure LineTo(const AP: TPoint);
procedure MoveTo(AX, AY: Integer); virtual; abstract; procedure MoveTo(AX, AY: Integer); virtual; abstract;
@ -147,6 +151,7 @@ type
procedure SetDoChartColorToFPColorFunc(AValue: TChartColorToFPColorFunc); procedure SetDoChartColorToFPColorFunc(AValue: TChartColorToFPColorFunc);
procedure SetGetFontOrientationFunc(AValue: TGetFontOrientationFunc); procedure SetGetFontOrientationFunc(AValue: TGetFontOrientationFunc);
procedure SetMonochromeColor(AColor: TChartColor); procedure SetMonochromeColor(AColor: TChartColor);
procedure SetRightToLeft(AValue: Boolean);
procedure SetTransparency(ATransparency: TChartTransparency); procedure SetTransparency(ATransparency: TChartTransparency);
procedure SetXor(AXor: Boolean); procedure SetXor(AXor: Boolean);
function TextExtent(const AText: String): TPoint; function TextExtent(const AText: String): TPoint;
@ -330,6 +335,11 @@ begin
Result := FChartColorToFPColorFunc(FMonochromeColor); Result := FChartColorToFPColorFunc(FMonochromeColor);
end; end;
function TBasicDrawer.GetRightToLeft: Boolean;
begin
Result := FRightToLeft;
end;
procedure TBasicDrawer.LineTo(const AP: TPoint); procedure TBasicDrawer.LineTo(const AP: TPoint);
begin begin
LineTo(AP.X, AP.Y) LineTo(AP.X, AP.Y)
@ -373,6 +383,11 @@ begin
FMonochromeColor := AColor; FMonochromeColor := AColor;
end; end;
procedure TBasicDrawer.SetRightToLeft(AValue: Boolean);
begin
FRightToLeft := AValue;
end;
procedure TBasicDrawer.SetTransparency(ATransparency: TChartTransparency); procedure TBasicDrawer.SetTransparency(ATransparency: TChartTransparency);
begin begin
FTransparency := ATransparency; FTransparency := ATransparency;

View File

@ -283,6 +283,7 @@ type
procedure PrepareAxis(ADrawer: IChartDrawer); procedure PrepareAxis(ADrawer: IChartDrawer);
function PrepareLegend( function PrepareLegend(
ADrawer: IChartDrawer; var AClipRect: TRect): TChartLegendDrawingData; ADrawer: IChartDrawer; var AClipRect: TRect): TChartLegendDrawingData;
procedure SetBiDiMode(AValue: TBiDiMode); override;
procedure SetName(const AValue: TComponentName); override; procedure SetName(const AValue: TComponentName); override;
public public
constructor Create(AOwner: TComponent); override; constructor Create(AOwner: TComponent); override;
@ -403,6 +404,7 @@ type
published published
property Align; property Align;
property Anchors; property Anchors;
property BiDiMode;
property BorderSpacing; property BorderSpacing;
property Color default clBtnFace; property Color default clBtnFace;
property DoubleBuffered; property DoubleBuffered;
@ -793,6 +795,8 @@ var
begin begin
Prepare; Prepare;
ADrawer.SetRightToLeft(BiDiMode <> bdLeftToRight);
FClipRect := ARect; FClipRect := ARect;
with MarginsExternal do begin with MarginsExternal do begin
FClipRect.Left += Left; FClipRect.Left += Left;
@ -1368,6 +1372,19 @@ begin
StyleChanged(Self); StyleChanged(Self);
end; end;
procedure TChart.SetBiDiMode(AValue: TBiDiMode);
begin
if AValue = BidiMode then
exit;
inherited SetBiDiMode(AValue);
if not (csLoading in ComponentState) then begin
AxisList.UpdateBidiMode;
Legend.UpdateBidiMode;
Title.UpdateBidiMode;
Foot.UpdateBidiMode;
end;
end;
procedure TChart.SetChildOrder(Child: TComponent; Order: Integer); procedure TChart.SetChildOrder(Child: TComponent; Order: Integer);
var var
i: Integer; i: Integer;

View File

@ -198,13 +198,13 @@ type
public public
constructor Create(AOwner: TCustomChart); constructor Create(AOwner: TCustomChart);
destructor Destroy; override; destructor Destroy; override;
public public
procedure AddGroups(AItems: TChartLegendItems); procedure AddGroups(AItems: TChartLegendItems);
procedure Assign(Source: TPersistent); override; procedure Assign(Source: TPersistent); override;
procedure Draw(var AData: TChartLegendDrawingData); procedure Draw(var AData: TChartLegendDrawingData);
procedure Prepare(var AData: TChartLegendDrawingData; var AClipRect: TRect); procedure Prepare(var AData: TChartLegendDrawingData; var AClipRect: TRect);
procedure SortItemsByOrder(AItems: TChartLegendItems); procedure SortItemsByOrder(AItems: TChartLegendItems);
procedure UpdateBidiMode;
published published
property Alignment: TLegendAlignment property Alignment: TLegendAlignment
read FAlignment write SetAlignment default laTopRight; read FAlignment write SetAlignment default laTopRight;
@ -341,8 +341,13 @@ end;
procedure TLegendItem.Draw(ADrawer: IChartDrawer; const ARect: TRect); procedure TLegendItem.Draw(ADrawer: IChartDrawer; const ARect: TRect);
begin begin
ADrawer.TextOut. if ADrawer.GetRightToLeft then
Pos(ARect.Right + SYMBOL_TEXT_SPACING, ARect.Top).Text(FText).Done; ADrawer.TextOut.
Pos(ARect.Left - SYMBOL_TEXT_SPACING - ADrawer.TextExtent(FText).X, ARect.Top).
Text(FText).Done
else
ADrawer.TextOut.
Pos(ARect.Right + SYMBOL_TEXT_SPACING, ARect.Top).Text(FText).Done;
end; end;
function TLegendItem.HasSymbol: Boolean; function TLegendItem.HasSymbol: Boolean;
@ -361,7 +366,12 @@ end;
procedure TLegendItemGroupTitle.Draw(ADrawer: IChartDrawer; const ARect: TRect); procedure TLegendItemGroupTitle.Draw(ADrawer: IChartDrawer; const ARect: TRect);
begin begin
ADrawer.TextOut.Pos(ARect.Left, ARect.Top).Text(Text).Done; if ADrawer.GetRightToLeft then
ADrawer.TextOut.
Pos(ARect.Right - ADrawer.TextExtent(Text).X, ARect.Top).Text(Text).Done
else
ADrawer.TextOut.
Pos(ARect.Left, ARect.Top).Text(Text).Done;
end; end;
function TLegendItemGroupTitle.HasSymbol: Boolean; function TLegendItemGroupTitle.HasSymbol: Boolean;
@ -545,7 +555,9 @@ var
i, x, y: Integer; i, x, y: Integer;
prevFont: TFont = nil; prevFont: TFont = nil;
r: TRect; r: TRect;
isRTL: Boolean;
begin begin
isRTL := drawer.GetRightToLeft;
with AData do begin with AData do begin
for i := 0 to FItems.Count - 1 do begin for i := 0 to FItems.Count - 1 do begin
FItems[i].UpdateFont(drawer, prevFont); FItems[i].UpdateFont(drawer, prevFont);
@ -560,10 +572,16 @@ var
lfoColRow: DivMod(i, FRowCount, x, y); lfoColRow: DivMod(i, FRowCount, x, y);
lfoRowCol: DivMod(i, FColCount, y, x); lfoRowCol: DivMod(i, FColCount, y, x);
end; end;
r := Bounds( if isRTL then
FBounds.Left + Spacing + x * (FItemSize.X + Spacing), r := Bounds(
FBounds.Top + Spacing + y * (FItemSize.Y + Spacing), FBounds.Right - Spacing - x * (FItemSize.X + Spacing) - SymbolWidth,
SymbolWidth, FItemSize.Y); FBounds.Top + Spacing + y * (FItemSize.Y + Spacing),
SymbolWidth, FItemSize.Y)
else
r := Bounds(
FBounds.Left + Spacing + x * (FItemSize.X + Spacing),
FBounds.Top + Spacing + y * (FItemSize.Y + Spacing),
SymbolWidth, FItemSize.Y);
FItems[i].Draw(drawer, r); FItems[i].Draw(drawer, r);
OffsetRect(r, 0, FItemSize.Y + Spacing); OffsetRect(r, 0, FItemSize.Y + Spacing);
end; end;
@ -830,6 +848,18 @@ begin
AItems.Sort(@LegendItemCompare); AItems.Sort(@LegendItemCompare);
end; end;
procedure TChartLegend.UpdateBidiMode;
begin
case Alignment of
laTopLeft : Alignment := laTopRight;
laCenterLeft : Alignment := laCenterRight;
laBottomLeft : Alignment := laBottomRight;
laTopRight : Alignment := laTopLeft;
laCenterRight : Alignment := laCenterLeft;
laBottomRight : Alignment := laBottomLeft;
end;
end;
{ TChartSeriesLegend } { TChartSeriesLegend }
procedure TChartSeriesLegend.Assign(Source: TPersistent); procedure TChartSeriesLegend.Assign(Source: TPersistent);

View File

@ -136,6 +136,7 @@ type
procedure Draw(ADrawer: IChartDrawer); procedure Draw(ADrawer: IChartDrawer);
procedure Measure( procedure Measure(
ADrawer: IChartDrawer; ADir, ALeft, ARight: Integer; var AY: Integer); ADrawer: IChartDrawer; ADir, ALeft, ARight: Integer; var AY: Integer);
procedure UpdateBidiMode;
published published
property Alignment default taCenter; property Alignment default taCenter;
property Brush: TBrush read FBrush write SetBrush; property Brush: TBrush read FBrush write SetBrush;
@ -580,6 +581,14 @@ begin
StyleChanged(Self); StyleChanged(Self);
end; end;
procedure TChartTitle.UpdateBidiMode;
begin
case Alignment of
taLeftJustify : Alignment := taRightJustify;
taRightJustify : Alignment := taLeftJustify;
end;
end;
{ TGenericChartMarks } { TGenericChartMarks }
procedure TGenericChartMarks.ApplyLabelFont(ADrawer: IChartDrawer); procedure TGenericChartMarks.ApplyLabelFont(ADrawer: IChartDrawer);