Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Algorithmen, Datenstrukturen und Klassendesign (https://www.delphipraxis.net/78-algorithmen-datenstrukturen-und-klassendesign/)
-   -   Delphi Buttons/Controls sortieren (https://www.delphipraxis.net/193848-buttons-controls-sortieren.html)

Schwedenbitter 14. Sep 2017 19:47


Buttons/Controls sortieren
 
Liste der Anhänge anzeigen (Anzahl: 1)
Hallo,

ich benutze in einem Programm zur Laufzeit erzeugte Objekte, die ich von TBitBtn abgeleitet habe. Diese Buttons können vom Benutzer verschoben werden so wie in der IDE von Delphi. Das funktioniert ganz gut, aber nicht perfekt.
Ich hätte gern, dass nach jedem Verschieben bzw. hinzukommenden Button die TabOrder angepasst wird. Dabei sollen wie beim Lesen die Buttons oben links eine kleinere TabOrder als die Buttons unten rechts haben. Sonst wird das am Ende unschön. Dazu muss ich die Properties Top/Left verwenden. Eigentlich ist das nichts anderes als ein mehrdimensionales Array?

Hat jemand so etwas schon mal gemacht oder eine Idee, wie ich herangehen/wo suchen kann?

Gruß, Alex

samso 15. Sep 2017 06:59

AW: Buttons/Controls sortieren
 
Ich würde zunächst ein temporäre Liste (LButtons: TList) mit allen Buttons mit füllen. Diese Liste würde ich sortieren und zwar mit einer Vergleichsfunktionen die dafür sorgt, dass die Buttons entsprechend der (gedachten) Zeile und Spalte bewertet werden. Ein Button ist dann in einer anderen Zeile, wenn seine Y-Position mindestens um die Höhe des Buttons von dem anderen Button abweicht.

Delphi-Quellcode:
function BtnCompare(P1, P2: Pointer): Integer;
var
  btn1, btn2: TBitButton;
begin
  btn1 := TObject(P1) as TBitButton;
  btn2 := TObject(P2) as TBitButton;
  if btn1.Top>btn2.Top+btn2.Height
  then // btn1 ist tiefer als btn2
    Result := 1
  else
  if btn1.Top+btn1.Height<btn2.Top
  then // btn1 ist höher als btn2
    Result := -1
  else // die beiden Knöpfe sind in der gleichen Zeile
    Result := btn2.Left-btn1.Left;
end;
Nachdem ich nun ein Liste habe, in der die Buttons in der Lese-Reihenfolgen geordnet sind, brauche ich nur noch durch die Liste zu gehen und alle Taborder-Werte gleich dem Index zu setzen.
Delphi-Quellcode:
  for i:=0 to LButtons.Count-1 do
    TBitButton(LButtons[i]).TabOrder := i;
Danach kann die temporäre Liste wieder frei geben werden.

Schwedenbitter 15. Sep 2017 08:13

AW: Buttons/Controls sortieren
 
Erst einmal danke für die Antwort.

Ich habe jetzt auch gegrübelt und am Ende getrickst. Meine Überlegung war die, dass erst die "Höhe" und dann der linke Abstand entscheidend ist. Also habe ich mir erstmal so beholfen:
Delphi-Quellcode:
With TStringList.Create Do
Try
   Sorted:= True;
   For I:= 0 To Pred(ScrollBox1.ControlCount) Do   // alle Buttons durchgehen
      If (ScrollBox1.Controls[I] Is TBitBtn) Then
      Begin
         lItem:= (ScrollBox1.Controls[I] As TBitBtn);
         AddObject(
            FormatFloat('00000', lItem.Top) +   // von oben nach unten
            FormatFloat('00000', lItem.Left),   // von links nach rechts
            lItem);                              // Object anhängen
      End;
   For I:= 0 To Pred(Count) Do                  // Listenplatz = Taborder
      (Objects[I] As TBitBtn).TabOrder:= I;
Finally
   Free;
 End;
Ich werde mir aber auf jeden Fall Deine Version mal ansehen, weil meine "Wurschprogrammiererei" einen Nachteil hat: ab einer bestimmten Auflösung klappt es nicht mehr.

Eine Nachfrage habe ich dann aber noch:
Irgend jemand muss ja dieses
Delphi-Quellcode:
BtnCompare();
aufrufen. Ich vermute mal, die
Delphi-Quellcode:
TList
. Wie bringe ich sie dazu? Nach meiner Recherche müsste es mit Deinem Codebeispiel so gehen:
Delphi-Quellcode:
TList.Sort(@BtnCompare);
Refresh;
Ist das richtig?

uligerhardt 15. Sep 2017 09:12

AW: Buttons/Controls sortieren
 
Zitat:

Zitat von Schwedenbitter (Beitrag 1381263)
Irgend jemand muss ja dieses
Delphi-Quellcode:
BtnCompare();
aufrufen. Ich vermute mal, die
Delphi-Quellcode:
TList
. Wie bringe ich sie dazu? Nach meiner Recherche müsste es mit Deinem Codebeispiel so gehen:
Delphi-Quellcode:
TList.Sort(@BtnCompare);
Refresh;
Ist das richtig?

Prinzipiell ja, aber schau lieber mal, ob es ohne Klammeraffen geht. Der ist bei Routinenzeigern meistens unnötig oder aber ein Zeichen, dass was nicht passt.

freimatz 18. Sep 2017 14:42

AW: Buttons/Controls sortieren
 
Zitat:

Zitat von Schwedenbitter (Beitrag 1381263)
Ich habe jetzt auch gegrübelt und am Ende getrickst. Meine Überlegung war die, dass erst die "Höhe" und dann der linke Abstand entscheidend ist.

Warum soll das getrickst sein? TabOrder ist eine Dimension, Top und Left zwei. Irgend ein Mapping muss mna ja machen und das von Dir gewählte finde ich ist das sinnvollste.


Alle Zeitangaben in WEZ +1. Es ist jetzt 13:21 Uhr.

Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz