Difference between revisions of "Anchor Sides/ru"

From Lazarus wiki
Jump to navigationJump to search
(copied the English version for translating)
 
(translated from English)
Line 1: Line 1:
 
{{Anchor Sides}}
 
{{Anchor Sides}}
  
There are some new properties and methods for automatic layout of
+
Есть несколько новых свойств и методов для автоматического расположения элементов управления.
controls.
+
Теперь вы можете настроить элементы управления для поддержания определённого расстояния до других элементов управления или центрирования относительно других элементов управления. Смотрите пример ниже.
You can now setup controls to keep a certain distance to other controls,
 
or center relative to other controls. See below for examples.
 
  
Each of the four sides of a control (Left, Top, Right, Bottom) can now
+
Каждая из четырёх сторон элемента управления (Left, Top, Right, Bottom) теперь может быть прикреплена/привязана к стороне другого элемента управления.
be anchored/bound to a side of another control. For example you can now
+
Например, теперь вы можете привязать левую сторону TEdit к правой стороне TLabel.
anchor the left side of TEdit to the right side of a TLabel. Everytime
+
Каждый раз, когда Label перемещается или меняет размер, левая сторона Edit будет следовать за ней, что обычно приводит к перемещению Edit параллельно Label.
the Label is moved or resized the Edit's left side will follow, which
+
 
normally results in moving the Edit parallel to the Label.
+
= Пример 1 =
  
=Example 1=
 
 
  +--------+ +-------+
 
  +--------+ +-------+
 
  | Label1 | | Edit1 |
 
  | Label1 | | Edit1 |
 
  +--------+ |      |
 
  +--------+ |      |
 
             +-------+
 
             +-------+
==In code==
+
== В коде ==
  
<syntaxhighlight>Edit1.AnchorSide[akLeft].Side := asrRight;
+
<syntaxhighlight>
 +
Edit1.AnchorSide[akLeft].Side := asrRight;
 
Edit1.AnchorSide[akLeft].Control := Label1;
 
Edit1.AnchorSide[akLeft].Control := Label1;
Edit1.Anchors := Edit1.Anchors + [akLeft];</syntaxhighlight>
+
Edit1.Anchors := Edit1.Anchors + [akLeft];
 +
</syntaxhighlight>
 +
 
 +
Вы можете задать расстояние с помощью свойств BorderSpacing:
  
You can define the distance with the BorderSpacing properties:
+
<syntaxhighlight>
<syntaxhighlight>Edit1.BorderSpacing.Left := 10;</syntaxhighlight>
+
Edit1.BorderSpacing.Left := 10;
The same can be done with the method:
+
</syntaxhighlight>
<syntaxhighlight>Edit1.AnchorToNeighbour(akLeft, 10, Label1);</syntaxhighlight>
 
  
==Notes==
+
То-же самое может быть сделано с помощью метода:
The Edit1.Left will follow Label1.Left+Label1.Width, not the other way
 
around. That means, moving Label1 will move Edit1. But moving Edit1 will
 
be undone by the LCL.
 
If you also anchor the right side of Label1 to the left side of Edit1,
 
you created a circle, and this can result together with some other
 
autosize properties in a loop. This is ignored by the LCL or automagically repaired when the Parent.AutoSize is true.
 
  
==Via the Anchor Editor==
+
<syntaxhighlight>
 +
Edit1.AnchorToNeighbour(akLeft, 10, Label1);
 +
</syntaxhighlight>
  
The anchor editor is a floating window that is available via the menu '''View / Anchor Editor''' or via the button on the '''Anchors''' property in the object inspector.
+
== Примечания ==
 +
 
 +
'''Edit1.Left''' будет следовать за '''Label1.Left+Label1.Width''', но не наоборот. Это означает, что перемещение Label1 будет вызывать перемещение Edit1. Но перемещение Edit1 будет отменяться LCL.
 +
Если вы также привяжете правую сторону Label1 к левой стороне Edit1, вы создадите кольцо и в сочетании с некоторыми другими свойствами авторазмера это приведёт к циклу. Это игнорируется LCL или автоматически исправляется, когда Parent.AutoSize установлено в True.
 +
 
 +
== С помощью редактора якорей ==
 +
 
 +
Редактор якорей - плавающее окно, доступное через меню '''View / Anchor Editor''' или через кнопку в свойстве '''Anchors''' в инспекторе объектов.
  
 
[[Image:Anchoreditor.png]]
 
[[Image:Anchoreditor.png]]
  
=Example 2=
+
= Пример 2 =
  
You can anchor the Edit's top side to follow the Label's top side:
+
Вы можете привязать верхний край Edit для следования за верхним краем Label:
 
<pre>
 
<pre>
 
+--------+ +-------+
 
+--------+ +-------+
Line 51: Line 54:
 
           +-------+
 
           +-------+
 
</pre>
 
</pre>
<syntaxhighlight>Edit1.AnchorSide[akTop].Side := asrTop;
+
 
 +
<syntaxhighlight>
 +
Edit1.AnchorSide[akTop].Side := asrTop;
 
Edit1.AnchorSide[akTop].Control := Label1;
 
Edit1.AnchorSide[akTop].Control := Label1;
Edit1.Anchors := Edit1.Anchors + [akTop];</syntaxhighlight>
+
Edit1.Anchors := Edit1.Anchors + [akTop];
 +
</syntaxhighlight>
 +
 
 +
То-же самое может быть сделано с помощью метода:
  
The same can be done with the method:
+
<syntaxhighlight>
<syntaxhighlight>Edit1.AnchorParallel(akTop,0,Label1);</syntaxhighlight>
+
Edit1.AnchorParallel(akTop,0,Label1);
 +
</syntaxhighlight>
  
=Example 3=
+
= Пример 3 =
  
Centering a Label vertically to an Edit:
+
Вертикальное центрирование Edit относительно Label:
 
<pre>
 
<pre>
 
           +-------+
 
           +-------+
Line 68: Line 77:
 
           +-------+
 
           +-------+
 
</pre>
 
</pre>
<syntaxhighlight>Edit1.AnchorSide[akTop].Side := asrCenter;
+
 
 +
<syntaxhighlight>
 +
Edit1.AnchorSide[akTop].Side := asrCenter;
 
Edit1.AnchorSide[akTop].Control := Label1;
 
Edit1.AnchorSide[akTop].Control := Label1;
Edit1.Anchors := Edit1.Anchors + [akTop] - [akBottom];</syntaxhighlight>
+
Edit1.Anchors := Edit1.Anchors + [akTop] - [akBottom];
 +
</syntaxhighlight>
  
The same can be done with the method:
+
То-же самое может быть сделано с помощью метода:
<syntaxhighlight>Edit1.AnchorVerticalCenterTo(Label1);</syntaxhighlight>
 
  
Obviously anchoring the bottom side of Edit1 does not make sense when
+
<syntaxhighlight>
centering.
+
Edit1.AnchorVerticalCenterTo(Label1);
 +
</syntaxhighlight>
  
=New property=
+
Очевидно, что привязка нижнего края Edit1 не имеет смысла при центрировании.
<syntaxhighlight>property AnchorSide[Kind: TAnchorKind]: TAnchorSide read GetAnchorSide;</syntaxhighlight>
 
This is not published in the [http://wiki.lazarus.freepascal.org/IDE_Window:_Object_Inspector object inspector]. You can edit it in the
 
designer via the [http://wiki.lazarus.freepascal.org/IDE_Window:_Anchor_Editor anchor editor] (Menu: View -> View anchor editor, or
 
click on button of 'Anchors' property).
 
  
=New methods to easily configure common layouts=
+
= Новое свойство =
  
<syntaxhighlight>procedure AnchorToNeighbour(Side: TAnchorKind; Space: integer;
+
<syntaxhighlight>
 +
property AnchorSide[Kind: TAnchorKind]: TAnchorSide read GetAnchorSide;
 +
</syntaxhighlight>
 +
 
 +
Это свойство не опубликовано в  [[IDE_Window:_Object_Inspector|инспекторе объектов]]. Вы можете редактировать его в дизайнере с помощью [[IDE_Window:_Anchor_Editor|редактора якорей]]<br>
 +
(меню '''View -> View anchor editor''' или щелчок на кнопке свойства '''Anchors''').
 +
 
 +
= Новые методы для лёгкого конфигурирования общего расположения =
 +
 
 +
<syntaxhighlight>
 +
procedure AnchorToNeighbour(Side: TAnchorKind; Space: integer;
 
                             Sibling: TControl);
 
                             Sibling: TControl);
 
procedure AnchorParallel(Side: TAnchorKind; Space: integer;
 
procedure AnchorParallel(Side: TAnchorKind; Space: integer;
Line 92: Line 110:
 
procedure AnchorHorizontalCenterTo(Sibling: TControl);
 
procedure AnchorHorizontalCenterTo(Sibling: TControl);
 
procedure AnchorVerticalCenterTo(Sibling: TControl);
 
procedure AnchorVerticalCenterTo(Sibling: TControl);
procedure AnchorAsAlign(TheAlign: TAlign; Space: Integer);</syntaxhighlight>
+
procedure AnchorAsAlign(TheAlign: TAlign; Space: Integer);
 +
</syntaxhighlight>
  
AnchorVerticalCenterTo works with Parent too. Then it will center on the client area, that means the center of the control is at ''ClientHeight div 2''.
+
'''AnchorVerticalCenterTo''' работает также с '''Parent'''. Тогда центрирование будет происходить по клиентской области, это означает, что центр элемента управления будет в ''ClientHeight div 2''.
  
Center anchoring is not yet fully supported when computing the size of the parent. For example when you put a label center anchored into a Groupbox1 and set Groupbox1,AutoSize to true then Groupbox1 height will shrink leaving no space for the label. The solution is to center to a control that is not centered. For example center a Label1 to a ComboBox and use for the ComboBox the default anchors (Anchors=[akLeft,akTop]).
+
Привязка по центру пока не полностью поддерживается при вычислении размера родителя. Например, когда вы помещаете привязанную по центру метку в Groupbox1 и устанавливаете Groupbox1.AutoSize в True, то высота Groupbox1 будет уменьшаться, не оставляя места для метки. Решение состоит в центрировании по элементу, который не центрирован. Например, центрируйте Label1 по ComboBox и используйте для ComboBox якоря по умолчанию (Anchors=[akLeft,akTop]).
  
=Anchoring to invisible controls=
+
= Привязка к невидимым элементам управления =
  
Since 0.9.25 rev 12800 anchoring to invisible controls has changed to work more intuitively. For example: The below controls A, B, C are anchored (C.Left to B.Right and B.Left to A.Right):
+
Начиная с 0.9.25 rev 12800 привязка к невидимым элементам управления была изменена, чтобы работать более интуитивно. Например, ниже элементы управления  A, B, C привязаны (C.Left к B.Right и  B.Left к A.Right):
  
 
   +---+ +---+ +---+
 
   +---+ +---+ +---+
Line 106: Line 125:
 
   +---+ +---+ +---+
 
   +---+ +---+ +---+
  
If B is hidden (Visible:=false) then C.Left will skip B and use the right of A, resulting in
+
Если B скрыт (Visible:=false), то C.Left будет пропускать B и использовать правый край A, в результате получим следующее:
  
 
   +---+ +---+
 
   +---+ +---+
Line 112: Line 131:
 
   +---+ +---+
 
   +---+ +---+
  
=Circular references=
+
= Циклические ссылки =
  
You can build circular references by anchoring two sides to each other, which creates an impossible anchoring. The LCL notices that, but will not raise an exception, because it can be a temporary circle. For example: A row of buttons. Button1 is left of Button2, Button2 is left of Button3. Now the order is changed to: Button3, Button1, Button2. If the reanchoring is started with Button3, a circle is created temporarily and is fixed when the reordering is completed. The LCL detects circles and will not move the Button. Circles are not the only anomaly.
+
Вы можете создать циклические ссылки, привязав два края друг к другу, что создаёт невозможную привязку. LCL замечает это, но не генерирует исключения, поскольку этот цикл может быть времнным. Например, ряд кнопок: Button1 слева от Button2, Button2 слева от Button3. Теперь меняем порядок на следующий: Button3, Button1, Button2. Если перепривязка начата с Button3, временно создаётся цикл, который исправляется по завершению переупорядочивания. LCL обнаруживает цикл и не перемещает Button. Циклы - не единственная аномалия.
  
There is one exception to this rule. If the Parent.AutoSize is true, then the LCL will automatically break circles on autosize and writes a warning via debugln (windows: --debug-log.txt, linux, et al: stdout). Which anchor is broken depends on the order of controls and the sides. So, temporary circles are still allowed with AutoSize=true if you enclose the change in
+
Есть одно исключение из этого правила. Если '''Parent.AutoSize''' установлено в True, то LCL будет автоматически разрывать циклы на autosize и писать предупреждение через '''debugln''' (windows: --debug-log.txt, linux, et al: stdout). Которая из привязок будет нарушена, зависит от порядка элементов управления и сторон. Таким образом, временные циклы остаются разрешёнными при AutoSize=true, если вы заключите изменение в:
  
 
<syntaxhighlight>
 
<syntaxhighlight>
Line 127: Line 146:
 
</syntaxhighlight>
 
</syntaxhighlight>
  
The AutoSize algorithm does not only break circles, but fixes Align/AnchorSide inconsistencies too.
+
Алгоритм AutoSize не только разрушает циклы, но также исправляет несоответствия Align/AnchorSide.
 
 
Eventually it would be good to add some hints in the designer or a tool to list the circles and inconsistencies.
 
  
 
=See also=
 
=See also=
  
* [[Autosize / Layout]]
+
*[[Autosize / Layout]]

Revision as of 23:40, 27 January 2016

Deutsch (de) English (en) français (fr) 日本語 (ja) русский (ru)

Есть несколько новых свойств и методов для автоматического расположения элементов управления. Теперь вы можете настроить элементы управления для поддержания определённого расстояния до других элементов управления или центрирования относительно других элементов управления. Смотрите пример ниже.

Каждая из четырёх сторон элемента управления (Left, Top, Right, Bottom) теперь может быть прикреплена/привязана к стороне другого элемента управления. Например, теперь вы можете привязать левую сторону TEdit к правой стороне TLabel. Каждый раз, когда Label перемещается или меняет размер, левая сторона Edit будет следовать за ней, что обычно приводит к перемещению Edit параллельно Label.

Пример 1

+--------+ +-------+
| Label1 | | Edit1 |
+--------+ |       |
           +-------+

В коде

Edit1.AnchorSide[akLeft].Side := asrRight;
Edit1.AnchorSide[akLeft].Control := Label1;
Edit1.Anchors := Edit1.Anchors + [akLeft];

Вы можете задать расстояние с помощью свойств BorderSpacing:

Edit1.BorderSpacing.Left := 10;

То-же самое может быть сделано с помощью метода:

Edit1.AnchorToNeighbour(akLeft, 10, Label1);

Примечания

Edit1.Left будет следовать за Label1.Left+Label1.Width, но не наоборот. Это означает, что перемещение Label1 будет вызывать перемещение Edit1. Но перемещение Edit1 будет отменяться LCL. Если вы также привяжете правую сторону Label1 к левой стороне Edit1, вы создадите кольцо и в сочетании с некоторыми другими свойствами авторазмера это приведёт к циклу. Это игнорируется LCL или автоматически исправляется, когда Parent.AutoSize установлено в True.

С помощью редактора якорей

Редактор якорей - плавающее окно, доступное через меню View / Anchor Editor или через кнопку в свойстве Anchors в инспекторе объектов.

Anchoreditor.png

Пример 2

Вы можете привязать верхний край Edit для следования за верхним краем Label:

+--------+ +-------+
| Label1 | | Edit1 |
+--------+ |       |
           +-------+
Edit1.AnchorSide[akTop].Side := asrTop;
Edit1.AnchorSide[akTop].Control := Label1;
Edit1.Anchors := Edit1.Anchors + [akTop];

То-же самое может быть сделано с помощью метода:

Edit1.AnchorParallel(akTop,0,Label1);

Пример 3

Вертикальное центрирование Edit относительно Label:

           +-------+
+--------+ |       |
| Label1 | | Edit1 |
+--------+ |       |
           +-------+
Edit1.AnchorSide[akTop].Side := asrCenter;
Edit1.AnchorSide[akTop].Control := Label1;
Edit1.Anchors := Edit1.Anchors + [akTop] - [akBottom];

То-же самое может быть сделано с помощью метода:

Edit1.AnchorVerticalCenterTo(Label1);

Очевидно, что привязка нижнего края Edit1 не имеет смысла при центрировании.

Новое свойство

property AnchorSide[Kind: TAnchorKind]: TAnchorSide read GetAnchorSide;

Это свойство не опубликовано в инспекторе объектов. Вы можете редактировать его в дизайнере с помощью редактора якорей
(меню View -> View anchor editor или щелчок на кнопке свойства Anchors).

Новые методы для лёгкого конфигурирования общего расположения

procedure AnchorToNeighbour(Side: TAnchorKind; Space: integer;
                            Sibling: TControl);
procedure AnchorParallel(Side: TAnchorKind; Space: integer;
                         Sibling: TControl);
procedure AnchorHorizontalCenterTo(Sibling: TControl);
procedure AnchorVerticalCenterTo(Sibling: TControl);
procedure AnchorAsAlign(TheAlign: TAlign; Space: Integer);

AnchorVerticalCenterTo работает также с Parent. Тогда центрирование будет происходить по клиентской области, это означает, что центр элемента управления будет в ClientHeight div 2.

Привязка по центру пока не полностью поддерживается при вычислении размера родителя. Например, когда вы помещаете привязанную по центру метку в Groupbox1 и устанавливаете Groupbox1.AutoSize в True, то высота Groupbox1 будет уменьшаться, не оставляя места для метки. Решение состоит в центрировании по элементу, который не центрирован. Например, центрируйте Label1 по ComboBox и используйте для ComboBox якоря по умолчанию (Anchors=[akLeft,akTop]).

Привязка к невидимым элементам управления

Начиная с 0.9.25 rev 12800 привязка к невидимым элементам управления была изменена, чтобы работать более интуитивно. Например, ниже элементы управления A, B, C привязаны (C.Left к B.Right и B.Left к A.Right):

 +---+ +---+ +---+
 | A | | B | | C |
 +---+ +---+ +---+

Если B скрыт (Visible:=false), то C.Left будет пропускать B и использовать правый край A, в результате получим следующее:

 +---+ +---+
 | A | | C |
 +---+ +---+

Циклические ссылки

Вы можете создать циклические ссылки, привязав два края друг к другу, что создаёт невозможную привязку. LCL замечает это, но не генерирует исключения, поскольку этот цикл может быть времнным. Например, ряд кнопок: Button1 слева от Button2, Button2 слева от Button3. Теперь меняем порядок на следующий: Button3, Button1, Button2. Если перепривязка начата с Button3, временно создаётся цикл, который исправляется по завершению переупорядочивания. LCL обнаруживает цикл и не перемещает Button. Циклы - не единственная аномалия.

Есть одно исключение из этого правила. Если Parent.AutoSize установлено в True, то LCL будет автоматически разрывать циклы на autosize и писать предупреждение через debugln (windows: --debug-log.txt, linux, et al: stdout). Которая из привязок будет нарушена, зависит от порядка элементов управления и сторон. Таким образом, временные циклы остаются разрешёнными при AutoSize=true, если вы заключите изменение в:

Parent.DisableAutosizing;
try
  // change anchors, aligns, bounds...
finally
  Parent.EnableAutosizing;
end;

Алгоритм AutoSize не только разрушает циклы, но также исправляет несоответствия Align/AnchorSide.

See also