TAChart: Fix arrows at axes and constant line series with respect to rtl bidi mode and line flips

git-svn-id: trunk@48496 -
This commit is contained in:
wp 2015-03-24 23:05:13 +00:00
parent 56a9ba3535
commit 7b6b5c3ce1
4 changed files with 73 additions and 23 deletions

View File

@ -147,6 +147,7 @@ type
function GetChart: TCustomChart; inline;
function GetTransform: TChartAxisTransformations;
function IsDefaultPosition: Boolean;
function IsFlipped: Boolean; override;
function IsPointInside(const APoint: TPoint): Boolean;
function IsVertical: Boolean; inline;
procedure Measure(
@ -551,7 +552,7 @@ const
INVERTED_NAME: array [Boolean] of String = ('', ' Inverted');
begin
Result :=
SIDE_NAME[Alignment] + VISIBLE_NAME[Visible] + INVERTED_NAME[Inverted] +
SIDE_NAME[Alignment] + VISIBLE_NAME[Visible] + INVERTED_NAME[IsFlipped] +
FormatIfNotEmpty(' (%s)', Title.Caption);
end;
@ -589,12 +590,6 @@ begin
FMinForMarks := GetTransform.AxisToGraph(d.FMin);
FMaxForMarks := GetTransform.AxisToGraph(d.FMax);
end;
if Inverted and (Length(FMarkValues) > 0) then
for i := 0 to High(FMarkValues) div 2 do begin
t := FMarkValues[i];
FMarkValues[i] := FMarkValues[High(FMarkValues) - i];
FMarkValues[High(FMarkValues) - i] := t;
end;
if Assigned(FOnMarkToText) then
for i := 0 to High(FMarkValues) do
@ -623,6 +618,18 @@ begin
Result := (PositionUnits = cuPercent) and (Position = 0);
end;
function TChartAxis.IsFlipped: Boolean;
{ Returns drawing direction of the axis:
FALSE - left to right, or bottom to tip
TRUE - right to left, or top to bottom }
begin
Result := FInverted;
if (FAlignment in [calBottom, calTop]) and
(GetChart.BiDiMode <> bdLeftToRight)
then
Result := not Result;
end;
function TChartAxis.IsPointInside(const APoint: TPoint): Boolean;
begin
Result := PtInRect(FTitleRect, APoint) and not PtInRect(FAxisRect, APoint);
@ -745,7 +752,7 @@ begin
if Arrow.Visible then
with AMeasureData do begin
FSize := Max(d.Scale(Arrow.Width), FSize);
if Arrow.Inverted then
if IsFlipped then
FFirstMark := Max(d.Scale(Arrow.Length), FFirstMark)
else
FLastMark := Max(d.Scale(Arrow.Length), FLastMark);
@ -823,6 +830,7 @@ procedure TChartAxis.SetInverted(AValue: Boolean);
begin
if FInverted = AValue then exit;
FInverted := AValue;
if Arrow <> nil then Arrow.Inverted := IsFlipped;
StyleChanged(Self);
end;
@ -936,12 +944,8 @@ begin
Alignment := calLeft;
Title.LabelFont.Orientation := -Title.LabelFont.Orientation;
end;
calBottom,
calTop:
begin
Inverted := not Inverted;
if Arrow <> nil then Arrow.Inverted := not Arrow.Inverted;
end;
calBottom, calTop:
if Arrow <> nil then Arrow.Inverted := IsFlipped;
end;
end;
@ -1183,7 +1187,7 @@ end;
function TAxisCoeffHelper.CalcScale(ASign: Integer): Double;
begin
if (FMax^ = FMin^) or (Sign(FHi - FLo) <> ASign) then exit(1.0);
if (FAxis <> nil) and FAxis.Inverted then
if (FAxis <> nil) and FAxis.IsFlipped then
Exchange(FLo, FHi);
Result := (FHi - FLo) / (FMax^ - FMin^);
end;
@ -1197,7 +1201,7 @@ procedure TAxisCoeffHelper.UpdateMinMax(AConv: TAxisConvFunc);
begin
FMin^ := AConv(FImageLo);
FMax^ := AConv(FImageHi);
if (FAxis <> nil) and FAxis.Inverted then
if (FAxis <> nil) and FAxis.IsFlipped then
Exchange(FMin^, FMax^);
end;

View File

@ -172,6 +172,7 @@ type
destructor Destroy; override;
public
procedure Assign(ASource: TPersistent); override;
function IsFlipped: Boolean; virtual;
function TryApplyStripes(
ADrawer: IChartDrawer; var AIndex: Cardinal): Boolean;
@ -349,16 +350,28 @@ end;
procedure TAxisDrawHelper.InternalAxisLine(
APen: TChartPen; const AStart, AEnd: TPoint; AAngle: Double);
var
arrowBase: TPoint;
arrowFlipped: boolean;
begin
if not APen.Visible and not FAxis.Arrow.Visible then exit;
FDrawer.Pen := APen;
if APen.Visible then
LineZ(AStart, AEnd);
if FAxis.Arrow.Visible then
if FAxis.Arrow.Inverted then
FAxis.Arrow.Draw(FDrawer, AStart - FZOffset, AAngle, APen)
else
FAxis.Arrow.Draw(FDrawer, AEnd + FZOffset, AAngle, APen);
if FAxis.Arrow.Visible then begin
arrowFlipped := FAxis.IsFlipped;
if arrowFlipped <> FAxis.Arrow.Inverted then arrowFlipped := not arrowFlipped;
if FAxis.IsFlipped then begin
arrowBase := AStart - FZOffset;
if not arrowFlipped then
arrowBase -= RotatePointX(-FDrawer.Scale(FAxis.Arrow.Length), AAngle);
end else begin
arrowBase := AEnd + FZOffset;
if arrowFlipped then
arrowBase += RotatePointX(-FDrawer.Scale(FAxis.Arrow.Length), AAngle);
end;
FAxis.Arrow.Draw(FDrawer, arrowBase, AAngle, APen)
end;
end;
function TAxisDrawHelper.IsInClipRange(ACoord: Integer): Boolean;
@ -391,7 +404,7 @@ procedure TAxisDrawHelperX.DrawAxisLine(APen: TChartPen; AFixedCoord: Integer);
var
p: TPoint;
begin
if FAxis.Arrow.Inverted then begin
if FAxis.IsFlipped then begin
p := Point(FClipRect^.Left, AFixedCoord);
if FAxis.Arrow.Visible then
p.X -= FDrawer.Scale(FAxis.Arrow.Length);
@ -456,7 +469,7 @@ procedure TAxisDrawHelperY.DrawAxisLine(APen: TChartPen; AFixedCoord: Integer);
var
p: TPoint;
begin
if FAxis.Arrow.Inverted then begin
if FAxis.IsFlipped then begin
p := Point(AFixedCoord, FClipRect^.Bottom);
if FAxis.Arrow.Visible then
p.Y += FDrawer.Scale(FAxis.Arrow.Length);
@ -696,6 +709,11 @@ begin
Result := Marks.DefaultSource.Params;
end;
function TChartBasicAxis.IsFlipped: Boolean;
begin
Result := false;
end;
procedure TChartBasicAxis.SetArrow(AValue: TChartArrow);
begin
FArrow.Assign(AValue);

View File

@ -82,6 +82,7 @@ type
function IsEmpty: Boolean; virtual; abstract;
procedure MovePoint(var AIndex: Integer; const ANewPos: TPoint); overload; inline;
procedure MovePoint(var AIndex: Integer; const ANewPos: TDoublePoint); overload; virtual;
procedure UpdateBiDiMode; virtual;
property Active: Boolean read FActive write SetActive default true;
property Depth: TChartDistance read FDepth write SetDepth default 0;
@ -139,6 +140,7 @@ type
procedure Clear;
function Count: Integer;
function GetEnumerator: TBasicChartSeriesEnumerator;
procedure UpdateBiDiMode;
public
property Items[AIndex: Integer]: TBasicChartSeries read GetItem; default;
property List: TIndexedComponentList read FList;
@ -986,6 +988,11 @@ end;
function TChart.GetAxisByAlign(AAlign: TChartAxisAlignment): TChartAxis;
begin
if (BidiMode <> bdLeftToRight) then
case AAlign of
calLeft: AAlign := calRight;
calRight: AAlign := calLeft;
end;
Result := FAxisList.GetAxisByAlign(AAlign);
end;
@ -1418,6 +1425,7 @@ begin
Legend.UpdateBidiMode;
Title.UpdateBidiMode;
Foot.UpdateBidiMode;
Series.UpdateBiDiMode;
end;
end;
@ -1749,6 +1757,11 @@ begin
MovePoint(AIndex, FChart.ImageToGraph(ANewPos));
end;
procedure TBasicChartSeries.UpdateBiDiMode;
begin
// normally nothing to do. Override, e.g., to flip arrows
end;
procedure TBasicChartSeries.UpdateMargins(
ADrawer: IChartDrawer; var AMargins: TRect);
begin
@ -1804,6 +1817,14 @@ begin
Result := TBasicChartSeries(FList.Items[AIndex]);
end;
procedure TChartSeriesList.UpdateBiDiMode;
var
s: TBasicChartseries;
begin
for s in self do
s.UpdateBiDiMode;
end;
{ TBasicChartTool }
procedure TBasicChartTool.Activate;

View File

@ -289,6 +289,7 @@ type
out AResults: TNearestPointResults): Boolean; override;
function IsEmpty: Boolean; override;
procedure MovePoint(var AIndex: Integer; const ANewPos: TDoublePoint); override;
procedure UpdateBiDiMode; override;
published
property Active default true;
@ -894,6 +895,12 @@ begin
UpdateParentChart;
end;
procedure TConstantLine.UpdateBiDiMode;
begin
if LineStyle = lsHorizontal then
Arrow.Inverted := not Arrow.Inverted;
end;
{ TBarSeries }
procedure TBarSeries.Assign(ASource: TPersistent);