[FMX] 写了一个Helper,为TCustomScrollBox的子类添加ScrollInView方法

因为要用到,所以特意添加了这么个方法,FMX 的 TCustomScrollBox 没有提供,或者是我没有找到正确的,所以特意加了一个。另外,针对 TControl 加了一个 LocalToParent 函数用于将指针的坐标转换为指定级别的父控件的坐标。

完整源码奉上,但声明下,我只测试了一部分我用到的情况,其它情况没测试,如果你发现有问题,欢迎改正好发我更新下。

type
   TControlHelper = class helper for TControl
    function OffsetOf(AParent: TControl): TPointF;
    function LocalToParent(AParent: TControl; APoint: TPointF)
      : TPointF; overload;
    function LocalToParent(AParent: TControl; R: TRectF): TRectF; overload;
  end;

  TScrollBoxHelper = class helper for TCustomScrollBox
  public
    procedure ScrollInView(ACtrl: TControl);
  end;

{ TScrollBoxHelper }

procedure TScrollBoxHelper.ScrollInView(ACtrl: TControl);
var
  R, LR: TRectF;
  dx, dy: Single;
begin
  R := ACtrl.LocalToParent(Self, ACtrl.LocalRect);
  LR := LocalRect;
  if not LR.Contains(R) then
  begin
    if R.Left > LR.Right then
      dx := LR.Right-R.Right
    else if R.Right < R.Left then
      dx := R.Left
    else
      dx := 0;
    if R.Top > LR.Bottom then
      dy := LR.Bottom-R.Bottom
    else if R.Bottom < LR.Top then
      dy := R.Top
    else
      dy := 0;
    ScrollBy(dx, dy);
  end;
end;

{ TControlHelper }

function TControlHelper.LocalToParent(AParent: TControl;
APoint: TPointF): TPointF;
var
  AOffset: TPointF;
begin
  AOffset := OffsetOf(AParent);
  Result.X := APoint.X + AOffset.X;
  Result.Y := APoint.Y + AOffset.Y;
end;

function TControlHelper.LocalToParent(AParent: TControl; R: TRectF): TRectF;
var
  AOffset: TPointF;
begin
  AOffset := OffsetOf(AParent);
  Result := R;
  Result.Offset(AOffset.X, AOffset.Y);
end;

function TControlHelper.OffsetOf(AParent: TControl): TPointF;
var
  ACtrl: TControl;
begin
  ACtrl := Self;
  Result.X := 0;
  Result.Y := 0;
  while (ACtrl <> nil) and (ACtrl <> AParent) do
  begin
    Result.X := Result.X + ACtrl.Position.X;
    Result.Y := Result.Y + ACtrl.Position.Y;
    ACtrl := ACtrl.ParentControl;
  end;
  if not Assigned(ACtrl) then
    raise Exception.CreateFmt('指定的控件 %s 不是 %s 的子控件', [Name, AParent.Name]);
end;

 

分享到: