Difference between revisions of "LCL AutoSizing/ru"
(Created page with "{{MenuTranslate|page=LCL AutoSizing}} ==Overview / Terminology== This page explains the LCL auto sizing algorithm. AutoSizing means here: Automatic resizing and repositionin...") |
(Switched template, deleted English categories.) |
||
(10 intermediate revisions by one other user not shown) | |||
Line 1: | Line 1: | ||
− | {{ | + | {{LCL AutoSizing}} |
− | + | __TOC__ | |
− | + | ==Обзор / Терминология== | |
− | + | На этой странице объясняется алгоритм автомасштабирования в LCL. AutoSizing означает здесь: автоматическое изменение размера и перемещение элементов управления LCL. | |
− | + | Если вам просто интересно, как использовать свойства AutoSize, см. [[Autosize_/_Layout/ru#Разметка (Layout)|Autosize/Layout]]. | |
− | + | ==Свойства== | |
+ | |||
+ | Следующие свойства определяют поведение автомасштабирования в LCL: | ||
*Current Left,Top,Width,Height,ClientWidth,ClientHeight | *Current Left,Top,Width,Height,ClientWidth,ClientHeight | ||
Line 21: | Line 23: | ||
*Constraints | *Constraints | ||
− | + | Для совместимости с Delphi LCL поддерживает метод AdjustClientRect, который является расширением свойств ChildSize.LeftRightSpacing/TopBottomSpacing. | |
− | == | + | ==Порядок== |
− | === | + | ===Обзор=== |
− | + | Автомасштабирование работает в несколько этапов: | |
− | *DisableAutosizing. | + | *DisableAutosizing. На первом этапе приложение изменяет свойства, создает или удаляет элементы управления. Вся форма заблокирована. Отсутствует автоматическая настройка, никакие границы в виджет не отправляются . |
− | *EnableAutoSizing. | + | *EnableAutoSizing. Вызывается [методом] DoAllAutoSize родительской формы. |
− | * | + | *Все необходимые дескрипторы создаются рекурсивно [методом] TWinControl.DoAllAutoSize. Они еще не сделаны видимыми. |
− | *TControl.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, которое может использоваться приложением для выполнения произвольных действий. |
− | === | + | ===Алгоритм выравнивания и привязки=== |
− | + | Основным методом является TWinControl.AlignControls. | |
− | # | + | #инициация RemainingClientRect в ClientRect и RemainingBorderSpace в Rect(0,0,0,0) |
− | # | + | #вызов AdjustClient, чтобы настроить RemainingClientRect |
− | # | + | #применение ChildSizing.LeftRightSpacing,ChildSizing.TopBottomSpacing |
− | # | + | #вызов DoAlign с alTop,alBottom,alLeft,alRight,alClient,alCustom,alNone |
− | ##DoAlign | + | ##DoAlign собирает дочерние элементы управления с этим значением Align и вызывает для каждого такого контрола DoPosition |
− | ###DoPosition | + | ###DoPosition вычисляет новые Left,Top,Width,Height |
+ | ===DoAutoSize=== | ||
− | + | Этот [метод] вызывается [методом] DoAllAutoSize и не должен вызываться приложением. Приложения должны вызывать AdjustSize и/или InvalidatePreferredSize. | |
− | + | Если он не переопределен, нормальный TWinControl.DoAutoSize делает следующее, когда AutoSize=true: | |
− | + | Он будет перемещать "элементы управления без выравнивания" - дочерние элементы управления с привязками по умолчанию (Anchors=[akLeft,akTop],Align=alNone). Он переместит все их одинаковое количество, поэтому их общий ограничивающий прямоугольник растягивается влево и вверх. Рассматривается интервал между BorderSpacing и ChildSize.<br /> | |
− | + | Перед перемещением есть место слева и над кнопками: | |
− | |||
[[Image:Autosize before move childs.png]] | [[Image:Autosize before move childs.png]] | ||
− | + | После перемещения: | |
+ | |||
[[Image:Autosize after move childs.png]] | [[Image:Autosize after move childs.png]] | ||
− | + | Затем вычисляется предпочтительный размер элемента управления. В этом расчете учитываются дочерние элементы управления, Align, Anchors, Constraints, ChildSizing.Layout и другие свойства LCL. | |
+ | |||
+ | Размер элемента управления изменен: | ||
− | |||
[[Image:Autosize after shrink.png]] | [[Image:Autosize after shrink.png]] | ||
− | + | См. также: [[Autosize_/_Layout/ru#Выравнивание и свойство AutoSize родителя|Выравнивание и свойство AutoSize родителя]] | |
===DisableAutoSizing/EnableAutosizing=== | ===DisableAutoSizing/EnableAutosizing=== | ||
− | + | см [[Autosize_/_Layout/ru#.D0.A1.D0.BE.D0.BA.D1.80.D0.B0.D1.89.D0.B5.D0.BD.D0.B8.D0.B5_.D0.BD.D0.B0.D0.BA.D0.BB.D0.B0.D0.B4.D0.BD.D1.8B.D1.85_.D1.80.D0.B0.D1.81.D1.85.D0.BE.D0.B4.D0.BE.D0.B2_.D1.81_.D0.BF.D0.BE.D0.BC.D0.BE.D1.89.D1.8C.D1.8E_.5B.D0.BC.D0.B5.D1.82.D0.BE.D0.B4.D0.BE.D0.B2.5D_DisableAutoSizing.2C_EnableAutoSizing|здесь]]. | |
− | === | + | ===Отличия от Delphi=== |
− | *Delphi | + | *Delphi не имеет BorderSpacing, AnchorSides, ChildSizing. |
− | *Delphi | + | *Delphi не поддерживает AutoSize и Align на всех элементах управления. |
− | *Delphi | + | *Алгоритм автомасштабирования Delphi не поддерживает вложенные автомасштабируемые элементы управления со свойством Align. Например, Panel1 с Align=alTop в Panel2 и обе панели имеют AutoSize=true. Panel2 не будет уменьшаться/увеличиваться по горизонтали, что означает, что Panel1 также не будет уменьшаться/увеличиваться. Таким образом, Panel1 не имеет автомасштабирования для своих дочерних элементов. |
==FAQ== | ==FAQ== | ||
− | + | см. [[Autosize_/_Layout/ru|Autosize / Layout]]. | |
− | |||
− | |||
− | |||
− |
Latest revision as of 22:27, 9 December 2018
│
English (en) │
русский (ru) │
Обзор / Терминология
На этой странице объясняется алгоритм автомасштабирования в 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, которое может использоваться приложением для выполнения произвольных действий.
Алгоритм выравнивания и привязки
Основным методом является TWinControl.AlignControls.
- инициация RemainingClientRect в ClientRect и RemainingBorderSpace в Rect(0,0,0,0)
- вызов AdjustClient, чтобы настроить RemainingClientRect
- применение ChildSizing.LeftRightSpacing,ChildSizing.TopBottomSpacing
- вызов DoAlign с alTop,alBottom,alLeft,alRight,alClient,alCustom,alNone
- DoAlign собирает дочерние элементы управления с этим значением Align и вызывает для каждого такого контрола DoPosition
- DoPosition вычисляет новые Left,Top,Width,Height
- DoAlign собирает дочерние элементы управления с этим значением Align и вызывает для каждого такого контрола DoPosition
DoAutoSize
Этот [метод] вызывается [методом] DoAllAutoSize и не должен вызываться приложением. Приложения должны вызывать AdjustSize и/или InvalidatePreferredSize.
Если он не переопределен, нормальный TWinControl.DoAutoSize делает следующее, когда AutoSize=true:
Он будет перемещать "элементы управления без выравнивания" - дочерние элементы управления с привязками по умолчанию (Anchors=[akLeft,akTop],Align=alNone). Он переместит все их одинаковое количество, поэтому их общий ограничивающий прямоугольник растягивается влево и вверх. Рассматривается интервал между BorderSpacing и ChildSize.
Перед перемещением есть место слева и над кнопками:
После перемещения:
Затем вычисляется предпочтительный размер элемента управления. В этом расчете учитываются дочерние элементы управления, Align, Anchors, Constraints, ChildSizing.Layout и другие свойства LCL.
Размер элемента управления изменен:
См. также: Выравнивание и свойство AutoSize родителя
DisableAutoSizing/EnableAutosizing
см здесь.
Отличия от Delphi
- Delphi не имеет BorderSpacing, AnchorSides, ChildSizing.
- Delphi не поддерживает AutoSize и Align на всех элементах управления.
- Алгоритм автомасштабирования Delphi не поддерживает вложенные автомасштабируемые элементы управления со свойством Align. Например, Panel1 с Align=alTop в Panel2 и обе панели имеют AutoSize=true. Panel2 не будет уменьшаться/увеличиваться по горизонтали, что означает, что Panel1 также не будет уменьшаться/увеличиваться. Таким образом, Panel1 не имеет автомасштабирования для своих дочерних элементов.
FAQ
см. Autosize / Layout.