Skip to content

TStyledToolbar AutoSize does not resize height when Wrapable=True #107

Description

@surfjf69

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.

  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.

  1. 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.

  1. 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.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions