Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Tutorials und Kurse (https://www.delphipraxis.net/36-tutorials-und-kurse/)
-   -   ListView natürliches Scrollen mit Finger | Touchscreen (https://www.delphipraxis.net/185684-listview-natuerliches-scrollen-mit-finger-%7C-touchscreen.html)

TTF 29. Jun 2015 16:00

ListView natürliches Scrollen mit Finger | Touchscreen
 
Stopp, bevor du jetzt sofort anfängst zu sagen: "Das ist doch sowieso schon drin!".
Das stimmt, aber es gibt Fälle, in denen man Einfluss auf das gesamte Scroll-Verhalten haben muss, den man bei den Gesture Events nicht hat.
Ich probierte lange herum mit den Gesture Events, bis ich mir ein Herz fasste und alles selber schrieb.

Hier zeige ich euch, wie man ein natürliches Scroll-Verhalten mittels Mouse Events implementiert.
Also eigentlich ist es gar kein richtiges Tutorial. Ich wollte einfach mal den Code ins Netz bringen; vielleicht hilft er ja jemandem...

Ich behaupte nicht, dass mein Code besonders schön(!:lol:) oder effizient ist, also, wenn ihr Verbesserungsvorschläge habt, schreibt sie!

Code:
FMouseDown : Boolean;
FStartMousePoint : TPoint;
FThisMousePoint : TPoint;
FLastMousePoint : TPoint;
FStartTime : Cardinal;


procedure TForm1.ListView1MouseMove(Sender: TObject; Shift: TShiftState; X,
  Y: Integer);
begin
  if FMouseDown then
  begin
    FLastMousePoint := FThisMousePoint;
    FThisMousePoint := TPoint.Create(X,Y);

    if (Y - FLastMousePoint.Y > 0) then
    begin
      //Wenn die Richtung zum ersten Mal positiv ist
      if (Vorzeichen <> Plus) then
      begin
        FStartMousePoint := FThisMousePoint;
        //Zeit stoppen
        FStartTime := GetTickCount();
      end;
      Vorzeichen := Plus;
    end
    else if (Y - FLastMousePoint.Y < 0) then
    begin
      //Wenn die Richtung zum ersten Mal negativ ist
      if (Vorzeichen <> Minus) then
      begin
        FStartMousePoint := FThisMousePoint;
        //Zeit stoppen
        FStartTime := GetTickCount();
      end;
      Vorzeichen := Minus;
    end;

    //Deselect item
    if Assigned(ListView1.Selected) then
      ListView1.Selected.MakeVisible(false);

    //Scroll
    ListView1.Scroll(0, FLastMousePoint.Y - FThisMousePoint.Y);
  end;
end;

procedure TForm1.ListView1MouseDown(Sender: TObject; Button: TMouseButton;
  Shift: TShiftState; X, Y: Integer);
begin
  FMouseDown := true;
  FStartMousePoint := TPoint.Create(X,Y);
  FThisMousePoint := FStartMousePoint;
  FLastMousePoint := FThisMousePoint;
  //Zeit stoppen
  FStartTime := GetTickCount();

   //Deselect item
  if Assigned(ListView1.Selected) then
    ListView1.Selected.MakeVisible(false);
end;

//Wenn ich nur von der ListView den MouseEvent nähme, würde ein Absetzen des Fingers auch nur auf der ListView registriert...
//Wer nicht weiss woher ich den Event habe: AppEvents ist ne Komponente und das ist der OnMessage Event
procedure TForm1.AppEventsMessage(var Msg: tagMSG; var Handled: Boolean);
var
  i    : Integer;
  dTime : Double;
  dPos : Integer;
  speed : Integer;
procedure Delay(Milliseconds: Integer);
  {by Hagen Reddmann}
var
  Tick: DWORD;
  Event: THandle;
begin
  Event := CreateEvent(nil, False, False, nil);
  try
    Tick := GetTickCount + DWORD(Milliseconds);
    while (Milliseconds > 0) and
      (MsgWaitForMultipleObjects(1, Event, False, Milliseconds,
      QS_ALLINPUT) <> WAIT_TIMEOUT) do
    begin
      Application.ProcessMessages;
      Milliseconds := Tick - GetTickCount;
    end;
  finally
    CloseHandle(Event);
  end;
end;
begin
  if (Msg.message = WM_LBUTTONUP) and (FMouseDown) then
  begin
    FMouseDown := false;

    //Get speed
    dTime := (GetTickCount() - FStartTime) / 100;//Resultatgrösse optimieren
    dPos := (FStartMousePoint.Y - FThisMousePoint.Y);
    if (dTime <> 0) then
      speed := Round(dPos / dTime)
    else
      exit;

    //Deselect item
    if Assigned(ListView1.Selected)then
      ListView1.Selected.MakeVisible(false);

    //Decelerate
    if (Vorzeichen = Minus) then
      for i := speed downto 0 do //+
      begin
        if FMouseDown = false then
          Delay(5)
        else
          exit;
        ListView1.Scroll(0, i DIV 15);
      end
    else
      for i := speed to 0 do     //-
      begin
        if FMouseDown = false then
          Delay(5)
        else
          exit;
        ListView1.Scroll(0, i DIV 15);
      end;
  end;
end;

Der schöne Günther 29. Jun 2015 16:42

AW: ListView natürliches Scrollen mit Finger | Touchscreen
 
Zitat:

es gibt Fälle, in denen man Einfluss auf das gesamte Scroll-Verhalten haben muss, den man bei den Gesture Events nicht hat.
Kannst du einmal erläutern was genau das "gesamte Scroll-Verhalten" ist, bzw. was du erreichen wolltest?


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