Krita/krita/pykrita/krita-redesign/floating_toolbox_(scripter).py

184 lines
6.5 KiB
Python
Raw Permalink Normal View History

2025-03-07 08:03:18 +01:00
"""
Plugin for Krita UI Redesign, Copyright (C) 2020 Kapyia, Pedro Reis
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <https://www.gnu.org/licenses/>.
"""
from krita import *
from PyQt5.QtWidgets import QWidget, QToolButton
import sys
class subWindowFilter(QObject):
"""Event Filter object"""
def __init__(self, parent=None):
super().__init__(parent)
qWin = Application.activeWindow().qwindow()
self.mdiArea = qWin.centralWidget().findChild(QMdiArea)
self.target = None
def eventFilter(self, obj, e):
"""Event filter: Update the Toolbox's position to match to the current view
if the (sub-)window has moved, changed in size or been activated."""
if (e.type() == QEvent.Move or
e.type() == QEvent.Resize or
e.type() == QEvent.WindowActivate):
self.moveToolBox()
return False
def moveToolBox(self):
"""Move the toolbox to the position of the current View"""
subWin = self.mdiArea.activeSubWindow()
if subWin and self.target:
for c in subWin.children():
if 'view' in c.objectName(): # Grab the View from the tab/sub-window
view = c
### NOTE: Determining the correct corner position might be better done based
### on whether Krita is set to handle multiple documents as 'Subwindows' or 'Tabs'
# pos = self.mdiArea.pos() # Move to top of QMdiArea. Only suitable for 'Subwindows' mode.
pos = self.mdiArea.mapFromGlobal(view.mapToGlobal(QPoint(0,0))) # Move to top left corner of current view
self.target.move(pos)
if view.height() < self.target.sizeHint().height():
self.target.resize(self.target.sizeHint().width(), view.height())
else:
self.target.resize(self.target.sizeHint())
def setTargetWidget(self, wdgt):
self.target = wdgt
class floatingToolbarWidget(QWidget):
def __init__(self, parent=None):
super(floatingToolbarWidget, self).__init__(parent)
self.setWindowFlags(
Qt.WindowStaysOnTopHint |
Qt.FramelessWindowHint
)
self.setLayout(QVBoxLayout())
self.layout().setContentsMargins(4,4,4,4)
self.btnHide = QToolButton()
self.btnHide.setIcon(Application.icon("light_visible"))
self.btnHide.setIconSize(QSize(14,14))
self.btnHide.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Maximum)
self.btnHide.clicked.connect(self.toggleWidgetVisible)
self.layout().addWidget(self.btnHide)
self.widget = None
self.widgetDocker = None
def closeEvent(self, e):
self.returnDocker()
return super().closeEvent(e)
def borrowDocker(self, name):
"""Borrow a docker widget from Krita's existing list of dockers"""
docker = Application.activeWindow().qwindow().findChild(QDockWidget, name)
# Does requested widget exist?
if docker and docker.widget():
# Return any previous widget
self.returnDocker()
self.widgetDocker = docker
self.widget = docker.widget()
self.layout().addWidget(self.widget)
self.resize(self.sizeHint())
return True
return False
def returnDocker(self):
"""Return the borrowed docker to it's original QDockerWidget"""
# Ensure there's a widget to return
if self.widget:
self.widgetDocker.setWidget(self.widget)
self.widget = None
self.widgetDocker = None
def toggleWidgetVisible(self):
self.widget.setVisible(not self.widget.isVisible())
self.resize(self.sizeHint())
# Get all the Krita widgets we need
qWin = Application.activeWindow().qwindow()
tlbx = qWin.findChild(QDockWidget, 'ToolBox')
mdiArea = qWin.findChild(QMdiArea)
def createWidget(name, parent=None):
wdgt = floatingToolbarWidget(parent)
wdgt.setObjectName(name)
return wdgt
def slotMdiFilterManager(subWin):
'''Ensure that the current SubWindow has the filter installed,
and immediately move the Toolbox to current View.'''
if subWin:
subWin.installEventFilter(filterObj)
filterObj.moveToolBox()
# Create the new floating widget
floater = createWidget('floatingToolbox', mdiArea)
floater.setStyleSheet("""
QWidget {
background-color: rgba(128, 128, 128, .01);
}
.QScrollArea {
background-color: #00000000;
}
QScrollArea * {
background-color: #00000000;
}
QScrollArea QToolTip {
background-color: #ffffff;
}
QAbstractButton {
background-color: #77000000;
border: none;
border-radius: 4px;
}
QAbstractButton:checked {
background-color: #aa306fa8;
}
QAbstractButton:hover {
background-color: #1c1c1c;
}
QAbstractButton:pressed {
background-color: #53728e;
}
""")
floater.borrowDocker('ToolBox')
# Create and install event filter to sub window(s) and main window
filterObj = subWindowFilter() # Create filter object
filterObj.setTargetWidget(floater)
mdiArea.subWindowActivated.connect(slotMdiFilterManager)
qWin.installEventFilter(filterObj)
floater.show()