diff --git a/lcl/controls.pp b/lcl/controls.pp index 2f9f0dc594..7c2d965448 100644 --- a/lcl/controls.pp +++ b/lcl/controls.pp @@ -418,6 +418,12 @@ type procedure AdjustDockRect(ARect: TRect); virtual; function GetDragCursor(Accepted: Boolean; X, Y: Integer): TCursor; override; procedure EndDrag(Target: TObject; X, Y: Integer); override; + + // dock image drawing + procedure InitDock(APosition: TPoint); virtual; + procedure ShowDockImage; virtual; + procedure HideDockImage; virtual; + procedure MoveDockImage; virtual; public property DockOffset: TPoint read FDockOffset write FDockOffset; property DockRect: TRect read FDockRect write FDockRect; diff --git a/lcl/include/dragmanager.inc b/lcl/include/dragmanager.inc index 08e56ce343..911aec4b8d 100644 --- a/lcl/include/dragmanager.inc +++ b/lcl/include/dragmanager.inc @@ -8,7 +8,7 @@ * * * This file is part of the Lazarus Component Library (LCL) * * * - * See the file COPYING.modifiedLGPL.txt, included in this distribution, * + * See the file COPYING.modifiedLGPL.txt, included in this distribution, * * for details about the copyright. * * * * This program is distributed in the hope that it will be useful, * @@ -59,7 +59,6 @@ type TDockPerformer = class(TDragDockCommon) private FDockObject: TDragDockObject; - procedure DefaultDockImage(AOldRect, ANewRect: TRect; AOperation: TDockImageOperation); protected function Dragging(AControl: TControl): boolean; override; procedure DragStarted(APosition: TPoint); override; @@ -264,27 +263,15 @@ end; constructor TDockPerformer.Create(AManager: TDragManagerDefault; AControl: TControl); //Start a drag operation, if not already running var - p, cp: TPoint; + APoint: TPoint; begin inherited Create(AManager, AControl); AControl.DoStartDock(FDockObject); if FDockObject = nil then FDockObject := TDragDockObject.AutoCreate(AControl); - // we should handle somehow difference between - // Control.BoundsRect.LeftTop and CursorPos - - GetCursorPos(p); - FDockObject.DragPos := p; - // mouse click offset from control TopLeft in screen coordinates - cp := AControl.BoundsRect.TopLeft; - if AControl.Parent <> nil then - cp := AControl.Parent.ClientToScreen(cp); - FDockObject.DockOffset := Point(p.x - cp.x, p.y - cp.y); - AControl.CalculateDockSizes; - FDockObject.DockRect := Rect(p.x, p.y, p.x + AControl.Width, p.y + AControl.Height); - FDockObject.EraseDockRect := Rect(MaxInt, 0, MaxInt, 0); - + GetCursorPos(APoint); + FDockObject.InitDock(APoint); // we are tracking capture change to stop drag/dock is happen SetCaptureControl(AControl); end; @@ -301,15 +288,14 @@ begin end; procedure TDockPerformer.DragStarted(APosition: TPoint); -//Imput device has moved beyond tresholt (or immediate docking) +// Input device has moved beyond threshold (or immediate docking) begin if FDockObject = nil then Exit; FDragImageList := FDockObject.GetDragImages; if FDragImageList <> nil then FDragImageList.BeginDrag(0, APosition.X, APosition.Y); - DefaultDockImage(FDockObject.EraseDockRect, FDockObject.DockRect, disShow); - FDockObject.EraseDockRect := FDockObject.DockRect; + FDockObject.ShowDockImage; end; procedure TDockPerformer.DragMove(APosition: TPoint); @@ -468,12 +454,7 @@ begin DropAlign := DropOnControl.GetDockEdge(DropOnControl.ScreenToClient(APosition)); end; - //Draw the form outlines when the position has changed - if not CompareMem(@DockRect, @EraseDockRect, SizeOf(TRect)) then - begin - DefaultDockImage(FDockObject.EraseDockRect, FDockObject.DockRect, disMove); - EraseDockRect := DockRect; - end; + MoveDockImage; end; end; @@ -491,7 +472,7 @@ begin FDockObject := nil; SetCaptureControl(nil); - DefaultDockImage(ADockObjectCopy.EraseDockRect, ADockObjectCopy.DockRect, disHide); + ADockObjectCopy.HideDockImage; ADockObjectCopy.Floating := ADockObjectCopy.DragTarget = nil; Accepted := ADockObjectCopy.DragTarget <> nil; @@ -547,11 +528,6 @@ begin end; -procedure TDockPerformer.DefaultDockImage(AOldRect, ANewRect: TRect; AOperation: TDockImageOperation); -begin - WidgetSet.DrawDefaultDockImage(AOldRect, ANewRect, AOperation); -end; - { TDragManagerDefault } destructor TDragManagerDefault.Destroy; diff --git a/lcl/include/dragobject.inc b/lcl/include/dragobject.inc index db32de8f79..c84fad43b1 100644 --- a/lcl/include/dragobject.inc +++ b/lcl/include/dragobject.inc @@ -112,6 +112,49 @@ begin FControl.DoEndDock(Target, X, Y); end; +procedure TDragDockObject.InitDock(APosition: TPoint); +begin + // Determine hotspot scale for adjusting the undocked rectangle. + // Since the undocked extent of the control doesn't change, we fix the hotspot offset. + // Usage: OffsetRect(DockRect, FDockOffset); + + DragPos := APosition; //should have been done before + Control.CalculateDockSizes; + // mouse click offset from control TopLeft in screen coordinates + FDockRect.TopLeft := Control.ClientToScreen(Point(0, 0)); + if Control.Width > 0 then + FDockOffset.x := Round((APosition.x - FDockRect.Left) / Control.Width * Control.UndockWidth) + else + FDockOffset.X := 0; + if Control.Height > 0 then + FDockOffset.Y := Round((APosition.y - FDockRect.Top) / Control.Height * Control.UndockHeight) + else + FDockOffset.Y := 0; + FEraseDockRect := Rect(MaxInt, 0, MaxInt, 0); +end; + +procedure TDragDockObject.ShowDockImage; +begin + WidgetSet.DrawDefaultDockImage(EraseDockRect, DockRect, disShow); + EraseDockRect := DockRect; +end; + +procedure TDragDockObject.HideDockImage; +begin + WidgetSet.DrawDefaultDockImage(EraseDockRect, DockRect, disHide); + FEraseDockRect := Rect(MaxInt, 0, MaxInt, 0); +end; + +procedure TDragDockObject.MoveDockImage; +begin + //Draw the form outlines when the position has changed + if not CompareMem(@DockRect, @EraseDockRect, SizeOf(TRect)) then + begin + WidgetSet.DrawDefaultDockImage(EraseDockRect, DockRect, disMove); + EraseDockRect := DockRect; + end; +end; + { TDragDockObjectEx } constructor TDragDockObjectEx.Create(AControl: TControl);