139 lines
4.7 KiB
Python
Executable File
139 lines
4.7 KiB
Python
Executable File
"""
|
|
Opens up a 2nd window for docking mobu and R* widgets to
|
|
"""
|
|
import sys
|
|
|
|
from PySide import QtGui, QtCore
|
|
|
|
from RS.Tools import UI
|
|
from RS.Tools.UI import Application, QPrint
|
|
|
|
|
|
class SecondDockableWindow(UI.QtMainWindowBase):
|
|
"""
|
|
Singleton class
|
|
|
|
Do not instance more than one of this class!!
|
|
|
|
This is the window for the second dockable window for motion builder
|
|
"""
|
|
def __init__(self, parent=None):
|
|
"""
|
|
Constructor
|
|
"""
|
|
super(SecondDockableWindow, self).__init__(parent=parent, title='Secondary Dockable Window')
|
|
self._mobuWindow = Application.GetMainWindow()
|
|
|
|
self._mouseReleaseEventCalls = [
|
|
(QtCore.QEvent.Type.Move, QtCore.QEvent.Type.NonClientAreaMouseMove),
|
|
(QtCore.QEvent.Type.Move, QtCore.QEvent.Type.MouseButtonRelease)
|
|
]
|
|
self._lastEvent = None
|
|
self._dockWidge = []
|
|
self._dockWidgetLastEventDict = {}
|
|
self.updateDockWidgets()
|
|
|
|
def updateDockWidgets(self):
|
|
"""
|
|
Update the widgets which can dock with it from the list of motion builder child dock widgets
|
|
"""
|
|
dockWindows = {wid.windowTitle():wid for wid in self._mobuWindow.children() if isinstance(wid, QtGui.QDockWidget)}
|
|
dockWindows.pop("Viewer") # Remove the viewer at all costs!!
|
|
for win in dockWindows.itervalues():
|
|
if win not in self._dockWidge:
|
|
self._setupMobuDockWidget(win)
|
|
|
|
def _setupMobuDockWidget(self, dockWidget):
|
|
"""
|
|
Internal Method
|
|
|
|
Setup a given dockwidget to work with the secondary dock
|
|
|
|
Args:
|
|
dockWidget (QDockWidget): A dock widget to dock with the secondary dock
|
|
"""
|
|
QPrint(dockWidget.windowTitle())
|
|
dockWidget.setAllowedAreas(QtCore.Qt.AllDockWidgetAreas)
|
|
dockWidget.installEventFilter(self)
|
|
self._dockWidge.append(dockWidget)
|
|
|
|
def eventFilter(self, target, event):
|
|
"""
|
|
Reimplemeted
|
|
|
|
Qt's Event filter method for filtering out event methods which get triggered
|
|
|
|
Args:
|
|
target (QObject): The object which the filter is installed on
|
|
event (QEvent): The triggering event
|
|
|
|
Returns:
|
|
bool
|
|
"""
|
|
returnVal = None
|
|
if (self._dockWidgetLastEventDict.get(target, None), event.type()) in self._mouseReleaseEventCalls:
|
|
self._reparent(target)
|
|
returnVal = True
|
|
self._dockWidgetLastEventDict[target] = event.type()
|
|
|
|
if returnVal is not None:
|
|
return returnVal
|
|
|
|
return super(QtGui.QDockWidget, target).eventFilter(target, event)
|
|
|
|
def _reparent(self, dockWidget):
|
|
"""
|
|
Reparents the given dock widget based off its over the secondary dock widget or not
|
|
|
|
Args:
|
|
dockWidget (QDockWidget): The dock widget to re-parent if needed
|
|
"""
|
|
currentParent = dockWidget.parent()
|
|
parent = (self._mobuWindow, self)[self._isUnderCursor(self)]
|
|
|
|
# The instance of the mobu QMainWindow never seems to be
|
|
# the same, so a safer approach is to compare window titles
|
|
if currentParent.windowTitle() != parent.windowTitle():
|
|
# We set floating to True to cancel out any docking
|
|
# Changing the parent when docking results in crashes
|
|
dockWidget.setFloating(True)
|
|
dockWidget.setParent(parent)
|
|
# We call show and setFloating to True to make sure
|
|
# the widget is visible
|
|
dockWidget.show()
|
|
dockWidget.setFloating(True)
|
|
|
|
def _isUnderCursor(self, widget):
|
|
"""
|
|
Checks if the mouse is under the given widget
|
|
|
|
Arguments:
|
|
widget (QWidget): widget to check
|
|
"""
|
|
pos = QtGui.QCursor.pos()
|
|
corner = widget.pos()
|
|
size = widget.size()
|
|
isInHorizontalBoundary = corner.x() <= pos.x() <= (corner.x() + size.width())
|
|
isInVerticalBoundary = corner.y() <= pos.y() <= (corner.y() + size.height())
|
|
return isInHorizontalBoundary and isInVerticalBoundary
|
|
|
|
|
|
# Make sure there is only one instance of the widget open
|
|
thisModule = sys.modules[__name__]
|
|
if not hasattr(thisModule, "_secondaryDockableWindow"):
|
|
setattr(thisModule, "_secondaryDockableWindow", None)
|
|
|
|
def Run(show=True):
|
|
thisModule = sys.modules[__name__]
|
|
win = getattr(thisModule, "_secondaryDockableWindow")
|
|
if _secondaryDockableWindow is None:
|
|
win = SecondDockableWindow()
|
|
setattr(thisModule, "_secondaryDockableWindow", win)
|
|
else:
|
|
win.updateDockWidgets()
|
|
|
|
if show:
|
|
win.show()
|
|
|
|
return win
|