From 6f7d66cb3110d8709555c26ea2efe510ea822da5 Mon Sep 17 00:00:00 2001
From: "Veronica K. B. Olsen" <1619840+vkbo@users.noreply.github.com>
Date: Mon, 1 Jun 2020 23:08:40 +0200
Subject: [PATCH] Merged the custom widgets and layouts into one file
---
nw/gui/additions/__init__.py | 4 +-
nw/gui/additions/pageddialog.py | 125 ----------------
nw/gui/additions/qconfiglayout.py | 238 +++++++++++++++++++++++++++++-
nw/gui/additions/qswitch.py | 164 --------------------
4 files changed, 236 insertions(+), 295 deletions(-)
delete mode 100644 nw/gui/additions/pageddialog.py
delete mode 100644 nw/gui/additions/qswitch.py
diff --git a/nw/gui/additions/__init__.py b/nw/gui/additions/__init__.py
index dbacd16e..83c73cdc 100644
--- a/nw/gui/additions/__init__.py
+++ b/nw/gui/additions/__init__.py
@@ -1,8 +1,8 @@
# -*- coding: utf-8 -*-
-from nw.gui.additions.pageddialog import PagedDialog
+from nw.gui.additions.qconfiglayout import PagedDialog
from nw.gui.additions.qconfiglayout import QConfigLayout
from nw.gui.additions.qconfiglayout import QHelpLabel
-from nw.gui.additions.qswitch import QSwitch
+from nw.gui.additions.qconfiglayout import QSwitch
__all__ = [
"PagedDialog",
diff --git a/nw/gui/additions/pageddialog.py b/nw/gui/additions/pageddialog.py
deleted file mode 100644
index 2b65cbb9..00000000
--- a/nw/gui/additions/pageddialog.py
+++ /dev/null
@@ -1,125 +0,0 @@
-# -*- coding: utf-8 -*-
-"""novelWriter Paged Dialog
-
- novelWriter – Paged Dialog
-============================
- A custom QDialog with a built-in QTabWidget and vertical tabs.
-
- File History:
- Created: 2020-05-17 [0.5.1]
-
- This file is a part of novelWriter
- Copyright 2020, Veronica Berglyd Olsen
-
- 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 .
-"""
-
-import logging
-import nw
-
-from PyQt5.QtCore import Qt, QRect, QPoint
-from PyQt5.QtWidgets import (
- QDialog, QHBoxLayout, QVBoxLayout, QTabWidget, QTabBar, QStyle,
- QStylePainter, QStyleOptionTab
-)
-
-logger = logging.getLogger(__name__)
-
-class PagedDialog(QDialog):
-
- def __init__(self, theParent=None):
- QDialog.__init__(self, parent=theParent)
-
- self._outerBox = QVBoxLayout()
- self._buttonBox = QHBoxLayout()
- self._tabBox = QTabWidget()
-
- self._tabBar = VerticalTabBar(self)
- self._tabBox.setTabBar(self._tabBar)
- self._tabBox.setTabPosition(QTabWidget.West)
- self._tabBar.setExpanding(False)
-
- self._outerBox.addWidget(self._tabBox)
- self._outerBox.addLayout(self._buttonBox)
- self.setLayout(self._outerBox)
-
- # Default Margins
- qM = self._outerBox.contentsMargins()
- mL = qM.left()
- mR = qM.right()
- mT = qM.top()
- mB = qM.bottom()
-
- self.setContentsMargins(0, 0, 0, 0)
- self._outerBox.setContentsMargins(0, 0, 0, mB)
- self._buttonBox.setContentsMargins(mL, 0, mR, 0)
- self._outerBox.setSpacing(mT)
-
- return
-
- def addTab(self, tabWidget, tabLabel):
- """Forwards the adding of tabs to the QTabWidget.
- """
- self._tabBox.addTab(tabWidget, tabLabel)
- return
-
- def addControls(self, buttonBar):
- """Adds a button bar to the dialog.
- """
- self._buttonBox.addWidget(buttonBar)
- return
-
-# END Class PagedDialog
-
-class VerticalTabBar(QTabBar):
-
- def __init__(self, theParent=None):
- QTabBar.__init__(self, parent=theParent)
- return
-
- def tabSizeHint(self, theIndex):
- """Returns a transposed size hint for the rotated bar.
- """
- tSize = QTabBar.tabSizeHint(self, theIndex)
- tSize.transpose()
- return tSize
-
- def paintEvent(self, theEvent):
- """Custom implementation of the label painter that rotates the
- label 90 degrees.
- """
- pObj = QStylePainter(self)
- oObj = QStyleOptionTab()
-
- for i in range(self.count()):
- self.initStyleOption(oObj, i)
- pObj.drawControl(QStyle.CE_TabBarTabShape, oObj)
- pObj.save()
-
- oSize = oObj.rect.size()
- oSize.transpose()
- oRect = QRect(QPoint(), oSize)
- oRect.moveCenter(oObj.rect.center())
- oObj.rect = oRect
-
- oCenter = self.tabRect(i).center()
- pObj.translate(oCenter)
- pObj.rotate(90)
- pObj.translate(-oCenter)
- pObj.drawControl(QStyle.CE_TabBarTabLabel, oObj)
- pObj.restore()
-
- return
-
-# END Class VerticalTabBar
diff --git a/nw/gui/additions/qconfiglayout.py b/nw/gui/additions/qconfiglayout.py
index 70b3042d..96e0c482 100644
--- a/nw/gui/additions/qconfiglayout.py
+++ b/nw/gui/additions/qconfiglayout.py
@@ -6,7 +6,9 @@
A custom Qt grid layout for config forms similar to QFormLayout
File History:
- Created: 2020-05-03 [0.4.5]
+ Created: 2020-05-03 [0.4.5] QConfigLayout
+ Created: 2020-05-03 [0.4.5] QSwitch
+ Created: 2020-05-17 [0.5.1] PagedDialog
This file is a part of novelWriter
Copyright 2020, Veronica Berglyd Olsen
@@ -28,16 +30,24 @@
import logging
import nw
-from PyQt5.QtCore import Qt
-from PyQt5.QtGui import QColor, QPalette
+from PyQt5.QtGui import QColor, QPalette, QPainter
+from PyQt5.QtCore import (
+ Qt, QRect, QPoint, QSize, QRectF, QPropertyAnimation, pyqtProperty
+)
from PyQt5.QtWidgets import (
- QGridLayout, QLabel, QWidget, QVBoxLayout, QHBoxLayout
+ QGridLayout, QLabel, QWidget, QVBoxLayout, QHBoxLayout, QSizePolicy,
+ QAbstractButton, QDialog, QTabWidget, QTabBar, QStyle,
+ QStylePainter, QStyleOptionTab
)
from nw.constants import nwUnicode
logger = logging.getLogger(__name__)
+# =============================================================================================== #
+# Config FOrm Layout
+# =============================================================================================== #
+
class QConfigLayout(QGridLayout):
def __init__(self):
@@ -198,3 +208,223 @@ class QHelpLabel(QLabel):
return
# END Class QHelpLabel
+
+# =============================================================================================== #
+# Switch Widget
+# =============================================================================================== #
+
+class QSwitch(QAbstractButton):
+
+ def __init__(self, parent=None):
+ super().__init__(parent=parent)
+
+ self.setCheckable(True)
+ self.setSizePolicy(QSizePolicy.Fixed, QSizePolicy.Fixed)
+ self.setFixedWidth(40)
+ self.setFixedHeight(20)
+ self._offset = 10
+
+ return
+
+ ##
+ # Properties
+ ##
+
+ @pyqtProperty(int)
+ def offset(self):
+ return self._offset
+
+ @offset.setter
+ def offset(self, theOffset):
+ self._offset = theOffset
+ self.update()
+ return
+
+ ##
+ # Getters and Setters
+ ##
+
+ def setChecked(self, isChecked):
+ """Overload setChecked to also alter the offset.
+ """
+ super().setChecked(isChecked)
+ if isChecked:
+ self.offset = 30
+ else:
+ self.offset = 10
+ return
+
+ ##
+ # Events
+ ##
+
+ def resizeEvent(self, theEvent):
+ """Overload resize to ensure correct offset.
+ """
+ super().resizeEvent(theEvent)
+ if self.isChecked():
+ self.offset = 30
+ else:
+ self.offset = 10
+ return
+
+ def paintEvent(self, event):
+ """Drawing the switch itself.
+ """
+ qPaint = QPainter(self)
+ qPaint.setRenderHint(QPainter.Antialiasing, True)
+ qPaint.setPen(Qt.NoPen)
+
+ qPalette = self.palette()
+ if self.isChecked():
+ trackBrush = qPalette.highlight()
+ thumbBrush = qPalette.highlightedText()
+ textColor = qPalette.highlight().color()
+ thumbText = nwUnicode.U_CHECK
+ else:
+ trackBrush = qPalette.dark()
+ thumbBrush = qPalette.light()
+ textColor = qPalette.dark().color()
+ thumbText = nwUnicode.U_MULT
+
+ if self.isEnabled():
+ trackOpacity = 1.0
+ else:
+ trackOpacity = 0.6
+ trackBrush = qPalette.shadow()
+ thumbBrush = qPalette.mid()
+ textColor = qPalette.shadow().color()
+
+ qPaint.setBrush(trackBrush)
+ qPaint.setOpacity(trackOpacity)
+ qPaint.drawRoundedRect(0, 0, 40, 20, 10, 10)
+
+ qPaint.setBrush(thumbBrush)
+ qPaint.drawEllipse(self.offset - 8, 2, 16, 16)
+
+ theFont = qPaint.font()
+ theFont.setPixelSize(12)
+ qPaint.setPen(textColor)
+ qPaint.setFont(theFont)
+ qPaint.drawText(
+ QRectF(self.offset - 8, 2, 16, 16),
+ Qt.AlignCenter, thumbText
+ )
+
+ return
+
+ def mouseReleaseEvent(self, event):
+ """Animate the switch on mouse release.
+ """
+ super().mouseReleaseEvent(event)
+ if event.button() == Qt.LeftButton:
+ doAnim = QPropertyAnimation(self, b'offset', self)
+ doAnim.setDuration(120)
+ doAnim.setStartValue(self.offset)
+ if self.isChecked():
+ doAnim.setEndValue(30)
+ else:
+ doAnim.setEndValue(10)
+ doAnim.start()
+ return
+
+ def enterEvent(self, event):
+ """Change the cursor when hovering the button.
+ """
+ self.setCursor(Qt.PointingHandCursor)
+ super().enterEvent(event)
+ return
+
+# END Class QSwitch
+
+# =============================================================================================== #
+# Paged Dialog w/Custom TabWidget
+# =============================================================================================== #
+
+class PagedDialog(QDialog):
+
+ def __init__(self, theParent=None):
+ QDialog.__init__(self, parent=theParent)
+
+ self._outerBox = QVBoxLayout()
+ self._buttonBox = QHBoxLayout()
+ self._tabBox = QTabWidget()
+
+ self._tabBar = VerticalTabBar(self)
+ self._tabBox.setTabBar(self._tabBar)
+ self._tabBox.setTabPosition(QTabWidget.West)
+ self._tabBar.setExpanding(False)
+
+ self._outerBox.addWidget(self._tabBox)
+ self._outerBox.addLayout(self._buttonBox)
+ self.setLayout(self._outerBox)
+
+ # Default Margins
+ qM = self._outerBox.contentsMargins()
+ mL = qM.left()
+ mR = qM.right()
+ mT = qM.top()
+ mB = qM.bottom()
+
+ self.setContentsMargins(0, 0, 0, 0)
+ self._outerBox.setContentsMargins(0, 0, 0, mB)
+ self._buttonBox.setContentsMargins(mL, 0, mR, 0)
+ self._outerBox.setSpacing(mT)
+
+ return
+
+ def addTab(self, tabWidget, tabLabel):
+ """Forwards the adding of tabs to the QTabWidget.
+ """
+ self._tabBox.addTab(tabWidget, tabLabel)
+ return
+
+ def addControls(self, buttonBar):
+ """Adds a button bar to the dialog.
+ """
+ self._buttonBox.addWidget(buttonBar)
+ return
+
+# END Class PagedDialog
+
+class VerticalTabBar(QTabBar):
+
+ def __init__(self, theParent=None):
+ QTabBar.__init__(self, parent=theParent)
+ return
+
+ def tabSizeHint(self, theIndex):
+ """Returns a transposed size hint for the rotated bar.
+ """
+ tSize = QTabBar.tabSizeHint(self, theIndex)
+ tSize.transpose()
+ return tSize
+
+ def paintEvent(self, theEvent):
+ """Custom implementation of the label painter that rotates the
+ label 90 degrees.
+ """
+ pObj = QStylePainter(self)
+ oObj = QStyleOptionTab()
+
+ for i in range(self.count()):
+ self.initStyleOption(oObj, i)
+ pObj.drawControl(QStyle.CE_TabBarTabShape, oObj)
+ pObj.save()
+
+ oSize = oObj.rect.size()
+ oSize.transpose()
+ oRect = QRect(QPoint(), oSize)
+ oRect.moveCenter(oObj.rect.center())
+ oObj.rect = oRect
+
+ oCenter = self.tabRect(i).center()
+ pObj.translate(oCenter)
+ pObj.rotate(90)
+ pObj.translate(-oCenter)
+ pObj.drawControl(QStyle.CE_TabBarTabLabel, oObj)
+ pObj.restore()
+
+ return
+
+# END Class VerticalTabBar
diff --git a/nw/gui/additions/qswitch.py b/nw/gui/additions/qswitch.py
deleted file mode 100644
index 7eb32830..00000000
--- a/nw/gui/additions/qswitch.py
+++ /dev/null
@@ -1,164 +0,0 @@
-# -*- coding: utf-8 -*-
-"""novelWriter Addition QSwitch
-
- novelWriter – Addition QSwitch
-================================
- A custom Qt switch button
-
- File History:
- Created: 2020-05-03 [0.4.5]
-
- The core code of this class is based on Stack Overflow example by
- Stefan Scherfke: https://stackoverflow.com/a/51825815/5825851
-
- This file is a part of novelWriter
- Copyright 2020, Veronica Berglyd Olsen
-
- 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 .
-"""
-
-import logging
-import nw
-
-from PyQt5.QtCore import Qt, QSize, QRectF, QPropertyAnimation, pyqtProperty
-from PyQt5.QtWidgets import QAbstractButton, QSizePolicy
-from PyQt5.QtGui import QPainter
-
-from nw.constants import nwUnicode
-
-logger = logging.getLogger(__name__)
-
-class QSwitch(QAbstractButton):
-
- def __init__(self, parent=None):
- super().__init__(parent=parent)
-
- self.setCheckable(True)
- self.setSizePolicy(QSizePolicy.Fixed, QSizePolicy.Fixed)
- self.setFixedWidth(40)
- self.setFixedHeight(20)
- self._offset = 10
-
- return
-
- ##
- # Properties
- ##
-
- @pyqtProperty(int)
- def offset(self):
- return self._offset
-
- @offset.setter
- def offset(self, theOffset):
- self._offset = theOffset
- self.update()
- return
-
- ##
- # Getters and Setters
- ##
-
- def setChecked(self, isChecked):
- """Overload setChecked to also alter the offset.
- """
- super().setChecked(isChecked)
- if isChecked:
- self.offset = 30
- else:
- self.offset = 10
- return
-
- ##
- # Events
- ##
-
- def resizeEvent(self, theEvent):
- """Overload resize to ensure correct offset.
- """
- super().resizeEvent(theEvent)
- if self.isChecked():
- self.offset = 30
- else:
- self.offset = 10
- return
-
- def paintEvent(self, event):
- """Drawing the switch itself.
- """
- qPaint = QPainter(self)
- qPaint.setRenderHint(QPainter.Antialiasing, True)
- qPaint.setPen(Qt.NoPen)
-
- qPalette = self.palette()
- if self.isChecked():
- trackBrush = qPalette.highlight()
- thumbBrush = qPalette.highlightedText()
- textColor = qPalette.highlight().color()
- thumbText = nwUnicode.U_CHECK
- else:
- trackBrush = qPalette.dark()
- thumbBrush = qPalette.light()
- textColor = qPalette.dark().color()
- thumbText = nwUnicode.U_MULT
-
- if self.isEnabled():
- trackOpacity = 1.0
- else:
- trackOpacity = 0.6
- trackBrush = qPalette.shadow()
- thumbBrush = qPalette.mid()
- textColor = qPalette.shadow().color()
-
- qPaint.setBrush(trackBrush)
- qPaint.setOpacity(trackOpacity)
- qPaint.drawRoundedRect(0, 0, 40, 20, 10, 10)
-
- qPaint.setBrush(thumbBrush)
- qPaint.drawEllipse(self.offset - 8, 2, 16, 16)
-
- theFont = qPaint.font()
- theFont.setPixelSize(12)
- qPaint.setPen(textColor)
- qPaint.setFont(theFont)
- qPaint.drawText(
- QRectF(self.offset - 8, 2, 16, 16),
- Qt.AlignCenter, thumbText
- )
-
- return
-
- def mouseReleaseEvent(self, event):
- """Animate the switch on mouse release.
- """
- super().mouseReleaseEvent(event)
- if event.button() == Qt.LeftButton:
- doAnim = QPropertyAnimation(self, b'offset', self)
- doAnim.setDuration(120)
- doAnim.setStartValue(self.offset)
- if self.isChecked():
- doAnim.setEndValue(30)
- else:
- doAnim.setEndValue(10)
- doAnim.start()
- return
-
- def enterEvent(self, event):
- """Change the cursor when hovering the button.
- """
- self.setCursor(Qt.PointingHandCursor)
- super().enterEvent(event)
- return
-
-# END Class QSwitch