Improve how tool buttons are generated

This commit is contained in:
Veronica Berglyd Olsen
2024-04-01 20:21:34 +02:00
parent c3467d89c2
commit 24e45fb661
36 changed files with 278 additions and 285 deletions
+30 -50
View File
@@ -40,7 +40,7 @@ from typing import TYPE_CHECKING
from PyQt5.QtCore import (
pyqtSignal, pyqtSlot, QObject, QPoint, QRegExp, QRegularExpression,
QRunnable, QSize, Qt, QTimer
QRunnable, Qt, QTimer
)
from PyQt5.QtGui import (
QColor, QCursor, QFont, QKeyEvent, QKeySequence, QMouseEvent, QPalette,
@@ -48,8 +48,7 @@ from PyQt5.QtGui import (
)
from PyQt5.QtWidgets import (
QAction, QFrame, QGridLayout, QHBoxLayout, QLabel, QLineEdit, QMenu,
QPlainTextEdit, QPushButton, QShortcut, QToolBar, QToolButton, QVBoxLayout,
QWidget, qApp
QPlainTextEdit, QShortcut, QToolBar, QVBoxLayout, QWidget, qApp
)
from novelwriter import CONFIG, SHARED
@@ -58,7 +57,7 @@ from novelwriter.constants import nwConst, nwKeyWords, nwShortcode, nwUnicode
from novelwriter.core.document import NWDocument
from novelwriter.enum import nwDocAction, nwDocInsert, nwDocMode, nwItemClass, nwTrinary
from novelwriter.extensions.eventfilters import WheelEventFilter
from novelwriter.extensions.modified import NIconToolButton
from novelwriter.extensions.modified import NIconToggleButton, NIconToolButton
from novelwriter.gui.dochighlight import BLOCK_META, BLOCK_TITLE
from novelwriter.gui.editordocument import GuiTextDocument
from novelwriter.gui.theme import STYLES_MIN_TOOLBUTTON
@@ -2263,79 +2262,68 @@ class GuiDocToolBar(QWidget):
logger.debug("Create: GuiDocToolBar")
iSz = SHARED.theme.baseIconSize
cM = CONFIG.pxInt(4)
tPx = int(0.8*SHARED.theme.fontPixelSize)
iconSize = QSize(tPx, tPx)
self.setContentsMargins(0, 0, 0, 0)
# General Buttons
# ===============
self.tbBoldMD = QToolButton(self)
self.tbBoldMD.setIconSize(iconSize)
self.tbBoldMD = NIconToolButton(self, iSz)
self.tbBoldMD.setToolTip(self.tr("Markdown Bold"))
self.tbBoldMD.clicked.connect(
lambda: self.requestDocAction.emit(nwDocAction.MD_BOLD)
)
self.tbItalicMD = QToolButton(self)
self.tbItalicMD.setIconSize(iconSize)
self.tbItalicMD = NIconToolButton(self, iSz)
self.tbItalicMD.setToolTip(self.tr("Markdown Italic"))
self.tbItalicMD.clicked.connect(
lambda: self.requestDocAction.emit(nwDocAction.MD_ITALIC)
)
self.tbStrikeMD = QToolButton(self)
self.tbStrikeMD.setIconSize(iconSize)
self.tbStrikeMD = NIconToolButton(self, iSz)
self.tbStrikeMD.setToolTip(self.tr("Markdown Strikethrough"))
self.tbStrikeMD.clicked.connect(
lambda: self.requestDocAction.emit(nwDocAction.MD_STRIKE)
)
self.tbBold = QToolButton(self)
self.tbBold.setIconSize(iconSize)
self.tbBold = NIconToolButton(self, iSz)
self.tbBold.setToolTip(self.tr("Shortcode Bold"))
self.tbBold.clicked.connect(
lambda: self.requestDocAction.emit(nwDocAction.SC_BOLD)
)
self.tbItalic = QToolButton(self)
self.tbItalic.setIconSize(iconSize)
self.tbItalic = NIconToolButton(self, iSz)
self.tbItalic.setToolTip(self.tr("Shortcode Italic"))
self.tbItalic.clicked.connect(
lambda: self.requestDocAction.emit(nwDocAction.SC_ITALIC)
)
self.tbStrike = QToolButton(self)
self.tbStrike.setIconSize(iconSize)
self.tbStrike = NIconToolButton(self, iSz)
self.tbStrike.setToolTip(self.tr("Shortcode Strikethrough"))
self.tbStrike.clicked.connect(
lambda: self.requestDocAction.emit(nwDocAction.SC_STRIKE)
)
self.tbUnderline = QToolButton(self)
self.tbUnderline.setIconSize(iconSize)
self.tbUnderline = NIconToolButton(self, iSz)
self.tbUnderline.setToolTip(self.tr("Shortcode Underline"))
self.tbUnderline.clicked.connect(
lambda: self.requestDocAction.emit(nwDocAction.SC_ULINE)
)
self.tbMark = QToolButton(self)
self.tbMark.setIconSize(iconSize)
self.tbMark = NIconToolButton(self, iSz)
self.tbMark.setToolTip(self.tr("Shortcode Highlight"))
self.tbMark.clicked.connect(
lambda: self.requestDocAction.emit(nwDocAction.SC_MARK)
)
self.tbSuperscript = QToolButton(self)
self.tbSuperscript.setIconSize(iconSize)
self.tbSuperscript = NIconToolButton(self, iSz)
self.tbSuperscript.setToolTip(self.tr("Shortcode Superscript"))
self.tbSuperscript.clicked.connect(
lambda: self.requestDocAction.emit(nwDocAction.SC_SUP)
)
self.tbSubscript = QToolButton(self)
self.tbSubscript.setIconSize(iconSize)
self.tbSubscript = NIconToolButton(self, iSz)
self.tbSubscript.setToolTip(self.tr("Shortcode Subscript"))
self.tbSubscript.clicked.connect(
lambda: self.requestDocAction.emit(nwDocAction.SC_SUB)
@@ -2415,8 +2403,9 @@ class GuiDocEditSearch(QFrame):
self.doNextFile = CONFIG.searchNextFile
self.doMatchCap = CONFIG.searchMatchCap
iSz = SHARED.theme.baseIconSize
mPx = CONFIG.pxInt(6)
tPx = int(0.8*SHARED.theme.fontPixelSize)
self.boxFont = SHARED.theme.guiFont
self.boxFont.setPointSizeF(0.9*SHARED.theme.fontPointSize)
@@ -2442,7 +2431,7 @@ class GuiDocEditSearch(QFrame):
self.searchOpt = QToolBar(self)
self.searchOpt.setToolButtonStyle(Qt.ToolButtonStyle.ToolButtonIconOnly)
self.searchOpt.setIconSize(QSize(tPx, tPx))
self.searchOpt.setIconSize(iSz)
self.searchOpt.setContentsMargins(0, 0, 0, 0)
self.searchLabel = QLabel(self.tr("Search"))
@@ -2500,20 +2489,14 @@ class GuiDocEditSearch(QFrame):
# Buttons
# =======
bPx = self.searchBox.sizeHint().height()
self.showReplace = QToolButton(self)
self.showReplace.setArrowType(Qt.ArrowType.RightArrow)
self.showReplace.setCheckable(True)
self.showReplace = NIconToggleButton(self, iSz, "unfold")
self.showReplace.toggled.connect(self._doToggleReplace)
self.searchButton = QPushButton("")
self.searchButton.setFixedSize(QSize(bPx, bPx))
self.searchButton = NIconToolButton(self, iSz)
self.searchButton.setToolTip(self.tr("Find in current document"))
self.searchButton.clicked.connect(self._doSearch)
self.replaceButton = QPushButton("")
self.replaceButton.setFixedSize(QSize(bPx, bPx))
self.replaceButton = NIconToolButton(self, iSz)
self.replaceButton.setToolTip(self.tr("Find and replace in current document"))
self.replaceButton.clicked.connect(self._doReplace)
@@ -2738,10 +2721,6 @@ class GuiDocEditSearch(QFrame):
@pyqtSlot(bool)
def _doToggleReplace(self, state: bool) -> None:
"""Toggle the show/hide of the replace box."""
if state:
self.showReplace.setArrowType(Qt.ArrowType.DownArrow)
else:
self.showReplace.setArrowType(Qt.ArrowType.RightArrow)
self.replaceBox.setVisible(state)
self.replaceButton.setVisible(state)
self.repVisible = state
@@ -2821,7 +2800,8 @@ class GuiDocEditHeader(QWidget):
self._docHandle = None
self._docOutline: dict[int, str] = {}
iPx = SHARED.theme.baseIconSize
iPx = SHARED.theme.baseIconHeight
iSz = SHARED.theme.baseIconSize
mPx = CONFIG.pxInt(4)
# Main Widget Settings
@@ -2844,27 +2824,27 @@ class GuiDocEditHeader(QWidget):
self.outlineMenu = QMenu(self)
# Buttons
self.tbButton = NIconToolButton(self, iPx)
self.tbButton = NIconToolButton(self, iSz)
self.tbButton.setVisible(False)
self.tbButton.setToolTip(self.tr("Toggle Tool Bar"))
self.tbButton.clicked.connect(lambda: self.toggleToolBarRequest.emit())
self.outlineButton = NIconToolButton(self, iPx)
self.outlineButton = NIconToolButton(self, iSz)
self.outlineButton.setVisible(False)
self.outlineButton.setToolTip(self.tr("Outline"))
self.outlineButton.setMenu(self.outlineMenu)
self.searchButton = NIconToolButton(self, iPx)
self.searchButton = NIconToolButton(self, iSz)
self.searchButton.setVisible(False)
self.searchButton.setToolTip(self.tr("Search"))
self.searchButton.clicked.connect(self.docEditor.toggleSearch)
self.minmaxButton = NIconToolButton(self, iPx)
self.minmaxButton = NIconToolButton(self, iSz)
self.minmaxButton.setVisible(False)
self.minmaxButton.setToolTip(self.tr("Toggle Focus Mode"))
self.minmaxButton.clicked.connect(lambda: self.docEditor.toggleFocusModeRequest.emit())
self.closeButton = NIconToolButton(self, iPx)
self.closeButton = NIconToolButton(self, iSz)
self.closeButton.setVisible(False)
self.closeButton.setToolTip(self.tr("Close"))
self.closeButton.clicked.connect(self._closeDocument)
@@ -3038,7 +3018,7 @@ class GuiDocEditFooter(QWidget):
self._tItem = None
self._docHandle = None
iPx = round(0.9*SHARED.theme.baseIconSize)
iPx = round(0.9*SHARED.theme.baseIconHeight)
fPx = int(0.9*SHARED.theme.fontPixelSize)
mPx = CONFIG.pxInt(8)
bSp = CONFIG.pxInt(4)
@@ -3137,7 +3117,7 @@ class GuiDocEditFooter(QWidget):
def updateTheme(self) -> None:
"""Update theme elements."""
iPx = round(0.9*SHARED.theme.baseIconSize)
iPx = round(0.9*SHARED.theme.baseIconHeight)
self.linesIcon.setPixmap(SHARED.theme.getPixmap("status_lines", (iPx, iPx)))
self.wordsIcon.setPixmap(SHARED.theme.getPixmap("status_stats", (iPx, iPx)))
self.matchColours()
@@ -3179,7 +3159,7 @@ class GuiDocEditFooter(QWidget):
sIcon = QPixmap()
sText = ""
else:
iPx = round(0.9*SHARED.theme.baseIconSize)
iPx = round(0.9*SHARED.theme.baseIconHeight)
status, icon = self._tItem.getImportStatus(incIcon=True)
sIcon = icon.pixmap(iPx, iPx)
sText = f"{status} / {self._tItem.describeMe()}"
+13 -12
View File
@@ -30,7 +30,7 @@ import logging
from enum import Enum
from PyQt5.QtCore import pyqtSignal, pyqtSlot, QPoint, QSize, Qt, QUrl
from PyQt5.QtCore import pyqtSignal, pyqtSlot, QPoint, Qt, QUrl
from PyQt5.QtGui import (
QCursor, QFont, QMouseEvent, QPalette, QResizeEvent, QTextCursor,
QTextOption
@@ -627,7 +627,8 @@ class GuiDocViewHeader(QWidget):
self._docHandle = None
self._docOutline: dict[str, tuple[str, int]] = {}
iPx = SHARED.theme.baseIconSize
iPx = SHARED.theme.baseIconHeight
iSz = SHARED.theme.baseIconSize
mPx = CONFIG.pxInt(4)
# Main Widget Settings
@@ -651,27 +652,27 @@ class GuiDocViewHeader(QWidget):
self.outlineMenu = QMenu(self)
# Buttons
self.outlineButton = NIconToolButton(self, iPx)
self.outlineButton = NIconToolButton(self, iSz)
self.outlineButton.setVisible(False)
self.outlineButton.setToolTip(self.tr("Outline"))
self.outlineButton.setMenu(self.outlineMenu)
self.backButton = NIconToolButton(self, iPx)
self.backButton = NIconToolButton(self, iSz)
self.backButton.setVisible(False)
self.backButton.setToolTip(self.tr("Go Backward"))
self.backButton.clicked.connect(self.docViewer.navBackward)
self.forwardButton = NIconToolButton(self, iPx)
self.forwardButton = NIconToolButton(self, iSz)
self.forwardButton.setVisible(False)
self.forwardButton.setToolTip(self.tr("Go Forward"))
self.forwardButton.clicked.connect(self.docViewer.navForward)
self.refreshButton = NIconToolButton(self, iPx)
self.refreshButton = NIconToolButton(self, iSz)
self.refreshButton.setVisible(False)
self.refreshButton.setToolTip(self.tr("Reload"))
self.refreshButton.clicked.connect(self._refreshDocument)
self.closeButton = NIconToolButton(self, iPx)
self.closeButton = NIconToolButton(self, iSz)
self.closeButton.setVisible(False)
self.closeButton.setToolTip(self.tr("Close"))
self.closeButton.clicked.connect(self._closeDocument)
@@ -849,17 +850,17 @@ class GuiDocViewFooter(QWidget):
# Internal Variables
self._docHandle = None
iPx = SHARED.theme.baseIconSize
iPx = SHARED.theme.baseIconHeight
iSz = SHARED.theme.baseIconSize
hSp = CONFIG.pxInt(4)
mPx = CONFIG.pxInt(4)
iconSize = QSize(iPx, iPx)
# Main Widget Settings
self.setContentsMargins(0, 0, 0, 0)
self.setAutoFillBackground(True)
# Show/Hide Details
self.showHide = NIconToolButton(self, iPx)
self.showHide = NIconToolButton(self, iSz)
self.showHide.clicked.connect(lambda: self.docViewer.togglePanelVisibility.emit())
self.showHide.setToolTip(self.tr("Show/Hide Viewer Panel"))
@@ -869,7 +870,7 @@ class GuiDocViewFooter(QWidget):
self.showComments.setCheckable(True)
self.showComments.setChecked(CONFIG.viewComments)
self.showComments.setToolButtonStyle(Qt.ToolButtonStyle.ToolButtonTextBesideIcon)
self.showComments.setIconSize(iconSize)
self.showComments.setIconSize(iSz)
self.showComments.toggled.connect(self._doToggleComments)
self.showComments.setToolTip(self.tr("Show Comments"))
@@ -879,7 +880,7 @@ class GuiDocViewFooter(QWidget):
self.showSynopsis.setCheckable(True)
self.showSynopsis.setChecked(CONFIG.viewSynopsis)
self.showSynopsis.setToolButtonStyle(Qt.ToolButtonStyle.ToolButtonTextBesideIcon)
self.showSynopsis.setIconSize(iconSize)
self.showSynopsis.setIconSize(iSz)
self.showSynopsis.toggled.connect(self._doToggleSynopsis)
self.showSynopsis.setToolTip(self.tr("Show Synopsis Comments"))
+9 -7
View File
@@ -27,7 +27,7 @@ import logging
from enum import Enum
from PyQt5.QtCore import QModelIndex, QSize, Qt, pyqtSignal, pyqtSlot
from PyQt5.QtCore import QModelIndex, Qt, pyqtSignal, pyqtSlot
from PyQt5.QtWidgets import (
QAbstractItemView, QFrame, QHeaderView, QMenu, QTabWidget, QToolButton,
QTreeWidget, QTreeWidgetItem, QVBoxLayout, QWidget
@@ -55,7 +55,7 @@ class GuiDocViewerPanel(QWidget):
self._lastHandle = None
iPx = int(1.0*SHARED.theme.baseIconSize)
iSz = SHARED.theme.baseIconSize
self.tabBackRefs = _ViewPanelBackRefs(self)
@@ -66,7 +66,7 @@ class GuiDocViewerPanel(QWidget):
self.aInactive.toggled.connect(self._toggleHideInactive)
self.optsButton = QToolButton(self)
self.optsButton.setIconSize(QSize(iPx, iPx))
self.optsButton.setIconSize(iSz)
self.optsButton.setMenu(self.optsMenu)
self.optsButton.setPopupMode(QToolButton.ToolButtonPopupMode.InstantPopup)
@@ -240,13 +240,14 @@ class _ViewPanelBackRefs(QTreeWidget):
self._parent = parent
self._treeMap: dict[str, QTreeWidgetItem] = {}
iPx = SHARED.theme.baseIconSize
iPx = SHARED.theme.baseIconHeight
iSz = SHARED.theme.baseIconSize
cMg = CONFIG.pxInt(6)
self.setHeaderLabels([self.tr("Document"), "", "", self.tr("First Heading")])
self.setIndentation(0)
self.setSelectionMode(QAbstractItemView.SelectionMode.NoSelection)
self.setIconSize(QSize(iPx, iPx))
self.setIconSize(iSz)
self.setFrameStyle(QFrame.Shape.NoFrame)
# Set Header Sizes
@@ -382,7 +383,8 @@ class _ViewPanelKeyWords(QTreeWidget):
self._class = itemClass
self._treeMap: dict[str, QTreeWidgetItem] = {}
iPx = SHARED.theme.baseIconSize
iPx = SHARED.theme.baseIconHeight
iSz = SHARED.theme.baseIconSize
cMg = CONFIG.pxInt(6)
self.setHeaderLabels([
@@ -390,7 +392,7 @@ class _ViewPanelKeyWords(QTreeWidget):
self.tr("Heading"), self.tr("Short Description")
])
self.setIndentation(0)
self.setIconSize(QSize(iPx, iPx))
self.setIconSize(iSz)
self.setFrameStyle(QFrame.Shape.NoFrame)
self.setSelectionMode(QAbstractItemView.SelectionMode.NoSelection)
self.setExpandsOnDoubleClick(False)
+1 -1
View File
@@ -231,7 +231,7 @@ class GuiItemDetails(QWidget):
return
self._handle = tHandle
iPx = int(round(0.9*SHARED.theme.baseIconSize))
iPx = int(round(0.9*SHARED.theme.baseIconHeight))
# Label
# =====
+9 -8
View File
@@ -32,7 +32,7 @@ from time import time
from typing import TYPE_CHECKING
from PyQt5.QtGui import QFocusEvent, QFont, QMouseEvent, QPalette, QResizeEvent
from PyQt5.QtCore import QModelIndex, QPoint, Qt, QSize, pyqtSlot, pyqtSignal
from PyQt5.QtCore import QModelIndex, QPoint, Qt, pyqtSlot, pyqtSignal
from PyQt5.QtWidgets import (
QAbstractItemView, QActionGroup, QFrame, QHBoxLayout, QHeaderView,
QInputDialog, QMenu, QSizePolicy, QToolTip, QTreeWidget, QTreeWidgetItem,
@@ -201,7 +201,7 @@ class GuiNovelToolBar(QWidget):
self.novelView = novelView
self.mainGui = novelView.mainGui
iPx = SHARED.theme.baseIconSize
iSz = SHARED.theme.baseIconSize
mPx = CONFIG.pxInt(2)
self.setContentsMargins(0, 0, 0, 0)
@@ -218,12 +218,12 @@ class GuiNovelToolBar(QWidget):
self.novelValue.setSizePolicy(QSizePolicy.Policy.Expanding, QSizePolicy.Policy.Expanding)
self.novelValue.novelSelectionChanged.connect(self.setCurrentRoot)
self.tbNovel = NIconToolButton(self, iPx)
self.tbNovel = NIconToolButton(self, iSz)
self.tbNovel.setToolTip(self.tr("Novel Root"))
self.tbNovel.clicked.connect(self.novelValue.showPopup)
# Refresh Button
self.tbRefresh = NIconToolButton(self, iPx)
self.tbRefresh = NIconToolButton(self, iSz)
self.tbRefresh.setToolTip(self.tr("Refresh"))
self.tbRefresh.clicked.connect(self._refreshNovelTree)
@@ -242,7 +242,7 @@ class GuiNovelToolBar(QWidget):
self.aLastColSize = self.mLastCol.addAction(self.tr("Column Size"))
self.aLastColSize.triggered.connect(self._selectLastColumnSize)
self.tbMore = NIconToolButton(self, iPx)
self.tbMore = NIconToolButton(self, iSz)
self.tbMore.setToolTip(self.tr("More Options"))
self.tbMore.setMenu(self.mMore)
@@ -392,10 +392,11 @@ class GuiNovelTree(QTreeWidget):
# Build GUI
# =========
iPx = SHARED.theme.baseIconSize
iPx = SHARED.theme.baseIconHeight
iSz = SHARED.theme.baseIconSize
cMg = CONFIG.pxInt(6)
self.setIconSize(QSize(iPx, iPx))
self.setIconSize(iSz)
self.setFrameStyle(QFrame.Shape.NoFrame)
self.setUniformRowHeights(True)
self.setAllColumnsShowFocus(True)
@@ -456,7 +457,7 @@ class GuiNovelTree(QTreeWidget):
def updateTheme(self) -> None:
"""Update theme elements."""
iPx = SHARED.theme.baseIconSize
iPx = SHARED.theme.baseIconHeight
self._pMore = SHARED.theme.loadDecoration("deco_doc_more", h=iPx)
return
+4 -5
View File
@@ -33,7 +33,7 @@ import logging
from time import time
from enum import Enum
from PyQt5.QtCore import Qt, pyqtSignal, pyqtSlot, QSize, QT_TRANSLATE_NOOP
from PyQt5.QtCore import Qt, pyqtSignal, pyqtSlot, QT_TRANSLATE_NOOP
from PyQt5.QtWidgets import (
QAbstractItemView, QAction, QFileDialog, QFrame, QGridLayout, QGroupBox,
QHBoxLayout, QLabel, QMenu, QScrollArea, QSizePolicy, QSplitter, QToolBar,
@@ -207,11 +207,11 @@ class GuiOutlineToolBar(QToolBar):
logger.debug("Create: GuiOutlineToolBar")
bPx = SHARED.theme.baseButtonHeight
iSz = SHARED.theme.baseIconSize
mPx = CONFIG.pxInt(12)
self.setMovable(False)
self.setIconSize(QSize(bPx, bPx))
self.setIconSize(iSz)
self.setContentsMargins(0, 0, 0, 0)
stretch = QWidget(self)
@@ -376,8 +376,7 @@ class GuiOutlineTree(QTreeWidget):
self.itemDoubleClicked.connect(self._treeDoubleClick)
self.itemSelectionChanged.connect(self._itemSelected)
iPx = SHARED.theme.baseIconSize
self.setIconSize(QSize(iPx, iPx))
self.setIconSize(SHARED.theme.baseIconSize)
self.setIndentation(0)
self.treeHead = self.header()
+10 -10
View File
@@ -35,7 +35,7 @@ from typing import TYPE_CHECKING
from PyQt5.QtGui import (
QDragEnterEvent, QDragMoveEvent, QDropEvent, QIcon, QMouseEvent, QPalette
)
from PyQt5.QtCore import QPoint, QTimer, Qt, QSize, pyqtSignal, pyqtSlot
from PyQt5.QtCore import QPoint, QTimer, Qt, pyqtSignal, pyqtSlot
from PyQt5.QtWidgets import (
QAbstractItemView, QAction, QDialog, QFrame, QHBoxLayout, QHeaderView,
QLabel, QMenu, QShortcut, QSizePolicy, QTreeWidget, QTreeWidgetItem,
@@ -264,7 +264,7 @@ class GuiProjectToolBar(QWidget):
self.projTree = projView.projTree
self.mainGui = projView.mainGui
iPx = SHARED.theme.baseIconSize
iSz = SHARED.theme.baseIconSize
mPx = CONFIG.pxInt(2)
self.setContentsMargins(0, 0, 0, 0)
@@ -279,17 +279,17 @@ class GuiProjectToolBar(QWidget):
# Quick Links
self.mQuick = QMenu(self)
self.tbQuick = NIconToolButton(self, iPx)
self.tbQuick = NIconToolButton(self, iSz)
self.tbQuick.setToolTip("%s [Ctrl+L]" % self.tr("Quick Links"))
self.tbQuick.setShortcut("Ctrl+L")
self.tbQuick.setMenu(self.mQuick)
# Move Buttons
self.tbMoveU = NIconToolButton(self, iPx)
self.tbMoveU = NIconToolButton(self, iSz)
self.tbMoveU.setToolTip("%s [Ctrl+Up]" % self.tr("Move Up"))
self.tbMoveU.clicked.connect(lambda: self.projTree.moveTreeItem(-1))
self.tbMoveD = NIconToolButton(self, iPx)
self.tbMoveD = NIconToolButton(self, iSz)
self.tbMoveD.setToolTip("%s [Ctrl+Down]" % self.tr("Move Down"))
self.tbMoveD.clicked.connect(lambda: self.projTree.moveTreeItem(1))
@@ -329,7 +329,7 @@ class GuiProjectToolBar(QWidget):
self.mAddRoot = self.mAdd.addMenu(trConst(nwLabels.ITEM_DESCRIPTION["root"]))
self._buildRootMenu()
self.tbAdd = NIconToolButton(self, iPx)
self.tbAdd = NIconToolButton(self, iSz)
self.tbAdd.setToolTip("%s [Ctrl+N]" % self.tr("Add Item"))
self.tbAdd.setShortcut("Ctrl+N")
self.tbAdd.setMenu(self.mAdd)
@@ -346,7 +346,7 @@ class GuiProjectToolBar(QWidget):
self.aEmptyTrash = self.mMore.addAction(self.tr("Empty Trash"))
self.aEmptyTrash.triggered.connect(lambda: self.projTree.emptyTrash())
self.tbMore = NIconToolButton(self, iPx)
self.tbMore = NIconToolButton(self, iSz)
self.tbMore.setToolTip(self.tr("More Options"))
self.tbMore.setMenu(self.mMore)
@@ -517,10 +517,10 @@ class GuiProjectTree(QTreeWidget):
self.customContextMenuRequested.connect(self._openContextMenu)
# Tree Settings
iPx = SHARED.theme.baseIconSize
iPx = SHARED.theme.baseIconHeight
cMg = CONFIG.pxInt(6)
self.setIconSize(QSize(iPx, iPx))
self.setIconSize(SHARED.theme.baseIconSize)
self.setFrameStyle(QFrame.Shape.NoFrame)
self.setUniformRowHeights(True)
self.setAllColumnsShowFocus(True)
@@ -564,7 +564,7 @@ class GuiProjectTree(QTreeWidget):
self.itemSelectionChanged.connect(self._treeSelectionChange)
# Auto Scroll
self._scrollMargin = SHARED.theme.baseIconSize
self._scrollMargin = SHARED.theme.baseIconHeight
self._scrollDirection = 0
self._scrollTimer = QTimer(self)
self._scrollTimer.timeout.connect(self._doAutoScroll)
+5 -4
View File
@@ -27,7 +27,7 @@ import logging
from time import time
from PyQt5.QtCore import QSize, Qt, pyqtSignal, pyqtSlot
from PyQt5.QtCore import Qt, pyqtSignal, pyqtSlot
from PyQt5.QtGui import QCursor, QKeyEvent
from PyQt5.QtWidgets import (
QFrame, QHBoxLayout, QHeaderView, QLabel, QLineEdit, QToolBar, QTreeWidget,
@@ -60,7 +60,8 @@ class GuiProjectSearch(QWidget):
logger.debug("Create: GuiProjectSearch")
iPx = SHARED.theme.baseIconSize
iPx = SHARED.theme.baseIconHeight
iSz = SHARED.theme.baseIconSize
mPx = CONFIG.pxInt(2)
tPx = CONFIG.pxInt(4)
@@ -77,7 +78,7 @@ class GuiProjectSearch(QWidget):
# Options
self.searchOpt = QToolBar(self)
self.searchOpt.setToolButtonStyle(Qt.ToolButtonStyle.ToolButtonIconOnly)
self.searchOpt.setIconSize(QSize(iPx, iPx))
self.searchOpt.setIconSize(iSz)
self.searchOpt.setContentsMargins(0, 0, 0, 0)
self.toggleCase = self.searchOpt.addAction(self.tr("Case Sensitive"))
@@ -109,7 +110,7 @@ class GuiProjectSearch(QWidget):
self.searchResult = QTreeWidget(self)
self.searchResult.setHeaderHidden(True)
self.searchResult.setColumnCount(2)
self.searchResult.setIconSize(QSize(iPx, iPx))
self.searchResult.setIconSize(iSz)
self.searchResult.setIndentation(iPx)
self.searchResult.setFrameStyle(QFrame.Shape.NoFrame)
self.searchResult.setUniformRowHeights(True)
+11 -9
View File
@@ -28,7 +28,7 @@ import logging
from typing import TYPE_CHECKING
from PyQt5.QtGui import QPalette
from PyQt5.QtCore import QEvent, QPoint, pyqtSignal
from PyQt5.QtCore import QEvent, QPoint, QSize, pyqtSignal
from PyQt5.QtWidgets import QMenu, QVBoxLayout, QWidget
from novelwriter import CONFIG, SHARED
@@ -55,40 +55,42 @@ class GuiSideBar(QWidget):
self.mainGui = mainGui
iPx = int(1.2*SHARED.theme.baseButtonHeight)
iSz = QSize(iPx, iPx)
self.setContentsMargins(0, 0, 0, 0)
self.installEventFilter(StatusTipFilter(mainGui))
# Buttons
self.tbProject = NIconToolButton(self, iPx)
self.tbProject = NIconToolButton(self, iSz)
self.tbProject.setToolTip("{0} [Ctrl+T]".format(self.tr("Project Tree View")))
self.tbProject.clicked.connect(lambda: self.requestViewChange.emit(nwView.PROJECT))
self.tbNovel = NIconToolButton(self, iPx)
self.tbNovel = NIconToolButton(self, iSz)
self.tbNovel.setToolTip("{0} [Ctrl+T]".format(self.tr("Novel Tree View")))
self.tbNovel.clicked.connect(lambda: self.requestViewChange.emit(nwView.NOVEL))
self.tbSearch = NIconToolButton(self, iPx)
self.tbSearch = NIconToolButton(self, iSz)
self.tbSearch.setToolTip("{0} [Ctrl+Shift+F]".format(self.tr("Project Search")))
self.tbSearch.clicked.connect(lambda: self.requestViewChange.emit(nwView.SEARCH))
self.tbOutline = NIconToolButton(self, iPx)
self.tbOutline = NIconToolButton(self, iSz)
self.tbOutline.setToolTip("{0} [Ctrl+Shift+T]".format(self.tr("Novel Outline View")))
self.tbOutline.clicked.connect(lambda: self.requestViewChange.emit(nwView.OUTLINE))
self.tbBuild = NIconToolButton(self, iPx)
self.tbBuild = NIconToolButton(self, iSz)
self.tbBuild.setToolTip("{0} [F5]".format(self.tr("Build Manuscript")))
self.tbBuild.clicked.connect(self.mainGui.showBuildManuscriptDialog)
self.tbDetails = NIconToolButton(self, iPx)
self.tbDetails = NIconToolButton(self, iSz)
self.tbDetails.setToolTip("{0} [Shift+F6]".format(self.tr("Novel Details")))
self.tbDetails.clicked.connect(self.mainGui.showNovelDetailsDialog)
self.tbStats = NIconToolButton(self, iPx)
self.tbStats = NIconToolButton(self, iSz)
self.tbStats.setToolTip("{0} [F6]".format(self.tr("Writing Statistics")))
self.tbStats.clicked.connect(self.mainGui.showWritingStatsDialog)
# Settings Menu
self.tbSettings = NIconToolButton(self, iPx)
self.tbSettings = NIconToolButton(self, iSz)
self.tbSettings.setToolTip(self.tr("Settings"))
self.mSettings = _PopRightMenu(self.tbSettings)
+2 -2
View File
@@ -58,7 +58,7 @@ class GuiMainStatus(QStatusBar):
colSaved = SHARED.theme.statSaved
colUnsaved = SHARED.theme.statUnsaved
iPx = SHARED.theme.baseIconSize
iPx = SHARED.theme.baseIconHeight
# Permanent Widgets
# =================
@@ -130,7 +130,7 @@ class GuiMainStatus(QStatusBar):
def updateTheme(self) -> None:
"""Update theme elements."""
iPx = SHARED.theme.baseIconSize
iPx = SHARED.theme.baseIconHeight
self.langIcon.setPixmap(SHARED.theme.getPixmap("status_lang", (iPx, iPx)))
self.statsIcon.setPixmap(SHARED.theme.getPixmap("status_stats", (iPx, iPx)))
self.timePixmap = SHARED.theme.getPixmap("status_time", (iPx, iPx))
+13 -8
View File
@@ -29,7 +29,7 @@ import logging
from math import ceil
from pathlib import Path
from PyQt5.QtCore import Qt
from PyQt5.QtCore import QSize, Qt
from PyQt5.QtWidgets import qApp
from PyQt5.QtGui import (
QPalette, QColor, QIcon, QFont, QFontMetrics, QFontDatabase, QPixmap
@@ -156,13 +156,18 @@ class GuiTheme:
self.guiFontB.setBold(True)
qMetric = QFontMetrics(self.guiFont)
fHeight = qMetric.height()
fAscent = qMetric.ascent()
self.fontPointSize = self.guiFont.pointSizeF()
self.fontPixelSize = int(round(qMetric.height()))
self.baseIconSize = int(round(qMetric.ascent()))
self.baseButtonHeight = int(round(1.35*qMetric.ascent()))
self.fontPixelSize = int(round(fHeight))
self.baseIconHeight = int(round(fAscent))
self.baseButtonHeight = int(round(1.35*fAscent))
self.textNHeight = qMetric.boundingRect("N").height()
self.textNWidth = qMetric.boundingRect("N").width()
self.baseIconSize = QSize(self.baseIconHeight, self.baseIconHeight)
self.buttonIconSize = QSize(int(0.9*self.baseIconHeight), int(0.9*self.baseIconHeight))
# Monospace Font
self.guiFontFixed = QFont()
self.guiFontFixed.setPointSizeF(0.95*self.fontPointSize)
@@ -171,7 +176,7 @@ class GuiTheme:
logger.debug("GUI Font Family: %s", self.guiFont.family())
logger.debug("GUI Font Point Size: %.2f", self.fontPointSize)
logger.debug("GUI Font Pixel Size: %d", self.fontPixelSize)
logger.debug("GUI Base Icon Size: %d", self.baseIconSize)
logger.debug("GUI Base Icon Height: %d", self.baseIconHeight)
logger.debug("GUI Base Button Height: %d", self.baseButtonHeight)
logger.debug("Text 'N' Height: %d", self.textNHeight)
logger.debug("Text 'N' Width: %d", self.textNWidth)
@@ -679,7 +684,7 @@ class GuiIcons:
def getToggleIcon(self, name: str, size: tuple[int, int]) -> QIcon:
"""Return a toggle icon from the icon buffer. or load it."""
if name in self.TOGGLE_ICON_KEYS:
pOne = self.getPixmap(self.TOGGLE_ICON_KEYS[name][0], size)
pOne = self.getPixmap(self.TOGGLE_ICON_KEYS[name][0], size)
pTwo = self.getPixmap(self.TOGGLE_ICON_KEYS[name][1], size)
icon = QIcon()
icon.addPixmap(pOne, QIcon.Mode.Normal, QIcon.State.On)
@@ -724,7 +729,7 @@ class GuiIcons:
def getHeaderDecoration(self, hLevel: int) -> QPixmap:
"""Get the decoration for a specific heading level."""
if not self._headerDec:
iPx = self.mainTheme.baseIconSize
iPx = self.mainTheme.baseIconHeight
self._headerDec = [
self.loadDecoration("deco_doc_h0", h=iPx),
self.loadDecoration("deco_doc_h1", h=iPx),
@@ -737,7 +742,7 @@ class GuiIcons:
def getHeaderDecorationNarrow(self, hLevel: int) -> QPixmap:
"""Get the narrow decoration for a specific heading level."""
if not self._headerDecNarrow:
iPx = self.mainTheme.baseIconSize
iPx = self.mainTheme.baseIconHeight
self._headerDecNarrow = [
self.loadDecoration("deco_doc_h0_n", h=iPx),
self.loadDecoration("deco_doc_h1_n", h=iPx),