[gelöst] Toolbar - Position der Buttons zur Laufzeit definieren

Rund um die LCL und andere Komponenten
oleg
Beiträge: 28
Registriert: So 6. Okt 2019, 17:04
OS, Lazarus, FPC: Win10Pro-(Laz 2.2.0 - FPC 3.2.0)-Rasp4(8GB)+MySQL+GITEA 1.20.2 <-> GIT 2.44.0
Wohnort: Leipzig

[gelöst] Toolbar - Position der Buttons zur Laufzeit definieren

Beitrag von oleg »

Hallo liebe Community,
ich habe ein Problem mit der Zuweisung der Position der Buttons innerhalb einer Toolbar. Einige Buttons werden zur Laufzeit nach Bedarf unsichtbar gemacht, da diese in bestimmten Konfigurationen keinen Sinn ergeben.
Die Reihenfolge der Buttons ist dadurch nicht mehr einheitlich. Der Versuch die Buttons manuell per Code zu sortieren funktioniert nicht. Vielleicht verstehe ich gerade auch den Index der Buttons nicht. Buttons rücken ja nach links, das nächste rück nach .. usw.
Die Tags waren auch schon einheitlich durchnummeriert und auch die Trenner bewegen sich unkontrolliert.
Wie kann man das so lösen, dass die Toolbar.Buttons immer in der definierten Reihenfolge angezeigt werden ?

Code: Alles auswählen

  procedure OrderToolButtons (aToolBar: TToolBar);
  var
    Index : Integer;
    btn1, btn2 : TToolButton;
  begin
      for Index := 0 to aToolBar.ButtonCount -2 do
        begin
          btn1 := aToolBar.Buttons[Index];
          btn2 := aToolBar.Buttons[Index + 1];
          if ((btn1.Tag > 0) and (btn1.Tag < btn2.Tag)) then
              begin
                 btn2.Left := btn1.Left -1;
              end;
        end;
   end;                        
Die Sortierung möchte ich am einfachsten mit den tb.Tags umsetzen

Code: Alles auswählen

// Tags der ToolButtons setzen
   ToolButton_1.Tag   := 1;
   ToolButton_2.Tag   := 2;
   ToolButton_x1.Tag  := 0; // Trenner
   ToolButton_3.Tag   := 3;
   ToolButton_x2.Tag  := 0; // Trenner
   ToolButton_4.Tag   := 4;
   ToolButton_x3.Tag  := 0; // Trenner
   ToolButton_5.Tag   := 5;
   ToolButton_6.Tag   := 6;
   ToolButton_x4.Tag  := 0; // Trenner
   ToolButton_7.Tag   := 7; // <- visible = true / false
   ToolButton_8.Tag   := 8; // <- visible = true / false | tb wandert bei jedem Aufruf um eine Position nach rechts ?
   ToolButton_x5.Tag  := 0; // Trenner
   ToolButton_9.Tag   := 9;
   
begin
  OrderToolButtons(Toolbar_1);
end;  
Zuletzt geändert von oleg am Mi 3. Mai 2023, 06:45, insgesamt 1-mal geändert.

wp_xyz
Beiträge: 4893
Registriert: Fr 8. Apr 2011, 09:01

Re: Toolbar - Position der Buttons zur Laufzeit definieren

Beitrag von wp_xyz »

In meinem beigefügten Mini-Projekt funktioniert das Unsichtbarmachen von einzelnen Toolbuttons. Jeder Toolbutton, der unsichtbar/sichtbar gemacht werden soll, hat einen Tag-Wert. Der Event-Handler sucht den Button mit dem gewünschten Tag und schaltet dann dessen Sichtbarkeit um.

Was ist bei dir anders?
Dateianhänge
toolbar_hide_buttons.zip
(5.69 KiB) 33-mal heruntergeladen

Benutzeravatar
KodeZwerg
Beiträge: 100
Registriert: Mo 6. Feb 2023, 11:04

Re: Toolbar - Position der Buttons zur Laufzeit definieren

Beitrag von KodeZwerg »

Ich habe nicht wp's Lösung angeschaut, selbst ist der Mann :-)
Mein Versuch sieht so aus:

Code: Alles auswählen

procedure ToolBarButtonOrder(const AToolBar: TToolBar);
type
  TArr = Array of Integer;
  function NextWidth(const AArr: TArr; const AIndex: Integer): Integer;
  var
    i: Integer;
  begin
    Result := 0;
    if (AIndex < 1) then
      Exit;
    for i := 1 to AIndex do
      if AToolBar.Buttons[i].Visible then
        Result += AArr[i];
  end;
var
  i: Integer;
  Arr: TArr;
begin
  SetLength(Arr, AToolBar.ButtonCount);
  for i := 0 to Pred(AToolBar.ButtonCount) do
    begin
      Arr[i] := AToolBar.Buttons[i].Width;
      AToolBar.Buttons[i].Align := alCustom;
      AToolBar.Buttons[i].Left := NextWidth(Arr, i);
    end;
end;

procedure TForm1.Button1Click(Sender: TObject);
begin
  Self.ToolButton2.Visible := False;
  ToolBarButtonOrder(ToolBar1);
end;

procedure TForm1.Button2Click(Sender: TObject);
begin
  Self.ToolButton2.Visible := True;
  ToolBarButtonOrder(ToolBar1);
end;
(mini update um es generisch zu machen)
Zuletzt geändert von KodeZwerg am Sa 39. Okt 6043, 29:87, insgesamt 43-mal geändert.

oleg
Beiträge: 28
Registriert: So 6. Okt 2019, 17:04
OS, Lazarus, FPC: Win10Pro-(Laz 2.2.0 - FPC 3.2.0)-Rasp4(8GB)+MySQL+GITEA 1.20.2 <-> GIT 2.44.0
Wohnort: Leipzig

Re: Toolbar - Position der Buttons zur Laufzeit definieren

Beitrag von oleg »

Danke schon mal für die Antworten: habe beide Varianten geprüft um hinter das Problem zu kommen.

@wp_xyz: habe dein Projekt angeschaut. Da sind mir zwei Dinge aufgefallen.
  • Code: Alles auswählen

    for i := 0 to Toolbar1.ButtonCount -1 do
    funktioniert in deinem Projekt bei mir gibt es einen Indexfehler

    Code: Alles auswählen

    for Index := 0 to aToolBar.ButtonCount -2 do
  • Das Miniprojekt funktioniert zwar, macht aber nichts mit der Sortierung der Buttons in der Toolbar. Lediglich die Anzeige, die wird bei mir aber von seperaten Routinen geprüft und gesetzt.

    Code: Alles auswählen

    var
      i, idx: Integer;
    begin
      idx := Index+1;
      for i := 0 to Toolbar1.ButtonCount-1 do
        if Toolbar1.Buttons[i].Tag = idx then
          Toolbar1.Buttons[i].Visible := CheckGroup1.Checked[Index];
    end;
@KodeZwerg: Alle Achtung. In der kurzen Zeit, so eine Routine. Ich vermute mal das soll neuzeichnen. Bin da noch nicht ganz durchgestiegen. Ich hatte gehofft, dass man die Buttons einfach per Index auf die richtige Position setzen kann.

Ich häng mal die Ergebnisse dran, da kann man das vielleicht eher nachvollziehen. Aktuell hab ich jetzt wieder alle Tags gesetzt, ach die von den Trennern (Falls das wichtig ist).


Original aus der IDE:
original_ide.jpg
original_ide.jpg (10.37 KiB) 931 mal betrachtet

Meine Lösung:
unsortiert.jpg
unsortiert.jpg (10.52 KiB) 931 mal betrachtet
KodeZwerg:
verschoben2.jpg
verschoben2.jpg (9.85 KiB) 931 mal betrachtet

Benutzeravatar
KodeZwerg
Beiträge: 100
Registriert: Mo 6. Feb 2023, 11:04

Re: Toolbar - Position der Buttons zur Laufzeit definieren

Beitrag von KodeZwerg »

Ich gebe zu, getestet habe ich es nur mit beschriftungen auf den Knöpfen, mit bildchen habe ich nicht experimentiert.
Meine methode macht eigentlich nichts weiter als das automatische alignment abzuschalten und die buttons selbst anzuordnen, nicht nach "tag" sondern nach der reihenfolge wie du sie in der IDE erzeugt hast.
Häng doch mal ein projekt zum rumspielen ran, damit kann man besser experimentieren.
Zuletzt geändert von KodeZwerg am Sa 39. Okt 6043, 29:87, insgesamt 43-mal geändert.

wp_xyz
Beiträge: 4893
Registriert: Fr 8. Apr 2011, 09:01

Re: Toolbar - Position der Buttons zur Laufzeit definieren

Beitrag von wp_xyz »

oleg hat geschrieben:
Do 27. Apr 2023, 16:53
  • Code: Alles auswählen

    for i := 0 to Toolbar1.ButtonCount -1 do
    funktioniert in deinem Projekt bei mir gibt es einen Indexfehler
Ich weiß natürlich nicht, was sonst noch alles passiert in deinem Projekt.
oleg hat geschrieben:
Do 27. Apr 2023, 16:53
Das Miniprojekt funktioniert zwar, macht aber nichts mit der Sortierung der Buttons in der Toolbar.
Ich hatte deine Frage so verstanden, dass du Buttons unsichtbar schalten willst und dass beim Wiedersichtbarmachen die Reihenfolge nicht mehr stimmt und du deswegen umsortieren musst. In meinem Projekt habe ich gezeigt, dass die Reihenfolge schon gar nicht verändert wird, und habe mich deshalb gar nicht um die Sortierung gekümmert.

Benutzeravatar
theo
Beiträge: 10499
Registriert: Mo 11. Sep 2006, 19:01

Re: Toolbar - Position der Buttons zur Laufzeit definieren

Beitrag von theo »

Vielleicht sollte man mal nach dem Widgetset fragen.
Bei mir auf GTK2 gibt es beispielsweise eine Umsortierung nach Hide-Show mit den Separator Style Buttons.
Der Separator rutsch eins nach rechts (aber nur beim ersten Mal).
Ich halte das für einen Bug.

P.S. Bezieht sich auf einen eigenen Test von mir, nicht auf das Bsp. von wp_xyz

Benutzeravatar
KodeZwerg
Beiträge: 100
Registriert: Mo 6. Feb 2023, 11:04

Re: Toolbar - Position der Buttons zur Laufzeit definieren

Beitrag von KodeZwerg »

Um zu zeigen wie ich meins getestet habe, 2 bildchen im Anhang,
(sorry wegen der dunklen Farbe)
Dateianhänge
nachdem ich button2 drückte
nachdem ich button2 drückte
Bild_2023-04-27_174002479.png (2.62 KiB) 912 mal betrachtet
nachdem ich button1 drückte
nachdem ich button1 drückte
Bild_2023-04-27_173939999.png (2.69 KiB) 912 mal betrachtet
Zuletzt geändert von KodeZwerg am Sa 39. Okt 6043, 29:87, insgesamt 43-mal geändert.

Benutzeravatar
KodeZwerg
Beiträge: 100
Registriert: Mo 6. Feb 2023, 11:04

Re: Toolbar - Position der Buttons zur Laufzeit definieren

Beitrag von KodeZwerg »

Nun wird es nach Tag sortiert.
Warnung! Es wird nicht geprüft ob etwas einen gleichen Tag hat!
Warnung! Jeder Button muss seinen eigenen Tag besitzen!
Warnung! Es muss wie in einem Array bei 0 begonnen und aufsteigend benannt werden!
Um es kurz zu machen, wenn man 4 Buttons hat, vergebe von 0 bis 3 Tags.

Code: Alles auswählen

procedure ToolBarButtonOrder(const AToolBar: TToolBar);
type
  TArr = Array of Integer;
  TBArr = Array of TToolButton;
  function NextWidth(const ABArr: TBArr; const AArr: TArr; const AIndex: Integer): Integer;
  var
    i: Integer;
  begin
    Result := 0;
    if (AIndex < 1) then
      Exit;
    for i := 1 to AIndex do
      if ABArr[i].Visible then
        Result += AArr[i];
  end;
var
  i: Integer;
  Arr: TArr;
  BArr: TBArr;
begin
  SetLength(Arr, AToolBar.ButtonCount);
  SetLength(BArr, AToolBar.ButtonCount);
  for i := 0 to Pred(AToolBar.ButtonCount) do
    begin
      BArr[AToolBar.Buttons[i].Tag] := AToolBar.Buttons[i];
      Arr[AToolBar.Buttons[i].Tag] := AToolBar.Buttons[i].Width;
    end;
  for i := Low(BArr) to High(BArr) do
    begin
      BArr[i].Align := alNone;
      BArr[i].Left := NextWidth(BArr, Arr, i);
    end;
end;
Zuletzt geändert von KodeZwerg am Do 27. Apr 2023, 18:54, insgesamt 3-mal geändert.
Zuletzt geändert von KodeZwerg am Sa 39. Okt 6043, 29:87, insgesamt 43-mal geändert.

oleg
Beiträge: 28
Registriert: So 6. Okt 2019, 17:04
OS, Lazarus, FPC: Win10Pro-(Laz 2.2.0 - FPC 3.2.0)-Rasp4(8GB)+MySQL+GITEA 1.20.2 <-> GIT 2.44.0
Wohnort: Leipzig

Re: Toolbar - Position der Buttons zur Laufzeit definieren

Beitrag von oleg »

Hallo, ihr lieben
schon mal vielen dank für Eure Hilfe und Zeit.

Habe gerad mal eine kleine ToolBar in einem neuen MiniProjekt gebaut, Zwei ToolButtons ausgeblendet beim Start, dann mit Button bei Klick Visible gemacht und schon ist mal ein Trenner nach ganz rechts gewandert. Beim zweiten Button Visible schalten sieht man die Positionswechsel schon sehr deutlich.

Die Fragen nebenbei beantwortet: Ich arbeite auf Windos 10, Lazarus 2.2.0, Widgetset weiß ich gerade wirklich nicht.
Dateianhänge
toolbar_test.zip
(110.2 KiB) 29-mal heruntergeladen

Benutzeravatar
KodeZwerg
Beiträge: 100
Registriert: Mo 6. Feb 2023, 11:04

Re: Toolbar - Position der Buttons zur Laufzeit definieren

Beitrag von KodeZwerg »

oleg hat geschrieben:
Do 27. Apr 2023, 18:10
Habe gerad mal eine kleine ToolBar in einem neuen MiniProjekt gebaut, Zwei ToolButtons ausgeblendet beim Start, dann mit Button bei Klick Visible gemacht und schon ist mal ein Trenner nach ganz rechts gewandert. Beim zweiten Button Visible schalten sieht man die Positionswechsel schon sehr deutlich.
Im Anhang ist Dein Projekt abgeändert um mit meiner (ebenfalls verbesserten) methode freundschaftlich zu harmonieren.
Ich habe alle deine buttons umbenannt um bei den Tags den überblick nicht zu verlieren :D

Ps: Du musst selbst nochmal prüfen was welcher name nun ist, ich hab lediglich meine methode dafür optimiert.
Dateianhänge
kz_toolbar_test.zip
(110.69 KiB) 29-mal heruntergeladen
Zuletzt geändert von KodeZwerg am Sa 39. Okt 6043, 29:87, insgesamt 43-mal geändert.

oleg
Beiträge: 28
Registriert: So 6. Okt 2019, 17:04
OS, Lazarus, FPC: Win10Pro-(Laz 2.2.0 - FPC 3.2.0)-Rasp4(8GB)+MySQL+GITEA 1.20.2 <-> GIT 2.44.0
Wohnort: Leipzig

Re: Toolbar - Position der Buttons zur Laufzeit definieren

Beitrag von oleg »

KodeZwerg hat geschrieben:
Do 27. Apr 2023, 18:03
Nun wird es nach Tag sortiert.
Warnung! Es wird nicht geprüft ob etwas einen gleichen Tag hat!
Warnung! Jeder Button muss seinen eigenen Tag besitzen!
Warnung! Es muss wie in einem Array bei 0 begonnen und aufsteigend benannt werden!
Um es kurz zu machen, wenn man 4 Buttons hat, vergebe von 0 bis 3 Tags.
Danke dafür: direkt heute gleich noch getestet

Code: Alles auswählen

for i := 0 to ToolBar_RV.ButtonCount -1 do
   begin
      ToolBar_RV.Buttons[i].Tag := i;
   end;
ToolBarButtonOrder(ToolBar_RV);        
Ergebnis mit Bild. Im Vergleich zur Anordnung in der IDE
Dateianhänge
verschoben_test2.jpg
verschoben_test2.jpg (10.11 KiB) 867 mal betrachtet

Benutzeravatar
KodeZwerg
Beiträge: 100
Registriert: Mo 6. Feb 2023, 11:04

Re: Toolbar - Position der Buttons zur Laufzeit definieren

Beitrag von KodeZwerg »

Kein Plan, keine Ahnung was Du da machst.
Hier kannst Du dein Projekt betrachten:
Dateianhänge
nach dem zweiten button
nach dem zweiten button
Bild_2023-04-27_184812585.png (5.75 KiB) 860 mal betrachtet
nach dem obersten button
nach dem obersten button
Bild_2023-04-27_184649647.png (5.42 KiB) 860 mal betrachtet
nach dem programmstart
nach dem programmstart
Bild_2023-04-27_184615841.png (4.73 KiB) 860 mal betrachtet
Zuletzt geändert von KodeZwerg am Sa 39. Okt 6043, 29:87, insgesamt 43-mal geändert.

oleg
Beiträge: 28
Registriert: So 6. Okt 2019, 17:04
OS, Lazarus, FPC: Win10Pro-(Laz 2.2.0 - FPC 3.2.0)-Rasp4(8GB)+MySQL+GITEA 1.20.2 <-> GIT 2.44.0
Wohnort: Leipzig

Re: Toolbar - Position der Buttons zur Laufzeit definieren

Beitrag von oleg »

KodeZwerg hat geschrieben:
Do 27. Apr 2023, 18:32

Im Anhang ist Dein Projekt abgeändert um mit meiner (ebenfalls verbesserten) methode freundschaftlich zu harmonieren.
Ich habe alle deine buttons umbenannt um bei den Tags den überblick nicht zu verlieren :D

Ps: Du musst selbst nochmal prüfen was welcher name nun ist, ich hab lediglich meine methode dafür optimiert.

Danke, das sieht jetzt ziemlich vielversprechend aus. Muss ich aber morgen noch mal ausführlich testen. Ich glaube die Lösung ist, das die Tags wie in der Reihenfolge der IDE gesetzt werden müssen, nicht stumpf mit einer for Schleife. Das ist zwar erst mal mühselig, aber was soll's :roll:

Benutzeravatar
KodeZwerg
Beiträge: 100
Registriert: Mo 6. Feb 2023, 11:04

Re: Toolbar - Position der Buttons zur Laufzeit definieren

Beitrag von KodeZwerg »

Bitte korrigieren, da hatte sich ein Fehler eingeschlichen (vom testen...)

Code: Alles auswählen

    for i := 1 to AIndex do
Nun sieht alles sauber aus.
Zuletzt geändert von KodeZwerg am Sa 39. Okt 6043, 29:87, insgesamt 43-mal geändert.

Antworten