cocoa: suppressing mouse events for scrollbars of ManualScroll. #34090

git-svn-id: trunk@58685 -
This commit is contained in:
dmitry 2018-08-07 04:31:30 +00:00
parent 8c7c839198
commit 002ec43393
3 changed files with 89 additions and 6 deletions

View File

@ -117,6 +117,7 @@ type
function lclContentView: NSView; message 'lclContentView'; function lclContentView: NSView; message 'lclContentView';
procedure lclOffsetMousePos(var Point: NSPoint); message 'lclOffsetMousePos:'; procedure lclOffsetMousePos(var Point: NSPoint); message 'lclOffsetMousePos:';
procedure lclExpectedKeys(var wantTabs, wantArrows, wantAll: Boolean); message 'lclExpectedKeys:::'; procedure lclExpectedKeys(var wantTabs, wantArrows, wantAll: Boolean); message 'lclExpectedKeys:::';
function lclIsMouseInAuxArea(Event: NSEvent): Boolean; message 'lclMouseInAuxArea:';
end; end;
{ LCLViewExtension } { LCLViewExtension }
@ -164,6 +165,7 @@ type
faileddraw : Boolean; faileddraw : Boolean;
public public
callback: ICommonCallback; callback: ICommonCallback;
auxMouseByParent: Boolean;
procedure dealloc; override; procedure dealloc; override;
function acceptsFirstResponder: Boolean; override; function acceptsFirstResponder: Boolean; override;
function becomeFirstResponder: Boolean; override; function becomeFirstResponder: Boolean; override;
@ -171,6 +173,7 @@ type
procedure drawRect(dirtyRect: NSRect); override; procedure drawRect(dirtyRect: NSRect); override;
function lclGetCallback: ICommonCallback; override; function lclGetCallback: ICommonCallback; override;
procedure lclClearCallback; override; procedure lclClearCallback; override;
function lclIsMouseInAuxArea(Event: NSevent): Boolean; override;
// mouse // mouse
function acceptsFirstMouse(event: NSEvent): Boolean; override; function acceptsFirstMouse(event: NSEvent): Boolean; override;
procedure mouseDown(event: NSEvent); override; procedure mouseDown(event: NSEvent); override;
@ -542,6 +545,14 @@ begin
callback := nil; callback := nil;
end; end;
function TCocoaCustomControl.lclIsMouseInAuxArea(Event: NSevent): Boolean;
begin
if auxMouseByParent and Assigned(superview) then
Result := superview.lclIsMouseInAuxArea(Event)
else
Result := false;
end;
procedure TCocoaCustomControl.mouseDown(event: NSEvent); procedure TCocoaCustomControl.mouseDown(event: NSEvent);
begin begin
if not Assigned(callback) or not callback.MouseUpDownEvent(event) then if not Assigned(callback) or not callback.MouseUpDownEvent(event) then
@ -787,6 +798,19 @@ begin
wantAll := false; wantAll := false;
end; end;
{ The method should return TRUE, if mouse is located above an auxilary area
of a (composited) control, and thus MOUSE MOVE event should not be propagated
to LCL. For example, controls with Scrollbars should not report mouse events
if mouse cursor is above ScrollBar and scroll bar is visible. (ScrollBar = Auxillary area)
By default, the whole area is considered to be non-auxillary and must be
reported to LCL.
}
function LCLObjectExtension.lclIsMouseInAuxArea(Event: NSEvent): Boolean;
begin
Result := false;
end;
{ LCLControlExtension } { LCLControlExtension }
function RectToViewCoord(view: NSView; const r: TRect): NSRect; function RectToViewCoord(view: NSView; const r: TRect): NSRect;

View File

@ -71,6 +71,7 @@ type
function lclIsHandle: Boolean; override; function lclIsHandle: Boolean; override;
function lclContentView: NSView; override; function lclContentView: NSView; override;
function lclClientFrame: TRect; override; function lclClientFrame: TRect; override;
function lclIsMouseInAuxArea(event: NSEvent): Boolean; override;
procedure setDocumentView(AView: NSView); message 'setDocumentView:'; procedure setDocumentView(AView: NSView); message 'setDocumentView:';
function documentView: NSView; message 'documentView'; function documentView: NSView; message 'documentView';
@ -110,6 +111,7 @@ type
minInt : Integer; minInt : Integer;
maxInt : Integer; maxInt : Integer;
pageInt : Integer; pageInt : Integer;
suppressLCLMouse: Boolean;
procedure actionScrolling(sender: NSObject); message 'actionScrolling:'; procedure actionScrolling(sender: NSObject); message 'actionScrolling:';
function IsHorizontal: Boolean; message 'IsHorizontal'; function IsHorizontal: Boolean; message 'IsHorizontal';
function acceptsFirstResponder: Boolean; override; function acceptsFirstResponder: Boolean; override;
@ -137,6 +139,8 @@ type
end; end;
function isMouseEventInScrollBar(host: TCocoaManualScrollView; event: NSEvent): Boolean;
implementation implementation
{ TCocoaManualScrollView } { TCocoaManualScrollView }
@ -170,6 +174,11 @@ begin
else Result:=inherited lclClientFrame; else Result:=inherited lclClientFrame;
end; end;
function TCocoaManualScrollView.lclIsMouseInAuxArea(event: NSEvent): Boolean;
begin
Result := isMouseEventInScrollBar(Self, event);
end;
procedure TCocoaManualScrollView.setDocumentView(AView: NSView); procedure TCocoaManualScrollView.setDocumentView(AView: NSView);
var var
f : NSrect; f : NSrect;
@ -202,7 +211,9 @@ begin
sc.setEnabled(true); sc.setEnabled(true);
sc.setHidden(not AVisible); sc.setHidden(not AVisible);
TCocoaScrollBar(sc).preventBlock := true; TCocoaScrollBar(sc).preventBlock := true;
TCocoaScrollBar(sc).callback:=parent.callback; //Suppress scrollers notifications.
TCocoaScrollBar(sc).callback := parent.callback;
TCocoaScrollBar(sc).suppressLCLMouse := true;
sc.setTarget(sc); sc.setTarget(sc);
sc.setAction(objcselector('actionScrolling:')); sc.setAction(objcselector('actionScrolling:'));
@ -462,7 +473,11 @@ end;
procedure TCocoaManualScrollView.mouseMoved(event: NSEvent); procedure TCocoaManualScrollView.mouseMoved(event: NSEvent);
begin begin
if isMouseEventInScrollBar(self, event) or not Assigned(callback) or not callback.MouseMove(event) then if isMouseEventInScrollBar(self, event) then
begin
inherited mouseMoved(event)
end
else if not Assigned(callback) or not callback.MouseMove(event) then
inherited mouseMoved(event); inherited mouseMoved(event);
end; end;
@ -651,70 +666,103 @@ end;
procedure TCocoaScrollBar.mouseDown(event: NSEvent); procedure TCocoaScrollBar.mouseDown(event: NSEvent);
begin begin
if not Assigned(callback) or not callback.MouseUpDownEvent(event, false, preventBlock) then if suppressLCLMouse then
inherited mouseDown(event)
else if not Assigned(callback) or not callback.MouseUpDownEvent(event, false, preventBlock) then
begin begin
inherited mouseDown(event); inherited mouseDown(event);
callback.MouseUpDownEvent(event, true, preventBlock); if Assigned(callback) then
callback.MouseUpDownEvent(event, true, preventBlock);
end; end;
end; end;
procedure TCocoaScrollBar.mouseUp(event: NSEvent); procedure TCocoaScrollBar.mouseUp(event: NSEvent);
begin begin
if suppressLCLMouse then
inherited mouseDown(event)
else
if not Assigned(callback) or not callback.MouseUpDownEvent(event, false, preventBlock) then if not Assigned(callback) or not callback.MouseUpDownEvent(event, false, preventBlock) then
inherited mouseUp(event); inherited mouseUp(event);
end; end;
procedure TCocoaScrollBar.rightMouseDown(event: NSEvent); procedure TCocoaScrollBar.rightMouseDown(event: NSEvent);
begin begin
if suppressLCLMouse then
inherited rightMouseDown(event)
else
if not Assigned(callback) or not callback.MouseUpDownEvent(event) then if not Assigned(callback) or not callback.MouseUpDownEvent(event) then
inherited rightMouseDown(event); inherited rightMouseDown(event);
end; end;
procedure TCocoaScrollBar.rightMouseUp(event: NSEvent); procedure TCocoaScrollBar.rightMouseUp(event: NSEvent);
begin begin
if suppressLCLMouse then
inherited rightMouseUp(event)
else
if not Assigned(callback) or not callback.MouseUpDownEvent(event) then if not Assigned(callback) or not callback.MouseUpDownEvent(event) then
inherited rightMouseUp(event); inherited rightMouseUp(event);
end; end;
procedure TCocoaScrollBar.rightMouseDragged(event: NSEvent); procedure TCocoaScrollBar.rightMouseDragged(event: NSEvent);
begin begin
if suppressLCLMouse then
inherited rightMouseDragged(event)
else
if not Assigned(callback) or not callback.MouseUpDownEvent(event) then if not Assigned(callback) or not callback.MouseUpDownEvent(event) then
inherited rightMouseDragged(event); inherited rightMouseDragged(event);
end; end;
procedure TCocoaScrollBar.otherMouseDown(event: NSEvent); procedure TCocoaScrollBar.otherMouseDown(event: NSEvent);
begin begin
if suppressLCLMouse then
inherited otherMouseDown(event)
else
if not Assigned(callback) or not callback.MouseUpDownEvent(event) then if not Assigned(callback) or not callback.MouseUpDownEvent(event) then
inherited otherMouseDown(event); inherited otherMouseDown(event);
end; end;
procedure TCocoaScrollBar.otherMouseUp(event: NSEvent); procedure TCocoaScrollBar.otherMouseUp(event: NSEvent);
begin begin
if suppressLCLMouse then
inherited otherMouseUp(event)
else
if not Assigned(callback) or not callback.MouseUpDownEvent(event) then if not Assigned(callback) or not callback.MouseUpDownEvent(event) then
inherited otherMouseUp(event); inherited otherMouseUp(event);
end; end;
procedure TCocoaScrollBar.otherMouseDragged(event: NSEvent); procedure TCocoaScrollBar.otherMouseDragged(event: NSEvent);
begin begin
if suppressLCLMouse then
inherited otherMouseDragged(event)
else
if not Assigned(callback) or not callback.MouseMove(event) then if not Assigned(callback) or not callback.MouseMove(event) then
inherited otherMouseDragged(event); inherited otherMouseDragged(event);
end; end;
procedure TCocoaScrollBar.mouseDragged(event: NSEvent); procedure TCocoaScrollBar.mouseDragged(event: NSEvent);
begin begin
if suppressLCLMouse then
inherited mouseDragged(event)
else
if not Assigned(callback) or not callback.MouseMove(event) then if not Assigned(callback) or not callback.MouseMove(event) then
inherited mouseDragged(event); inherited mouseDragged(event);
end; end;
procedure TCocoaScrollBar.mouseMoved(event: NSEvent); procedure TCocoaScrollBar.mouseMoved(event: NSEvent);
begin begin
if not Assigned(callback) or not callback.MouseMove(event) then if suppressLCLMouse then
inherited mouseMoved(event); inherited mouseMoved(event)
else
if (not Assigned(callback) or not callback.MouseMove(event)) then
inherited mouseMoved(event)
end; end;
procedure TCocoaScrollBar.scrollWheel(event: NSEvent); procedure TCocoaScrollBar.scrollWheel(event: NSEvent);
begin begin
if suppressLCLMouse then
inherited scrollWheel(event)
else
if not Assigned(callback) or not callback.scrollWheel(event) then if not Assigned(callback) or not callback.scrollWheel(event) then
inherited scrollWheel(event); inherited scrollWheel(event);
end; end;

View File

@ -191,6 +191,8 @@ begin
Result.setDocumentView(AView); Result.setDocumentView(AView);
AView.setHidden(false); AView.setHidden(false);
SetViewDefaults(Result); SetViewDefaults(Result);
if AView.isKindOfClass(TCocoaCustomControl) then
TCocoaCustomControl(AView).auxMouseByParent := true;
end; end;
{ TLCLCommonCallback } { TLCLCommonCallback }
@ -1288,6 +1290,15 @@ begin
exit; exit;
end; end;
if (Event.type_ = NSMouseMoved) and Owner.lclIsMouseInAuxArea(Event) then
begin
// mouse is over auxillary area that's "blind" to mouse moves
// even though the mouse cursos is within the control bounds.
// (i.e. scrollbars)
Result := false;
Exit;
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);