Skip to content

Commit

Permalink
Add focus indication to editor and viewer header
Browse files Browse the repository at this point in the history
  • Loading branch information
vkbo committed Jun 18, 2024
1 parent 930c60a commit c6569b6
Show file tree
Hide file tree
Showing 4 changed files with 53 additions and 15 deletions.
10 changes: 8 additions & 2 deletions novelwriter/gui/doceditor.py
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,7 @@
from novelwriter.constants import nwConst, nwKeyWords, nwShortcode, nwUnicode
from novelwriter.core.document import NWDocument
from novelwriter.enum import nwComment, nwDocAction, nwDocInsert, nwDocMode, nwItemClass, nwTrinary
from novelwriter.extensions.configlayout import NColourLabel
from novelwriter.extensions.eventfilters import WheelEventFilter
from novelwriter.extensions.modified import NIconToggleButton, NIconToolButton
from novelwriter.gui.dochighlight import BLOCK_META, BLOCK_TITLE
Expand Down Expand Up @@ -210,6 +211,7 @@ def __init__(self, parent: QWidget) -> None:
# Function Mapping
self.closeSearch = self.docSearch.closeSearch
self.searchVisible = self.docSearch.isVisible
self.changeFocusState = self.docHeader.changeFocusState

# Finalise
self.updateSyntaxColours()
Expand Down Expand Up @@ -2785,8 +2787,7 @@ def __init__(self, docEditor: GuiDocEditor) -> None:
self.setAutoFillBackground(True)

# Title Label
self.itemTitle = QLabel("", self)
self.itemTitle.setIndent(0)
self.itemTitle = NColourLabel("", self, faded=SHARED.theme.fadedText)
self.itemTitle.setMargin(0)
self.itemTitle.setContentsMargins(0, 0, 0, 0)
self.itemTitle.setAutoFillBackground(True)
Expand Down Expand Up @@ -2924,6 +2925,11 @@ def matchColours(self) -> None:

return

def changeFocusState(self, state: bool) -> None:
"""Toggle focus state."""
self.itemTitle.setColorState(state)
return

def setHandle(self, tHandle: str) -> None:
"""Set the document title from the handle, or alternatively, set
the whole document path within the project.
Expand Down
15 changes: 11 additions & 4 deletions novelwriter/gui/docviewer.py
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@
from PyQt5.QtCore import QPoint, Qt, QUrl, pyqtSignal, pyqtSlot
from PyQt5.QtGui import QCursor, QMouseEvent, QPalette, QResizeEvent, QTextCursor
from PyQt5.QtWidgets import (
QAction, QApplication, QFrame, QHBoxLayout, QLabel, QMenu, QTextBrowser,
QAction, QApplication, QFrame, QHBoxLayout, QMenu, QTextBrowser,
QToolButton, QWidget
)

Expand All @@ -42,6 +42,7 @@
from novelwriter.core.toqdoc import TextDocumentTheme, ToQTextDocument
from novelwriter.enum import nwDocAction, nwDocMode, nwItemType
from novelwriter.error import logException
from novelwriter.extensions.configlayout import NColourLabel
from novelwriter.extensions.eventfilters import WheelEventFilter
from novelwriter.extensions.modified import NIconToolButton
from novelwriter.gui.theme import STYLES_MIN_TOOLBUTTON
Expand Down Expand Up @@ -92,6 +93,9 @@ def __init__(self, parent: QWidget) -> None:
self.setContextMenuPolicy(Qt.ContextMenuPolicy.CustomContextMenu)
self.customContextMenuRequested.connect(self._openContextMenu)

# Function Mapping
self.changeFocusState = self.docHeader.changeFocusState

self.initViewer()

logger.debug("Ready: GuiDocViewer")
Expand Down Expand Up @@ -597,9 +601,7 @@ def __init__(self, docViewer: GuiDocViewer) -> None:
self.setAutoFillBackground(True)

# Title Label
self.itemTitle = QLabel(self)
self.itemTitle.setText("")
self.itemTitle.setIndent(0)
self.itemTitle = NColourLabel("", self, faded=SHARED.theme.fadedText)
self.itemTitle.setMargin(0)
self.itemTitle.setContentsMargins(0, 0, 0, 0)
self.itemTitle.setAutoFillBackground(True)
Expand Down Expand Up @@ -738,6 +740,11 @@ def matchColours(self) -> None:
self.itemTitle.setPalette(palette)
return

def changeFocusState(self, state: bool) -> None:
"""Toggle focus state."""
self.itemTitle.setColorState(state)
return

def setHandle(self, tHandle: str) -> None:
"""Sets the document title from the handle, or alternatively,
set the whole document path.
Expand Down
23 changes: 23 additions & 0 deletions novelwriter/guimain.py
Original file line number Diff line number Diff line change
Expand Up @@ -326,6 +326,11 @@ def initMain(self) -> None:

def postLaunchTasks(self, cmdOpen: str | None) -> None:
"""Process tasks after the main window has been created."""
QApplication.processEvents()
app = QApplication.instance()
if isinstance(app, QApplication):
app.focusChanged.connect(self._appFocusChanged)

# Check that config loaded fine
if CONFIG.hasError:
SHARED.error(CONFIG.errorText())
Expand Down Expand Up @@ -948,6 +953,24 @@ def toggleFocusMode(self) -> None:
# Private Slots
##

@pyqtSlot("QWidget*", "QWidget*")
def _appFocusChanged(self, old: QWidget, new: QWidget) -> None:
"""Alert main widgets that they have received or lost focus."""
if isinstance(new, QWidget):
docEditor = False
docViewer = False
if self.docEditor.isAncestorOf(new):
docEditor = True
elif self.docViewer.isAncestorOf(new):
docViewer = True

self.docEditor.changeFocusState(docEditor)
self.docViewer.changeFocusState(docViewer)

logger.debug("Main focus switched to: %s", type(new).__name__)

return

@pyqtSlot(bool)
def _focusModeChanged(self, focusMode: bool) -> None:
"""Handle change of focus mode. The Main GUI Focus Mode hides
Expand Down
20 changes: 11 additions & 9 deletions tests/test_base/test_base_init.py
Original file line number Diff line number Diff line change
Expand Up @@ -62,15 +62,17 @@ def testBaseInit_Launch(caplog, monkeypatch, fncPath):
CONFIG.osWindows = osWindows

# Normal Launch
monkeypatch.setattr("PyQt5.QtWidgets.QApplication.__init__", lambda *a: None)
monkeypatch.setattr("PyQt5.QtWidgets.QApplication.setApplicationName", lambda *a: None)
monkeypatch.setattr("PyQt5.QtWidgets.QApplication.setApplicationVersion", lambda *a: None)
monkeypatch.setattr("PyQt5.QtWidgets.QApplication.setWindowIcon", lambda *a: None)
monkeypatch.setattr("PyQt5.QtWidgets.QApplication.setOrganizationDomain", lambda *a: None)
monkeypatch.setattr("PyQt5.QtWidgets.QApplication.exec", lambda *a: 0)
with pytest.raises(SystemExit) as ex:
main([f"--config={fncPath}", f"--data={fncPath}"])
assert ex.value.code == 0
with monkeypatch.context() as mp:
mp.setattr("PyQt5.QtWidgets.QApplication.__init__", lambda *a: None)
mp.setattr("PyQt5.QtWidgets.QApplication.setApplicationName", lambda *a: None)
mp.setattr("PyQt5.QtWidgets.QApplication.setApplicationVersion", lambda *a: None)
mp.setattr("PyQt5.QtWidgets.QApplication.setWindowIcon", lambda *a: None)
mp.setattr("PyQt5.QtWidgets.QApplication.setOrganizationDomain", lambda *a: None)
mp.setattr("PyQt5.QtWidgets.QApplication.exec", lambda *a: 0)
# mp.setattr("PyQt5.QtWidgets.QApplication.focusChange.connect", lambda *a: None)
with pytest.raises(SystemExit) as ex:
main([f"--config={fncPath}", f"--data={fncPath}"])
assert ex.value.code == 0


@pytest.mark.base
Expand Down

0 comments on commit c6569b6

Please sign in to comment.