lcl: flowpanel: add FlowLayout property.

git-svn-id: trunk@51566 -
This commit is contained in:
ondrej 2016-02-10 12:25:16 +00:00
parent e46e912fff
commit aeb6eb81a1
3 changed files with 82 additions and 3 deletions

View File

@ -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>

View File

@ -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;

View File

@ -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;