Cocoa: Enable MouseCapture

git-svn-id: trunk@43939 -
This commit is contained in:
freq 2014-02-07 13:16:50 +00:00
parent af91af27e9
commit b90ff1c48b
5 changed files with 77 additions and 24 deletions

View File

@ -64,6 +64,7 @@ type
pool: NSAutoreleasePool; pool: NSAutoreleasePool;
FNSApp: NSApplication; FNSApp: NSApplication;
FCurrentCursor: HCursor; FCurrentCursor: HCursor;
FCaptureControl: HWND;
delegate: TCocoaAppDelegate; delegate: TCocoaAppDelegate;
protected protected
FStockNullBrush: HBRUSH; FStockNullBrush: HBRUSH;
@ -129,6 +130,7 @@ type
function GetImagePixelData(AImage: CGImageRef; out bitmapByteCount: PtrUInt): Pointer; function GetImagePixelData(AImage: CGImageRef; out bitmapByteCount: PtrUInt): Pointer;
property NSApp: NSApplication read FNSApp; property NSApp: NSApplication read FNSApp;
property CurrentCursor: HCursor read FCurrentCursor write FCurrentCursor; property CurrentCursor: HCursor read FCurrentCursor write FCurrentCursor;
property CaptureControl: HWND read FCaptureControl;
// the winapi compatibility methods // the winapi compatibility methods
{$I cocoawinapih.inc} {$I cocoawinapih.inc}
// the extra LCL interface methods // the extra LCL interface methods

View File

@ -87,6 +87,7 @@ begin
inherited Create; inherited Create;
FTerminating := False; FTerminating := False;
FCurrentCursor:= 0; FCurrentCursor:= 0;
FCaptureControl:= 0;
{ Creates the AutoreleasePool } { Creates the AutoreleasePool }
pool := NSAutoreleasePool.alloc.init; pool := NSAutoreleasePool.alloc.init;

View File

@ -557,6 +557,11 @@ begin
Result := CLR_INVALID; Result := CLR_INVALID;
end; end;
function TCocoaWidgetSet.GetCapture: HWND;
begin
Result:=FCaptureControl;
end;
function TCocoaWidgetSet.GetCaretPos(var lpPoint: TPoint): Boolean; function TCocoaWidgetSet.GetCaretPos(var lpPoint: TPoint): Boolean;
begin begin
Result := CocoaCaret.GetCaretPos(lpPoint); Result := CocoaCaret.GetCaretPos(lpPoint);
@ -1686,6 +1691,11 @@ begin
Result := 0; Result := 0;
end; end;
function TCocoaWidgetSet.SetCapture(AHandle: HWND): HWND;
begin
FCaptureControl:= AHandle;
end;
function TCocoaWidgetSet.SetCaretPos(X, Y: Integer): Boolean; function TCocoaWidgetSet.SetCaretPos(X, Y: Integer): Boolean;
begin begin
Result := CocoaCaret.SetCaretPos(X, Y); Result := CocoaCaret.SetCaretPos(X, Y);
@ -1720,6 +1730,11 @@ begin
Result := IntersectRect(R, ARect, CGRectToRect(ClipBox)); Result := IntersectRect(R, ARect, CGRectToRect(ClipBox));
end; end;
function TCocoaWidgetSet.ReleaseCapture : Boolean;
begin
FCaptureControl:=0;
end;
function TCocoaWidgetSet.ReleaseDC(hWnd: HWND; DC: HDC): Integer; function TCocoaWidgetSet.ReleaseDC(hWnd: HWND; DC: HDC): Integer;
var var
ctx: TCocoaContext; ctx: TCocoaContext;

View File

@ -83,7 +83,7 @@ function FrameRect(DC: HDC; const ARect: TRect; hBr: HBRUSH): Integer; override;
function GetActiveWindow: HWND; override; function GetActiveWindow: HWND; override;
{function GetBitmapBits(Bitmap: HBITMAP; Count: Longint; Bits: Pointer): Longint; override;} {function GetBitmapBits(Bitmap: HBITMAP; Count: Longint; Bits: Pointer): Longint; override;}
function GetBkColor(DC: HDC): TColorRef; override; function GetBkColor(DC: HDC): TColorRef; override;
{function GetCapture: HWND; override;} function GetCapture: HWND; override;
function GetCaretPos(var lpPoint: TPoint): Boolean; override; function GetCaretPos(var lpPoint: TPoint): Boolean; override;
function GetCaretRespondToFocus(handle: HWND; var ShowHideOnFocus: boolean): Boolean; override; function GetCaretRespondToFocus(handle: HWND; var ShowHideOnFocus: boolean): Boolean; override;
function GetClientBounds(handle : HWND; var ARect : TRect) : Boolean; override; function GetClientBounds(handle : HWND; var ARect : TRect) : Boolean; override;
@ -147,7 +147,7 @@ function PostMessage(Handle: HWND; Msg: Cardinal; wParam: WParam; lParam: LParam
function Rectangle(DC: HDC; X1, Y1, X2, Y2: Integer): Boolean; override; function Rectangle(DC: HDC; X1, Y1, X2, Y2: Integer): Boolean; override;
function RectVisible(dc : hdc; const ARect: TRect) : Boolean; override; function RectVisible(dc : hdc; const ARect: TRect) : Boolean; override;
{function ReleaseCapture : Boolean; override;} function ReleaseCapture : Boolean; override;
function ReleaseDC(hWnd: HWND; DC: HDC): Integer; override; function ReleaseDC(hWnd: HWND; DC: HDC): Integer; override;
function RestoreDC(DC: HDC; SavedDC: Integer): Boolean; override; function RestoreDC(DC: HDC; SavedDC: Integer): Boolean; override;
function RoundRect(DC: HDC; X1, Y1, X2, Y2: Integer; RX, RY : Integer): Boolean; override; function RoundRect(DC: HDC; X1, Y1, X2, Y2: Integer; RX, RY : Integer): Boolean; override;
@ -160,7 +160,7 @@ function SendMessage(Handle: HWND; Msg: Cardinal; WParam: WParam; LParam: LParam
function SetActiveWindow(Handle: HWND): HWND; override; function SetActiveWindow(Handle: HWND): HWND; override;
function SetBKColor(DC: HDC; Color: TColorRef): TColorRef; override; function SetBKColor(DC: HDC; Color: TColorRef): TColorRef; override;
function SetBkMode(DC: HDC; bkMode : Integer) : Integer; override; function SetBkMode(DC: HDC; bkMode : Integer) : Integer; override;
{function SetCapture(AHandle: HWND): HWND; override;} function SetCapture(AHandle: HWND): HWND; override;
function SetCaretPos(X, Y: Integer): Boolean; override; function SetCaretPos(X, Y: Integer): Boolean; override;
function SetCaretPosEx(Handle: HWnd; X, Y: Integer): Boolean; override; function SetCaretPosEx(Handle: HWnd; X, Y: Integer): Boolean; override;
function SetCaretRespondToFocus(handle: HWND; ShowHideOnFocus: boolean): Boolean; override; function SetCaretRespondToFocus(handle: HWND; ShowHideOnFocus: boolean): Boolean; override;

View File

@ -29,6 +29,7 @@ type
FTarget: TWinControl; FTarget: TWinControl;
FBoundsReportedToChildren: boolean; FBoundsReportedToChildren: boolean;
FIsOpaque:boolean; FIsOpaque:boolean;
FIsEventRouting:boolean;
function CheckMouseButtonDown(Event: NSEvent; AButton: Integer): Cardinal; function CheckMouseButtonDown(Event: NSEvent; AButton: Integer): Cardinal;
function GetHasCaret: Boolean; function GetHasCaret: Boolean;
procedure SetHasCaret(AValue: Boolean); procedure SetHasCaret(AValue: Boolean);
@ -250,6 +251,7 @@ begin
FPropStorage.Duplicates := dupAccept; FPropStorage.Duplicates := dupAccept;
FBoundsReportedToChildren:=false; FBoundsReportedToChildren:=false;
FIsOpaque:=false; FIsOpaque:=false;
FIsEventRouting:=false;
end; end;
destructor TLCLCommonCallback.Destroy; destructor TLCLCommonCallback.Destroy;
@ -685,6 +687,8 @@ var
MsgContext: TLMContextMenu; MsgContext: TLMContextMenu;
MousePos: NSPoint; MousePos: NSPoint;
MButton: NSInteger; MButton: NSInteger;
obj:NSObject;
callback: ICommonCallback;
begin begin
Result := False; // allow cocoa to handle message Result := False; // allow cocoa to handle message
@ -692,6 +696,20 @@ begin
if Assigned(Target) and (not (csDesigning in Target.ComponentState) and not Owner.lclIsEnabled) then if Assigned(Target) and (not (csDesigning in Target.ComponentState) and not Owner.lclIsEnabled) then
Exit; Exit;
//debugln('MouseUpDownEvent '+Target.name);
if CocoaWidgetSet.CaptureControl<>0 then // check if to route event to capture control
begin
obj:=NSObject(CocoaWidgetSet.CaptureControl);
if (obj<>Owner) and not FIsEventRouting then
begin
FIsEventRouting:=true;
callback:=obj.lclGetCallback;
Result:=callback.MouseUpDownEvent(Event);
FIsEventRouting:=false;
exit;
end;
end;
// idea of multi click implementation is taken from gtk // idea of multi click implementation is taken from gtk
FillChar(Msg, SizeOf(Msg), #0); FillChar(Msg, SizeOf(Msg), #0);
@ -775,32 +793,49 @@ begin
rect:=Owner.lclClientFrame; rect:=Owner.lclClientFrame;
targetControl:=nil; targetControl:=nil;
if assigned(Target.Parent) and not PtInRect(rect, mp) then if CocoaWidgetSet.CaptureControl<>0 then // check if to route event to capture control
targetControl:=Target.Parent // outside myself then go to parent begin
else obj:=NSObject(CocoaWidgetSet.CaptureControl);
for i:=Target.ComponentCount-1 downto 0 do // otherwise check, if over child if (obj<>Owner) and not FIsEventRouting then
if Target.Components[i] is TWinControl then begin
begin FIsEventRouting:=true;
childControl:=TWinControl(Target.Components[i]); callback:=obj.lclGetCallback;
rect:=childControl.BoundsRect; result:=callback.MouseMove(Event);
if PtInRect(rect, mp) then FIsEventRouting:=false;
begin exit;
targetControl:=childControl; end;
break; end
end; else
end; begin
if assigned(Target.Parent) and not PtInRect(rect, mp) then
targetControl:=Target.Parent // outside myself then route to parent
else
for i:=Target.ComponentCount-1 downto 0 do // otherwise check, if over child and route to child
if Target.Components[i] is TWinControl then
begin
childControl:=TWinControl(Target.Components[i]);
rect:=childControl.BoundsRect;
if PtInRect(rect, mp) then
begin
targetControl:=childControl;
break;
end;
end;
end;
if assigned(targetControl) then if assigned(targetControl) and not FIsEventRouting then
begin begin
//debugln(Target.name+' -> '+targetControl.Name+'- is parent:'+dbgs(targetControl=Target.Parent)+' Point: '+dbgs(mp)+' Rect'+dbgs(rect)); FIsEventRouting:=true;
obj:=NSView(targetControl.Handle); // debugln(Target.name+' -> '+targetControl.Name+'- is parent:'+dbgs(targetControl=Target.Parent)+' Point: '+dbgs(mp)+' Rect'+dbgs(rect));
callback:=obj.lclGetCallback; obj:=NSView(targetControl.Handle);
result:=callback.MouseMove(Event); callback:=obj.lclGetCallback;
exit; result:=callback.MouseMove(Event);
FIsEventRouting:=false;
exit;
end; end;
//debugln('Send to: '+Target.name+' Point: '+dbgs(mp)); // debugln('Send to: '+Target.name+' Point: '+dbgs(mp));
FillChar(Msg, SizeOf(Msg), #0); FillChar(Msg, SizeOf(Msg), #0);
Msg.Msg := LM_MOUSEMOVE; Msg.Msg := LM_MOUSEMOVE;