2

多年来,我一直使用 VCL 表单应用程序布局策略来自动调整主表单上的表单控件的大小。用户可以使用与按钮布局、图表等相同的一般外观和感觉随意最大化或调整应用程序的大小。为此,我编写了代码来根据表单的 FormResize 事件来操作子控件的 BoundsRect,并且这种简单的技术保留了文本字体大小和纵横比(例如按钮)。我还有更简单的代码来提高和降低字体大小以跟踪主控件的扩展和缩小按钮/标签大小,但是当应用程序最小化时,许多控件(例如 TChart)留下了可读的小字体——我很高兴有了这个。

我想迁移我的布局以使用具有 TScaledLayout 的 FireMonkey,当您将其对齐 alClient 时,它会整齐地调整其所有包含的控件的大小。不幸的是,调整大小也扩展到所有文本字体,这确实是不可取的。将 TScaledLayout 设置为 alFit 会保持内容的原始纵横比,但可能会导致顶部或侧面的空白填充以实现此目的。

有什么方法可以在 TScaledLayout 操作下“关闭”所有字体的大小调整?我已经探索了FireMonkey Layouts Strategies中的信息,并且还尝试了每个大大增加的“对齐”设置,但均未成功。在各种显示设备之间移动时使用全屏肯定需要这种能力吗?

4

2 回答 2

1

想想像投影仪上的透明层(还记得那些吗?)。将文本标签放在表单上的面板上。将 scaledlayout 放在面板上。将控件放在 scaledlayout 上。现在,当窗体调整大小时,控件也会这样做,但标签不会。

于 2015-04-26T14:28:05.410 回答
0

可以尝试以下策略:

  • 使用 ScaledLayout 并将其 Align 属性设置为 Fit。我想您还必须在其子项上使用 Align := None 和 no Anchors。
  • 将它放在面板内并将其设置为 Align:=Client。
  • 将面板放置在表单中

就我而言,我想在 TScrollBox 布局内制作一个可缩放面板(保留纵横比),因此我在该面板上使用 Align:=Center 并以编程方式设置其缩放比例以进行缩放。

请注意,Embarcadero 的 ScaledLayout 示例在这种情况下具有误导性,因为它设置了 ScaledLayout 的比例(这与 ScaledLayout 在调整大小时的子级缩放功能无关 - 他们可以在 TPanel 或任何其他容器上设置 Scale)

另一个令人困惑的方面是 Align := Scale at controls 与 Scaling 无关,而是在父调整大小时保持其相对位置和相对大小(即它们不缩放显示,它们实际上调整大小)时调整子控件的大小。

更新:

我发现当使用上述策略放大/缩小时,滚动条的行为与预期相反。我意识到它与未调整大小的外部面板有关,而只是设置了它的比例(请注意,由于它在我的情况下位于滚动框中,因此我将其设置为 Align:=Center,而不是 Align:=Client 就像您在表单)

因此,我使用了另一个 TScaleLayout 而不是外部面板,因为它具有额外有用的属性 OriginalWidth/OriginalHeight 可以保持控件的原始大小。这是基于在放大/缩小时应用的新比例计算新大小所必需的(不使用它的 Scale 属性,因为 Embarcadero 的示例误导性地暗示,除了 Unit/-Unit 轴比例值以支持负比例 [aka轴翻转]):

procedure TForm2.FormCreate(Sender: TObject);
begin
  BeginUpdate;
  Zoomer.Align := TAlignLayout.Center; //at design mode we have it set to TAlignLayout.Client
  UpdateZoomFromTrackbars;
  EndUpdate;
end;

procedure TForm2.SetZoom(const Value: Single);
begin
  SetZoom(Value, Value);
end;

procedure TForm2.SetZoom(const ValueX, ValueY: Single);
begin
  if (ValueX <> 0) and (ValueY <>0) then //FMX has bug where Scale won't work anymore if set to 0
    begin
    BeginUpdate;

    //update track bars
    trackZoomX.BeginUpdate; trackZoomX.ValueRange.Value := ValueX; trackZoomX.EndUpdate;
    trackZoomY.BeginUpdate; trackZoomY.ValueRange.Value := ValueY; trackZoomY.EndUpdate;

    with Zoomer do
    begin
      Size.Size := TSizeF.Create(OriginalWidth * abs(ValueX), OriginalHeight * abs(ValueY)); //don't use Scale to resize (won't work well here), ScaledLayout scales its contents automatically
      Scale.Point := TPointF.Create(sign(ValueX), sign(ValueY));
    end;
    //ScrollBox.InvalidateContentSize;

    EndUpdate;
    end;
end;

procedure TForm2.UpdateZoomFromTrackbars;
begin
  SetZoom(trackZoomX.Value, trackZoomY.Value);
end;

procedure TForm2.ScrollBoxResize(Sender: TObject);
begin
  var scrollBoxSize := ScrollBox.Size.Size;
  if not scrollBoxSize.IsZero then
    begin
    BeginUpdate;
    Zoomer.Size.Size := scrollBoxSize;
    with Zoomer do
    begin
      OriginalWidth := Width;
      OriginalHeight := Height;
    end;
    UpdateZoomFromTrackbars;
    //ScrollBox.InvalidateContentSize;
    EndUpdate;
    end;
end;

procedure TForm2.trackZoomXTracking(Sender: TObject);
begin
  if trackZoomX.IsUpdating then exit;

  BeginUpdate;
  if switchSyncAxes.IsChecked then
    trackZoomY.Value := trackZoomX.Value;

  UpdateZoomFromTrackbars;
  EndUpdate;
end;

procedure TForm2.trackZoomYTracking(Sender: TObject);
begin
  if trackZoomY.IsUpdating then exit;

  BeginUpdate;
  if switchSyncAxes.IsChecked then
    trackZoomX.Value := trackZoomY.Value;

  UpdateZoomFromTrackbars;
  EndUpdate;
end;
于 2021-10-26T10:52:35.703 回答