Recent

Author Topic: ToolButton changes position!  (Read 12988 times)

MoellerCLaus

  • Full Member
  • ***
  • Posts: 114
    • Vig Foreningsprogram
ToolButton changes position!
« on: December 04, 2013, 09:28:30 pm »
In my application I use a Toolbar with buttons.
Depending on a which page in a pagecontrol is shown some of the buttons should be invisable. This I wanted to realize by setting the action associated to the toolbutton to visable := false and vice versa.  %) but this has the effect that the buttons change position - and this an unwanted side-effect.
Any ideas or work-arounds?

howardpc

  • Hero Member
  • *****
  • Posts: 4144
Re: ToolButton changes position!
« Reply #1 on: December 04, 2013, 11:00:42 pm »
You could change the Enabled rather than the Visible property of the toolbuttons. Depending on your OS and theme etc. this should have a distinct visual effect (as well as disabling the toolbutton), without removing the button entirely and shifting the positions of the others.
But without knowing why you want invisible buttons (just to make them inactive, or is it imperative that they be absent?) it's hard to say more.

MoellerCLaus

  • Full Member
  • ***
  • Posts: 114
    • Vig Foreningsprogram
Re: ToolButton changes position!
« Reply #2 on: December 05, 2013, 11:20:00 am »
Thanks
The reason why want them inactive and non - visuable is that there are many of them and only a few is needed on every page.
The alternative may be to have a toolbar for every page in the pagecontrol; and then set the toolbar invisable.
I wondered just why toolbuttoms switch position; in Delphi they do not.

eric

  • Sr. Member
  • ****
  • Posts: 267
Re: ToolButton changes position!
« Reply #3 on: December 05, 2013, 01:40:25 pm »
One simple option is to use a panel instead of a toolbar.

howardpc

  • Hero Member
  • *****
  • Posts: 4144
Re: ToolButton changes position!
« Reply #4 on: December 05, 2013, 03:21:35 pm »
The alternative may be to have a toolbar for every page in the pagecontrol; and then set the toolbar invisable.
? If the toolbar is invisible all the buttons will be invisible.
An example of using a panel to preserve the positions of buttons whatever their visibility is given below. A TCheckGroup dropped on the form allows you to toggle the visibility of individual buttons.

Code: [Select]
unit mainButtonArray;

{$mode objfpc}{$H+}

interface

uses
  Classes, Forms, Controls, ExtCtrls, Buttons;

const
  ButtonWidth = 25;

type

  { TButtonPanel }

  TButtonPanel=class(TCustomPanel)
  private
    FButtons: array[0..20] of TSpeedButton;
    FMaxIndex: integer;
    function GetButton(index: integer): TSpeedButton;
  public
    constructor Create(TheOwner: TComponent; bCaptions: array of const);
    property Buttons[index:integer]: TSpeedButton read GetButton;
  end;

  { TForm1 }

  TForm1 = class(TForm)
    cgButtonInvisibility: TCheckGroup;
    procedure cgButtonInvisibilityItemClick(Sender: TObject; Index: integer);
    procedure FormCreate(Sender: TObject);
  private
    bp:TButtonPanel;
  end;

var
  Form1: TForm1;

implementation

{ TForm1 }

procedure TForm1.cgButtonInvisibilityItemClick(Sender: TObject; Index: integer);
begin
  bp.Buttons[Index].Visible:=not bp.Buttons[Index].Visible;
end;

procedure TForm1.FormCreate(Sender: TObject);
begin
  bp:=TButtonPanel.Create(Self, ['1','2','3','4','5','6','7','8','9','10']);
  bp.Top:=10;
  bp.Left:=10;
  bp.Parent:=Self;
end;

{$R *.lfm}

{ TButtonPanel }

function TButtonPanel.GetButton(index: integer): TSpeedButton;
begin
  if (index>=0) and (index<=FMaxIndex) and Assigned(FButtons[index]) then
   Result:=FButtons[index]
  else Result:=nil;
end;

constructor TButtonPanel.Create(TheOwner: TComponent;
  bCaptions: array of const);

  function NewButton(const aCaption:string; aLeft:integer): TSpeedButton;
  begin
    Result:=TSpeedButton.Create(Self);
    Result.SetInitialBounds(aLeft, 0, ButtonWidth, ButtonWidth);
    Result.ShowCaption:=True;
    Result.Caption:=aCaption;
    Result.Parent:=Self;
  end;

var
  i: integer;
begin
  Inherited Create(TheOwner);
  BevelInner:=bvSpace;
  BevelOuter:=bvSpace;
  FMaxIndex:=High(bCaptions);
  for i := 0 to FMaxIndex do
    if (bCaptions[i].VType=vtAnsiString) then
     FButtons[i]:=NewButton(ansistring(bCaptions[i].VAnsiString), i*ButtonWidth)
    else if (bCaptions[i].VType=vtChar) then
     FButtons[i]:=NewButton(Char(bCaptions[i].VChar), i*ButtonWidth);
  Height:=ButtonWidth;
  Width:=ButtonWidth*Succ(FMaxIndex);
end;

end.


engkin

  • Hero Member
  • *****
  • Posts: 3112
Re: ToolButton changes position!
« Reply #5 on: December 05, 2013, 04:20:28 pm »
According to the source code:

Quote from: $(LazarusDir)\lcl\include\toolbar.inc
{------------------------------------------------------------------------------
  function TToolBar.WrapButtons(var NewWidth, NewHeight: Integer): Boolean;
 
  Position all controls, that have Align=alNone.
  The controls are put from left to right.
...

So simply make sure Align is not alNone. I believe alCustom should work:

Code: [Select]
procedure TForm1.FormCreate(Sender: TObject);
var
  i:integer;
begin
  for i := 0 to ToolBar1.ControlCount - 1 do
      ToolBar1.Controls[i].Align:=alCustom;
...
end;

MoellerCLaus

  • Full Member
  • ***
  • Posts: 114
    • Vig Foreningsprogram
Re: ToolButton changes position!
« Reply #6 on: December 05, 2013, 05:09:33 pm »
Thanks a lot for the constructive suggestions.

I ended with following which works fine. I want to avoid "blanks" in the row of buttons. Toolbar give advantage in adding buttons further disabling the "actions" also works in menus and popupmenu's.

Code: [Select]
procedure TKasseKladdeForm.PageControl1Change(Sender: TObject);
Var A : Integer;
begin
  For A := 0 To Toolbar1.ButtonCount-1 do
    Begin
      Toolbar1.Buttons[A].Align := alCustom;
    end;
  If PageControl1.ActivePageIndex = 0 Then
    Begin  // Kassekladde
      NytBilag.Visible                := True;
      Slet.Visible                    := True;
      RedigerAfstemningskonti.Visible := True;
      TjekKassekladde.Visible         := True;
      BogFoer.Visible                 := True;
      BogFoerAlle.Visible             := True;
      VisAfstemningsKonti.Visible     := True;
      Udskriv_Kassekladde.Visible     := True;
      Udskriv_Kontoplan.Visible       := False;
    end
  Else if PageControl1.ActivePageIndex = 1 Then
    Begin  // Kontoplan
      NytBilag.Visible                := False;
      Slet.Visible                    := False;
      RedigerAfstemningskonti.Visible := False;
      TjekKassekladde.Visible         := False;
      BogFoer.Visible                 := False;
      BogFoerAlle.Visible             := False;
      VisAfstemningsKonti.Visible     := False;
      Udskriv_Kassekladde.Visible     := False;
      Udskriv_Kontoplan.Visible       := True;

    end
  Else if PageControl1.ActivePageIndex = 2 Then
    Begin  // Posteringsoversigt
      NytBilag.Visible                := False;
      Slet.Visible                    := False;
      RedigerAfstemningskonti.Visible := False;
      TjekKassekladde.Visible         := False;
      BogFoer.Visible                 := False;
      BogFoerAlle.Visible             := False;
      VisAfstemningsKonti.Visible     := False;
      Udskriv_Kassekladde.Visible     := False;
      Udskriv_Kontoplan.Visible       := False;
      IndlaesPostering;
    end
  Else if PageControl1.ActivePageIndex = 3 Then
    Begin  // Indstillinger
      NytBilag.Visible                := False;
      Slet.Visible                    := False;
      RedigerAfstemningskonti.Visible := False;
      TjekKassekladde.Visible         := False;
      BogFoer.Visible                 := False;
      BogFoerAlle.Visible             := False;
      VisAfstemningsKonti.Visible     := False;
      Udskriv_Kassekladde.Visible     := False;
      Udskriv_Kontoplan.Visible       := False;
    end;
  For A := 0 To Toolbar1.ButtonCount-1 do
    Begin
      Toolbar1.Buttons[A].Align := alNone;
    end;
end;

wp

  • Hero Member
  • *****
  • Posts: 12910
Re: ToolButton changes position!
« Reply #7 on: December 05, 2013, 05:26:00 pm »
If I understand your problem correctly you want to hide toolbuttons, but keep the order of the visible buttons. When you turn the hidden buttons on again you expect them to be at their old places.

As I found out in my experiments, the alCustom method proposed above does not work properly once I had rearranged the buttons at design time.

Maybe this procedure helps you:
Code: [Select]
type
  TMyToolbutton = class(TToolButton);

procedure SetToolButtonIndex(AToolbutton: TToolButton; Value: Integer);
var
  btns: array of TToolbutton;
  i, n, currentIdx : integer;
  toolbar: TToolbar;
begin
  if not AToolbutton.Visible then
    exit;

  currentIdx := AToolButton.Index;
  toolbar := TMyToolbutton(AToolButton).FToolbar;

  // Create a separate list of current toolbuttons, invisible ones marked by nil
  SetLength(btns, toolbar.ButtonCount);
  for i:=0 to toolbar.ButtonCount-1 do
    if toolbar.Buttons[i].Visible then
      btns[i] := toolbar.Buttons[i]
    else
      btns[i] := nil;

  // Swap "AToolButton" with the button currently at index "Value"
  btns[currentIdx] := btns[Value];
  btns[Value] := AToolButton;

  // Now, going from the last to the first button, move each visible button to
  // the left of the toolbar. This reorders the buttons in the requested order.
  for i:=Length(btns)-1 downto 0 do
    if btns[i] <> nil then
      btns[i].Left := -1;
end;

The basic trick is to create a list of the visible toolbuttons in the requested order, and then, beginning at the end of the list, move each button beyond the left edge of the toolbar which makes this button the first one. After this loop is finished, all visible buttons will be in their correct order.

Call this procedure for all toolbuttons whenever you show/hide toolbuttons, like here:
Code: [Select]
procedure TForm1.CheckBox1Change(Sender: TObject);
begin
  Toolbutton1.Visible := Checkbox1.Checked;
  Toolbutton3.Visible := Checkbox1.Checked;
  Toolbutton5.Visible := Checkbox1.Checked;
  SetToolButtonIndex(Toolbutton1, 0);
  SetToolButtonIndex(Toolbutton2, 1);
  SetToolButtonIndex(Toolbutton3, 2);
  SetToolButtonIndex(Toolbutton4, 3);
  SetToolButtonIndex(Toolbutton5, 4);
  SetToolButtonIndex(Toolbutton6, 5);
  SetToolButtonIndex(Toolbutton7, 6);
end;

engkin

  • Hero Member
  • *****
  • Posts: 3112
Re: ToolButton changes position!
« Reply #8 on: December 05, 2013, 06:20:19 pm »
Whatever method you decide to use is fine. If you don't mind I tried to figure out an easier way to maintain button visibility:

Code: [Select]
procedure TKasseKladdeForm.PageControl1Change(Sender: TObject);
var
  Idx: Integer;
...
  Idx := PageControl1.ActivePageIndex;

// 0: Kassekladde
// 1: Kontoplan
// 2: Posteringsoversigt
// 3: Indstillinger

  NytBilag.Visible                := Idx = 0;
  Slet.Visible                    := Idx = 0;
  RedigerAfstemningskonti.Visible := Idx = 0;
  TjekKassekladde.Visible         := Idx = 0;
  BogFoer.Visible                 := Idx = 0;
  BogFoerAlle.Visible             := Idx = 0;
  VisAfstemningsKonti.Visible     := Idx = 0;
  Udskriv_Kassekladde.Visible     := Idx = 0;
  Udskriv_Kontoplan.Visible       := Idx = 1;

  if Idx = 3 then
    IndlaesPostering;
...
end;

I don't know if it's any better.

MoellerCLaus

  • Full Member
  • ***
  • Posts: 114
    • Vig Foreningsprogram
Re: ToolButton changes position!
« Reply #9 on: December 07, 2013, 12:34:06 pm »
 :) Fantastic thank you all. I am delighted and surpriced how good advice you get here in this forum.

 

TinyPortal © 2005-2018