LCL: TToolBar: fixed wrap

git-svn-id: trunk@24620 -
This commit is contained in:
mattias 2010-04-14 13:01:02 +00:00
parent 5b24e1fcc4
commit 8798f09aa7

View File

@ -565,7 +565,8 @@ var
y: Integer; y: Integer;
NewControlWidth: Integer; NewControlWidth: Integer;
CurControl: TControl; CurControl: TControl;
AlignedControls: TFPList; ObstacleControls: TFPList;
FullSizeObstacleControls: TFPList;
StartX: Integer; StartX: Integer;
w: LongInt; w: LongInt;
h: LongInt; h: LongInt;
@ -580,59 +581,59 @@ var
PreferredBtnHeight: Integer; PreferredBtnHeight: Integer;
Intersects: Boolean; Intersects: Boolean;
IntersectsWithLimitedHeightControl: Boolean; IntersectsWithLimitedHeightControl: Boolean;
AnchorControl: TControl; StartedAtRowStart: Boolean;
AnchorSide: TAnchorSideReference;
p: integer;
begin begin
// compute the size
if (CurControl is TToolButton) and (not CurControl.AutoSize) then if (CurControl is TToolButton) and (not CurControl.AutoSize) then
begin begin
PreferredBtnWidth := 0; PreferredBtnWidth := 0;
PreferredBtnHeight := 0; PreferredBtnHeight := 0;
CurControl.GetPreferredSize(PreferredBtnWidth, PreferredBtnHeight); CurControl.GetPreferredSize(PreferredBtnWidth, PreferredBtnHeight);
NewControlWidth := PreferredBtnWidth; NewControlWidth := PreferredBtnWidth;
if (NewControlWidth < ButtonWidth) if (TToolButton(CurControl).Style in [tbsButton, tbsDropDown, tbsCheck]) then
and (TToolButton(CurControl).Style in [tbsButton, tbsDropDown, tbsCheck]) then begin
NewControlWidth := ButtonWidth; if (NewControlWidth < ButtonWidth) then
NewControlWidth := ButtonWidth;
end;
end end
else else
NewControlWidth := CurControl.Width; NewControlWidth := CurControl.Width;
NewBounds := Bounds(x, y, NewControlWidth, ButtonHeight); NewBounds := Bounds(x, y, NewControlWidth, ButtonHeight);
//DebugLn(['CalculatePosition ',DbgSName(CurControl)]); //DebugLn(['CalculatePosition ',DbgSName(CurControl)]);
StartedAtRowStart:=x=StartX;
repeat repeat
// move control to the right, until it does not overlap // move control to the right, until it does not overlap
IntersectsWithLimitedHeightControl:=false; IntersectsWithLimitedHeightControl:=false;
for j := 0 to AlignedControls.Count - 1 do j:=0;
while j<ObstacleControls.Count do
begin begin
AlignedControl := TControl(AlignedControls[j]); AlignedControl := TControl(ObstacleControls[j]);
SiblingBounds := Bounds(AlignedControl.Left, AlignedControl.Top, SiblingBounds := AlignedControl.BoundsRect;
AlignedControl.Width, AlignedControl.Height);
Intersects:=(SiblingBounds.Right > NewBounds.Left) and Intersects:=(SiblingBounds.Right > NewBounds.Left) and
(SiblingBounds.Left < NewBounds.Right) and (SiblingBounds.Left < NewBounds.Right) and
(SiblingBounds.Bottom > NewBounds.Top) and (SiblingBounds.Bottom > NewBounds.Top) and
(SiblingBounds.Top < NewBounds.Bottom); (SiblingBounds.Top < NewBounds.Bottom);
if Intersects then begin if Intersects then begin
//DebugLn('CalculatePosition Move ',NewBounds.Left,'->',SiblingBounds.Right); //DebugLn(['CalculatePosition Move ',NewBounds.Left,'->',SiblingBounds.Right]);
NewBounds.Left := SiblingBounds.Right; NewBounds.Left := SiblingBounds.Right;
NewBounds.Right := NewBounds.Left + NewControlWidth; NewBounds.Right := NewBounds.Left + NewControlWidth;
AnchorControl:=nil; j:=0; // check again, needed, because ObstacleControls are not sorted
// check if bottom is anchored tp parent // (and can not be sorted, because they can overlap)
if (akBottom in AlignedControl.Anchors) then if FullSizeObstacleControls.IndexOf(AlignedControl)<0 then
AlignedControl.AnchorSideBottom.GetSidePosition(AnchorControl,AnchorSide,P);
if AnchorControl=nil then
AnchorControl:=AlignedControl;
if not (akBottom in AnchorControl.Anchors) then
IntersectsWithLimitedHeightControl:=true; IntersectsWithLimitedHeightControl:=true;
end; end else
inc(j);
end; end;
if (not Wrapable) if (not Wrapable)
or (NewBounds.Right <= ARect.Right) or (NewBounds.Left = StartX) or (NewBounds.Right <= ARect.Right) or (NewBounds.Left = StartX)
or (not IntersectsWithLimitedHeightControl) then or (StartedAtRowStart and not IntersectsWithLimitedHeightControl) then
begin begin
// control fits into the row (or does not fit in the client area) // control fits into the row
//DebugLn(['CalculatePosition fits: ',DbgSName(CurControl),' ',dbgs(NewBounds)]);
x := NewBounds.Left; x := NewBounds.Left;
y := NewBounds.Top; y := NewBounds.Top;
Exit; break;
end; end;
// try next row // try next row
@ -640,8 +641,23 @@ var
NewBounds.Right := NewBounds.Left + NewControlWidth; NewBounds.Right := NewBounds.Left + NewControlWidth;
inc(NewBounds.Top, ButtonHeight); inc(NewBounds.Top, ButtonHeight);
inc(NewBounds.Bottom, ButtonHeight); inc(NewBounds.Bottom, ButtonHeight);
StartedAtRowStart:=true;
//DebugLn('CalculatePosition Next Row ',DbgSName(CurControl),' ',dbgs(NewBounds)); //DebugLn('CalculatePosition Next Row ',DbgSName(CurControl),' ',dbgs(NewBounds));
until False; until false;
end;
function AnchoredToParent(AControl: TControl; Side: TAnchorKind): boolean;
var
AnchorControl: TControl;
AnchorSide: TAnchorSideReference;
p: integer;
begin
if not (Side in CurControl.Anchors) then exit(false);
AnchorControl:=nil;
CurControl.AnchorSide[Side].GetSidePosition(AnchorControl,AnchorSide,P);
if AnchorControl=nil then
AnchorControl:=CurControl;
Result:=(Side in AnchorControl.Anchors);
end; end;
var var
@ -649,29 +665,42 @@ var
CurClientRect: TRect; CurClientRect: TRect;
AdjustClientFrame: TRect; AdjustClientFrame: TRect;
i: Integer; i: Integer;
GrowSide: TAnchorKind;
begin begin
//DebugLn(['WrapButtons ',DbgSName(Self),' Wrapable=',Wrapable,' ',dbgs(BoundsRect)]); //DebugLn(['WrapButtons ',DbgSName(Self),' Wrapable=',Wrapable,' ',dbgs(BoundsRect)]);
Result := True; Result := True;
NewWidth := 0; NewWidth := 0;
NewHeight := 0; NewHeight := 0;
AlignedControls := TFPList.Create; ObstacleControls := TFPList.Create;
FullSizeObstacleControls := TFPList.Create;
OrderedControls := TFPList.Create; OrderedControls := TFPList.Create;
if not Simulate then if not Simulate then
FRowCount := 0; FRowCount := 0;
DisableAlign; DisableAlign;
BeginUpdate; BeginUpdate;
try try
GrowSide:=akBottom;
for i:=0 to ControlCount-1 do for i:=0 to ControlCount-1 do
begin begin
CurControl := Controls[i]; CurControl := Controls[i];
if CurControl.Align = alNone then begin if CurControl.Align = alNone then begin
// set to Left,Top anchoring // this control will be auto positioned and auto sized by this function
// => set to Left,Top anchoring
CurControl.Anchors:=[akLeft,akTop]; CurControl.Anchors:=[akLeft,akTop];
CurControl.AnchorSide[akLeft].Control:=nil; CurControl.AnchorSide[akLeft].Control:=nil;
CurControl.AnchorSide[akTop].Control:=nil; CurControl.AnchorSide[akTop].Control:=nil;
OrderedControls.Add(CurControl); OrderedControls.Add(CurControl);
end else end else begin
AlignedControls.Add(CurControl) // this control will be positioned/sized by the default LCL functions
// the OrderedControls will be positioned around them (without overlapping)
ObstacleControls.Add(CurControl);
// check if this obstacle auto grows, for example if this toolbar is
// aligned to the top, check if the obstacle grows downwards (Align=alLeft)
if AnchoredToParent(CurControl,GrowSide) then begin
// this obstacle auto grows (important for the wrap algorithm)
FullSizeObstacleControls.Add(CurControl);
end;
end;
end; end;
// sort OrderedControls // sort OrderedControls
if FRealizedButtonHeight = 0 then if FRealizedButtonHeight = 0 then
@ -699,14 +728,13 @@ begin
if not CurControl.Visible then if not CurControl.Visible then
Continue; Continue;
CalculatePosition; CalculatePosition;
//DebugLn(['WrapButtons ',CurControl.Name,':',CurControl.ClassName,' ',x,',',y,',',CurControl.Width,',',CurControl.Height]); //DebugLn(['WrapButtons ',CurControl.Name,':',CurControl.ClassName,' ',x,',',y,',',CurControl.Width,'x',CurControl.Height]);
if ButtonHeight <= 0 then if ButtonHeight <= 0 then
h := CurControl.Height h := CurControl.Height
else else
h := ButtonHeight; h := ButtonHeight;
if CurControl.AutoSize then if CurControl.AutoSize then
begin begin
// TODO: center vertically
w := CurControl.Width; w := CurControl.Width;
h := CurControl.Height; h := CurControl.Height;
end end
@ -745,8 +773,9 @@ begin
end; end;
FRealizedButtonHeight := FButtonHeight; FRealizedButtonHeight := FButtonHeight;
finally finally
AlignedControls.Free; ObstacleControls.Free;
OrderedControls.Free; OrderedControls.Free;
FullSizeObstacleControls.Free;
EndUpdate; EndUpdate;
EnableAlign; EnableAlign;
end; end;