Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   GUI-Design mit VCL / FireMonkey / Common Controls (https://www.delphipraxis.net/18-gui-design-mit-vcl-firemonkey-common-controls/)
-   -   Delphi Listboxeintrag merken und wiederherstellen (https://www.delphipraxis.net/59791-listboxeintrag-merken-und-wiederherstellen.html)

bluescreen25 28. Dez 2005 17:59


Listboxeintrag merken und wiederherstellen
 
Hallo,
ehrlich gesagt weiss ich nicht mehr weiter . Folgende Knobelaufgabe für eine Listbox mit MP3-Files:

Ich möchte den laufenden MP3-Track farbig hinterlegt haben, auch wenn dieser innerhalb der Listbox-Indexe verschoben wird und vor allem muss der richtige Track farbig sein, auch wenn es in der Listbox zwei mal die gleichen Einträge gibt.

1. Im Moment habe ich es nur hinbekommen, das er über den Index immer richtig den laufenden Track farbig anzeigt, aber bei verschieben wieder den falschen, oder
2. das über den PlayList.IndexOf(Playsong) auch bei verschieben der laufende Track immer farbig hinterlegt bleibt, aber bei zwei gleichen Einträgen er immer den ersten gefundenen farbig hinterlegt, obwohl er den zweiten richtigen abspielt.


Hier die Procedure des abspielenden Tracks mit den z.Z. verfügbaren Variablen:
Delphi-Quellcode:
procedure Tmediaplayer_frm.PlayFile(songNumber: integer);
 begin
   if fileexists(Playlist.Strings[songNumber]) then
     begin
      CurrentSong := songNumber;
      playsong := Playlist.Strings[songNumber];
      playsong_name := PlayList_ListBox.Items.Strings[songNumber];
      bassplayer.play(playsong);
      trackbar_position.MaxValue := BassPlayer.length;
      media_scroll_txt_run;
      show_tracktime;
      PlayList_ListBox.Refresh;
     end;
 end;

Hier die procedure für das Halten des Topindex der Listbox im sichtbaren Bereich:
Delphi-Quellcode:
procedure Tmediaplayer_frm.Listbox_track_middle_timerTimer(
  Sender: TObject);
 begin
   if currentsong = 0 then
   PlayList_ListBox.TopIndex := currentsong;//PlayList.IndexOf(Playsong) ;
   if currentsong > 0 then
   PlayList_ListBox.TopIndex := currentsong -5;//PlayList.IndexOf(Playsong)-5 ;
 end;
Hier die procedure für das farbige hinterlegen des laufenden Tracks:
Delphi-Quellcode:
procedure Tmediaplayer_frm.PlayList_ListBoxDrawItem(Control: TWinControl;
  Index: Integer; Rect: TRect; State: TOwnerDrawState);
var
  C:TCanvas;

 begin
   C := TListbox(Control).Canvas;
   C.Font.Assign(TListbox(Control).Font);

    if Index = currentsong then//PlayList.IndexOf(Playsong) then
        C.Brush.Color := clTeal;
      C.Font.Color := clWhite;
    If odSelected in State Then
      C.Brush.Color := clHighlight;
      C.FillRect(Rect);
      C.TextRect(Rect, Rect.Left, Rect.Top, TListbox(Control).Items[Index]);
    If odFocused in State Then
      C.DrawFocusRect(Rect);
 end;
Hier die procedure zum verschieben der Listboxeinträge sowie TStringlist(Playlist):
Delphi-Quellcode:
procedure Tmediaplayer_frm.PlayList_ListBoxDragDrop(Sender,
  Source: TObject; X, Y: Integer);
var
    i,j,k : Integer;
                   //Playlisteneinträge verschieben
 begin
   i := PlayList_ListBox.ItemIndex;
   j := PlayList_ListBox.ItemAtPos(point(x,y),true);

   if j >-1 then //nur drag & drop ,wenn auch item vorhanden
   begin
     PlayList_ListBox.Items.Move(i,j);
     PlayList.Move(i,j);
     PlayList_ListBox.Refresh;
     PlayList_ListBox.Selected[j]:=false;
   end;
 end;

Der komplette Code hier hinterlegt immer den laufenden Track farbig, aber bei verschieben ist es falsch.

Mein Ansatz wäre beim verschieben sich den Track nochmal separat zu merken, aber wie? Der Index ändert sich und es gibt doppelte Einträge in der Listbox, welches PlayList.IndexOf(Playsong) auch ausschliesst. :wall:

Bitte nicht über das Konstrukt meckern, mache Delphi erst seit 6 Wochen.... :oops:

marabu 28. Dez 2005 18:19

Re: Listboxeintrag merken und wiederherstellen
 
Ich habe mir jetzt nur deinen event handler für OnDragDrop() angesehen - warum setzt du denn den korrekten Index nicht nachdem du ein Item verschoben hast?

Delphi-Quellcode:
//Playlisteneinträge verschieben
procedure Tmediaplayer_frm.PlayList_ListBoxDragDrop(Sender,
  Source: TObject; X, Y: Integer);
var
  i,j : Integer;
begin
  i := PlayList_ListBox.ItemIndex;
  j := PlayList_ListBox.ItemAtPos(Point(x, y), true);

  // diesen Test solltest du im OnDragOver machenvorhanden
  if j > -1 then
  begin
    // die nächste Zeile würde bei virtueller Listbox entfallen
    PlayList_ListBox.Items.Move(i,j);
    PlayList.Move(i,j);
    PlayList_ListBox.ItemIndex := j;
  end;
end;
Grüße vom marabu

bluescreen25 28. Dez 2005 18:37

Re: Listboxeintrag merken und wiederherstellen
 
Zitat:

Zitat von marabu
Ich habe mir jetzt nur deinen event handler für OnDragDrop() angesehen - warum setzt du denn den korrekten Index nicht nachdem du ein Item verschoben hast?

Delphi-Quellcode:
//Playlisteneinträge verschieben
procedure Tmediaplayer_frm.PlayList_ListBoxDragDrop(Sender,
  Source: TObject; X, Y: Integer);
var
  i,j : Integer;
begin
  i := PlayList_ListBox.ItemIndex;
  j := PlayList_ListBox.ItemAtPos(Point(x, y), true);

  // diesen Test solltest du im OnDragOver machenvorhanden
  if j > -1 then
  begin
    // die nächste Zeile würde bei virtueller Listbox entfallen
    PlayList_ListBox.Items.Move(i,j);
    PlayList.Move(i,j);
    PlayList_ListBox.ItemIndex := j;
  end;
end;
Grüße vom marabu

Hmm , jetzt hast du doch nur den Index vom verschobenem Item, oder sehe ich das falsch?

Wenn ich Items verschiebe und der abspielende (farbig hinterlegte) Track liegt darüber, macht es nicht aus.

Wenn ich aber ein Item über den abspielenden Track schiebe, dann bekomme ich die Hinterlegung automatisch auf das falsche Item.

Das gleiche gilt ,wenn ich den abspielenden Track selbst verschiebe.Die farbige Hinterlegung bleibt auf den gemerkten Index.

Ich habe zuwenig Möglichkeiten, um den Track ganz genau zu erfassen, denn der Index kann sich ändern und der Name des Index kann zweimal vorhanden sein...lol

Bei deinem Vorschlag müsste ich schaun, welcher Index farbig hinterlegt ist und beim verschieben von irgendwelchen Items müsste ich gucken,ob dieser gewandert ist, nur ich kann diesen nicht richtig "fassen"...


PS: Marabu ist everwhere i look.....großes Dank für dein Interesse....! :xmas:

marabu 28. Dez 2005 19:12

Re: Listboxeintrag merken und wiederherstellen
 
Ja, da bin ich wohl etwas zu kurz gesprungen - irgendwo musst du natürlich deine Variable CurrentSong korrigieren:

Delphi-Quellcode:
//Playlisteneinträge verschieben
procedure Tmediaplayer_frm.PlayList_ListBoxDragDrop(Sender,
  Source: TObject; X, Y: Integer);
var
  i,j : Integer;
begin
  i := PlayList_ListBox.ItemIndex;
  j := PlayList_ListBox.ItemAtPos(Point(x, y), true);

  // diesen Test solltest du im OnDragOver machenvorhanden
  if j > -1 then
  begin
    // die nächste Zeile würde bei virtueller Listbox entfallen
    PlayList_ListBox.Items.Move(i,j);
    PlayList.Move(i,j);
    AdjustCurrentSong(i, j);
    PlayList_ListBox.ItemIndex := j;
  end;
end;

// interval test
procedure TMediaPlayer_frm.AdjustCurrentSong(iFrom, iTo: integer);
begin
  if (CurrentSong < iFrom) and (CurrentSong < iTo)
  or (CurrentSong > iFrom) and (CurrentSong > iTo) then
    Exit; // above and below don't matter
  if iFrom < iTo
    then Dec(CurrentSong) // sliding up
    else Inc(CurrentSong); // sliding down
end;
Ob es jetzt < oder <= bzw. > oder >= sein muss, dass überlasse ich dir zum Grübeln.

marabu

bluescreen25 28. Dez 2005 19:27

Re: Listboxeintrag merken und wiederherstellen
 
was hälste hiervon ?Habe auch mal meinen Kopf überanstrengt:

Delphi-Quellcode:
procedure Tmediaplayer_frm.PlayList_ListBoxDragDrop(Sender,
  Source: TObject; X, Y: Integer);
var
    i,j,k : Integer;
                   //Playlisteneinträge verschieben
 begin
   i := PlayList_ListBox.ItemIndex;
   j := PlayList_ListBox.ItemAtPos(point(x,y),true);
   k := currentsong;

   if j >-1 then //nur drag & drop ,wenn auch item vorhanden
   begin

     if i = k then   // hatte ich noch vergessen !
     currentsong := j;
     
     if (i > k) and (j <= k) then
     currentsong := k +1;

     if (i < k) and (j >= k) then
     currentsong := k -1;

     PlayList_ListBox.Items.Move(i,j);
     PlayList.Move(i,j);
     PlayList_ListBox.Refresh;
     PlayList_ListBox.Selected[j]:=false;
   end;
 end;

marabu 28. Dez 2005 19:46

Re: Listboxeintrag merken und wiederherstellen
 
Respekt.

Warum schaltest du die Selektion von item j ab? Wenn bei deiner ListBox MultiSelect = TRUE ist, dann gehört das so - wenn nicht, dann sollte es auch ohne gehen.

marabu

bluescreen25 28. Dez 2005 20:01

Re: Listboxeintrag merken und wiederherstellen
 
Zitat:

Zitat von marabu
Respekt.

Warum schaltest du die Selektion von item j ab? Wenn bei deiner ListBox MultiSelect = TRUE ist, dann gehört das so - wenn nicht, dann sollte es auch ohne gehen.

marabu

weil j ja auch der abspielende Track sein kann und der wäre dann farbig grün hinterlegt und nochmal blau weil selektiert.

Und selektiert muss es ja nicht mehr sein, wenn mein Verschieben fertig ist.
Das einzige Mal wo ich das Selektieren wieder einblende, aber das in einer anderen procedure, ist wenn ich einen Track selektiere und dann lösche, dann wird der nächste gleich wieder selektiert.

Ich habe kein Mehrfachselektieren zugelassen....hatte damit schlechte Erfahrungen gemacht, wegen der Indexe....Lol....aber im Ernst...für meine Anwendung brauch das nicht.


Vielen Dank nochmal.....ich hatte die Eingebung irgendwie bei der Fragestellung hier im Thread...komisch!


Übrigens hatte ich noch eine Möglichkeit vergessen und noch eben hinzugefügt.(siehe Code)

Grüße aus Geldern


Alle Zeitangaben in WEZ +1. Es ist jetzt 14:50 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