LCL AutoSizing/ru: what changed
Revision 1 to 2. Removed lines have a minus sign; added lines have a plus sign.
| Old | New | Line | |
|---|---|---|---|
| 1 | 1 | ## Обзор / Терминология | |
| 2 | 2 | ||
| 3 | 3 | На этой странице объясняется алгоритм автомасштабирования в LCL. AutoSizing означает здесь: автоматическое изменение размера и перемещение элементов управления LCL. | |
| 4 | 4 | ||
| 5 | 5 | Если вам просто интересно, как использовать свойства AutoSize, см. [[Autosize / Layout/ru|Autosize/Layout]]. | |
| 6 | 6 | ||
| 7 | 7 | ## Свойства | |
| 8 | 8 | ||
| 9 | 9 | Следующие свойства определяют поведение автомасштабирования в LCL: | |
| 10 | 10 | ||
| 11 | 11 | - Current Left,Top,Width,Height,ClientWidth,ClientHeight | |
| 12 | 12 | - Loaded Left,Top,Width,Height,ClientWidth,ClientHeight | |
| 13 | 13 | - AutoSize | |
| 14 | 14 | - Anchors | |
| 15 | 15 | - AnchorSides | |
| 16 | 16 | - Align | |
| 17 | 17 | - BorderSpacing | |
| 18 | 18 | - ChildSizing | |
| 19 | 19 | - Constraints | |
| 20 | 20 | ||
| 21 | 21 | Для совместимости с Delphi LCL поддерживает метод AdjustClientRect, который является расширением свойств ChildSize.LeftRightSpacing/TopBottomSpacing. | |
| 22 | 22 | ||
| 23 | 23 | ## Порядок | |
| 24 | 24 | ||
| 25 | 25 | ### Обзор | |
| 26 | 26 | ||
| 27 | 27 | Автомасштабирование работает в несколько этапов: | |
| 28 | 28 | ||
| 29 | 29 | - DisableAutosizing. На первом этапе приложение изменяет свойства, создает или удаляет элементы управления. Вся форма заблокирована. Отсутствует автоматическая настройка, никакие границы в виджет не отправляются . | |
| 30 | 30 | - EnableAutoSizing. Вызывается \[методом\] DoAllAutoSize родительской формы. | |
| 31 | 31 | - Все необходимые дескрипторы создаются рекурсивно \[методом\] TWinControl.DoAllAutoSize. Они еще не сделаны видимыми. | |
| 32 | 32 | - \[Метод\] TControl.DoAllAutoSize вычисляет границы, вызывая DoAutoSize для всех элементов управления. Он делает это в цикле, пока никакие границы не изменены. | |
| 33 | 33 | - Границы отправляются в виджет (TWinControl.RealizeBoundsRecursive вызывает RealizeBounds). | |
| 34 | 34 | - Дескрипторы становятся видимыми (если \[свойство\] HandleObjectShouldBeVisible \[имеет значение True\] и not Showing, то \[вызывается\] UpdateShowing). | |
| 35 | 35 | ||
| 36 | 36 | В основном свойство AutoSizing работает в следующем порядке: | |
| 37 | 37 | ||
| 38 | 38 | - Ограничения применяются к каждому шагу. | |
| 39 | 39 | - Сначала идет выравнивание в порядке alTop, alBottom, alLeft, alRight и, наконец, alClient. Например, alLeft имеет 3 выровненных стороны и одну свободную сторону. Свободная сторона обрабатывается приведенными ниже правилами. BorderSpacing применяется к выровненным сторонам. alCustom и alNone не имеют выровненных сторон. | |
| 40 | 40 | - Далее идет ChildSizing. Если ChildSizing.Layout не \[в значении\] cclNone, все дочерние элементы управления со \[значениями\] Align=alNone, Anchors=\[akLeft,akTop\] и элементы управления без AnchorSide масштабируются/репозиционируются. Эти дочерние элементы управления называются на этой странице "элементы управления без выравнивания". | |
| 41 | 41 | - Затем идет AutoSize. Если ChildSizing.Layout \[имеет значение\] cclNone, тогда все "элементы управления без выравнивания" перемещаются кверху и влево, а элемент управления сужается или расширяется, чтобы соответствовать всем его дочерним элементам (а не только "элементам управления без выравнивания"). | |
| 42 | 42 | - Потом идут якоря (привязки). Только те стороны \[считаются\] привязанными, которые не обрабатываются \[свойством\] Align (например, akRight в alLeft). Если у элемента управления установлено \[свойство\] AnchorSide, сторона \[этого контрола\] будет выровнена к стороне другого элемента управления. В противном случае применяются правила привязки по умолчанию, которые в основном аналогичны Delphi. | |
| 43 | 43 | - Каждое изменение границ запускает событие OnResize/OnChangeBounds, которое может использоваться приложением для выполнения произвольных действий. | |
| 44 | 44 | ||
| 45 | 45 | ### Алгоритм выравнивания и привязки | |
| 46 | 46 | ||
| 47 | 47 | Основным методом является TWinControl.AlignControls. | |
| 48 | 48 | ||
| 49 | 49 | 1. инициация RemainingClientRect в ClientRect и RemainingBorderSpace в Rect(0,0,0,0) | |
| 50 | 50 | 2. вызов AdjustClient, чтобы настроить RemainingClientRect | |
| 51 | 51 | 3. применение ChildSizing.LeftRightSpacing,ChildSizing.TopBottomSpacing | |
| 52 | 52 | 4. вызов DoAlign с alTop,alBottom,alLeft,alRight,alClient,alCustom,alNone | |
| 53 | 53 | 1. DoAlign собирает дочерние элементы управления с этим значением Align и вызывает для каждого такого контрола DoPosition | |
| 54 | 54 | 1. DoPosition вычисляет новые Left,Top,Width,Height | |
| 55 | 55 | ||
| 56 | 56 | ### DoAutoSize | |
| 57 | 57 | ||
| 58 | 58 | Этот \[метод\] вызывается \[методом\] DoAllAutoSize и не должен вызываться приложением. Приложения должны вызывать AdjustSize и/или InvalidatePreferredSize. | |
| 59 | 59 | ||
| 60 | 60 | Если он не переопределен, нормальный TWinControl.DoAutoSize делает следующее, когда AutoSize=true: | |
| 61 | 61 | ||
| 62 | 62 | Он будет перемещать "элементы управления без выравнивания" - дочерние элементы управления с привязками по умолчанию (Anchors=\[akLeft,akTop\],Align=alNone). Он переместит все их одинаковое количество, поэтому их общий ограничивающий прямоугольник растягивается влево и вверх. Рассматривается интервал между BorderSpacing и ChildSize.\ | |
| 63 | 63 | Перед перемещением есть место слева и над кнопками: | |
| 64 | 64 | ||
| 65 | - | ||
| 66 | - | ||
| 67 | - | ||
| 68 | - | ||
| 65 | + |  | |
| 69 | 66 | ||
| 70 | 67 | После перемещения: | |
| 71 | 68 | ||
| 72 | - | ||
| 73 | - | ||
| 74 | - | ||
| 75 | - | ||
| 69 | + |  | |
| 76 | 70 | ||
| 77 | 71 | Затем вычисляется предпочтительный размер элемента управления. В этом расчете учитываются дочерние элементы управления, Align, Anchors, Constraints, ChildSizing.Layout и другие свойства LCL. | |
| 78 | 72 | ||
| 79 | 73 | Размер элемента управления изменен: | |
| 80 | 74 | ||
| 81 | - | ||
| 82 | - | ||
| 83 | - | ||
| 84 | - | ||
| 75 | + |  | |
| 85 | 76 | ||
| 86 | 77 | См. также: [[Autosize / Layout/ru|Выравнивание и свойство AutoSize родителя]] | |
| 87 | 78 | ||
| 88 | 79 | ### DisableAutoSizing/EnableAutosizing | |
| 89 | 80 | ||
| 90 | 81 | см [[Autosize / Layout/ru|здесь]]. | |
| 91 | 82 | ||
| 92 | 83 | ### Отличия от Delphi | |
| 93 | 84 | ||
| 94 | 85 | - Delphi не имеет BorderSpacing, AnchorSides, ChildSizing. | |
| 95 | 86 | - Delphi не поддерживает AutoSize и Align на всех элементах управления. | |
| 96 | 87 | - Алгоритм автомасштабирования Delphi не поддерживает вложенные автомасштабируемые элементы управления со свойством Align. Например, Panel1 с Align=alTop в Panel2 и обе панели имеют AutoSize=true. Panel2 не будет уменьшаться/увеличиваться по горизонтали, что означает, что Panel1 также не будет уменьшаться/увеличиваться. Таким образом, Panel1 не имеет автомасштабирования для своих дочерних элементов. | |
| 97 | 88 | ||
| 98 | 89 | ## FAQ | |
| 99 | 90 | ||
| 100 | 91 | см. [[Autosize / Layout/ru|Autosize / Layout]]. | |
| 101 | 92 | ||
| 102 | 93 | --- | |
| 103 | 94 | *From the Free Pascal wiki, page "LCL AutoSizing/ru", as it stood on 2018-12-09 after a change by FTurtle, 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](/wiki-contact).* |
