فهرست منبع

scrolling: drag thumb

mattias 5 ماه پیش
والد
کامیت
5257c22a30
4فایلهای تغییر یافته به همراه96 افزوده شده و 57 حذف شده
  1. 7 8
      src/base/fresnel.dom.pas
  2. 2 25
      src/base/fresnel.events.pas
  3. 46 21
      src/base/fresnel.renderer.pas
  4. 41 3
      src/gtk3/fresnel.gtk3.pas

+ 7 - 8
src/base/fresnel.dom.pas

@@ -1606,9 +1606,9 @@ type
     Color: TFPColor;
     Box: TFresnelRect; // same coord system as parent, e.g. parent.UsedBorderBox
     MouseDownHit: THit;
-    MouseDownPos: TFresnelLength;
+    MouseDownPosition, MouseDownGrabPos: TFresnelLength;
     constructor Create(TheElement: TFresnelElement; aHorizontal: boolean); overload;
-    function GetHit(const X, Y: TFresnelLength; out aPosition: TFresnelLength): THit; virtual; abstract;
+    function GetHit(const X, Y: TFresnelLength; Nearest: boolean; out aPosition: TFresnelLength): THit; virtual; abstract;
     property Horizontal: boolean read FHorizontal;
   end;
 
@@ -7441,7 +7441,8 @@ begin
   begin
     // these events have ClientPos and are affected by pointer capture
 
-    CaptEl:=GetPointerCaptureEl(nil);
+    CaptEl:=GetPointerCaptureEl(WSData.PointerId);
+    writeln('TFresnelViewport.WSMouseXY CaptEl=',DbgSName(CaptEl));
     if CaptEl<>nil then
       El:=CaptEl
     else if length(NewHoverElements)>0 then
@@ -7541,16 +7542,14 @@ procedure TFresnelViewport.DispatchPointerCapture(El: TFresnelElement; Lost: boo
   const aPointerId: TFreHandle);
 var
   MouseData: TFresnelMouseEventInit;
-  PointerData: TFresnelPointerEventInit;
   Evt: TFresnelPointerEvent;
 begin
   MouseData:=Default(TFresnelMouseEventInit);
-  PointerData:=Default(TFresnelPointerEventInit);
-  PointerData.Id:=aPointerId;
+  MouseData.PointerId:=aPointerId;
   if Lost then
-    Evt:=TFresnelLostPointerCapture.Create(MouseData,PointerData)
+    Evt:=TFresnelLostPointerCapture.Create(MouseData)
   else
-    Evt:=TFresnelGetPointerCapture.Create(MouseData,PointerData);
+    Evt:=TFresnelGetPointerCapture.Create(MouseData);
   try
     El.DispatchEvent(Evt);
   finally

+ 2 - 25
src/base/fresnel.events.pas

@@ -183,19 +183,11 @@ Type
   TFLMouseEvent = TFresnelMouseEvent;
   TFresnelMouseEventHandler = Procedure(Event: TFresnelMouseEvent) of object;
 
-  TFresnelPointerEventInit = Record
-    Id: TFreHandle;
-  end;
-
   { TFresnelPointerEvent }
 
   TFresnelPointerEvent = class(TFresnelMouseEvent)
-  protected
-    FPointerInit : TFresnelPointerEventInit;
   public
-    Constructor Create(const aMouseInit: TFresnelMouseEventInit; const aPointerInit: TFresnelPointerEventInit); overload;
-    Procedure InitEvent(const aMouseInit: TFresnelMouseEventInit; const aPointerInit: TFresnelPointerEventInit); overload;
-    Property PointerId: TFreHandle read FPointerInit.Id;
+    Property PointerId: TFreHandle read FMouseInit.PointerId;
   end;
   TFresnelPointerEventHandler = Procedure(Event: TFresnelPointerEvent) of object;
 
@@ -231,7 +223,7 @@ Type
 
   { TFresnelMouseUpEvent }
 
-  TFresnelMouseUpEvent = class(TFresnelMouseEvent)
+  TFresnelMouseUpEvent = class(TFresnelPointerEvent)
   public
     class function FresnelEventID : TEventID; override;
   end;
@@ -602,21 +594,6 @@ begin
   FMouseInit:=aInit;
 end;
 
-{ TFresnelPointerEvent }
-
-constructor TFresnelPointerEvent.Create(const aMouseInit: TFresnelMouseEventInit;
-  const aPointerInit: TFresnelPointerEventInit);
-begin
-  InitEvent(aMouseInit,aPointerInit);
-end;
-
-procedure TFresnelPointerEvent.InitEvent(const aMouseInit: TFresnelMouseEventInit;
-  const aPointerInit: TFresnelPointerEventInit);
-begin
-  InitEvent(aMouseInit);
-  FPointerInit:=aPointerInit;
-end;
-
 { TFresnelChangeEvent }
 
 class function TFresnelChangeEvent.FresnelEventID: TEventID;

+ 46 - 21
src/base/fresnel.renderer.pas

@@ -43,7 +43,7 @@ type
     constructor Create(AOwner: TComponent); override; overload;
     procedure Draw(Renderer: TFresnelRenderer); virtual;
     procedure DrawCorner(Renderer: TFresnelRenderer; const r: TFresnelRect); virtual;
-    function GetHit(const X, Y: TFresnelLength; out aPosition: TFresnelLength): THit; override;
+    function GetHit(const X, Y: TFresnelLength; Nearest: boolean; out aPosition: TFresnelLength): THit; override;
   end;
 
   { TFresnelRenderer }
@@ -392,9 +392,23 @@ end;
 { TRendererScrollBar }
 
 procedure TRendererScrollBar.MouseHandler(Event: TAbstractEvent);
+
+  procedure SetScrollPos(NewPos: TFresnelLength);
+  begin
+    if Horizontal then
+    begin
+      if Parent.ComputedDirection=CSSRegistry.kwRTL then
+        NewPos:=NewPos-Size+Page;
+      Parent.ScrollLeft:=NewPos;
+    end
+    else
+      Parent.ScrollTop:=NewPos;
+  end;
+
 var
   MouseEvt: TFresnelMouseEvent absolute Event;
-  X, Y, NewPos: TFresnelLength;
+  X, Y, p, NewPos: TFresnelLength;
+  Hit: THit;
 begin
   // the mouse event has the coord of the Parent's clientbox
   // -> translate to GrandParent's child box
@@ -409,15 +423,17 @@ begin
   evtMouseDown:
     if MouseEvt.Button=mbLeft then
     begin
-      MouseDownHit:=GetHit(X,Y,MouseDownPos);
+      MouseDownHit:=GetHit(X,Y,false,MouseDownGrabPos);
+      MouseDownPosition:=Position;
       {$IFDEF VerboseFresnelScrolling}
-      writeln('TRendererScrollBar.MouseHandler Mouse Down ',Parent.Name,' Horz=',Horizontal,' Hit=',MouseDownHit,' p=',FloatToCSSStr(MouseDownPos));
+      writeln('TRendererScrollBar.MouseHandler Mouse Down ',Parent.Name,' Horz=',Horizontal,' Hit=',MouseDownHit,' p=',FloatToCSSStr(MouseDownGrabPos));
       {$ENDIF}
       case MouseDownHit of
       THit.hButtonLT: ;
       THit.hButtonRB: ;
       THit.hThumb:
         begin
+          SetPointerCapture((MouseEvt as TFresnelMouseDownEvent).PointerId);
           exit;
         end;
       THit.hTrackLT:
@@ -429,25 +445,33 @@ begin
       else exit;
       end;
       NewPos:=Max(0,Min(NewPos,Size-Page));
-      if Horizontal then
-      begin
-        if Parent.ComputedDirection=CSSRegistry.kwRTL then
-          NewPos:=NewPos-Size+Page;
-        Parent.ScrollLeft:=NewPos;
-      end
-      else
-        Parent.ScrollTop:=NewPos;
+      SetScrollPos(NewPos);
     end;
   evtMouseMove:
-    if MouseDownHit>THit.hNone then begin
-      //Hit:=GetHit(X,Y,p);
-      //writeln('TRendererScrollBar.MouseHandler Mouse Move ',Element.Name,' Hit=',Hit,' p=',FloatToCSSStr(p));
+    if (MouseEvt.Button=mbLeft) then
+    begin
+      Hit:=GetHit(X,Y,true,p);
+      {$IFDEF VerboseFresnelScrolling}
+      writeln('TRendererScrollBar.MouseHandler Mouse Move ',Parent.Name,' Horz=',Horizontal,' Hit=',Hit,' p=',FloatToCSSStr(p),' GrabPos=',FloatToCSSStr(MouseDownGrabPos));
+      {$ENDIF}
+      if MouseDownHit=THit.hThumb then
+      begin
+        // move thumb
+        NewPos:=MouseDownPosition+(p-MouseDownGrabPos);
+        NewPos:=Max(0,Min(NewPos,Size-Page));
+        SetScrollPos(NewPos);
+      end;
     end;
   evtMouseUp:
-    if (MouseEvt.Button=mbLeft) and (MouseDownHit>THit.hNone) then
+    if (MouseEvt.Button=mbLeft) then
     begin
-      //Hit:=GetHit(X,Y,p);
-      //writeln('TRendererScrollBar.MouseHandler Mouse Up ',Element.Name,' Hit=',Hit,' p=',FloatToCSSStr(p));
+      Hit:=GetHit(X,Y,true,p);
+      {$IFDEF VerboseFresnelScrolling}
+      writeln('TRendererScrollBar.MouseHandler Mouse Up ',Parent.Name,' Horz=',Horizontal,' Hit=',Hit,' p=',FloatToCSSStr(p));
+      {$ENDIF}
+      MouseDownGrabPos:=0;
+      MouseDownHit:=THit.hNone;
+      ReleasePointerCapture((MouseEvt as TFresnelMouseUpEvent).PointerId);
     end;
   end;
 end;
@@ -531,7 +555,8 @@ begin
   Renderer.FillRect(TrackColor,r);
 end;
 
-function TRendererScrollBar.GetHit(const X, Y: TFresnelLength; out aPosition: TFresnelLength): THit;
+function TRendererScrollBar.GetHit(const X, Y: TFresnelLength; Nearest: boolean; out
+  aPosition: TFresnelLength): THit;
 var
   LT, RB: TFresnelLength;
 begin
@@ -539,14 +564,14 @@ begin
   aPosition:=0;
   if Horizontal then
   begin
-    if (X<Box.Left) or (X>Box.Right) then
+    if (not Nearest) and ((X<Box.Left) or (X>Box.Right)) then
       exit;
     LT:=Box.Left+Border;
     RB:=Box.Right-Border;
     if LT>RB-1 then exit;
     aPosition:=(X-LT) / (RB-LT);
   end else begin
-    if (Y<Box.Top) or (Y>Box.Bottom) then
+    if (not Nearest) and ((Y<Box.Top) or (Y>Box.Bottom)) then
       exit;
     LT:=Box.Top+Border;
     RB:=Box.Bottom-Border;

+ 41 - 3
src/gtk3/fresnel.gtk3.pas

@@ -862,22 +862,60 @@ procedure TGtk3WSForm.SetPointerCapture(const aPointerId: TFreHandle);
 var
   w: PGtkWidget;
 begin
-  if aPointerId=nil then exit;
+  if aPointerId=nil then
+  begin
+    {$IFDEF VerboseFresnelScrolling}
+    writeln('TGtk3WSForm.SetPointerCapture failed PointerId=nil');
+    {$ENDIF}
+    exit;
+  end;
   w:=gtk_grab_get_current;
-  if w=PGtkWidget(Window) then exit;
+  if w=PGtkWidget(Window) then
+  begin
+    {$IFDEF VerboseFresnelScrolling}
+    writeln('TGtk3WSForm.SetPointerCapture was already grabbed');
+    {$ENDIF}
+    exit;
+  end;
   if w<>nil then
+  begin
+    {$IFDEF VerboseFresnelScrolling}
+    writeln('TGtk3WSForm.SetPointerCapture remove old grab...');
+    {$ENDIF}
     gtk_grab_remove(w);
+  end;
+  {$IFDEF VerboseFresnelScrolling}
+  writeln('TGtk3WSForm.SetPointerCapture grab...');
+  {$ENDIF}
   gtk_grab_add(Window);
+  {$IFDEF VerboseFresnelScrolling}
+  writeln('TGtk3WSForm.SetPointerCapture grabbed Result=',gtk_grab_get_current=PGtkWidget(Window));
+  {$ENDIF}
 end;
 
 procedure TGtk3WSForm.ReleasePointerCapture(const aPointerId: TFreHandle);
 var
   w: PGtkWidget;
 begin
-  if aPointerId=nil then exit;
+  if aPointerId=nil then
+  begin
+    {$IFDEF VerboseFresnelScrolling}
+    writeln('TGtk3WSForm.ReleasePointerCapture failed PointerId=nil');
+    {$ENDIF}
+    exit;
+  end;
   w:=gtk_grab_get_current;
   if w=PGtkWidget(Window) then
+  begin
+    {$IFDEF VerboseFresnelScrolling}
+    writeln('TGtk3WSForm.ReleasePointerCapture remove grab...');
+    {$ENDIF}
     gtk_grab_remove(w);
+  end else begin
+    {$IFDEF VerboseFresnelScrolling}
+    writeln('TGtk3WSForm.ReleasePointerCapture success, was not grabbed');
+    {$ENDIF}
+  end;
 end;
 
 procedure TGtk3WSForm.Notification(AComponent: TComponent; Operation: TOperation