unit FlowPanels;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, Contnrs, ExtCtrls, StdCtrls;

type
  TForm2 = class(TForm)
    Panel1: TPanel;
    btAddButton: TButton;
    btRemoveButton: TButton;
    btReArrange: TButton;
    procedure FormCreate(Sender: TObject);
    procedure FormDestroy(Sender: TObject);
    procedure btAddButtonClick(Sender: TObject);
    procedure btRemoveButtonClick(Sender: TObject);
    procedure btReArrangeClick(Sender: TObject);
  private
    { Private declarations }
    FStack : TObjectStack;
    FFlowPane: TFlowPanel;

    procedure btAButtonClick(Sender: TObject);
  public
    { Public declarations }
  end;

var
  Form2: TForm2;

implementation

{$R *.dfm}

// BeginExample: FlowPanels
// Class: ExtCtrls.TFlowPanel
// Property: ExtCtrls.TCustomFlowPanel.FlowStyle
// Type: ExtCtrls.TFlowStyle
// Class: Contnrs.TObjectStack
// Method: Contnrs.TObjectStack.Push
// Method: Contnrs.TObjectStack.Pop
// Method: Contnrs.TObjectStack.Peek
// BeginCode
{
This example demonstrates the use of Flow panel to automatically
align a set of controls and the different methods that can be used for that.
A Stack is used to control the order of destruction of buttons.
}
procedure TForm2.btAButtonClick(Sender: TObject);
var
  ThisButton : TButton;
  LastButton : TButton;
  Temp       : String;
begin
  { Sender is a TButton, cast it }
  ThisButton := Sender as TButton;

  if FStack.Count > 0 then
  begin
    { If there are buttons in stack, peek it }
    LastButton := FStack.Peek() as TButton;

    { Change the captions of this button and the last one }
    Temp := ThisButton.Caption;
    ThisButton.Caption := LastButton.Caption;
    LastButton.Caption := Temp;
  end;
end;

procedure TForm2.btAddButtonClick(Sender: TObject);
var
  Button : TButton;
begin
  { Create a new button }
  Button := TButton.Create(FFlowPane);
  Button.Parent := FFlowPane;
  Button.Caption := IntToStr(FStack.Count);
  Button.OnClick := btAButtonClick;

  { Push the button to the stack }
  FStack.Push(Button);
end;

procedure TForm2.btReArrangeClick(Sender: TObject);
var
  NewFlowStyle : TFlowStyle;
begin
  { Chnage the flow order (rotate) }
  NewFlowStyle := FFlowPane.FlowStyle;

  if NewFlowStyle = fsBottomTopRightLeft then
     NewFlowStyle := fsLeftRightTopBottom
  else
    Inc(NewFlowStyle);

  FFlowPane.FlowStyle := NewFlowStyle;
end;

procedure TForm2.btRemoveButtonClick(Sender: TObject);
var
  Button : TButton;
begin
  if FStack.Count > 0 then
  begin
    { if the stack is not empty, pop the last button }
    Button := FStack.Pop() as TButton;
    Button.Free();
  end;
end;

procedure TForm2.FormCreate(Sender: TObject);
begin
  { Create a new TFlowPanel pane and align it to client }
  FFlowPane := TFlowPanel.Create(Self);
  FFlowPane.Parent := Self;
  FFlowPane.Align := alClient;

  { Set the initial flowing style }
  FFlowPane.FlowStyle := fsLeftRightTopBottom;

  { Create the button stack }
  FStack := TObjectStack.Create();
end;

procedure TForm2.FormDestroy(Sender: TObject);
begin
  { Destroy the stack also }
  FStack.Free();
end;
// EndCode
// EndExample: FlowPanels

end.
