Sign in Join
Wiki copytemporary

Anchor Docking/zh CN

English · Русский · 中文(中国)

关于停靠的一般信息,请参阅Docking。

概述

停靠允许您将窗体组合起来,或将控件视为窗体。您可以使用鼠标将窗体拖放停靠在一起或取消停靠(拆分)它们。基本的拖动、停靠和取消停靠功能由LCL提供。但您需要停靠管理器来添加分割条和抓取区域,以及保存和恢复布局。

锚点停靠自0.9.29版本起在anchordocking.lpk包中实现,用于您自己的Lazarus应用程序,如果您希望使Lazarus IDE窗口可停靠,则使用AnchorDockingDsgn.lpk。它易于使用,并提供了许多早期停靠包中不可用的功能和选项。

您可以在以下位置找到代码示例:components/anchordocking/miniide/miniide1.lpi

这意味着早期的TLazDockingManager和LDockCtrl单元已过时,现在已被弃用。

特色

待办事项

使用方法一(为Lazarus IDE添加停靠支持)

如果您不喜欢Lazarus IDE的默认“单独窗口”外观,而更喜欢单窗口(例如RAD Studio™),您可以安装一个名为AnchorDockingDsgn的包(lazarus/components/anchordocking/design/anchordockingdsgn.lpk)。这个包使IDE窗口可停靠。

安装

卸载任何其他停靠管理器(例如easydockmgrdsgn)。从Lazarus主菜单中选择“包” - “安装/卸载包”,并安装“anchordockingdsgn”包。

成功安装该包并重新启动IDE后,IDE将以默认停靠布局启动,如下所示。请注意,AnchorDocking标题和分割条已添加到IDE的所有可停靠窗口中。如果标题不可见,请参阅下面的“选项”部分以了解如何启用/禁用它们。

您可以通过抓取带有Anchordocking标题的可停靠窗口并将其拖放到其他位置来更改布局,或者通过添加到窗口边框的分割条来调整停靠窗口的大小。您还可以在标题上右键单击以获取其他选项,例如更改标题的外观,如下所示。

您可以通过菜单项工具 / 将窗口布局保存为默认来保存布局。这将保存到~/.lazarus/anchordocklayout.xml,并在IDE启动时恢复。

您还可以将布局保存到文件并在以后加载它们。

从Lazarus 1.1开始,您可以传递命令行参数

./lazarus --anchordocklayout=<filename>

通过右键单击标题可以进一步调整外观(如标题)。

选项

成功安装AnchorDockingDsgn包后,Lazarus选项对话框(“工具” - “选项” - “环境”)中添加了一个额外的配置菜单。

调整大小时缩放

当调整窗口大小时,所有内部停靠的窗体都将按相同的百分比缩放。

显示标题

要停靠/取消停靠窗口,您需要启用此选项。

扁平化标题

标题中没有3D框架。

标题顶部/左对齐

标题根据这两个值自动放置在顶部或左侧:

这意味着标题默认情况下被放置在停靠控件的较小一侧。当控件被调整大小时,标题会切换到较小的一侧。

允许停靠站点被最小化

添加了一个额外的最小化按钮,以便可以最小化站点。然后,它旁边的站点会获得更多空间。如果需要,可以轻松打开最小化的站点。

多行选项卡

Lazarus 2.2中添加了此功能。如果操作系统支持多行选项卡(如Windows),并且选项卡不多,则它们将显示在多行中。

浮动窗口在最顶层

Lazarus 2.2中添加了此功能。如果显示了未停靠的窗口,则将它们显示在主窗口的顶部。在自定义应用程序中,可以设置DockMaster.MainDockForm,然后所有浮动窗口都将显示在其顶部。如果未设置MainDockForm,则使用Application.MainForm。

使用方法二(为您自己的应用程序添加停靠支持)

快速入门

将包AnchorDocking添加到项目检查器中的必需包中。

然后将单元AnchorDocking添加到您的主单元(包含主窗体的单元)的uses部分。

在主窗体的FormCreate中添加:

pascal
  DockMaster.MakeDockSite(Self,[akBottom],admrpChild);

对于其他可停靠的窗体,将所有对Show和ShowOnTop的调用替换为

pascal
  DockMaster.MakeDockable(Form1,true,true);

对于其他可停靠的窗体,将所有对Visible:=true的调用替换为

pascal
  DockMaster.MakeDockable(Form1,true);

移除或注释掉所有Hide、Visible:=false、WindowState:=的调用。

先决条件

使窗体可停靠

有两种方法可以使窗体可停靠。您可以使用DockMaster.MakeDockable将窗体包装在一个停靠站点中。然后您的窗体可以完全自由地停靠和被停靠。您将对大部分窗体使用此方法,除了主窗体,因为gtk2和qt上仅支持主窗体。第二种方法是使用DockMaster.MakeDockSite。窗体可以停靠其他站点,但不能自身被停靠。您可能希望为主窗体使用MakeDockSite。 对于大多数其他窗体,您可能想使用这个:

pascal
// 显示YourForm
// 如果尚未完成,将窗体包装在一个停靠站点中
DockMaster.MakeDockable(YourForm);

以下是一些使用DockMaster.MakeDockable使窗体可停靠后的示例:

标题位置通常会自动完成,用户可以通过右键单击将其放置在四个边的任何一边。

示例:miniide1

示例可以在lazarus/components/anchordocking/miniide/miniide1.lpi中找到。它有一个在unit1.pas单元中的mainform,具有一个作为停靠站点的主菜单和几个可停靠的窗体。

将主窗体设置为停靠站点

在TMainIDE.FormCreate中,主窗体MainIDE被转换为一个停靠站点:

pascal
DockMaster.MakeDockSite(Self,[akBottom],admrpChild);

参数[akBottom]允许在MainIDE的底部停靠其他站点。参数admrpChild告诉DockMaster,当MainIDE被放大时,额外的空间将分配给停靠的站点。

当用户将一个站点停靠到MainIDE的底部时,站点将被放置在MainIDE上(Site.Parent:=MainIDE),并设置Site.Align=alBottom。MainIDE上的其他控件必须与此兼容。例如,MainIDE有一个Align=alLeft的BtnPanel和一个Align=alClient的TNoteBook。请参阅此处了解Align的工作原理。

DockMaster会自动添加一个分割条:

一旦一个可停靠的窗体被停靠,其标题就会显示在停靠标题栏中。

自定义停靠站点的要求

在没有任何内容停靠到自定义停靠站点之前,您的窗体可以像普通窗体一样做任何事情。但是,当一个站点停靠到它上面时,一些属性和方法需要特别注意:

按名称创建所有其他窗体的过程

MainIDE设置了DockMaster.OnCreateControl事件,以允许DockMaster按名称创建窗体。这是恢复布局所必需的。

pascal
DockMaster.OnCreateControl:=@DockMasterCreateControl;
pascal
procedure TMainIDE.DockMasterCreateControl(Sender: TObject; aName: string; var
  AControl: TControl; DoDisableAutoSizing: boolean);

  procedure CreateForm(Caption: string; NewBounds: TRect);
  begin
    AControl:=CreateSimpleForm(aName,Caption,NewBounds,DoDisableAutoSizing);
  end;

begin
  // 首先检查窗体是否已存在
  // LCL Screen有一个所有现有窗体的列表。
  // 注意:请记住,LCL只允许窗体名称使用标准的Pascal标识符,并且不区分大小写
  AControl:=Screen.FindForm(aName);
  if AControl<>nil then begin
    // 如果它已经存在,只是根据请求禁用自动调整大小
    if DoDisableAutoSizing then
      AControl.DisableAutoSizing;
    exit;
  end;
  // 如果窗体尚不存在,则创建它
  if aName='CodeExplorer' then
    CreateForm('Code Explorer',Bounds(700,230,100,250))
  ...
  else if aName='DebugOutput' then
    CreateForm('Debug Output',Bounds(400,400,350,150));
end;

创建一个窗体可以像这样简单:

pascal
MyForm:=TMyForm.Create(Self);
if DoDisableAutoSizing then
  MyForm.DisableAutoSizing;

但当然,您可以在那里放置所有类型的初始化代码。

DisableAutoSizing减少了闪烁。确保您的窗体Visible属性设置为false。

如果设置了参数DoDisableAutoSizing为true,请记得为窗体调用DisableAutoSizing,因为Disable-和EnableAutosizing调用必须平衡。如果您错过了DisableAutosizing,LCL稍后会引发异常: TControl.EnableAutoSizing SourceEditor1:TSimpleForm: missing DisableAutoSizing

如果您调用DisableAutoSizing过多,您的窗体将不会出现和/或无法正确调整大小,因为LCL正在等待永远不会到来的EnableAutoSizing调用。

显示窗体

当要显示一个窗体时,您可能使用过类似MyForm.Show的东西。现在您应该使用

pascal
DockMaster.MakeDockable(MyForm);

这将把MyForm包装在一个停靠站点中并显示它。它足够聪明,可以判断窗体是否已经被包装在一个停靠站点中。

如果您设置了DockMaster.OnCreateControl事件,您可以使用这个:

pascal
DockMaster.ShowControl('MyForm',true);

通过代码手动停靠

使用过程DockMaster.ManualDock将一个站点停靠到另一个站点或停靠到另一个站点内部。

pascal
procedure ManualDock(SrcSite, TargetSite: TAnchorDockHostSite; Align: TAlign; TargetControl: TControl = nil);

通过代码手动取消停靠

使用过程DockMaster.ManualFloat将一个站点从其邻居中取消停靠并创建一个浮动的顶层窗体。嵌入的控件仍然嵌入在TAnchorDockHostSite中。

pascal
procedure ManualFloat(AControl: TControl);

您可以提供一个TAnchorDockHostSite或嵌入在TAnchorDockHostSite中的控件(例如,使用MakeDockable制作的窗体)作为参数。站点将被放置在相同的屏幕位置。

保存布局

DockMaster允许将当前布局保存到TConfigStorage。miniide示例使用了xml版本:

pascal
procedure TMainIDE.SaveLayout(Filename: string);
var
  XMLConfig: TXMLConfigStorage;
begin
  try
    // 创建一个新的xml配置文件
    XMLConfig:=TXMLConfigStorage.Create(Filename,false);
    try
      // 保存所有窗体的当前布局
      DockMaster.SaveLayoutToConfig(XMLConfig);
      XMLConfig.WriteToDisk;
    finally
      XMLConfig.Free;
    end;
  except
    on E: Exception do begin
      MessageDlg('错误',
        '将布局保存到文件'+Filename+'时出错:'#13+E.Message,mtError,
        [mbCancel],0);
    end;
  end;
end;

加载布局

pascal
procedure TMainIDE.LoadLayout(Filename: string);
var
  XMLConfig: TXMLConfigStorage;
begin
  try
    // 加载xml配置文件
    XMLConfig:=TXMLConfigStorage.Create(Filename,True);
    try
      // 恢复布局
      // 这将关闭不需要的窗体,并为所有需要的窗体调用OnCreateControl
      DockMaster.LoadLayoutFromConfig(XMLConfig);
    finally
      XMLConfig.Free;
    end;
  except
    on E: Exception do begin
      MessageDlg('错误',
        '从文件'+Filename+'加载布局时出错:'#13+E.Message,mtError,
        [mbCancel],0);
    end;
  end;
end;

放大/缩小

锚点停靠管理器可以放大/缩小停靠的邻居窗体。这可以通过停靠标题栏的弹出菜单或使用函数DockMaster.ManualEnlarge在代码中完成:

pascal
function ManualEnlarge(Site: TAnchorDockHostSite; Side: TAnchorKind; OnlyCheckIfPossible: boolean): boolean;

Site是一个子站点,Side是要扩展的Site的侧边。如果只想测试是否可以放大,则将OnlyCheckIfPossible设置为true。

放大一个,缩小另一个

缩小邻居“对象检查器”,放大“消息”:右键单击“消息”的标题栏,然后点击“放大右侧”。两个分割条将被调整大小。

放大“消息”到右侧:

放大一个,缩小多个

缩小一侧的分割条,放大两个相邻的分割条,旋转后面的分割条,放大控件,缩小旋转分割条上的控件。右键单击“源代码编辑器1”的标题栏,然后点击“放大底部”。

变为

一般停靠选项

AnchorDocking包提供了一个对话框来设置DockMaster的一些属性。该对话框位于AnchorDockOptionsDlg单元中,您可以简单地使用它:

pascal
uses ... AnchorDockOptionsDlg;
...
procedure TMainIDE.FormCreate(Sender: TObject);
...
begin
  ...
  DockMaster.OnShowOptions:=@ShowAnchorDockOptions;
  ...
end;

这将向停靠标题栏和页面的弹出菜单中添加一个新的菜单项“停靠选项”。

为什么使用锚点而不是对齐?

锚点允许创建任何可能的矩形布局。对齐是有限制的。对齐与面板结合使用理论上可以创建很多布局,但仍然不是全部。而且,一些操作(如放大/缩小)使用对齐/面板比使用锚点更复杂。对齐对于少数窗体来说工作得很好,但停靠的窗体越多,对齐的缺点就越明显。

使用对齐可以创建的布局

对齐只能创建以下布局:

alTop控件始终位于顶部,填满整个水平宽度。这是因为LCL首先将所有控件与alTop对齐,然后是alBottom、alLeft、alRight,最后是alClient。

使用对齐和面板可以创建的布局

通过使用隐藏的面板,可以嵌套对齐布局。然后可以创建任何可以递归地分成两半的布局。例如,您可以创建:

这只需要一个隐藏的面板。

更改布局

现在用户想要水平放大“FPDocEditor”(并缩小“CodeExplorer”)。使用“AnchorDocking”,您只需右键单击“FPDocEditor”的标题栏,然后点击“放大右侧”。

其他停靠引擎至少需要两个面板。一个用于“SrcEditor”、“Messages”、“FPDocEdit”、“CodeExpl”,另一个用于“SrcEdit”和“Messages”。大多数停靠布局器甚至不提供以这种方式更改布局的简单方法。允许这种布局更改的算法必须分析整个结构,就好像没有面板一样,并且必须重新分配很多东西。基本上,该算法必须执行与锚点停靠算法相同的操作,但还需要将布局转换为对齐加上隐藏面板的额外工作。

使用对齐和面板无法创建的布局

现在用户想要水平放大“源代码编辑器1”(并缩小“对象检查器”):

这个布局使用对齐和面板是无法实现的,因为您无法将其切成两半。与以下情况相同:

结论

使用隐藏面板的对齐允许您轻松地创建一个简单的停靠管理器,适用于少数窗体,但它始终会限制用户。对齐对于行和列布局很有用,但对于表格布局则不然。锚点停靠甚至适用于复杂的窗体。

旧版/已弃用的锚点停靠

创建一个TLazDockingManager

pascal
  DockingManager:=TLazDockingManager.Create(Self);

作为参数的Self仅用作Owner。这意味着,当主窗体被释放时,DockingManager也会被释放。您可以使用nil并自行释放DockingManager。

可选:加载配置

您可以从磁盘加载用户配置。

pascal
  Config:=TXMLConfigStorage.Create('config.xml',true);
  DockingManager.LoadFromConfig(Config);
  Config.Free;

这将加载文件config.xml。该配置可以使用SaveToConfig函数创建。见下文。

使窗体/控件可停靠

为每个应该可停靠的窗体/控件创建一个TLazControlDocker

pascal
  ControlDocker1:=TLazControlDocker.Create(Self);
  ControlDocker1.Name:='DockerForm1';
  ControlDocker1.Manager:=DockingManager;

可选:将用户配置保存到磁盘

当程序关闭时,您可以将用户配置保存到磁盘

pascal
  Config:=TXMLConfigStorage.Create('config.xml',true);
  DockingManager.SaveToConfig(Config);
  Config.WriteToDisk;
  Config.Free;

另请参阅


From the Free Pascal wiki, page "Anchor Docking/zh CN", as it stood on 2024-05-07 after a change by Hieroly, out of the wiki's dump of 2024-05-26. Copyright stays with the author who wrote it, according to the old wiki's Licensing page. If you have concerns about this material, message the admin.

Revision 3, last changed by WikiArchive .

Edited on wiki.freepascal.org by 2 people, 2022–2024

From the official wiki's backup of 26 May 2024: who edited this page there, and when. Edits made there after that date were not recorded, and the earlier versions are not shown here; the main page says why.

WhenWhoWhat changed
RobseanCreated page
RobseanOverview
Hieroly

Talk about this page

Nobody has opened a bench for this page yet. Sign in to open one.