Sign in Join
Wiki copytemporary

Anchor Docking/ru

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

Про стыковку вообще см. Docking.

Обзор

Пристыковка окон позволяет комбинировать формы или обрабатывать элементы управления как формы. Вы используете мышь, чтобы перетаскивать и стыковать(скреплять) формы вместе или расстыковывать (разделять) их. Основная функциональность перетаскивания, пристыковки и расстыковки предоставляется LCL. Но вам нужен менеджер пристыковки для добавления разделителей и зон захвата, а также для сохранения и восстановления макетов.

Пристыковка с привязкой реализована, начиная с версии 0.9.29, в пакете anchordocking.lpk. Он прост в использовании и предоставляет множество функций и опций, недоступных в более ранних установочных пакетах.

Пример кода вы найдете здесь: components/anchordocking/miniide/miniide1.lpi

Это означает, что более ранние модули TLazDockingManager и LDockCtrl устарели и далее поддерживаться не будут.

Характеристики

Запланированное

Использование

Быстрый старт

Добавьте пакет AnchorDocking к требуемым пакетам в инспекторе проектов.

Затем добавьте модуль AnchorDocking в раздел uses вашего основного модуля (модуль вашей основной формы).

Добавьте в событие OnCreate вашей основной формы:

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, чтобы пристегнуть форму к док-узлу(стыковочному узлу). Тогда ваша форма может пристыковывать и быть стыкуемой совершенно свободно. Вы будете использовать этот способ для большей части ваших форм, за исключением MainForm, потому что это поддерживается для MainForm только в gtk2 и qt. Второй способ - использовать DockMaster.MakeDockSite. Форма может пристыковывать другие узлы, но не может быть пристыкована сама. Вы можете использовать MakeDockSite для MainForm. Для большинства других форм вы, вероятно, захотите использовать это:

pascal
// показываем YourForm
// если это еще не сделано, пристегиваем форму к док-узлу
DockMaster.MakeDockable(YourForm);

Вот несколько примеров того, как форма может быть пристыкована с помощью DockMaster.MakeDockable:

Top Top

Положение заголовка обычно устанавливается автоматически, и пользователь может щелкнуть правой кнопкой мыши по любой из четырех сторон.

Пример: miniide1

Пример можно найти в lazarus/components/anchordocking/miniide/miniide1.lpi. Он имеет mainform в модуле unit1.pas с главным меню, которая работает как док-узел, и несколькими формами, которые можно пристыковать.

Превращение главной формы в стыковочный узел

В TMainIDE.FormCreate основная форма MainIDE превращается в стыковочный узел:

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

Параметр [akBottom] позволяет пристыковывать другие узлы в нижней части MainIDE. Параметр admrpChild сообщает DockMaster, что при расширении MainIDE дополнительное пространство распределяется между закрепленными узлами.

Когда пользователь пристыковывает узел в нижней части MainIDE, узел помещается на MainIDE (Site.Parent:=MainIDE) с выравниванием Site.Align=alBottom. Другие элементы управления на MainIDE должны быть с ним совместимы. Например, MainIDE имеет BtnPanel с выравниванием Align=alLeft и TNoteBook с выравниванием Align=alClient. См. здесь, чтобы увидеть, как работает 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 допускает в качестве имен форм только стандартные
  // Паскаль идентификаторы и сравнивает их без учета регистра
  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.

Не забудьте вызвать DisableAutoSizing для формы, если для параметра DoDisableAutoSizing установлено значение true, поскольку вызовы Disable- и EnableAutosizing должны быть сбалансированы. Если вы пропустите DisableAutosizing, LCL создаст исключение позже:

pascal
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 - сторона узла, которая растянется. Если вы хотите только проверить, возможно ли увеличение, установите OnlyCheckIfPossible в true.

Растянуть один, ужать другой

Ужать соседний Object Inspector, растянуть Messages: щелкните правой кнопкой мыши заголовок Messages и выберите Enlarge right side(Увеличить правую сторону). Два сплиттера будут изменены в размерах.

⇒ ⇒ ⇒ узел Messages растягивается вправo: ⇒ ⇒ ⇒

Растянуть один, ужать остальные

Сожмите разделитель с одной стороны, растяните оба соседних разделителя, разверните разделитель кзади, растяните Control, уменьшите элементы управления при повороте разделителя. Щелкните правой кнопкой мыши по заголовку Source Editor 1, затем нажмите Enlarge bottom side(Увеличить нижнюю сторону).

⇒ ⇒ ⇒ становится ⇒ ⇒ ⇒

Общие настройки стыковки

Пакет AnchorDocking предоставляет диалог для настройки некоторых свойств DockMaster. Диалог находится в модуле AnchorDockOptionsDlg, и вы можете использовать его весьма просто:

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

Это добавит новый пункт меню во всплывающие меню заголовков стыковочных узлов и страниц под названием Docking options(Опции стыковки).

Стыковка в IDE

Если вам не нравится внешний вид "обособленных окон" по умолчанию в среде IDE Lazarus и вы предпочитаете единое окно (например, как RAD Studio™), вы можете установить пакет с именем AnchorDockingDsgn. Этот пакет делает окна стыкуемыми (lazarus/components/anchordocking/design/anchordockingdsgn.lpk). Удалите все другие менеджеры стыковки (например, easydockmgrdsgn).

После того, как вы установили пакет и перезапустили IDE, IDE начинает пристыковываться с макетом по умолчанию. Вы можете изменить макет: вы можете перетаскивать и закреплять заголовки (полосы вверху или слева от каждого окна), изменять размер через разделители или границы окна. Вы можете щелкнуть правой кнопкой мыши по заголовку, чтобы выбрать другие параметры, например, чтобы изменить внешний вид заголовков, как показано ниже:

Вы можете сохранить макет через пункт меню Tools / Save window layout as default(Инструменты/Сохранить макет окна по умолчанию). Это сохраняет настройки в ~/.lazarus/anchordocklayout.xml и восстанавливает их при запуске IDE.


Прим.перев.: на самом деле, на момент перевода статьи расположение окон в IDE сохраняется в Tools(Сервис) / Desktops(Рабочие столы) / Manage desktops (Управление рабочими столами), а настройки хранятся в environmentoptions.xml в каталоге с прочими настройками Лазаруса.


Вы также можете сохранить макет в файл и загрузить его позже.

Начиная с Lazarus 1.1 вы можете передавать параметр командной строки

bash
./lazarus --anchordocklayout=<filename>

Вот пример того, как выглядит стыкуемая IDE в Windows 7:

Это пример того, как выглядит стыкуемая IDE ( пакеты AnchorDockingDsgn и sparta_DockedFormEditor) в Windows 10:

Внешний вид (как и заголовки) можно изменить, щелкнув по ним правой кнопкой мыши.

Настройки

Scale on resize (масштабирование при изменении размера)

При изменении размера окна все закрепленные внутри формы масштабируются пропорционально.

Flatten headers (отображать заголовки плоскими)

Заголовки без 3D рамки.

Header align top/left (помещение заголовка сверху/слева)

Заголовки автоматически помещаются сверху или слева в зависимости от этих двух значений:

Это означает, что заголовок по умолчанию размещен на меньшей стороне закрепленного элемента управления. При изменении размера элемента управления заголовок переключается на меньшую сторону.

Зачем использовать Anchors(привязки) вместо Align(выравнивания)?

Привязки позволяют создать любую возможную прямоугольную планировку. Выравнивание ограничено в своих возможностях. Выравнивание с панелями может теоретически создать множество макетов, но все же не всё. И некоторые операции, такие как растяжение/сжатие, более сложны при их реализации с помощью выравнивания/панелей, чем при использовании привязок. Выравнивание работает хорошо для нескольких форм, но чем больше форм пристыковано, тем больше становятся очевидными недостатки выравнивания.

Макеты, которые можно создавать с помощью выравнивания

Выравнивание может создавать только следующие макеты:

Элементы управления с alTop всегда находятся вверху, заполняя всю горизонтальную ширину. Это потому, что LCL сначала выравнивает все элементы управления с помощью alTop, затем всех alBottom, затем alLeft, затем alRight и, наконец, alClient.

Макеты, которые можно создавать с помощью выравнивания и панелями

Можно смонтировать выравнивание макетов с помощью скрытых панелей. Затем можно создать любой макет, который можно рекурсивно разбить на две части. Тогда вы можете создать, например:

Для этого требуется только одна скрытая панель.

Изменение макетов

Теперь пользователь хочет расширить FPDocEditor по горизонтали (и ужать CodeExplorer). С помощью AnchorDocking вы можете просто щелкнуть правой кнопкой мыши по заголовку FPDocEditor и выбрать Увеличить правую сторону.

Другие стыковочные движки требуют как минимум 2 панели. Один для SrcEditor, Messages, FPDocEdit, CodeExpl и один для SrcEdit и Messages. Большинство стыковочных макетов даже не предоставляют простой способ изменить макет таким способом. Алгоритм, допускающий это изменение макета, должен анализировать всю структуру, как если бы не было панелей, и должен отражать многие вещи. По сути, алгоритм должен делать то же самое, что и алгоритм пристыковки, но с дополнительной работой по переводу макета с использованием выравнивания плюс скрытых панелей.

Макеты, которые невозможны с выравниванием и панелями

Теперь пользователь хочет расширить SourceEditor1 по горизонтали (и ужать ObjectInspector):

Такая компоновка невозможна при выравнивании и панелях, поскольку нельзя разрезать его на две половины. То же самое для стыковки с привязкой

Заключение

Выравнивание со скрытыми панелями позволяет легко создать простой менеджер стыковки, который хорошо работает для нескольких форм. Но это всегда будет ограничивать пользователя. Выравнивание полезно для макета строк и столбцов, а не для таблиц. Стыковка с привязкой работает даже для сложных форм.

Старый/устаревший механизм стыковки

Создание TLazDockingManager

pascal
  DockingManager:=TLazDockingManager.Create(Self);

Параметр Self используется только в качестве указания владельца. Это означает, что когда основная форма освобождается, 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/ru", as it stood on 2020-04-20 after a change by Zoltanleo, 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 2, last changed by WikiArchive .

Talk about this page

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