From aeb6eb81a1fb4780e13da288c28098f77a2069d6 Mon Sep 17 00:00:00 2001 From: ondrej Date: Wed, 10 Feb 2016 12:25:16 +0000 Subject: [PATCH] lcl: flowpanel: add FlowLayout property. git-svn-id: trunk@51566 - --- docs/xml/lcl/extctrls.xml | 5 +++ lcl/extctrls.pp | 4 ++ lcl/include/customflowpanel.inc | 76 +++++++++++++++++++++++++++++++-- 3 files changed, 82 insertions(+), 3 deletions(-) diff --git a/docs/xml/lcl/extctrls.xml b/docs/xml/lcl/extctrls.xml index 0d2c3ceab2..9b13fad3f1 100644 --- a/docs/xml/lcl/extctrls.xml +++ b/docs/xml/lcl/extctrls.xml @@ -6049,6 +6049,11 @@ will copy the contents of the Source class to the The base class for TFlowPanel + Use FlowLayout to set the layout (alignment) for the non-flow coordinate. Default: tlTopIn case of horizontal/vertical flow style: +tlTop: top/left alignment in row/column +tlCenter: center +tlBottom: bottom/right + diff --git a/lcl/extctrls.pp b/lcl/extctrls.pp index 02dc29d94e..782e1e13aa 100644 --- a/lcl/extctrls.pp +++ b/lcl/extctrls.pp @@ -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; diff --git a/lcl/include/customflowpanel.inc b/lcl/include/customflowpanel.inc index 5236a942b4..5321e69578 100644 --- a/lcl/include/customflowpanel.inc +++ b/lcl/include/customflowpanel.inc @@ -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;