diff --git a/nw/assets/icons/fallback/maximise-dark.svg b/nw/assets/icons/fallback/maximise-dark.svg new file mode 100644 index 00000000..1ce767a3 --- /dev/null +++ b/nw/assets/icons/fallback/maximise-dark.svg @@ -0,0 +1,56 @@ + + + + + + image/svg+xml + + + + + + + + + diff --git a/nw/assets/icons/fallback/maximise.svg b/nw/assets/icons/fallback/maximise.svg new file mode 100644 index 00000000..0e1d4a86 --- /dev/null +++ b/nw/assets/icons/fallback/maximise.svg @@ -0,0 +1,56 @@ + + + + + + image/svg+xml + + + + + + + + + diff --git a/nw/assets/icons/fallback/minimise-dark.svg b/nw/assets/icons/fallback/minimise-dark.svg new file mode 100644 index 00000000..4bc48ce2 --- /dev/null +++ b/nw/assets/icons/fallback/minimise-dark.svg @@ -0,0 +1,55 @@ + + + + + + image/svg+xml + + + + + + + + + diff --git a/nw/assets/icons/fallback/minimise.svg b/nw/assets/icons/fallback/minimise.svg new file mode 100644 index 00000000..b0a1972f --- /dev/null +++ b/nw/assets/icons/fallback/minimise.svg @@ -0,0 +1,55 @@ + + + + + + image/svg+xml + + + + + + + + + diff --git a/nw/assets/icons/fallback/refresh-dark.svg b/nw/assets/icons/fallback/refresh-dark.svg new file mode 100644 index 00000000..31367a18 --- /dev/null +++ b/nw/assets/icons/fallback/refresh-dark.svg @@ -0,0 +1,56 @@ + + + + + + image/svg+xml + + + + + + + + + diff --git a/nw/assets/icons/fallback/refresh.svg b/nw/assets/icons/fallback/refresh.svg new file mode 100644 index 00000000..c87d3257 --- /dev/null +++ b/nw/assets/icons/fallback/refresh.svg @@ -0,0 +1,56 @@ + + + + + + image/svg+xml + + + + + + + + + diff --git a/nw/assets/icons/typicons_colour_dark/arrow-maximise.svg b/nw/assets/icons/typicons_colour_dark/arrow-maximise.svg new file mode 100644 index 00000000..a5ee7fa0 --- /dev/null +++ b/nw/assets/icons/typicons_colour_dark/arrow-maximise.svg @@ -0,0 +1,55 @@ + + + + + + image/svg+xml + + + + + + + + + diff --git a/nw/assets/icons/typicons_colour_dark/arrow-minimise.svg b/nw/assets/icons/typicons_colour_dark/arrow-minimise.svg new file mode 100644 index 00000000..83d5a066 --- /dev/null +++ b/nw/assets/icons/typicons_colour_dark/arrow-minimise.svg @@ -0,0 +1,55 @@ + + + + + + image/svg+xml + + + + + + + + + diff --git a/nw/assets/icons/typicons_colour_dark/icons.conf b/nw/assets/icons/typicons_colour_dark/icons.conf index b0e75498..cffe7329 100644 --- a/nw/assets/icons/typicons_colour_dark/icons.conf +++ b/nw/assets/icons/typicons_colour_dark/icons.conf @@ -32,6 +32,9 @@ delete = delete.svg add = plus.svg remove = minus.svg close = times.svg +refresh = refresh.svg +maximise = arrow-maximise.svg +minimise = arrow-minimise.svg done = input-checked.svg search = search.svg search-replace = search-replace.svg diff --git a/nw/assets/icons/typicons_colour_dark/refresh.svg b/nw/assets/icons/typicons_colour_dark/refresh.svg new file mode 100644 index 00000000..f1853eb3 --- /dev/null +++ b/nw/assets/icons/typicons_colour_dark/refresh.svg @@ -0,0 +1,55 @@ + + + + + + image/svg+xml + + + + + + + + + diff --git a/nw/assets/icons/typicons_colour_light/arrow-maximise.svg b/nw/assets/icons/typicons_colour_light/arrow-maximise.svg new file mode 100644 index 00000000..3ef012fe --- /dev/null +++ b/nw/assets/icons/typicons_colour_light/arrow-maximise.svg @@ -0,0 +1,56 @@ + + + + + + image/svg+xml + + + + + + + + + diff --git a/nw/assets/icons/typicons_colour_light/arrow-minimise.svg b/nw/assets/icons/typicons_colour_light/arrow-minimise.svg new file mode 100644 index 00000000..0d9f7d13 --- /dev/null +++ b/nw/assets/icons/typicons_colour_light/arrow-minimise.svg @@ -0,0 +1,55 @@ + + + + + + image/svg+xml + + + + + + + + + diff --git a/nw/assets/icons/typicons_colour_light/icons.conf b/nw/assets/icons/typicons_colour_light/icons.conf index 70477f64..ac281962 100644 --- a/nw/assets/icons/typicons_colour_light/icons.conf +++ b/nw/assets/icons/typicons_colour_light/icons.conf @@ -32,6 +32,9 @@ delete = delete.svg add = plus.svg remove = minus.svg close = times.svg +refresh = refresh.svg +maximise = arrow-maximise.svg +minimise = arrow-minimise.svg done = input-checked.svg search = search.svg search-replace = search-replace.svg diff --git a/nw/assets/icons/typicons_colour_light/refresh.svg b/nw/assets/icons/typicons_colour_light/refresh.svg new file mode 100644 index 00000000..d1d9513b --- /dev/null +++ b/nw/assets/icons/typicons_colour_light/refresh.svg @@ -0,0 +1,56 @@ + + + + + + image/svg+xml + + + + + + + + + diff --git a/nw/assets/icons/typicons_grey_dark/arrow-maximise.svg b/nw/assets/icons/typicons_grey_dark/arrow-maximise.svg new file mode 100644 index 00000000..1ce767a3 --- /dev/null +++ b/nw/assets/icons/typicons_grey_dark/arrow-maximise.svg @@ -0,0 +1,56 @@ + + + + + + image/svg+xml + + + + + + + + + diff --git a/nw/assets/icons/typicons_grey_dark/arrow-minimise.svg b/nw/assets/icons/typicons_grey_dark/arrow-minimise.svg new file mode 100644 index 00000000..4bc48ce2 --- /dev/null +++ b/nw/assets/icons/typicons_grey_dark/arrow-minimise.svg @@ -0,0 +1,55 @@ + + + + + + image/svg+xml + + + + + + + + + diff --git a/nw/assets/icons/typicons_grey_dark/icons.conf b/nw/assets/icons/typicons_grey_dark/icons.conf index d06201b1..d03bec4d 100644 --- a/nw/assets/icons/typicons_grey_dark/icons.conf +++ b/nw/assets/icons/typicons_grey_dark/icons.conf @@ -32,6 +32,9 @@ delete = delete.svg add = plus.svg remove = minus.svg close = times.svg +refresh = refresh.svg +maximise = arrow-maximise.svg +minimise = arrow-minimise.svg done = input-checked.svg search = search.svg search-replace = search-replace.svg diff --git a/nw/assets/icons/typicons_grey_dark/refresh.svg b/nw/assets/icons/typicons_grey_dark/refresh.svg new file mode 100644 index 00000000..31367a18 --- /dev/null +++ b/nw/assets/icons/typicons_grey_dark/refresh.svg @@ -0,0 +1,56 @@ + + + + + + image/svg+xml + + + + + + + + + diff --git a/nw/assets/icons/typicons_grey_light/arrow-maximise.svg b/nw/assets/icons/typicons_grey_light/arrow-maximise.svg new file mode 100644 index 00000000..0e1d4a86 --- /dev/null +++ b/nw/assets/icons/typicons_grey_light/arrow-maximise.svg @@ -0,0 +1,56 @@ + + + + + + image/svg+xml + + + + + + + + + diff --git a/nw/assets/icons/typicons_grey_light/arrow-minimise.svg b/nw/assets/icons/typicons_grey_light/arrow-minimise.svg new file mode 100644 index 00000000..b0a1972f --- /dev/null +++ b/nw/assets/icons/typicons_grey_light/arrow-minimise.svg @@ -0,0 +1,55 @@ + + + + + + image/svg+xml + + + + + + + + + diff --git a/nw/assets/icons/typicons_grey_light/icons.conf b/nw/assets/icons/typicons_grey_light/icons.conf index dd97c4c8..9f04ee61 100644 --- a/nw/assets/icons/typicons_grey_light/icons.conf +++ b/nw/assets/icons/typicons_grey_light/icons.conf @@ -32,6 +32,9 @@ delete = delete.svg add = plus.svg remove = minus.svg close = times.svg +refresh = refresh.svg +maximise = arrow-maximise.svg +minimise = arrow-minimise.svg done = input-checked.svg search = search.svg search-replace = search-replace.svg diff --git a/nw/assets/icons/typicons_grey_light/refresh.svg b/nw/assets/icons/typicons_grey_light/refresh.svg new file mode 100644 index 00000000..c87d3257 --- /dev/null +++ b/nw/assets/icons/typicons_grey_light/refresh.svg @@ -0,0 +1,56 @@ + + + + + + image/svg+xml + + + + + + + + + diff --git a/nw/gui/docbars.py b/nw/gui/docbars.py index f0eeb326..e1240e2d 100644 --- a/nw/gui/docbars.py +++ b/nw/gui/docbars.py @@ -29,10 +29,10 @@ import logging import nw -from PyQt5.QtCore import Qt +from PyQt5.QtCore import Qt, QSize from PyQt5.QtGui import QPalette, QColor from PyQt5.QtWidgets import ( - qApp, QFrame, QGridLayout, QLabel, QLineEdit, QPushButton, + qApp, QWidget, QFrame, QGridLayout, QLabel, QLineEdit, QPushButton, QHBoxLayout ) @@ -40,10 +40,10 @@ from nw.constants import nwDocAction, nwUnicode logger = logging.getLogger(__name__) -class GuiSearchBar(QFrame): +class GuiSearchBar(QWidget): def __init__(self, theParent): - QFrame.__init__(self, theParent) + QWidget.__init__(self, theParent) logger.debug("Initialising GuiSearchBar ...") @@ -168,10 +168,10 @@ class GuiSearchBar(QFrame): # END Class GuiSearchBar -class GuiDocTitleBar(QLabel): +class GuiDocTitleBar(QWidget): - def __init__(self, theParent, theProject): - QLabel.__init__(self, theParent) + def __init__(self, theParent, theProject, isEditor): + QWidget.__init__(self, theParent) logger.debug("Initialising GuiDocTitleBar ...") @@ -180,25 +180,78 @@ class GuiDocTitleBar(QLabel): self.theProject = theProject self.theTheme = theParent.theTheme self.theHandle = None + self.isEditor = isEditor - self.setText("") - self.setIndent(0) - self.setMargin(0) + # Make a QPalette that matches the Syntax Theme + self.thePalette = QPalette() + self.thePalette.setColor(QPalette.Window, QColor(*self.theTheme.colBack)) + self.thePalette.setColor(QPalette.Text, QColor(*self.theTheme.colText)) + + # Main Widget Settings self.setContentsMargins(0, 0, 0, 0) self.setAutoFillBackground(True) - self.setAlignment(Qt.AlignCenter) - self.setWordWrap(True) - self.setFrameShape(QFrame.NoFrame) - self.setLineWidth(0) + self.setPalette(self.thePalette) - lblPalette = self.palette() - lblPalette.setColor(QPalette.Window, QColor(*self.theTheme.colBack)) - lblPalette.setColor(QPalette.Text, QColor(*self.theTheme.colText)) - self.setPalette(lblPalette) + # Title Label + self.theTitle = QLabel() + self.theTitle.setText("") + self.theTitle.setIndent(0) + self.theTitle.setMargin(0) + self.theTitle.setContentsMargins(10, 0, 0, 0) + self.theTitle.setAutoFillBackground(True) + self.theTitle.setAlignment(Qt.AlignCenter) + self.theTitle.setWordWrap(True) + self.theTitle.setFrameShape(QFrame.NoFrame) + self.theTitle.setLineWidth(0) + self.theTitle.setPalette(self.thePalette) - lblFont = self.font() + lblFont = self.theTitle.font() lblFont.setPointSizeF(0.9*self.theTheme.fontPointSize) - self.setFont(lblFont) + self.theTitle.setFont(lblFont) + + # Buttons + iPx = self.theTheme.textIconSize + + self.closeButton = QPushButton("") + self.closeButton.setIcon(self.theTheme.getIcon("close")) + self.closeButton.setContentsMargins(0, 0, 0, 0) + self.closeButton.setIconSize(QSize(iPx, iPx)) + self.closeButton.setFixedSize(iPx, iPx) + self.closeButton.setFlat(True) + self.closeButton.setVisible(False) + self.closeButton.clicked.connect(self._closeDocument) + + if self.isEditor: + self.minmaxButton = QPushButton("") + self.minmaxButton.setIcon(self.theTheme.getIcon("maximise")) + self.minmaxButton.setContentsMargins(0, 0, 0, 0) + self.minmaxButton.setIconSize(QSize(iPx, iPx)) + self.minmaxButton.setFixedSize(iPx, iPx) + self.minmaxButton.setFlat(True) + self.minmaxButton.setVisible(False) + self.minmaxButton.clicked.connect(self._minmaxDocument) + else: + self.refreshButton = QPushButton("") + self.refreshButton.setIcon(self.theTheme.getIcon("refresh")) + self.refreshButton.setContentsMargins(0, 0, 0, 0) + self.refreshButton.setIconSize(QSize(iPx, iPx)) + self.refreshButton.setFixedSize(iPx, iPx) + self.refreshButton.setFlat(True) + self.refreshButton.setVisible(False) + self.refreshButton.clicked.connect(self._refreshDocument) + + # Assemble Layout + hSp = self.mainConf.pxInt(6) + self.outerBox = QHBoxLayout() + self.outerBox.setSpacing(hSp) + self.outerBox.addSpacing(2*(iPx + hSp)) + self.outerBox.addWidget(self.theTitle, 1) + if self.isEditor: + self.outerBox.addWidget(self.minmaxButton, 0) + else: + self.outerBox.addWidget(self.refreshButton, 0) + self.outerBox.addWidget(self.closeButton, 0) + self.setLayout(self.outerBox) logger.debug("GuiDocTitleBar initialisation complete") @@ -212,9 +265,14 @@ class GuiDocTitleBar(QLabel): """Sets the document title from the handle, or alternatively, set the whole document path. """ - self.setText("") + self.theTitle.setText("") self.theHandle = tHandle if tHandle is None: + self.closeButton.setVisible(False) + if self.isEditor: + self.minmaxButton.setVisible(False) + else: + self.refreshButton.setVisible(False) return False if self.mainConf.showFullPath: @@ -225,16 +283,51 @@ class GuiDocTitleBar(QLabel): if nwItem is not None: tTitle.append(nwItem.itemName) sSep = " %s " % nwUnicode.U_RSAQUO - self.setText(sSep.join(tTitle)) + self.theTitle.setText(sSep.join(tTitle)) else: nwItem = self.theProject.projTree[tHandle] if nwItem is None: return False + self.theTitle.setText(nwItem.itemName) - self.setText(nwItem.itemName) + self.closeButton.setVisible(True) + if self.isEditor: + self.minmaxButton.setVisible(True) + else: + self.refreshButton.setVisible(True) return True + ## + # Slots + ## + + def _closeDocument(self): + """Trigger the close editor/viewer on the main window. + """ + if self.isEditor: + self.theParent.theParent.closeDocEditor() + else: + self.theParent.theParent.closeDocViewer() + return + + def _minmaxDocument(self): + """Switch on or off zen mode. + """ + self.theParent.theParent.toggleZenMode() + self.closeButton.setVisible(not self.theParent.theParent.isZenMode) + if self.theParent.theParent.isZenMode: + self.minmaxButton.setIcon(self.theTheme.getIcon("minimise")) + else: + self.minmaxButton.setIcon(self.theTheme.getIcon("maximise")) + return + + def _refreshDocument(self): + """Reload the content of the document. + """ + self.theParent.reloadText() + return + ## # Events ## diff --git a/nw/gui/doceditor.py b/nw/gui/doceditor.py index 97ef5c94..e523c6f7 100644 --- a/nw/gui/doceditor.py +++ b/nw/gui/doceditor.py @@ -85,7 +85,7 @@ class GuiDocEditor(QTextEdit): self.qDocument.contentsChange.connect(self._docChange) # Document Title - self.docTitle = GuiDocTitleBar(self, self.theProject) + self.docTitle = GuiDocTitleBar(self, self.theProject, isEditor=True) self.docTitle.setGeometry(0, 0, self.docTitle.width(), self.docTitle.height()) self.setViewportMargins(0, self.docTitle.height(), 0, 0) diff --git a/nw/gui/docviewer.py b/nw/gui/docviewer.py index a3d6eeda..3c4f86b9 100644 --- a/nw/gui/docviewer.py +++ b/nw/gui/docviewer.py @@ -58,7 +58,7 @@ class GuiDocViewer(QTextBrowser): self.initViewer() # Document Title - self.docTitle = GuiDocTitleBar(self, self.theProject) + self.docTitle = GuiDocTitleBar(self, self.theProject, isEditor=False) self.docTitle.setGeometry(0, 0, self.docTitle.width(), self.docTitle.height()) self.setViewportMargins(0, self.docTitle.height(), 0, 0) diff --git a/nw/gui/theme.py b/nw/gui/theme.py index 2f5a896f..8288e1fa 100644 --- a/nw/gui/theme.py +++ b/nw/gui/theme.py @@ -525,6 +525,9 @@ class GuiIcons: "check" : (None, None), "cross" : (None, None), "hash" : (None, None), + "maximise" : (None, None), + "minimise" : (None, None), + "refresh" : (None, None), ## Other Icons "warning" : (QStyle.SP_MessageBoxWarning, "dialog-warning"),