Files
gtav-src/tools_ng/techart/dcc/motionbuilder2014/python/RS/Tools/SecondDockableWindow.py
T
2025-09-29 00:52:08 +02:00

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