I found an AutoSize issue in TStyledToolbar when Wrapable=True.
The problem occurs with both horizontal and vertical toolbar layouts, but the vertical case also requires the FlowStyle to match the toolbar orientation.
Tested at runtime with StyledComponents 4.2.1.
- Horizontal toolbar - Align=alTop
Configuration:
- Align = alTop
- AutoSize = True
- Wrapable = True
- FlowStyle = fsLeftRightTopBottom
When the toolbar becomes too narrow, the buttons correctly wrap to a second row.
However, the toolbar height remains approximately one row high, so the additional row is clipped.
The issue appears to be in TStyledToolbar.ControlsHeight.
Current implementation:
function TStyledToolbar.ControlsHeight: Integer;
var
LSize: Integer;
begin
if AlignWithMargins then
LSize := Margins.Top + Margins.Bottom + 1
else
LSize := 1;
ProcessControls(
procedure (AControl: TControl)
begin
if AControl.Height > LSize then
LSize := LSize + AControl.Height;
end);
Result := LSize;
end;
This does not take into account the Top position assigned to controls after wrapping.
I changed it to:
function TStyledToolbar.ControlsHeight: Integer;
var
LSize: Integer;
begin
LSize := 0;
ProcessControls(
procedure (AControl: TControl)
begin
if AControl.Visible then
LSize := Max(LSize, AControl.Top + AControl.Height);
end);
if AlignWithMargins then
Inc(LSize, Margins.Top + Margins.Bottom);
Result := LSize;
end;
With this change, AutoSize correctly increases the toolbar height when buttons wrap to multiple rows.
It also correctly decreases the height again when the window is enlarged and the buttons return to a single row.
This fix has been tested successfully at runtime.
- Vertical toolbar - Align=alLeft
I also tested the equivalent case with:
- Align = alLeft
- AutoSize = True
- Wrapable = True
Changing ControlsWidth alone was not sufficient, because the underlying TFlowPanel was still using the default horizontal flow direction.
For a vertical toolbar, FlowStyle must be:
FlowStyle := fsTopBottomLeftRight;
With this FlowStyle and the following ControlsWidth implementation, vertical wrapping works correctly:
function TStyledToolbar.ControlsWidth: Integer;
var
LSize: Integer;
begin
LSize := 0;
ProcessControls(
procedure (AControl: TControl)
begin
if AControl.Visible then
LSize := Max(LSize, AControl.Left + AControl.Width);
end);
if AlignWithMargins then
Inc(LSize, Margins.Left + Margins.Right);
Result := LSize;
end;
With:
Align := alLeft;
FlowStyle := fsTopBottomLeftRight;
Wrapable := True;
AutoSize := True;
the buttons correctly flow from top to bottom and then wrap into a new column, and the toolbar width is correctly adjusted.
- Possible automatic FlowStyle handling
It may be useful for TStyledToolbar to automatically select the appropriate FlowStyle according to its orientation:
case Align of
alTop, alBottom:
FlowStyle := fsLeftRightTopBottom;
alLeft, alRight:
FlowStyle := fsTopBottomLeftRight;
end;
This would make Wrapable behave consistently for both horizontal and vertical toolbars without requiring the application to manually set FlowStyle.
Summary
Horizontal toolbar:
- wrapping already occurs correctly
- ControlsHeight does not calculate the wrapped height correctly
- using AControl.Top + AControl.Height fixes the issue
Vertical toolbar:
- ControlsWidth needs the equivalent Left + Width calculation
- FlowStyle must also be fsTopBottomLeftRight
- with both changes, vertical wrapping works correctly
Both horizontal and vertical fixes have been tested successfully at runtime.
I found an AutoSize issue in TStyledToolbar when Wrapable=True.
The problem occurs with both horizontal and vertical toolbar layouts, but the vertical case also requires the FlowStyle to match the toolbar orientation.
Tested at runtime with StyledComponents 4.2.1.
Configuration:
When the toolbar becomes too narrow, the buttons correctly wrap to a second row.
However, the toolbar height remains approximately one row high, so the additional row is clipped.
The issue appears to be in TStyledToolbar.ControlsHeight.
Current implementation:
function TStyledToolbar.ControlsHeight: Integer;
var
LSize: Integer;
begin
if AlignWithMargins then
LSize := Margins.Top + Margins.Bottom + 1
else
LSize := 1;
ProcessControls(
procedure (AControl: TControl)
begin
if AControl.Height > LSize then
LSize := LSize + AControl.Height;
end);
Result := LSize;
end;
This does not take into account the Top position assigned to controls after wrapping.
I changed it to:
function TStyledToolbar.ControlsHeight: Integer;
var
LSize: Integer;
begin
LSize := 0;
ProcessControls(
procedure (AControl: TControl)
begin
if AControl.Visible then
LSize := Max(LSize, AControl.Top + AControl.Height);
end);
if AlignWithMargins then
Inc(LSize, Margins.Top + Margins.Bottom);
Result := LSize;
end;
With this change, AutoSize correctly increases the toolbar height when buttons wrap to multiple rows.
It also correctly decreases the height again when the window is enlarged and the buttons return to a single row.
This fix has been tested successfully at runtime.
I also tested the equivalent case with:
Changing ControlsWidth alone was not sufficient, because the underlying TFlowPanel was still using the default horizontal flow direction.
For a vertical toolbar, FlowStyle must be:
FlowStyle := fsTopBottomLeftRight;
With this FlowStyle and the following ControlsWidth implementation, vertical wrapping works correctly:
function TStyledToolbar.ControlsWidth: Integer;
var
LSize: Integer;
begin
LSize := 0;
ProcessControls(
procedure (AControl: TControl)
begin
if AControl.Visible then
LSize := Max(LSize, AControl.Left + AControl.Width);
end);
if AlignWithMargins then
Inc(LSize, Margins.Left + Margins.Right);
Result := LSize;
end;
With:
Align := alLeft;
FlowStyle := fsTopBottomLeftRight;
Wrapable := True;
AutoSize := True;
the buttons correctly flow from top to bottom and then wrap into a new column, and the toolbar width is correctly adjusted.
It may be useful for TStyledToolbar to automatically select the appropriate FlowStyle according to its orientation:
case Align of
alTop, alBottom:
FlowStyle := fsLeftRightTopBottom;
alLeft, alRight:
FlowStyle := fsTopBottomLeftRight;
end;
This would make Wrapable behave consistently for both horizontal and vertical toolbars without requiring the application to manually set FlowStyle.
Summary
Horizontal toolbar:
Vertical toolbar:
Both horizontal and vertical fixes have been tested successfully at runtime.