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';
procedure lclOffsetMousePos(var Point: NSPoint); message 'lclOffsetMousePos:';
procedure lclExpectedKeys(var wantTabs, wantArrows, wantAll: Boolean); message 'lclExpectedKeys:::';
function lclIsMouseInAuxArea(Event: NSEvent): Boolean; message 'lclMouseInAuxArea:';
end;
{ LCLViewExtension }
@ -164,6 +165,7 @@ type
faileddraw : Boolean;
public
callback: ICommonCallback;
auxMouseByParent: Boolean;
procedure dealloc; override;
function acceptsFirstResponder: Boolean; override;
function becomeFirstResponder: Boolean; override;
@ -171,6 +173,7 @@ type
procedure drawRect(dirtyRect: NSRect); override;
function lclGetCallback: ICommonCallback; override;
procedure lclClearCallback; override;
function lclIsMouseInAuxArea(Event: NSevent): Boolean; override;
// mouse
function acceptsFirstMouse(event: NSEvent): Boolean; override;
procedure mouseDown(event: NSEvent); override;
@ -542,6 +545,14 @@ begin
callback := nil;
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);
begin
if not Assigned(callback) or not callback.MouseUpDownEvent(event) then
@ -787,6 +798,19 @@ begin
wantAll := false;
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 }
function RectToViewCoord(view: NSView; const r: TRect): NSRect;

View File

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

View File

@ -191,6 +191,8 @@ begin
Result.setDocumentView(AView);
AView.setHidden(false);
SetViewDefaults(Result);
if AView.isKindOfClass(TCocoaCustomControl) then
TCocoaCustomControl(AView).auxMouseByParent := true;
end;
{ TLCLCommonCallback }
@ -1288,6 +1290,15 @@ begin
exit;
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));
FillChar(Msg, SizeOf(Msg), #0);