Add a standard button generator

This commit is contained in:
Veronica Berglyd Olsen
2025-10-25 20:47:32 +02:00
parent ba5b2af394
commit 096686457d
4 changed files with 85 additions and 31 deletions
+15
View File
@@ -247,3 +247,18 @@ class nwStatusShape(Enum):
BLOCK_2 = 17
BLOCK_3 = 18
BLOCK_4 = 19
class nwStandardButton(Enum):
"""Enum: Standard Dialog Buttons."""
OK = 0
CANCEL = 1
YES = 2
NO = 3
OPEN = 4
CLOSE = 5
BROWSE = 6
LIST = 7
NEW = 8
CREATE = 9
+32 -2
View File
@@ -31,8 +31,8 @@ from typing import TYPE_CHECKING
from PyQt6.QtCore import QModelIndex, QSize, Qt, pyqtSignal, pyqtSlot
from PyQt6.QtWidgets import (
QApplication, QComboBox, QDialog, QDoubleSpinBox, QLabel, QSpinBox,
QToolButton, QTreeView, QWidget
QApplication, QComboBox, QDialog, QDoubleSpinBox, QLabel, QPushButton,
QSpinBox, QToolButton, QTreeView, QWidget
)
from novelwriter import CONFIG, SHARED
@@ -199,6 +199,36 @@ class NDoubleSpinBox(QDoubleSpinBox):
event.ignore()
class NPushButton(QPushButton):
"""Custom: Modified QPushButton.
A quicker way to create a push button using the app theme.
"""
def __init__(
self, parent: QWidget, text: str, iconSize: QSize,
icon: str | None = None, color: str | None = None
) -> None:
super().__init__(parent=parent)
self.setText(text)
self.setIconSize(iconSize)
self._icon = icon
self._color = color
if icon:
self.refreshIcon()
def setThemeIcon(self, icon: str, color: str | None = None) -> None:
"""Set an icon from the current theme."""
self._icon = icon
self._color = color
self.refreshIcon()
def refreshIcon(self) -> None:
"""Reload the theme icon."""
if self._icon:
self.setIcon(SHARED.theme.getIcon(self._icon, self._color))
class NIconToolButton(QToolButton):
"""Custom: Modified QToolButton.
+29 -6
View File
@@ -31,19 +31,20 @@ from dataclasses import dataclass
from math import ceil
from typing import TYPE_CHECKING, Final
from PyQt6.QtCore import QSize, Qt
from PyQt6.QtCore import QT_TRANSLATE_NOOP, QCoreApplication, QSize, Qt
from PyQt6.QtGui import (
QColor, QFont, QFontDatabase, QFontMetrics, QGuiApplication, QIcon,
QPainter, QPainterPath, QPalette, QPixmap
)
from PyQt6.QtWidgets import QApplication
from PyQt6.QtWidgets import QApplication, QWidget
from novelwriter import CONFIG
from novelwriter.common import checkInt, minmax
from novelwriter.config import DEF_GUI_DARK, DEF_GUI_LIGHT, DEF_ICONS, DEF_TREECOL
from novelwriter.constants import nwLabels
from novelwriter.enum import nwItemClass, nwItemLayout, nwItemType, nwTheme
from novelwriter.enum import nwItemClass, nwItemLayout, nwItemType, nwStandardButton, nwTheme
from novelwriter.error import logException
from novelwriter.extensions.modified import NPushButton
from novelwriter.types import QtBlack, QtHexArgb, QtPaintAntiAlias, QtTransparent
if TYPE_CHECKING:
@@ -55,6 +56,19 @@ STYLES_FLAT_TABS = "flatTabWidget"
STYLES_MIN_TOOLBUTTON = "minimalToolButton"
STYLES_BIG_TOOLBUTTON = "bigToolButton"
STANDARD_BUTTONS = {
nwStandardButton.OK: (QT_TRANSLATE_NOOP("Button", "OK"), "bullet-on", "blue"),
nwStandardButton.CANCEL: (QT_TRANSLATE_NOOP("Button", "Cancel"), "cancel", "red"),
nwStandardButton.YES: (QT_TRANSLATE_NOOP("Button", "Yes"), "bullet-on", "green"),
nwStandardButton.NO: (QT_TRANSLATE_NOOP("Button", "No"), "bullet-on", "red"),
nwStandardButton.OPEN: (QT_TRANSLATE_NOOP("Button", "Open"), "open", "blue"),
nwStandardButton.CLOSE: (QT_TRANSLATE_NOOP("Button", "Close"), "close", "default"),
nwStandardButton.BROWSE: (QT_TRANSLATE_NOOP("Button", "Browse"), "browse", "yellow"),
nwStandardButton.LIST: (QT_TRANSLATE_NOOP("Button", "List"), "list", "blue"),
nwStandardButton.NEW: (QT_TRANSLATE_NOOP("Button", "New"), "add", "green"),
nwStandardButton.CREATE: (QT_TRANSLATE_NOOP("Button", "Create"), "star", "yellow"),
}
@dataclass
class ThemeEntry:
@@ -120,9 +134,9 @@ class GuiTheme:
"_qColors", "_styleSheets", "_svgColors", "_syntaxList", "accentCol", "baseButtonHeight",
"baseIconHeight", "baseIconSize", "buttonIconSize", "errorText", "fadedText",
"fontPixelSize", "fontPointSize", "getDecoration", "getHeaderDecoration",
"getHeaderDecorationNarrow", "getIcon", "getItemIcon", "getPixmap", "getToggleIcon",
"guiFont", "guiFontB", "guiFontBU", "guiFontFixed", "guiFontSmall", "helpText",
"iconCache", "isDarkTheme", "syntaxTheme", "textNHeight", "textNWidth",
"getHeaderDecorationNarrow", "getIcon", "getItemIcon", "getPixmap", "getStandardButton",
"getToggleIcon", "guiFont", "guiFontB", "guiFontBU", "guiFontFixed", "guiFontSmall",
"helpText", "iconCache", "isDarkTheme", "syntaxTheme", "textNHeight", "textNWidth",
)
def __init__(self) -> None:
@@ -153,6 +167,7 @@ class GuiTheme:
self.getItemIcon = self.iconCache.getItemIcon
self.getToggleIcon = self.iconCache.getToggleIcon
self.getDecoration = self.iconCache.getDecoration
self.getStandardButton = self.iconCache.getStandardButton
self.getHeaderDecoration = self.iconCache.getHeaderDecoration
self.getHeaderDecorationNarrow = self.iconCache.getHeaderDecorationNarrow
@@ -808,6 +823,14 @@ class GuiIcons:
w, h = size
return self.getIcon(name, color, w, h).pixmap(w, h, QIcon.Mode.Normal)
def getStandardButton(self, button: nwStandardButton, parent: QWidget) -> NPushButton:
"""Return a standard button with icon and text."""
text, icon, color = STANDARD_BUTTONS.get(button, ("", "", ""))
return NPushButton(
parent, QCoreApplication.translate("Button", text),
self._theme.buttonIconSize, icon, color
)
def getDecoration(self, name: str, w: int | None = None, h: int | None = None) -> QPixmap:
"""Load graphical decoration element based on the decoration
map or the icon map. This function always returns a QPixmap.
+9 -23
View File
@@ -35,15 +35,15 @@ from PyQt6.QtCore import (
from PyQt6.QtGui import QAction, QCloseEvent, QFont, QPainter, QPaintEvent, QPen, QShortcut
from PyQt6.QtWidgets import (
QApplication, QFileDialog, QFormLayout, QHBoxLayout, QLabel, QLineEdit,
QListView, QMenu, QPushButton, QScrollArea, QStackedWidget,
QStyledItemDelegate, QStyleOptionViewItem, QVBoxLayout, QWidget
QListView, QMenu, QScrollArea, QStackedWidget, QStyledItemDelegate,
QStyleOptionViewItem, QVBoxLayout, QWidget
)
from novelwriter import CONFIG, SHARED
from novelwriter.common import formatInt, makeFileNameSafe, qtAddAction, qtLambda
from novelwriter.constants import nwFiles
from novelwriter.core.coretools import ProjectBuilder
from novelwriter.enum import nwItemClass
from novelwriter.enum import nwItemClass, nwStandardButton
from novelwriter.extensions.configlayout import NWrappedWidgetBox
from novelwriter.extensions.modified import NDialog, NIconToolButton, NSpinBox
from novelwriter.extensions.switch import NSwitch
@@ -75,8 +75,6 @@ class GuiWelcome(NDialog):
self.setMinimumHeight(450)
self.resize(*CONFIG.welcomeWinSize)
btnIconSize = SHARED.theme.buttonIconSize
# Elements
# ========
@@ -104,34 +102,22 @@ class GuiWelcome(NDialog):
# Buttons
# =======
self.btnList = QPushButton(self.tr("List"), self)
self.btnList.setIcon(SHARED.theme.getIcon("list", "blue"))
self.btnList.setIconSize(btnIconSize)
self.btnList = SHARED.theme.getStandardButton(nwStandardButton.LIST, self)
self.btnList.clicked.connect(self._showOpenProjectPage)
self.btnNew = QPushButton(self.tr("New"), self)
self.btnNew.setIcon(SHARED.theme.getIcon("add", "green"))
self.btnNew.setIconSize(btnIconSize)
self.btnNew = SHARED.theme.getStandardButton(nwStandardButton.NEW, self)
self.btnNew.clicked.connect(self._showNewProjectPage)
self.btnBrowse = QPushButton(self.tr("Browse"), self)
self.btnBrowse.setIcon(SHARED.theme.getIcon("browse", "yellow"))
self.btnBrowse.setIconSize(btnIconSize)
self.btnBrowse = SHARED.theme.getStandardButton(nwStandardButton.BROWSE, self)
self.btnBrowse.clicked.connect(self._browseForProject)
self.btnCancel = QPushButton(self.tr("Cancel"), self)
self.btnCancel.setIcon(SHARED.theme.getIcon("cancel", "red"))
self.btnCancel.setIconSize(btnIconSize)
self.btnCancel = SHARED.theme.getStandardButton(nwStandardButton.CANCEL, self)
self.btnCancel.clicked.connect(qtLambda(self.close))
self.btnCreate = QPushButton(self.tr("Create"), self)
self.btnCreate.setIcon(SHARED.theme.getIcon("star", "yellow"))
self.btnCreate.setIconSize(btnIconSize)
self.btnCreate = SHARED.theme.getStandardButton(nwStandardButton.CREATE, self)
self.btnCreate.clicked.connect(self.tabNew.createNewProject)
self.btnOpen = QPushButton(self.tr("Open"), self)
self.btnOpen.setIcon(SHARED.theme.getIcon("open", "blue"))
self.btnOpen.setIconSize(btnIconSize)
self.btnOpen = SHARED.theme.getStandardButton(nwStandardButton.OPEN, self)
self.btnOpen.clicked.connect(self._openSelectedItem)
self.btnBox = QHBoxLayout()