Add modified combo and spinboxes that don't scroll on mouse wheel

This commit is contained in:
Veronica Berglyd Olsen
2024-02-01 23:35:14 +01:00
parent c866491910
commit a8f61f2b98
5 changed files with 126 additions and 42 deletions
+18 -17
View File
@@ -29,15 +29,16 @@ import logging
from PyQt5.QtGui import QCloseEvent, QFont, QKeyEvent, QKeySequence from PyQt5.QtGui import QCloseEvent, QFont, QKeyEvent, QKeySequence
from PyQt5.QtCore import Qt, pyqtSignal, pyqtSlot from PyQt5.QtCore import Qt, pyqtSignal, pyqtSlot
from PyQt5.QtWidgets import ( from PyQt5.QtWidgets import (
QAbstractButton, QComboBox, QCompleter, QDialog, QDialogButtonBox, QAbstractButton, QCompleter, QDialog, QDialogButtonBox, QFileDialog,
QDoubleSpinBox, QFileDialog, QFontDialog, QHBoxLayout, QLineEdit, QFontDialog, QHBoxLayout, QLineEdit, QPushButton, QToolButton, QVBoxLayout,
QPushButton, QSpinBox, QToolButton, QVBoxLayout, QWidget, qApp QWidget, qApp
) )
from novelwriter import CONFIG, SHARED from novelwriter import CONFIG, SHARED
from novelwriter.constants import nwConst, nwUnicode from novelwriter.constants import nwConst, nwUnicode
from novelwriter.dialogs.quotes import GuiQuoteSelect from novelwriter.dialogs.quotes import GuiQuoteSelect
from novelwriter.extensions.switch import NSwitch from novelwriter.extensions.switch import NSwitch
from novelwriter.extensions.modified import NComboBox, NDoubleSpinBox, NSpinBox
from novelwriter.extensions.configlayout import NColourLabel, NScrollableForm from novelwriter.extensions.configlayout import NColourLabel, NScrollableForm
from novelwriter.extensions.pagedsidebar import NPagedSideBar from novelwriter.extensions.pagedsidebar import NPagedSideBar
@@ -146,7 +147,7 @@ class GuiPreferences(QDialog):
self.mainForm.addGroupLabel(title, section) self.mainForm.addGroupLabel(title, section)
# Display Language # Display Language
self.guiLocale = QComboBox(self) self.guiLocale = NComboBox(self)
self.guiLocale.setMinimumWidth(minWidth) self.guiLocale.setMinimumWidth(minWidth)
for lang, name in CONFIG.listLanguages(CONFIG.LANG_NW): for lang, name in CONFIG.listLanguages(CONFIG.LANG_NW):
self.guiLocale.addItem(name, lang) self.guiLocale.addItem(name, lang)
@@ -159,7 +160,7 @@ class GuiPreferences(QDialog):
) )
# Colour Theme # Colour Theme
self.guiTheme = QComboBox(self) self.guiTheme = NComboBox(self)
self.guiTheme.setMinimumWidth(minWidth) self.guiTheme.setMinimumWidth(minWidth)
for theme, name in SHARED.theme.listThemes(): for theme, name in SHARED.theme.listThemes():
self.guiTheme.addItem(name, theme) self.guiTheme.addItem(name, theme)
@@ -186,7 +187,7 @@ class GuiPreferences(QDialog):
) )
# Application Font Size # Application Font Size
self.guiFontSize = QSpinBox(self) self.guiFontSize = NSpinBox(self)
self.guiFontSize.setMinimum(8) self.guiFontSize.setMinimum(8)
self.guiFontSize.setMaximum(60) self.guiFontSize.setMaximum(60)
self.guiFontSize.setSingleStep(1) self.guiFontSize.setSingleStep(1)
@@ -221,7 +222,7 @@ class GuiPreferences(QDialog):
self.mainForm.addGroupLabel(title, section) self.mainForm.addGroupLabel(title, section)
# Document Colour Theme # Document Colour Theme
self.guiSyntax = QComboBox(self) self.guiSyntax = NComboBox(self)
self.guiSyntax.setMinimumWidth(CONFIG.pxInt(200)) self.guiSyntax.setMinimumWidth(CONFIG.pxInt(200))
for syntax, name in SHARED.theme.listSyntax(): for syntax, name in SHARED.theme.listSyntax():
self.guiSyntax.addItem(name, syntax) self.guiSyntax.addItem(name, syntax)
@@ -248,7 +249,7 @@ class GuiPreferences(QDialog):
) )
# Document Font Size # Document Font Size
self.textSize = QSpinBox(self) self.textSize = NSpinBox(self)
self.textSize.setMinimum(8) self.textSize.setMinimum(8)
self.textSize.setMaximum(60) self.textSize.setMaximum(60)
self.textSize.setSingleStep(1) self.textSize.setSingleStep(1)
@@ -290,7 +291,7 @@ class GuiPreferences(QDialog):
self.mainForm.addGroupLabel(title, section) self.mainForm.addGroupLabel(title, section)
# Document Save Timer # Document Save Timer
self.autoSaveDoc = QSpinBox(self) self.autoSaveDoc = NSpinBox(self)
self.autoSaveDoc.setMinimum(5) self.autoSaveDoc.setMinimum(5)
self.autoSaveDoc.setMaximum(600) self.autoSaveDoc.setMaximum(600)
self.autoSaveDoc.setSingleStep(1) self.autoSaveDoc.setSingleStep(1)
@@ -301,7 +302,7 @@ class GuiPreferences(QDialog):
) )
# Project Save Timer # Project Save Timer
self.autoSaveProj = QSpinBox(self) self.autoSaveProj = NSpinBox(self)
self.autoSaveProj.setMinimum(5) self.autoSaveProj.setMinimum(5)
self.autoSaveProj.setMaximum(600) self.autoSaveProj.setMaximum(600)
self.autoSaveProj.setSingleStep(1) self.autoSaveProj.setSingleStep(1)
@@ -364,7 +365,7 @@ class GuiPreferences(QDialog):
) )
# Inactive Time for Idle # Inactive Time for Idle
self.userIdleTime = QDoubleSpinBox(self) self.userIdleTime = NDoubleSpinBox(self)
self.userIdleTime.setMinimum(0.5) self.userIdleTime.setMinimum(0.5)
self.userIdleTime.setMaximum(600.0) self.userIdleTime.setMaximum(600.0)
self.userIdleTime.setSingleStep(0.5) self.userIdleTime.setSingleStep(0.5)
@@ -388,7 +389,7 @@ class GuiPreferences(QDialog):
self.mainForm.addGroupLabel(title, section) self.mainForm.addGroupLabel(title, section)
# Max Text Width in Normal Mode # Max Text Width in Normal Mode
self.textWidth = QSpinBox(self) self.textWidth = NSpinBox(self)
self.textWidth.setMinimum(0) self.textWidth.setMinimum(0)
self.textWidth.setMaximum(10000) self.textWidth.setMaximum(10000)
self.textWidth.setSingleStep(10) self.textWidth.setSingleStep(10)
@@ -399,7 +400,7 @@ class GuiPreferences(QDialog):
) )
# Max Text Width in Focus Mode # Max Text Width in Focus Mode
self.focusWidth = QSpinBox(self) self.focusWidth = NSpinBox(self)
self.focusWidth.setMinimum(200) self.focusWidth.setMinimum(200)
self.focusWidth.setMaximum(10000) self.focusWidth.setMaximum(10000)
self.focusWidth.setSingleStep(10) self.focusWidth.setSingleStep(10)
@@ -426,7 +427,7 @@ class GuiPreferences(QDialog):
) )
# Document Margins # Document Margins
self.textMargin = QSpinBox(self) self.textMargin = NSpinBox(self)
self.textMargin.setMinimum(0) self.textMargin.setMinimum(0)
self.textMargin.setMaximum(900) self.textMargin.setMaximum(900)
self.textMargin.setSingleStep(1) self.textMargin.setSingleStep(1)
@@ -438,7 +439,7 @@ class GuiPreferences(QDialog):
) )
# Tab Width # Tab Width
self.tabWidth = QSpinBox(self) self.tabWidth = NSpinBox(self)
self.tabWidth.setMinimum(0) self.tabWidth.setMinimum(0)
self.tabWidth.setMaximum(200) self.tabWidth.setMaximum(200)
self.tabWidth.setSingleStep(1) self.tabWidth.setSingleStep(1)
@@ -458,7 +459,7 @@ class GuiPreferences(QDialog):
self.mainForm.addGroupLabel(title, section) self.mainForm.addGroupLabel(title, section)
# Spell Checking # Spell Checking
self.spellLanguage = QComboBox(self) self.spellLanguage = NComboBox(self)
self.spellLanguage.setMinimumWidth(minWidth) self.spellLanguage.setMinimumWidth(minWidth)
if CONFIG.hasEnchant: if CONFIG.hasEnchant:
@@ -523,7 +524,7 @@ class GuiPreferences(QDialog):
) )
# Typewriter Position # Typewriter Position
self.autoScrollPos = QSpinBox(self) self.autoScrollPos = NSpinBox(self)
self.autoScrollPos.setMinimum(10) self.autoScrollPos.setMinimum(10)
self.autoScrollPos.setMaximum(90) self.autoScrollPos.setMaximum(90)
self.autoScrollPos.setSingleStep(1) self.autoScrollPos.setSingleStep(1)
+4 -3
View File
@@ -29,7 +29,7 @@ import logging
from PyQt5.QtGui import QCloseEvent, QColor, QIcon, QPixmap from PyQt5.QtGui import QCloseEvent, QColor, QIcon, QPixmap
from PyQt5.QtCore import Qt, pyqtSignal, pyqtSlot from PyQt5.QtCore import Qt, pyqtSignal, pyqtSlot
from PyQt5.QtWidgets import ( from PyQt5.QtWidgets import (
QColorDialog, QComboBox, QDialog, QDialogButtonBox, QHBoxLayout, QLineEdit, QColorDialog, QDialog, QDialogButtonBox, QHBoxLayout, QLineEdit,
QPushButton, QStackedWidget, QTreeWidget, QTreeWidgetItem, QVBoxLayout, QPushButton, QStackedWidget, QTreeWidget, QTreeWidgetItem, QVBoxLayout,
QWidget, qApp QWidget, qApp
) )
@@ -37,6 +37,7 @@ from PyQt5.QtWidgets import (
from novelwriter import CONFIG, SHARED from novelwriter import CONFIG, SHARED
from novelwriter.common import simplified from novelwriter.common import simplified
from novelwriter.extensions.switch import NSwitch from novelwriter.extensions.switch import NSwitch
from novelwriter.extensions.modified import NComboBox
from novelwriter.extensions.configlayout import NColourLabel, NFixedPage, NScrollableForm from novelwriter.extensions.configlayout import NColourLabel, NFixedPage, NScrollableForm
from novelwriter.extensions.pagedsidebar import NPagedSideBar from novelwriter.extensions.pagedsidebar import NPagedSideBar
@@ -257,7 +258,7 @@ class _SettingsPage(NScrollableForm):
) )
# Project Language # Project Language
self.projLang = QComboBox(self) self.projLang = NComboBox(self)
self.projLang.setMinimumWidth(xW) self.projLang.setMinimumWidth(xW)
for tag, language in CONFIG.listLanguages(CONFIG.LANG_PROJ): for tag, language in CONFIG.listLanguages(CONFIG.LANG_PROJ):
self.projLang.addItem(language, tag) self.projLang.addItem(language, tag)
@@ -270,7 +271,7 @@ class _SettingsPage(NScrollableForm):
self.projLang.setCurrentIndex(idx) self.projLang.setCurrentIndex(idx)
# Spell Check Language # Spell Check Language
self.spellLang = QComboBox(self) self.spellLang = NComboBox(self)
self.spellLang.setMinimumWidth(xW) self.spellLang.setMinimumWidth(xW)
self.spellLang.addItem(self.tr("Default"), "None") self.spellLang.addItem(self.tr("Default"), "None")
if CONFIG.hasEnchant: if CONFIG.hasEnchant:
+81
View File
@@ -0,0 +1,81 @@
"""
novelWriter Custom Widget: Modified Widgets
=============================================
File History:
Created: 2024-02-01 [2.3b1] NComboBox
Created: 2024-02-01 [2.3b1] NSpinBox
Created: 2024-02-01 [2.3b1] NDoubleSpinBox
This file is a part of novelWriter
Copyright 20182024, 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 <https://www.gnu.org/licenses/>.
"""
from __future__ import annotations
from PyQt5.QtCore import Qt
from PyQt5.QtGui import QWheelEvent
from PyQt5.QtWidgets import QComboBox, QDoubleSpinBox, QSpinBox, QWidget
class NComboBox(QComboBox):
def __init__(self, parent: QWidget | None = None) -> None:
super().__init__(parent=parent)
self.setFocusPolicy(Qt.FocusPolicy.StrongFocus)
return
def wheelEvent(self, event: QWheelEvent) -> None:
if self.hasFocus():
super().wheelEvent(event)
else:
event.ignore()
return
# END Class NComboBox
class NSpinBox(QSpinBox):
def __init__(self, parent: QWidget | None = None) -> None:
super().__init__(parent=parent)
self.setFocusPolicy(Qt.FocusPolicy.StrongFocus)
return
def wheelEvent(self, event: QWheelEvent) -> None:
if self.hasFocus():
super().wheelEvent(event)
else:
event.ignore()
return
# END Class NSpinBox
class NDoubleSpinBox(QDoubleSpinBox):
def __init__(self, parent: QWidget | None = None) -> None:
super().__init__(parent=parent)
self.setFocusPolicy(Qt.FocusPolicy.StrongFocus)
return
def wheelEvent(self, event: QWheelEvent) -> None:
if self.hasFocus():
super().wheelEvent(event)
else:
event.ignore()
return
# END Class NDoubleSpinBox
+16 -16
View File
@@ -30,17 +30,17 @@ from typing import TYPE_CHECKING
from PyQt5.QtGui import QFont, QIcon, QSyntaxHighlighter, QTextCharFormat, QTextDocument from PyQt5.QtGui import QFont, QIcon, QSyntaxHighlighter, QTextCharFormat, QTextDocument
from PyQt5.QtCore import QEvent, QSize, Qt, pyqtSignal, pyqtSlot from PyQt5.QtCore import QEvent, QSize, Qt, pyqtSignal, pyqtSlot
from PyQt5.QtWidgets import ( from PyQt5.QtWidgets import (
QAbstractButton, QAbstractItemView, QComboBox, QDialog, QDialogButtonBox, QAbstractButton, QAbstractItemView, QDialog, QDialogButtonBox,
QDoubleSpinBox, QFontDialog, QFrame, QGridLayout, QHBoxLayout, QHeaderView, QFontDialog, QFrame, QGridLayout, QHBoxLayout, QHeaderView, QLabel,
QLabel, QLineEdit, QMenu, QPlainTextEdit, QPushButton, QSpinBox, QSplitter, QLineEdit, QMenu, QPlainTextEdit, QPushButton, QSplitter, QStackedWidget,
QStackedWidget, QToolButton, QTreeWidget, QTreeWidgetItem, QVBoxLayout, QToolButton, QTreeWidget, QTreeWidgetItem, QVBoxLayout, QWidget
QWidget
) )
from novelwriter import CONFIG, SHARED from novelwriter import CONFIG, SHARED
from novelwriter.constants import nwHeadFmt, nwLabels, trConst from novelwriter.constants import nwHeadFmt, nwLabels, trConst
from novelwriter.core.buildsettings import BuildSettings, FilterMode from novelwriter.core.buildsettings import BuildSettings, FilterMode
from novelwriter.extensions.switch import NSwitch from novelwriter.extensions.switch import NSwitch
from novelwriter.extensions.modified import NComboBox, NDoubleSpinBox, NSpinBox
from novelwriter.extensions.switchbox import NSwitchBox from novelwriter.extensions.switchbox import NSwitchBox
from novelwriter.extensions.configlayout import ( from novelwriter.extensions.configlayout import (
NColourLabel, NFixedPage, NScrollableForm, NScrollablePage NColourLabel, NFixedPage, NScrollableForm, NScrollablePage
@@ -968,7 +968,7 @@ class _FormatTab(NScrollableForm):
) )
# Font Size # Font Size
self.textSize = QSpinBox(self) self.textSize = NSpinBox(self)
self.textSize.setMinimum(8) self.textSize.setMinimum(8)
self.textSize.setMaximum(60) self.textSize.setMaximum(60)
self.textSize.setSingleStep(1) self.textSize.setSingleStep(1)
@@ -976,7 +976,7 @@ class _FormatTab(NScrollableForm):
self.addRow(self._build.getLabel("format.textSize"), self.textSize, unit="pt") self.addRow(self._build.getLabel("format.textSize"), self.textSize, unit="pt")
# Line Height # Line Height
self.lineHeight = QDoubleSpinBox(self) self.lineHeight = NDoubleSpinBox(self)
self.lineHeight.setFixedWidth(spW) self.lineHeight.setFixedWidth(spW)
self.lineHeight.setMinimum(0.75) self.lineHeight.setMinimum(0.75)
self.lineHeight.setMaximum(3.0) self.lineHeight.setMaximum(3.0)
@@ -1002,34 +1002,34 @@ class _FormatTab(NScrollableForm):
self.addGroupLabel(self._build.getLabel("format.grpPage")) self.addGroupLabel(self._build.getLabel("format.grpPage"))
self.pageUnit = QComboBox(self) self.pageUnit = NComboBox(self)
for key, name in nwLabels.UNIT_NAME.items(): for key, name in nwLabels.UNIT_NAME.items():
self.pageUnit.addItem(trConst(name), key) self.pageUnit.addItem(trConst(name), key)
self.pageSize = QComboBox(self) self.pageSize = NComboBox(self)
for key, name in nwLabels.PAPER_NAME.items(): for key, name in nwLabels.PAPER_NAME.items():
self.pageSize.addItem(trConst(name), key) self.pageSize.addItem(trConst(name), key)
self.pageWidth = QDoubleSpinBox(self) self.pageWidth = NDoubleSpinBox(self)
self.pageWidth.setFixedWidth(dbW) self.pageWidth.setFixedWidth(dbW)
self.pageWidth.setMaximum(500.0) self.pageWidth.setMaximum(500.0)
self.pageWidth.valueChanged.connect(self._pageSizeValueChanged) self.pageWidth.valueChanged.connect(self._pageSizeValueChanged)
self.pageHeight = QDoubleSpinBox(self) self.pageHeight = NDoubleSpinBox(self)
self.pageHeight.setFixedWidth(dbW) self.pageHeight.setFixedWidth(dbW)
self.pageHeight.setMaximum(500.0) self.pageHeight.setMaximum(500.0)
self.pageHeight.valueChanged.connect(self._pageSizeValueChanged) self.pageHeight.valueChanged.connect(self._pageSizeValueChanged)
self.topMargin = QDoubleSpinBox(self) self.topMargin = NDoubleSpinBox(self)
self.topMargin.setFixedWidth(dbW) self.topMargin.setFixedWidth(dbW)
self.bottomMargin = QDoubleSpinBox(self) self.bottomMargin = NDoubleSpinBox(self)
self.bottomMargin.setFixedWidth(dbW) self.bottomMargin.setFixedWidth(dbW)
self.leftMargin = QDoubleSpinBox(self) self.leftMargin = NDoubleSpinBox(self)
self.leftMargin.setFixedWidth(dbW) self.leftMargin.setFixedWidth(dbW)
self.rightMargin = QDoubleSpinBox(self) self.rightMargin = NDoubleSpinBox(self)
self.rightMargin.setFixedWidth(dbW) self.rightMargin.setFixedWidth(dbW)
self.addRow(self._build.getLabel("format.pageUnit"), self.pageUnit) self.addRow(self._build.getLabel("format.pageUnit"), self.pageUnit)
@@ -1232,7 +1232,7 @@ class _OutputTab(NScrollableForm):
button=self.btnPageHeader, stretch=(1, 1) button=self.btnPageHeader, stretch=(1, 1)
) )
self.odtPageCountOffset = QSpinBox(self) self.odtPageCountOffset = NSpinBox(self)
self.odtPageCountOffset.setMinimum(0) self.odtPageCountOffset.setMinimum(0)
self.odtPageCountOffset.setMaximum(999) self.odtPageCountOffset.setMaximum(999)
self.odtPageCountOffset.setSingleStep(1) self.odtPageCountOffset.setSingleStep(1)
+7 -6
View File
@@ -34,9 +34,9 @@ from PyQt5.QtCore import (
pyqtSignal, pyqtSlot pyqtSignal, pyqtSlot
) )
from PyQt5.QtWidgets import ( from PyQt5.QtWidgets import (
QComboBox, QDialog, QDialogButtonBox, QFileDialog, QFormLayout, QDialog, QDialogButtonBox, QFileDialog, QFormLayout, QHBoxLayout, QLabel,
QHBoxLayout, QLabel, QLineEdit, QListView, QMenu, QPushButton, QScrollArea, QShortcut, QLineEdit, QListView, QMenu, QPushButton, QScrollArea, QShortcut,
QSpinBox, QStackedWidget, QStyle, QStyleOptionViewItem, QStyledItemDelegate, QStackedWidget, QStyle, QStyleOptionViewItem, QStyledItemDelegate,
QToolButton, QVBoxLayout, QWidget, qApp QToolButton, QVBoxLayout, QWidget, qApp
) )
@@ -46,6 +46,7 @@ from novelwriter.common import formatInt, formatVersion, makeFileNameSafe
from novelwriter.constants import nwUnicode from novelwriter.constants import nwUnicode
from novelwriter.core.coretools import ProjectBuilder from novelwriter.core.coretools import ProjectBuilder
from novelwriter.extensions.switch import NSwitch from novelwriter.extensions.switch import NSwitch
from novelwriter.extensions.modified import NComboBox, NSpinBox
logger = logging.getLogger(__name__) logger = logging.getLogger(__name__)
@@ -534,7 +535,7 @@ class _NewProjectForm(QWidget):
self.projAuthor.setPlaceholderText(self.tr("Optional")) self.projAuthor.setPlaceholderText(self.tr("Optional"))
# Project Language # Project Language
self.projLang = QComboBox(self) self.projLang = NComboBox(self)
for tag, language in CONFIG.listLanguages(CONFIG.LANG_PROJ): for tag, language in CONFIG.listLanguages(CONFIG.LANG_PROJ):
self.projLang.addItem(language, tag) self.projLang.addItem(language, tag)
@@ -594,7 +595,7 @@ class _NewProjectForm(QWidget):
# Chapters and Scenes # Chapters and Scenes
# =================== # ===================
self.numChapters = QSpinBox() self.numChapters = NSpinBox(self)
self.numChapters.setRange(0, 200) self.numChapters.setRange(0, 200)
self.numChapters.setValue(5) self.numChapters.setValue(5)
self.numChapters.setToolTip(self.tr("Set to 0 to only add scenes")) self.numChapters.setToolTip(self.tr("Set to 0 to only add scenes"))
@@ -605,7 +606,7 @@ class _NewProjectForm(QWidget):
self.chapterBox.addWidget(QLabel(self.tr("chapter documents"))) self.chapterBox.addWidget(QLabel(self.tr("chapter documents")))
self.chapterBox.addStretch(1) self.chapterBox.addStretch(1)
self.numScenes = QSpinBox() self.numScenes = NSpinBox(self)
self.numScenes.setRange(0, 200) self.numScenes.setRange(0, 200)
self.numScenes.setValue(5) self.numScenes.setValue(5)