mirror of
https://gitlab.com/freepascal.org/lazarus/lazarus.git
synced 2025-05-30 10:02:44 +02:00
lcl: flowpanel: add FlowLayout property.
git-svn-id: trunk@51566 -
This commit is contained in:
parent
e46e912fff
commit
aeb6eb81a1
@ -6049,6 +6049,11 @@ will copy the <var>contents</var> of the <var>Source</var> class to the
|
||||
</element><element name="TCustomFlowPanel"><short>The base class for <link id="#LCLBase.extctrls.TFlowPanel">TFlowPanel</link>
|
||||
</short>
|
||||
</element>
|
||||
<element name="TCustomFlowPanel.FlowLayout"><short>Use FlowLayout to set the layout (alignment) for the non-flow coordinate. Default: tlTop</short><descr>In case of horizontal/vertical flow style:
|
||||
tlTop: top/left alignment in row/column
|
||||
tlCenter: center
|
||||
tlBottom: bottom/right</descr>
|
||||
</element>
|
||||
</module>
|
||||
<!-- ExtCtrls -->
|
||||
</package>
|
||||
|
@ -1167,8 +1167,10 @@ type
|
||||
FControlList: TFlowPanelControlList;
|
||||
FAutoWrap: Boolean;
|
||||
FFlowStyle: TFlowStyle;
|
||||
FFlowLayout: TTextLayout;
|
||||
procedure SetAutoWrap(const AAutoWrap: Boolean);
|
||||
procedure SetControlList(const AControlList: TFlowPanelControlList);
|
||||
procedure SetFlowLayout(const aFlowLayout: TTextLayout);
|
||||
procedure SetFlowStyle(const AFlowStyle: TFlowStyle);
|
||||
protected
|
||||
procedure CMControlChange(var Message: TCMControlChange); message CM_CONTROLCHANGE;
|
||||
@ -1187,6 +1189,7 @@ type
|
||||
property AutoWrap: Boolean read FAutoWrap write SetAutoWrap;
|
||||
property ControlList: TFlowPanelControlList read FControlList write SetControlList;
|
||||
property FlowStyle: TFlowStyle read FFlowStyle write SetFlowStyle;
|
||||
property FlowLayout: TTextLayout read FFlowLayout write SetFlowLayout;
|
||||
end;
|
||||
|
||||
TFlowPanel = class(TCustomFlowPanel)
|
||||
@ -1213,6 +1216,7 @@ type
|
||||
property DragKind;
|
||||
property DragMode;
|
||||
property Enabled;
|
||||
property FlowLayout;
|
||||
property FlowStyle;
|
||||
property FullRepaint;
|
||||
property Font;
|
||||
|
@ -154,6 +154,41 @@ end;
|
||||
|
||||
procedure TCustomFlowPanel.AlignControls(AControl: TControl;
|
||||
var RemainingClientRect: TRect);
|
||||
|
||||
var
|
||||
xNewBounds: array of TRect; // right=width, bottom=height
|
||||
|
||||
procedure AlignLayout(const BStartControl, BEndControl, BTopLeft, BSize: Integer);
|
||||
var
|
||||
I: Integer;
|
||||
xControl: TControl;
|
||||
xConBS: TControlBorderSpacing;
|
||||
begin
|
||||
if FFlowLayout = tlTop then
|
||||
Exit;
|
||||
|
||||
for I := BStartControl to BEndControl do
|
||||
begin
|
||||
xControl := FControlList[I].Control;
|
||||
if not xControl.Visible and not (csDesigning in ComponentState) then
|
||||
Continue;
|
||||
|
||||
xConBS := xControl.BorderSpacing;
|
||||
if FFlowStyle in [fsLeftRightTopBottom, fsLeftRightBottomTop, fsRightLeftTopBottom, fsRightLeftBottomTop] then
|
||||
begin
|
||||
case FFlowLayout of
|
||||
tlCenter: xNewBounds[I].Top := BTopLeft + (BSize - xConBS.ControlHeight) div 2 + xConBS.Top + xConBS.Around;
|
||||
tlBottom: xNewBounds[I].Top := BTopLeft + BSize - xControl.Height - xConBS.Bottom - xConBS.Around;
|
||||
end;
|
||||
end else
|
||||
begin
|
||||
case FFlowLayout of
|
||||
tlCenter: xNewBounds[I].Left := BTopLeft + (BSize - xConBS.ControlWidth) div 2 + xConBS.Left + xConBS.Around;
|
||||
tlBottom: xNewBounds[I].Left := BTopLeft + BSize - xControl.Width - xConBS.Right - xConBS.Around;
|
||||
end;
|
||||
end;
|
||||
end;
|
||||
end;
|
||||
const
|
||||
cXIncDir: array[TFlowStyle] of Integer = (1, -1, 1, -1, 1, 1, -1, -1);
|
||||
cYIncDir: array[TFlowStyle] of Integer = (1, 1, -1, -1, 1, -1, 1, -1);
|
||||
@ -161,7 +196,7 @@ const
|
||||
cXDeltaConst: array[TFlowStyle] of Integer = (0, 0, 0, 0, 0, 0, -1, -1);
|
||||
var
|
||||
I, L: Integer;
|
||||
xMaxHeight, xMaxWidth: Integer;
|
||||
xMaxHeight, xMaxWidth, xRowStart: Integer;
|
||||
xPosition: TPoint;
|
||||
xSize, xGroupSize: TSize;
|
||||
xControl: TControl;
|
||||
@ -191,7 +226,9 @@ begin
|
||||
xPosition := RemainingClientRect.BottomRight;
|
||||
end;
|
||||
|
||||
for I := 0 to FControlList.Count - 1 do
|
||||
xRowStart := 0;
|
||||
SetLength(xNewBounds, FControlList.Count);
|
||||
for I := 0 to FControlList.Count-1 do
|
||||
begin
|
||||
xControl := FControlList[I].Control;
|
||||
xConBS := xControl.BorderSpacing;
|
||||
@ -227,8 +264,10 @@ begin
|
||||
if (xMaxHeight > 0) and FAutoWrap and not xForbidWrap
|
||||
and (xForceWrap or (xPosition.X + xGroupSize.cx >= RemainingClientRect.Right)) then
|
||||
begin
|
||||
AlignLayout(xRowStart, I-1, xPosition.Y, xMaxHeight);
|
||||
Inc(xPosition.Y, xMaxHeight * cYIncDir[FFlowStyle]);
|
||||
xMaxHeight := 0;
|
||||
xRowStart := I;
|
||||
xPosition.X := RemainingClientRect.Left;
|
||||
end;
|
||||
fsRightLeftTopBottom,
|
||||
@ -238,8 +277,10 @@ begin
|
||||
if (xMaxHeight > 0) and FAutoWrap and not xForbidWrap
|
||||
and (xForceWrap or (xPosition.X <= 0)) then
|
||||
begin
|
||||
AlignLayout(xRowStart, I-1, xPosition.Y, xMaxHeight);
|
||||
Inc(xPosition.Y, xMaxHeight * cYIncDir[FFlowStyle]);
|
||||
xMaxHeight := 0;
|
||||
xRowStart := I;
|
||||
xPosition.X := RemainingClientRect.Right - xSize.cx;
|
||||
end;
|
||||
end;
|
||||
@ -248,8 +289,10 @@ begin
|
||||
if (xMaxWidth > 0) and FAutoWrap and not xForbidWrap
|
||||
and (xForceWrap or (xPosition.Y + xGroupSize.cy >= RemainingClientRect.Bottom)) then
|
||||
begin
|
||||
AlignLayout(xRowStart, I-1, xPosition.X, xMaxWidth);
|
||||
Inc(xPosition.X, xMaxWidth * cXIncDir[FFlowStyle]);
|
||||
xMaxWidth := 0;
|
||||
xRowStart := I;
|
||||
xPosition.Y := RemainingClientRect.Top;
|
||||
end;
|
||||
fsBottomTopLeftRight,
|
||||
@ -259,8 +302,10 @@ begin
|
||||
if (xMaxWidth > 0) and FAutoWrap and not xForbidWrap
|
||||
and (xForceWrap or (xPosition.Y <= 0)) then
|
||||
begin
|
||||
AlignLayout(xRowStart, I-1, xPosition.X, xMaxWidth);
|
||||
Inc(xPosition.X, xMaxWidth * cXIncDir[FFlowStyle]);
|
||||
xMaxWidth := 0;
|
||||
xRowStart := I;
|
||||
xPosition.Y := RemainingClientRect.Bottom - xSize.cy;
|
||||
end;
|
||||
end;
|
||||
@ -269,7 +314,7 @@ begin
|
||||
xMaxHeight := xSize.cy;
|
||||
if xSize.cx > xMaxWidth then
|
||||
xMaxWidth := xSize.cx;
|
||||
xControl.SetBounds(
|
||||
xNewBounds[I] := Rect(
|
||||
xPosition.X + xConBS.Left + xConBS.Around + cXDeltaConst[FFlowStyle] * xSize.cx,
|
||||
xPosition.Y + xConBS.Top + xConBS.Around + cYDeltaConst[FFlowStyle] * xSize.cy,
|
||||
xSize.cx - (xConBS.Left + xConBS.Right + xConBS.Around*2),
|
||||
@ -279,6 +324,23 @@ begin
|
||||
else if FFlowStyle in [fsTopBottomLeftRight, fsTopBottomRightLeft] then
|
||||
Inc(xPosition.Y, xSize.cy + cYIncDir[FFlowStyle]);
|
||||
end;
|
||||
|
||||
if FFlowStyle in [fsLeftRightTopBottom, fsLeftRightBottomTop, fsRightLeftTopBottom, fsRightLeftBottomTop] then
|
||||
AlignLayout(xRowStart, FControlList.Count-1, xPosition.Y, xMaxHeight)
|
||||
else
|
||||
AlignLayout(xRowStart, FControlList.Count-1, xPosition.X, xMaxWidth);
|
||||
|
||||
for I := 0 to FControlList.Count-1 do
|
||||
begin
|
||||
xControl := FControlList[I].Control;
|
||||
xConBS := xControl.BorderSpacing;
|
||||
if not xControl.Visible and not (csDesigning in ComponentState) then
|
||||
continue;
|
||||
|
||||
xControl.SetBounds(
|
||||
xNewBounds[I].Left, xNewBounds[I].Top,
|
||||
xNewBounds[I].Right, xNewBounds[I].Bottom); // right=width, bottom=height
|
||||
end;
|
||||
finally
|
||||
EnableAlign;
|
||||
end;
|
||||
@ -373,6 +435,14 @@ begin
|
||||
FControlList.Assign(AControlList);
|
||||
end;
|
||||
|
||||
procedure TCustomFlowPanel.SetFlowLayout(const aFlowLayout: TTextLayout);
|
||||
begin
|
||||
if FFlowLayout = aFlowLayout then Exit;
|
||||
FFlowLayout := aFlowLayout;
|
||||
|
||||
ReAlign;
|
||||
end;
|
||||
|
||||
procedure TCustomFlowPanel.SetFlowStyle(const AFlowStyle: TFlowStyle);
|
||||
begin
|
||||
if FFlowStyle = AFlowStyle then Exit;
|
||||
|
Loading…
Reference in New Issue
Block a user