EtheaDev / StyledComponents

Components similar to Delphi VCL Buttons, Toolbar, DbNavigator, BindNavigator, ButtonGroup and CategoryButtons with Custom Graphic Styles, and an advanced, full-customizable TaskDialog, also with animations!
Apache License 2.0
152 stars 34 forks source link

Run time changing visibility of TStyledToolbarButtons on TStyledToolbar #31

Closed lancerasmussen closed 2 months ago

lancerasmussen commented 2 months ago

I have a StyledToolBar with 12 TStyledToolbarButtons.
I set the visibility of those toolbarbuttons based on if the datafile is open or not. So at the app startup, I set the visibility of 7 of them to false. On Datafile Open, change visibility to false on two of the 5 initially set to true and then the remaining to true.

The order of the buttons keeps getting jumbled around when doing this and I'm not seeing a clear way to keep or designate the index of these.

I've tried:

btnMenuFile.ComponentIndex := 0;
btnMenuOptions.ComponentIndex := 1;
btnMenuMaintenance.ComponentIndex := 2;
btnMenuSetup.ComponentIndex := 3;
btnMenuCertify.ComponentIndex := 4;
btnMenuWeekly.ComponentIndex := 5;
btnMenuBrackets.ComponentIndex := 6;
btnMenuReports.ComponentIndex := 7;
btnMenuTasks.ComponentIndex := 8;
btnMenuUtilities.ComponentIndex := 9;
btnMenuDev.ComponentIndex := 10;
btnMenuHelp.ComponentIndex := 11;
btnMenuMyMenu.ComponentIndex := 12;

btnMenuFile.Visible := True;
btnMenuOptions.Visible := True;
btnMenuMaintenance.Visible := True;
btnMenuSetup.Visible := True;
btnMenuCertify.Visible := True;
btnMenuWeekly.Visible := True;
btnMenuBrackets.Visible := True;
btnMenuReports.Visible := True;
btnMenuTasks.Visible := True;
btnMenuUtilities.Visible := True;
btnMenuDev.Visible := True;
btnMenuHelp.Visible := True;
btnMenuMyMenu.Visible := True;

To set them all to true at run time, then set visibility appropriate if data file is open or false.

On app start, datafile open is false and makes visible Index 0, 1, 2, 4 and 11 buttons. Usually works on app startup.  But when datafile is open, index 1 and 2 are set to false and the rest true.  But what I get is random, such as 0,3,12,4,6,9,7,8,5,11.
In the same session, if I close the datafile, usually I get the right order, but when opening the datafile, I get a whole new order of buttons.

Design time is in correct order.   

Am I missing how to set these correctly or how can I force the order I want in run time?
lancerasmussen commented 2 months ago

Note: I've tried things like iterating through the list of buttons to save in a TList, then free the buttons from the toolbar, then add them back in tag order (that I set in design time) and I get a stack overflow error. Also tried making the parent nil and set back the parent and same stack overflow error.

carloBarazzetta commented 2 months ago

Hello Lance, can you send me a little project for the issue so I can debug and try to resolve?

lancerasmussen commented 2 months ago

Here is a small project that has some examples where TToolbar behaves and StyledToolbar doesn't

BadMenuIndexing.zip

carloBarazzetta commented 2 months ago

After Removing line at 1426 from Vcl.StyledToolbar.pas RemoveControl(Control); it's seems to works...

carloBarazzetta commented 2 months ago

Fixed in 3.6.2, please confirm ;-)

lancerasmussen commented 2 months ago

This is the function I wrote to try to keep the menu in order based on tag, but doesn't seem to always work. I put in the start of the data is open or closed function then iterate items I want visible or not.

procedure TfrmMenu.RearrangeToolBarButtons(ToolBar: TStyledToolBar); var I,J: Integer; TagCheck: integer; temp_menu: TStyledToolbar; Idx: integer; cap: string; begin // Store the buttons in a temporary list temp_menu := TStyledToolbar.Create(self); try // Move the menu buttons to the temp menu while ToolBar.ButtonCount > 0 do ToolBar.Buttons[0].Parent := temp_Menu;

idx := 0;
// Iterate through the tempmenu buttons in order of tag until all moved;
TagCheck := 0;
while temp_Menu.ButtonCount > 0 do begin
  for I := temp_menu.ButtonCount-1 downto 0 do begin
    if temp_menu.Buttons[I].Tag = TagCheck then begin
      temp_menu.Buttons[I].ComponentIndex:= idx;
      temp_menu.Buttons[I].Parent:= ToolBar;
      cap := ToolBar.Buttons[idx].Caption;
      ToolBar.Buttons[idx].Left := idx * ToolBar.Buttons[idx].Width;  // Reposition
      inc(Idx);
    end;
  end;
  inc(TagCheck);
end;

finally temp_Menu.Free; end; end;

carloBarazzetta commented 2 months ago

My StyledToolBar inherits from TCustomFlowPanel, so the position of the "components" inside are managed by this class. Try to write a RearrangeToolBarButtons using a TFlowPanel and TButton, to check if the StyledToolbar introduces something wrong about the button position...

lancerasmussen commented 2 months ago

Created a pull request that assigns a sort order property to the buttons in the toolbar and added a procedure for the toolbar to sort the buttons.

lancerasmussen commented 2 months ago

Added pull request that has property and then a procedure to resolve.