From 93748c33bf12ab7a4fb8cc972bb9c9c1cd2de6d6 Mon Sep 17 00:00:00 2001 From: Tom Cowland Date: Mon, 7 Dec 2020 14:57:31 +0000 Subject: [PATCH] Widget : Ensure correct origin is used for MouseEvent position We noticed the disparity in #4045 where dragMove would have a different origin to mouseMove. --- Changes.md | 5 +++++ python/GafferUI/Widget.py | 40 +++++++++++++++++++++------------------ 2 files changed, 27 insertions(+), 18 deletions(-) diff --git a/Changes.md b/Changes.md index b5a22ff809f..e3d06d03f37 100644 --- a/Changes.md +++ b/Changes.md @@ -1,6 +1,11 @@ 0.59.x.x (relative to 0.59.0.0) ======== +Fixes +----- + +- Widget : Fixed incorrect `ButtonEvent` coordinate origin for mouse signals under certain widget configurations. + API --- diff --git a/python/GafferUI/Widget.py b/python/GafferUI/Widget.py index a252ca4ad4f..d13241f2a7a 100644 --- a/python/GafferUI/Widget.py +++ b/python/GafferUI/Widget.py @@ -1035,7 +1035,7 @@ def __mouseButtonPress( self, qObject, qEvent ) : event = GafferUI.ButtonEvent( Widget._buttons( qEvent.button() ), Widget._buttons( qEvent.buttons() ), - self.__positionToLine( qEvent.pos() ), + self.__widgetSpaceLine( qEvent, widget ), 0.0, Widget._modifiers( qEvent.modifiers() ), ) @@ -1064,7 +1064,7 @@ def __mouseButtonRelease( self, qObject, qEvent ) : event = GafferUI.ButtonEvent( Widget._buttons( qEvent.button() ), Widget._buttons( qEvent.buttons() ), - self.__positionToLine( qEvent.pos() ), + self.__widgetSpaceLine( qEvent, widget ), 0.0, Widget._modifiers( qEvent.modifiers() ), ) @@ -1083,7 +1083,7 @@ def __mouseButtonDblClick( self, qObject, qEvent ) : event = GafferUI.ButtonEvent( Widget._buttons( qEvent.button() ), Widget._buttons( qEvent.buttons() ), - self.__positionToLine( qEvent.pos() ), + self.__widgetSpaceLine( qEvent, widget ), 0.0, Widget._modifiers( qEvent.modifiers() ), ) @@ -1103,7 +1103,7 @@ def __mouseMove( self, qObject, qEvent ) : event = GafferUI.ButtonEvent( Widget._buttons( qEvent.button() ), Widget._buttons( qEvent.buttons() ), - self.__positionToLine( qEvent.pos() ), + self.__widgetSpaceLine( qEvent, widget ), 0.0, Widget._modifiers( qEvent.modifiers() ), ) @@ -1136,7 +1136,7 @@ def __wheel( self, qObject, qEvent ) : event = GafferUI.ButtonEvent( GafferUI.ButtonEvent.Buttons.None_, Widget._buttons( qEvent.buttons() ), - self.__positionToLine( qEvent.pos() ), + self.__widgetSpaceLine( qEvent, widget ), qEvent.delta() / 8.0, Widget._modifiers( qEvent.modifiers() ), ) @@ -1206,7 +1206,8 @@ def __startDrag( self, qObject, qEvent ) : self.__lastButtonPressWidget = None return False - if ( self.__lastButtonPressEvent.line.p0 - self.__positionToLine( qEvent.pos() ).p0 ).length() < 3 : + widget = Widget._owner( qObject ) + if ( self.__lastButtonPressEvent.line.p0 - self.__widgetSpaceLine( qEvent, widget ).p0 ).length() < 3 : return False sourceWidget = self.__lastButtonPressWidget() @@ -1241,8 +1242,7 @@ def __startDrag( self, qObject, qEvent ) : def __doDragEnterAndLeave( self, qObject, qEvent ) : - cursorPos = imath.V2i( qEvent.globalPos().x(), qEvent.globalPos().y() ) - candidateWidget = Widget.widgetAt( cursorPos ) + candidateWidget = Widget.widgetAt( imath.V2i( qEvent.globalPos().x(), qEvent.globalPos().y() ) ) if candidateWidget is self.__dragDropEvent.destinationWidget : return @@ -1251,7 +1251,7 @@ def __doDragEnterAndLeave( self, qObject, qEvent ) : if candidateWidget is not None : while candidateWidget is not None : if candidateWidget._dragEnterSignal is not None : - self.__dragDropEvent.line = self.__positionToLine( cursorPos - candidateWidget.bound().min() ) + self.__dragDropEvent.line = self.__widgetSpaceLine( qEvent, candidateWidget ) if candidateWidget._dragEnterSignal( candidateWidget, self.__dragDropEvent ) : newDestinationWidget = candidateWidget break @@ -1268,7 +1268,7 @@ def __doDragEnterAndLeave( self, qObject, qEvent ) : previousDestinationWidget = self.__dragDropEvent.destinationWidget self.__dragDropEvent.destinationWidget = newDestinationWidget if previousDestinationWidget is not None and previousDestinationWidget._dragLeaveSignal is not None : - self.__dragDropEvent.line = self.__positionToLine( cursorPos - previousDestinationWidget.bound().min() ) + self.__dragDropEvent.line = self.__widgetSpaceLine( qEvent, previousDestinationWidget ) previousDestinationWidget._dragLeaveSignal( previousDestinationWidget, self.__dragDropEvent ) def __updateDrag( self, qObject, qEvent ) : @@ -1285,10 +1285,7 @@ def __updateDrag( self, qObject, qEvent ) : return True if dst._dragMoveSignal : - - cursorPos = imath.V2i( qEvent.globalPos().x(), qEvent.globalPos().y() ) - self.__dragDropEvent.line = self.__positionToLine( cursorPos - dst.bound().min() ) - + self.__dragDropEvent.line = self.__widgetSpaceLine( qEvent, dst ) dst._dragMoveSignal( dst, self.__dragDropEvent ) return True @@ -1325,12 +1322,10 @@ def __endDrag( self, qObject, qEvent ) : # Emit dropSignal() on the destination. - cursorPos = imath.V2i( qEvent.globalPos().x(), qEvent.globalPos().y() ) - dst = dragDropEvent.destinationWidget if dst is not None and dst._dropSignal : - dragDropEvent.line = self.__positionToLine( cursorPos - dst.bound().min() ) + dragDropEvent.line = self.__widgetSpaceLine( qEvent, dst ) dragDropEvent.dropResult = dst._dropSignal( dst, dragDropEvent ) # Emit dragEndSignal() on source. @@ -1338,7 +1333,7 @@ def __endDrag( self, qObject, qEvent ) : src = dragDropEvent.sourceWidget if src._dragEndSignal : - dragDropEvent.line = self.__positionToLine( cursorPos - src.bound().min() ) + dragDropEvent.line = self.__widgetSpaceLine( qEvent, src ) src._dragEndSignal( src, @@ -1347,6 +1342,15 @@ def __endDrag( self, qObject, qEvent ) : return True + # Maps the position of the supplied Qt mouse event into the coordinate + # space of the target Gaffer widget. This is required as certain widget + # configurations (eg: QTableView with a visible header) result in qEvent + # coordinate origins differing from the Gaffer Widget's origin. + def __widgetSpaceLine( self, qEvent, targetWidget ) : + + cursorPos = imath.V2i( qEvent.globalPos().x(), qEvent.globalPos().y() ) + return self.__positionToLine( cursorPos - targetWidget.bound().min() ) + def __positionToLine( self, pos ) : if isinstance( pos, imath.V2i ) :