LCL AutoSizing/ru

From Free Pascal wiki
Revision as of 13:02, 7 December 2018 by Zoltanleo (talk | contribs)
Jump to navigationJump to search

Template:MenuTranslate


ENG: AT THE MOMENT THIS PAGE IS UNDER TRANSLATION.
RUS: В НАСТОЯЩИЙ МОМЕНТ СТРАНИЦА НАХОДИТСЯ В ПРОЦЕССЕ ПЕРЕВОДА.


Обзор / Терминология

На этой странице объясняется алгоритм автомасштабирования в LCL. AutoSizing означает здесь: автоматическое изменение размера и перемещение элементов управления LCL.

Если вам просто интересно, как использовать свойства AutoSize, см. Autosize/Layout.

Свойства

Следующие свойства определяют поведение автомасштабирования в LCL:

  • Current Left,Top,Width,Height,ClientWidth,ClientHeight
  • Loaded Left,Top,Width,Height,ClientWidth,ClientHeight
  • AutoSize
  • Anchors
  • AnchorSides
  • Align
  • BorderSpacing
  • ChildSizing
  • Constraints

Для совместимости с Delphi LCL поддерживает метод AdjustClientRect, который является расширением свойств ChildSize.LeftRightSpacing/TopBottomSpacing.

Порядок

Обзор

Автомасштабирование работает в несколько этапов:

  • DisableAutosizing. На первом этапе приложение изменяет свойства, создает или удаляет элементы управления. Вся форма заблокирована. Отсутствует автоматическая настройка, никакие границы в виджет не отправляются .
  • EnableAutoSizing. Вызывается [методом] DoAllAutoSize родительской формы.
  • Все необходимые дескрипторы создаются рекурсивно [методом] TWinControl.DoAllAutoSize. Они еще не сделаны видимыми.
  • [Метод] TControl.DoAllAutoSize вычисляет границы, вызывая DoAutoSize для всех элементов управления. Он делает это в цикле, пока никакие границы не изменены.
  • Границы отправляются в виджет (TWinControl.RealizeBoundsRecursive вызывает RealizeBounds).
  • Дескрипторы становятся видимыми (если [свойство] HandleObjectShouldBeVisible [имеет значение True] и not Showing, то [вызывается] UpdateShowing).

В основном свойство AutoSizing работает в следующем порядке:

  • Ограничения применяются к каждому шагу.
  • Сначала идет выравнивание в порядке alTop, alBottom, alLeft, alRight и, наконец, alClient. Например, alLeft имеет 3 выровненных стороны и одну свободную сторону. Свободная сторона обрабатывается приведенными ниже правилами. BorderSpacing применяется к выровненным сторонам. alCustom и alNone не имеют выровненных сторон.
  • Далее идет ChildSizing. Если ChildSizing.Layout не [в значении] cclNone, все дочерние элементы управления со [значениями] Align=alNone, Anchors=[akLeft,akTop] и элементы управления без AnchorSide масштабируются/репозиционируются. Эти дочерние элементы управления называются на этой странице "элементы управления без выравнивания".
  • Затем идет AutoSize. Если ChildSizing.Layout [имеет значение] cclNone, тогда все "элементы управления без выравнивания" перемещаются кверху и влево, а элемент управления сужается или расширяется, чтобы соответствовать всем его дочерним элементам (а не только "элементам управления без выравнивания").
  • Потом идут якоря (привязки). Только те стороны [считаются] привязанными, которые не обрабатываются [свойством] Align (например, akRight в alLeft). Если у элемента управления установлено [свойство] AnchorSide, сторона [этого контрола] будет выровнена к стороне другого элемента управления. В противном случае применяются правила привязки по умолчанию, которые в основном аналогичны Delphi.
  • Каждое изменение границ запускает событие OnResize/OnChangeBounds, которое может использоваться приложением для выполнения произвольных действий.

Algorithm for Align and Anchors

The main method is TWinControl.AlignControls.

  1. init RemainingClientRect to ClientRect and RemainingBorderSpace to Rect(0,0,0,0)
  2. call AdjustClient to adjust RemainingClientRect
  3. apply ChildSizing.LeftRightSpacing,ChildSizing.TopBottomSpacing
  4. call DoAlign with alTop,alBottom,alLeft,alRight,alClient,alCustom,alNone
    1. DoAlign collects child controls with this Align value and call for each such control DoPosition
      1. DoPosition calculates the new Left,Top,Width,Height


DoAutoSize

This is called by DoAllAutoSize and should not be called by the application. Applications should call AdjustSize and/or InvalidatePreferredSize.

If it is not overriden the normal TWinControl.DoAutoSize does the following, when AutoSize=true:

It will move "non aligned controls" - child controls with default anchors (Anchors=[akLeft,akTop],Align=alNone). It moves all of them the same amount, so their total bounding box fits left and top. The spacing of BorderSpacing and ChildSizing is considered.

Before the move, there is space to the left and above the buttons: Autosize before move childs.png

After the move: Autosize after move childs.png

Then the preferred size of the control is computed. This calculation considers child controls, Align, Anchors, Constraints, ChildSizing.Layout and the other LCL properties.

The control is resized: Autosize after shrink.png


See also: Align and parent AutoSize

DisableAutoSizing/EnableAutosizing

see here.

Differences from Delphi

  • Delphi has no BorderSpacing, AnchorSides, ChildSizing.
  • Delphi does not support AutoSize and Align on all controls.
  • Delphi's AutoSize algorithm does not support nested autosized controls with the Align property. For example a Panel1 with Align=alTop in a Panel2 and both panels have AutoSize=true. Panel2 will not shrink/enlarge horizontally, which means Panel1 will not shrink/enlarge either. So, Panel1 is not autosized to the needed size for its children.

FAQ

see Autosize / Layout.