diff --git a/novelwriter/assets/themes/default_dark.conf b/novelwriter/assets/themes/default_dark.conf index 8fcc4b18..906cc9fe 100644 --- a/novelwriter/assets/themes/default_dark.conf +++ b/novelwriter/assets/themes/default_dark.conf @@ -26,7 +26,7 @@ linkvisited = 102, 153, 204 [GUI] helptext = 164, 164, 164 -fadedtext = 128, 128, 128 +fadedtext = 148, 148, 148 errortext = 255, 164, 164 statusnone = 150, 152, 150 statussaved = 39, 135, 78 diff --git a/novelwriter/assets/themes/default_light.conf b/novelwriter/assets/themes/default_light.conf index 6f221c86..a02a12f9 100644 --- a/novelwriter/assets/themes/default_light.conf +++ b/novelwriter/assets/themes/default_light.conf @@ -26,7 +26,7 @@ linkvisited = 66, 113, 174 [GUI] helptext = 92, 92, 92 -fadedtext = 128, 128, 128 +fadedtext = 108, 108, 108 errortext = 255, 92, 92 statusnone = 120, 120, 120 statussaved = 200, 15, 39 diff --git a/novelwriter/enum.py b/novelwriter/enum.py index 53155d2a..649509a1 100644 --- a/novelwriter/enum.py +++ b/novelwriter/enum.py @@ -148,12 +148,11 @@ class nwView(Enum): SEARCH = 4 -class nwWidget(Enum): +class nwFocus(Enum): - TREE = 1 - EDITOR = 2 - VIEWER = 3 - OUTLINE = 4 + TREE = 1 + DOCUMENT = 2 + OUTLINE = 3 class nwOutline(Enum): diff --git a/novelwriter/extensions/configlayout.py b/novelwriter/extensions/configlayout.py index ca9d582e..3bb7b289 100644 --- a/novelwriter/extensions/configlayout.py +++ b/novelwriter/extensions/configlayout.py @@ -34,7 +34,7 @@ from PyQt5.QtWidgets import ( QVBoxLayout, QWidget ) -from novelwriter import CONFIG +from novelwriter import CONFIG, SHARED DEFAULT_SCALE = 0.9 @@ -266,7 +266,7 @@ class NColourLabel(QLabel): self._color = color or default self._faded = faded or default - font = self.font() + font = SHARED.theme.guiFont font.setPointSizeF(scale*font.pointSizeF()) font.setWeight(QFont.Weight.Bold if bold else QFont.Weight.Normal) if color: @@ -285,7 +285,6 @@ class NColourLabel(QLabel): """Change the colour state.""" if self._state is not state: self._state = state - print("State:", state, type(self.parent()).__name__) colour = self.palette() colour.setColor(QPalette.ColorRole.WindowText, self._color if state else self._faded) self.setPalette(colour) diff --git a/novelwriter/gui/docviewer.py b/novelwriter/gui/docviewer.py index 1029a152..b28411ab 100644 --- a/novelwriter/gui/docviewer.py +++ b/novelwriter/gui/docviewer.py @@ -282,6 +282,10 @@ class GuiDocViewer(QTextBrowser): return False return True + def anyFocus(self) -> bool: + """Check if any widget or child widget has focus.""" + return self.hasFocus() or self.isAncestorOf(QApplication.focusWidget()) + def clearNavHistory(self) -> None: """Clear the navigation history.""" self.docHistory.clear() diff --git a/novelwriter/gui/mainmenu.py b/novelwriter/gui/mainmenu.py index 56dc45d7..4a71c4f1 100644 --- a/novelwriter/gui/mainmenu.py +++ b/novelwriter/gui/mainmenu.py @@ -35,7 +35,7 @@ from PyQt5.QtWidgets import QAction, QMenuBar from novelwriter import CONFIG, SHARED from novelwriter.common import openExternalPath from novelwriter.constants import nwConst, nwKeyWords, nwLabels, nwUnicode, trConst -from novelwriter.enum import nwDocAction, nwDocInsert, nwView, nwWidget +from novelwriter.enum import nwDocAction, nwDocInsert, nwFocus, nwView from novelwriter.extensions.eventfilters import StatusTipFilter if TYPE_CHECKING: # pragma: no cover @@ -54,7 +54,7 @@ class GuiMainMenu(QMenuBar): requestDocInsert = pyqtSignal(nwDocInsert) requestDocInsertText = pyqtSignal(str) requestDocKeyWordInsert = pyqtSignal(str) - requestFocusChange = pyqtSignal(nwWidget) + requestFocusChange = pyqtSignal(nwFocus) requestViewChange = pyqtSignal(nwView) def __init__(self, mainGui: GuiMain) -> None: @@ -303,24 +303,24 @@ class GuiMainMenu(QMenuBar): self.viewMenu = self.addMenu(self.tr("&View")) # View > TreeView - self.aFocusTree = self.viewMenu.addAction(self.tr("Go to Project Tree")) + self.aFocusTree = self.viewMenu.addAction(self.tr("Go to Tree View")) self.aFocusTree.setShortcut("Ctrl+T") self.aFocusTree.triggered.connect( - lambda: self.requestFocusChange.emit(nwWidget.TREE) + lambda: self.requestFocusChange.emit(nwFocus.TREE) ) # View > Document Editor - self.aFocusEditor = self.viewMenu.addAction(self.tr("Go to Document Editor")) - self.aFocusEditor.setShortcut("Ctrl+E") - self.aFocusEditor.triggered.connect( - lambda: self.requestFocusChange.emit(nwWidget.EDITOR) + self.aFocusDocument = self.viewMenu.addAction(self.tr("Go to Document")) + self.aFocusDocument.setShortcut("Ctrl+E") + self.aFocusDocument.triggered.connect( + lambda: self.requestFocusChange.emit(nwFocus.DOCUMENT) ) # View > Outline self.aFocusOutline = self.viewMenu.addAction(self.tr("Go to Outline")) self.aFocusOutline.setShortcut("Ctrl+Shift+T") self.aFocusOutline.triggered.connect( - lambda: self.requestFocusChange.emit(nwWidget.OUTLINE) + lambda: self.requestFocusChange.emit(nwFocus.OUTLINE) ) # View > Separator diff --git a/novelwriter/guimain.py b/novelwriter/guimain.py index 00932967..443d3236 100644 --- a/novelwriter/guimain.py +++ b/novelwriter/guimain.py @@ -44,7 +44,7 @@ from novelwriter.dialogs.about import GuiAbout from novelwriter.dialogs.preferences import GuiPreferences from novelwriter.dialogs.projectsettings import GuiProjectSettings from novelwriter.dialogs.wordlist import GuiWordList -from novelwriter.enum import nwDocAction, nwDocInsert, nwDocMode, nwItemType, nwView, nwWidget +from novelwriter.enum import nwDocAction, nwDocInsert, nwDocMode, nwFocus, nwItemType, nwView from novelwriter.gui.doceditor import GuiDocEditor from novelwriter.gui.docviewer import GuiDocViewer from novelwriter.gui.docviewerpanel import GuiDocViewerPanel @@ -978,7 +978,8 @@ class GuiMain(QMainWindow): """ if focusMode: logger.debug("Activating Focus Mode") - self._switchFocus(nwWidget.EDITOR) + self._changeView(nwView.EDITOR) + self.docEditor.setFocus() else: logger.debug("Deactivating Focus Mode") @@ -1001,10 +1002,10 @@ class GuiMain(QMainWindow): self.docEditor.ensureCursorVisibleNoCentre() return - @pyqtSlot(nwWidget) - def _switchFocus(self, paneNo: nwWidget) -> None: + @pyqtSlot(nwFocus) + def _switchFocus(self, paneNo: nwFocus) -> None: """Switch focus between main GUI views.""" - if paneNo == nwWidget.TREE: + if paneNo == nwFocus.TREE: if self.projStack.currentWidget() is self.projView: if self.projView.treeHasFocus(): self._changeView(nwView.NOVEL) @@ -1020,13 +1021,15 @@ class GuiMain(QMainWindow): else: self._changeView(nwView.PROJECT) self.projView.setTreeFocus() - elif paneNo == nwWidget.EDITOR: + elif paneNo == nwFocus.DOCUMENT: self._changeView(nwView.EDITOR) - self.docEditor.setFocus() - elif paneNo == nwWidget.VIEWER: - self._changeView(nwView.EDITOR) - self.docViewer.setFocus() - elif paneNo == nwWidget.OUTLINE: + if self.docEditor.anyFocus(): + self.docViewer.setFocus() + elif self.docViewer.anyFocus(): + self.docEditor.setFocus() + else: + self.docEditor.setFocus() + elif paneNo == nwFocus.OUTLINE: self._changeView(nwView.OUTLINE) self.outlineView.setTreeFocus() return diff --git a/tests/test_gui/test_gui_doceditor.py b/tests/test_gui/test_gui_doceditor.py index a35cc16c..c4300be8 100644 --- a/tests/test_gui/test_gui_doceditor.py +++ b/tests/test_gui/test_gui_doceditor.py @@ -29,9 +29,7 @@ from PyQt5.QtWidgets import QAction, QApplication, QMenu from novelwriter import CONFIG, SHARED from novelwriter.constants import nwKeyWords, nwUnicode from novelwriter.dialogs.editlabel import GuiEditLabel -from novelwriter.enum import ( - nwDocAction, nwDocInsert, nwItemClass, nwItemLayout, nwTrinary, nwWidget -) +from novelwriter.enum import nwDocAction, nwDocInsert, nwItemClass, nwItemLayout, nwTrinary from novelwriter.gui.doceditor import GuiDocEditor from novelwriter.text.counting import standardCounter from novelwriter.types import ( @@ -1678,7 +1676,7 @@ def testGuiEditor_Completer(qtbot, nwGUI, projPath, mockRnd): completer = docEditor._completer # Create Scene - nwGUI._switchFocus(nwWidget.EDITOR) + nwGUI.docEditor.setFocus() for c in "### Scene One": qtbot.keyClick(docEditor, c, delay=KEY_DELAY) qtbot.keyClick(docEditor, Qt.Key_Return, delay=KEY_DELAY) diff --git a/tests/test_gui/test_gui_guimain.py b/tests/test_gui/test_gui_guimain.py index 1f011c37..683ce18f 100644 --- a/tests/test_gui/test_gui_guimain.py +++ b/tests/test_gui/test_gui_guimain.py @@ -32,7 +32,7 @@ from PyQt5.QtWidgets import QInputDialog, QMenu from novelwriter import CONFIG, SHARED from novelwriter.dialogs.editlabel import GuiEditLabel -from novelwriter.enum import nwItemType, nwView, nwWidget +from novelwriter.enum import nwFocus, nwItemType, nwView from novelwriter.gui.doceditor import GuiDocEditor from novelwriter.gui.noveltree import GuiNovelView from novelwriter.gui.outline import GuiOutlineView @@ -113,7 +113,7 @@ def testGuiMain_ProjectTreeItems(qtbot, monkeypatch, nwGUI, projPath, mockRnd): # Project Tree has focus nwGUI._changeView(nwView.PROJECT) - nwGUI._switchFocus(nwWidget.TREE) + nwGUI._switchFocus(nwFocus.TREE) nwGUI.projStack.setCurrentIndex(0) with monkeypatch.context() as mp: mp.setattr(GuiProjectTree, "hasFocus", lambda *a: True) @@ -137,7 +137,7 @@ def testGuiMain_ProjectTreeItems(qtbot, monkeypatch, nwGUI, projPath, mockRnd): # Project Outline has focus nwGUI._changeView(nwView.OUTLINE) - nwGUI._switchFocus(nwWidget.OUTLINE) + nwGUI._switchFocus(nwFocus.OUTLINE) with monkeypatch.context() as mp: mp.setattr(GuiOutlineView, "treeHasFocus", lambda *a: True) assert nwGUI.docEditor.docHandle is None @@ -230,7 +230,7 @@ def testGuiMain_Editing(qtbot, monkeypatch, nwGUI, projPath, tstPaths, mockRnd): CONFIG.autoScroll = True # Add a Character File - nwGUI._switchFocus(nwWidget.TREE) + nwGUI._switchFocus(nwFocus.TREE) nwGUI.projView.projTree.clearSelection() nwGUI.projView.projTree._getTreeItem(C.hCharRoot).setSelected(True) nwGUI.projView.projTree.newTreeItem(nwItemType.FILE, None, isNote=True) @@ -250,7 +250,7 @@ def testGuiMain_Editing(qtbot, monkeypatch, nwGUI, projPath, tstPaths, mockRnd): docEditor._qDocument.syntaxHighlighter.initHighlighter() # Type something into the document - nwGUI._switchFocus(nwWidget.EDITOR) + nwGUI.docEditor.setFocus() qtbot.keyClick(docEditor, "a", modifier=Qt.ControlModifier, delay=KEY_DELAY) for c in "# Jane Doe": qtbot.keyClick(docEditor, c, delay=KEY_DELAY) @@ -265,14 +265,14 @@ def testGuiMain_Editing(qtbot, monkeypatch, nwGUI, projPath, tstPaths, mockRnd): qtbot.keyClick(docEditor, Qt.Key_Return, delay=KEY_DELAY) # Add a Plot File - nwGUI._switchFocus(nwWidget.TREE) + nwGUI._switchFocus(nwFocus.TREE) nwGUI.projView.projTree.clearSelection() nwGUI.projView.projTree._getTreeItem(C.hPlotRoot).setSelected(True) nwGUI.projView.projTree.newTreeItem(nwItemType.FILE, None, isNote=True) nwGUI.openSelectedItem() # Type something into the document - nwGUI._switchFocus(nwWidget.EDITOR) + nwGUI.docEditor.setFocus() qtbot.keyClick(docEditor, "a", modifier=Qt.ControlModifier, delay=KEY_DELAY) for c in "# Main Plot": qtbot.keyClick(docEditor, c, delay=KEY_DELAY) @@ -287,7 +287,7 @@ def testGuiMain_Editing(qtbot, monkeypatch, nwGUI, projPath, tstPaths, mockRnd): qtbot.keyClick(docEditor, Qt.Key_Return, delay=KEY_DELAY) # Add a World File - nwGUI._switchFocus(nwWidget.TREE) + nwGUI._switchFocus(nwFocus.TREE) nwGUI.projView.projTree.clearSelection() nwGUI.projView.projTree._getTreeItem(C.hWorldRoot).setSelected(True) nwGUI.projView.projTree.newTreeItem(nwItemType.FILE, None, isNote=True) @@ -299,7 +299,7 @@ def testGuiMain_Editing(qtbot, monkeypatch, nwGUI, projPath, tstPaths, mockRnd): docEditor.replaceText("") # Type something into the document - nwGUI._switchFocus(nwWidget.EDITOR) + nwGUI.docEditor.setFocus() qtbot.keyClick(docEditor, "a", modifier=Qt.ControlModifier, delay=KEY_DELAY) for c in "# Main Location": qtbot.keyClick(docEditor, c, delay=KEY_DELAY) @@ -318,7 +318,7 @@ def testGuiMain_Editing(qtbot, monkeypatch, nwGUI, projPath, tstPaths, mockRnd): nwGUI._autoSaveProject() # Select the 'New Scene' file - nwGUI._switchFocus(nwWidget.TREE) + nwGUI._switchFocus(nwFocus.TREE) nwGUI.projView.projTree.clearSelection() nwGUI.projView.projTree._getTreeItem(C.hNovelRoot).setExpanded(True) nwGUI.projView.projTree._getTreeItem(C.hChapterDir).setExpanded(True) @@ -326,7 +326,7 @@ def testGuiMain_Editing(qtbot, monkeypatch, nwGUI, projPath, tstPaths, mockRnd): nwGUI.openSelectedItem() # Type something into the document - nwGUI._switchFocus(nwWidget.EDITOR) + nwGUI.docEditor.setFocus() qtbot.keyClick(docEditor, "a", modifier=Qt.ControlModifier, delay=KEY_DELAY) for c in "# Novel": qtbot.keyClick(docEditor, c, delay=KEY_DELAY) @@ -535,7 +535,7 @@ def testGuiMain_Editing(qtbot, monkeypatch, nwGUI, projPath, tstPaths, mockRnd): nwGUI.rebuildIndex() # Open and view the edited document - nwGUI._switchFocus(nwWidget.VIEWER) + nwGUI.docViewer.setFocus() assert nwGUI.openDocument(C.hSceneDoc) assert nwGUI.viewDocument(C.hSceneDoc) assert nwGUI.saveProject() diff --git a/tests/test_gui/test_gui_noveltree.py b/tests/test_gui/test_gui_noveltree.py index 593de829..288702c6 100644 --- a/tests/test_gui/test_gui_noveltree.py +++ b/tests/test_gui/test_gui_noveltree.py @@ -30,7 +30,7 @@ from PyQt5.QtWidgets import QInputDialog, QToolTip from novelwriter import CONFIG, SHARED from novelwriter.dialogs.editlabel import GuiEditLabel -from novelwriter.enum import nwItemType, nwWidget +from novelwriter.enum import nwFocus, nwItemType from novelwriter.gui.noveltree import GuiNovelTree, NovelTreeColumn from novelwriter.types import QtMouseLeft @@ -44,7 +44,7 @@ def testGuiNovelTree_TreeItems(qtbot, monkeypatch, nwGUI, projPath, mockRnd): buildTestProject(nwGUI, projPath) - nwGUI._switchFocus(nwWidget.TREE) + nwGUI._switchFocus(nwFocus.TREE) nwGUI.projView.projTree.clearSelection() nwGUI.projView.projTree._getTreeItem(C.hCharRoot).setSelected(True) nwGUI.projView.projTree.newTreeItem(nwItemType.FILE) diff --git a/tests/test_gui/test_gui_projtree.py b/tests/test_gui/test_gui_projtree.py index 8342150f..29a945cf 100644 --- a/tests/test_gui/test_gui_projtree.py +++ b/tests/test_gui/test_gui_projtree.py @@ -34,7 +34,7 @@ from novelwriter.core.project import NWProject from novelwriter.dialogs.docmerge import GuiDocMerge from novelwriter.dialogs.docsplit import GuiDocSplit from novelwriter.dialogs.editlabel import GuiEditLabel -from novelwriter.enum import nwItemClass, nwItemLayout, nwItemType, nwWidget +from novelwriter.enum import nwFocus, nwItemClass, nwItemLayout, nwItemType from novelwriter.gui.projtree import GuiProjectTree, GuiProjectView, _TreeContextMenu from novelwriter.guimain import GuiMain from novelwriter.types import QtAccepted, QtModNone, QtMouseLeft, QtMouseMiddle, QtRejected @@ -1111,7 +1111,7 @@ def testGuiProjTree_ContextMenu(qtbot, monkeypatch, nwGUI, projPath, mockRnd): # Create a project buildTestProject(nwGUI, projPath) nwGUI.openProject(projPath) - nwGUI._switchFocus(nwWidget.TREE) + nwGUI._switchFocus(nwFocus.TREE) # Handles for new objects hCharNote = "0000000000011" @@ -1408,7 +1408,7 @@ def testGuiProjTree_Templates(qtbot, monkeypatch, nwGUI, projPath, mockRnd): # Create a project buildTestProject(nwGUI, projPath) nwGUI.openProject(projPath) - nwGUI._switchFocus(nwWidget.TREE) + nwGUI._switchFocus(nwFocus.TREE) nwGUI.show() project = SHARED.project