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(
ADrawer: IChartDrawer; const ATransf: ICoordTransformer;
AClipRect: PRect; AMaxZPosition: Integer);
procedure UpdateBidiMode;
procedure UpdateBounds(var AMin, AMax: Double);
property DisplayName: String read GetDisplayName;
property Value[AIndex: Integer]: TChartValueText read GetValue;
@ -223,6 +224,7 @@ type
procedure Prepare(ARect: TRect);
procedure PrepareGroups;
procedure SetAxisByAlign(AAlign: TChartAxisAlignment; AValue: TChartAxis);
procedure UpdateBiDiMode;
property Axes[AIndex: Integer]: TChartAxis read GetAxes; default;
property BottomAxis: TChartAxis index calBottom read GetAxisByAlign write SetAxisByAlign;
@ -900,6 +902,26 @@ begin
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);
begin
with Range do begin
@ -1112,6 +1134,14 @@ begin
FChart.Invalidate;
end;
procedure TChartAxisList.UpdateBiDiMode;
var
a: TChartAxis;
begin
for a in self do
a.UpdateBidiMode;
end;
{ TAxisCoeffHelper }
constructor TAxisCoeffHelper.Init(

View File

@ -422,6 +422,19 @@ end;
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;
var
bmp: TBitmap;
@ -439,7 +452,7 @@ procedure TCanvasDrawer.SimpleTextOut(AX, AY: Integer; const AText: String);
bmp.Canvas.Brush.Style := bsClear;
bmp.Canvas.Font := GetCanvas.Font;
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;
BitBlt(
GetCanvas.Handle, AX - p.X, AY - p.Y, bmpSize.X, bmpSize.Y,
@ -453,7 +466,7 @@ begin
if FXor then
DrawXorText
else
GetCanvas.TextOut(AX, AY, AText);
DrawSimpleText(GetCanvas, AX, AY, AText);
end;
initialization

View File

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

View File

@ -283,6 +283,7 @@ type
procedure PrepareAxis(ADrawer: IChartDrawer);
function PrepareLegend(
ADrawer: IChartDrawer; var AClipRect: TRect): TChartLegendDrawingData;
procedure SetBiDiMode(AValue: TBiDiMode); override;
procedure SetName(const AValue: TComponentName); override;
public
constructor Create(AOwner: TComponent); override;
@ -403,6 +404,7 @@ type
published
property Align;
property Anchors;
property BiDiMode;
property BorderSpacing;
property Color default clBtnFace;
property DoubleBuffered;
@ -793,6 +795,8 @@ var
begin
Prepare;
ADrawer.SetRightToLeft(BiDiMode <> bdLeftToRight);
FClipRect := ARect;
with MarginsExternal do begin
FClipRect.Left += Left;
@ -1368,6 +1372,19 @@ begin
StyleChanged(Self);
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);
var
i: Integer;

View File

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

View File

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