From 9bf7dd2bbb56e9a91eba134fea54550a9c6c1338 Mon Sep 17 00:00:00 2001 From: Florian Bruhin Date: Tue, 28 Jan 2014 12:21:00 +0100 Subject: [PATCH] Make colors configurable --- TODO | 2 +- qutebrowser/app.py | 8 ++-- qutebrowser/utils/config.py | 57 ++++++++++++++++++++++- qutebrowser/widgets/completion.py | 52 +++++++++++---------- qutebrowser/widgets/statusbar/__init__.py | 31 +++++++----- qutebrowser/widgets/statusbar/progress.py | 21 +++++---- qutebrowser/widgets/tabbar.py | 32 +++++++------ 7 files changed, 138 insertions(+), 65 deletions(-) diff --git a/TODO b/TODO index b8198bc97..35d95169d 100644 --- a/TODO +++ b/TODO @@ -25,7 +25,7 @@ IPC, like dwb -x Mode handling? Bookmarks sensible crash handling (exceptions, segfaults [windows?]) -more configuration (colors, hide completion) +more configuration (hide completion) Minor features/bugs =================== diff --git a/qutebrowser/app.py b/qutebrowser/app.py index 9127c772c..7521619ff 100644 --- a/qutebrowser/app.py +++ b/qutebrowser/app.py @@ -7,9 +7,9 @@ from PyQt5.QtWidgets import QApplication from PyQt5.QtCore import QUrl, QTimer import qutebrowser.commands.utils as cmdutils +import qutebrowser.utils.config as config from qutebrowser.widgets.mainwindow import MainWindow from qutebrowser.commands.keys import KeyParser -from qutebrowser.utils.config import Config from qutebrowser.utils.appdirs import AppDirs class QuteBrowser(QApplication): @@ -35,14 +35,14 @@ class QuteBrowser(QApplication): confdir = None else: confdir = self.args.confdir - self.config = Config(confdir) + config.init(confdir) self.commandparser = cmdutils.CommandParser() self.keyparser = KeyParser(self.mainwindow) self.init_cmds() self.mainwindow = MainWindow() - self.aboutToQuit.connect(self.config.save) + self.aboutToQuit.connect(config.config.save) self.mainwindow.tabs.keypress.connect(self.keyparser.handle) self.keyparser.set_cmd_text.connect(self.mainwindow.status.cmd.set_cmd) self.mainwindow.status.cmd.got_cmd.connect(self.commandparser.run) @@ -104,7 +104,7 @@ class QuteBrowser(QApplication): for cmd in cmdutils.cmd_dict.values(): cmd.signal.connect(self.cmd_handler) try: - self.keyparser.from_config_sect(self.config['keybind']) + self.keyparser.from_config_sect(config.config['keybind']) except KeyError: pass diff --git a/qutebrowser/utils/config.py b/qutebrowser/utils/config.py index a34b12c30..567f40af9 100644 --- a/qutebrowser/utils/config.py +++ b/qutebrowser/utils/config.py @@ -4,6 +4,9 @@ import logging from configparser import ConfigParser +config = None +colordict = {} + default_config = { 'keybind': { 'o': 'open', @@ -21,9 +24,61 @@ default_config = { 'u': 'undo', 'gg': 'scroll_perc_y 0', 'G': 'scroll_perc_y', - } + }, + 'colors': { + 'completion.fg': '#333333', + 'completion.item.bg': 'white', + 'completion.category.bg': 'qlineargradient(x1:0, y1:0, x2:1, y2:1, stop:0 #e4e4e4, stop:1 #dbdbdb)', + 'completion.category.border.top': '#808080', + 'completion.category.border.bottom': '#bbbbbb', + 'completion.item.selected.fg': '#333333', + 'completion.item.selected.bg': '#ffec8b', + 'completion.item.selected.border.top': '#f2f2c0', + 'completion.item.selected.border.bottom': '#e6e680', + 'completion.match.fg': 'red', + 'statusbar.progress.bg': 'white', + 'statusbar.progress.bg.error': 'red', + 'statusbar.bg': 'black', + 'statusbar.fg': 'white', + 'statusbar.bg.error': 'red', + 'tab.bg': 'grey', + 'tab.bg.selected': 'black', + 'tab.fg': 'white', + 'tab.seperator': 'white', + }, } +def init(confdir): + global config, colordict + config = Config(confdir) + try: + colordict = ColorDict(config['colors']) + except KeyError: + colordict = ColorDict() + +def get_stylesheet(template): + global colordict + return template.strip().format(color=colordict) + +class ColorDict(dict): + def __getitem__(self, key): + try: + val = super().__getitem__(key) + except KeyError: + return '' + if 'fg' in key.split('.'): + return 'color: {};'.format(val) + elif 'bg' in key.split('.'): + return 'background-color: {};'.format(val) + else: + return val + + def getraw(self, key): + try: + return super().__getitem__(key) + except KeyError: + return None + class Config(ConfigParser): """Our own ConfigParser""" configdir = None diff --git a/qutebrowser/widgets/completion.py b/qutebrowser/widgets/completion.py index 1b96877c2..a82fb8bd0 100644 --- a/qutebrowser/widgets/completion.py +++ b/qutebrowser/widgets/completion.py @@ -8,33 +8,35 @@ from PyQt5.QtCore import (QRectF, QRect, QPoint, pyqtSignal, Qt, from PyQt5.QtGui import (QIcon, QPalette, QTextDocument, QTextOption, QTextCursor) +import qutebrowser.utils.config as config from qutebrowser.utils.completion import CompletionFilterModel from qutebrowser.commands.utils import CommandCompletionModel class CompletionView(QTreeView): _stylesheet = """ - QTreeView { + QTreeView {{ font-family: Monospace, Courier; - color: #333333; + {color[completion.fg]} + {color[completion.bg]} outline: 0; - } - QTreeView::item { - background: white; - } - QTreeView::item:has-children { + }} + QTreeView::item {{ + {color[completion.item.fg]} + {color[completion.item.bg]} + }} + QTreeView::item:has-children {{ font-weight: bold; - - background: qlineargradient(x1:0, y1:0, x2:1, y2:1, stop:0 #e4e4e4, - stop:1 #dbdbdb); - border-top: 1px solid #808080; - border-bottom: 1px solid #bbbbbb; - } - QTreeView::item:selected { - border-top: 1px solid #f2f2c0; - border-bottom: 1px solid #e6e680; - background-color: #ffec8b; - color: #333333; - } + {color[completion.category.fg]} + {color[completion.category.bg]} + border-top: 1px solid {color[completion.category.border.top]}; + border-bottom: 1px solid {color[completion.category.border.bottom]}; + }} + QTreeView::item:selected {{ + border-top: 1px solid {color[completon.item.selected.border.top]}; + border-bottom: 1px solid {color[completion.item.selected.border.bottom]}; + background-color: {color[completion.item.selected.bg]}; + {color[completion.item.selected.fg]} + }} """ # FIXME because we use :has-children, if a category is empty, it won't look # like one anymore @@ -53,7 +55,7 @@ class CompletionView(QTreeView): self.model.setSourceModel(self.completion_models['command']) self.model.pattern_changed.connect(self.resort) self.setItemDelegate(CompletionItemDelegate()) - self.setStyleSheet(self._stylesheet.strip()) + self.setStyleSheet(config.get_stylesheet(self._stylesheet)) self.expandAll() self.setHeaderHidden(True) self.setIndentation(0) @@ -242,11 +244,11 @@ class CompletionItemDelegate(QStyledItemDelegate): doc.setHtml('{}'.format(html.escape(self.opt.text))) doc.setDefaultFont(self.opt.font) doc.setDefaultTextOption(text_option) - doc.setDefaultStyleSheet(""" - .highlight { - color: red; - } - """) + doc.setDefaultStyleSheet(config.get_stylesheet(""" + .highlight {{ + {color[completion.match.fg]} + }} + """)) doc.setDocumentMargin(0) if index.column() == 0: diff --git a/qutebrowser/widgets/statusbar/__init__.py b/qutebrowser/widgets/statusbar/__init__.py index bcdb6ff71..f6f28e757 100644 --- a/qutebrowser/widgets/statusbar/__init__.py +++ b/qutebrowser/widgets/statusbar/__init__.py @@ -3,6 +3,7 @@ import logging from PyQt5.QtCore import pyqtSignal from PyQt5.QtWidgets import QHBoxLayout, QWidget +import qutebrowser.utils.config as config from qutebrowser.widgets.statusbar.command import Command from qutebrowser.widgets.statusbar.text import Text from qutebrowser.widgets.statusbar.progress import Progress @@ -14,27 +15,33 @@ class StatusBar(QWidget): txt = None prog = None resized = pyqtSignal('QRect') - fgcolor = 'white' - bgcolor = 'black' - font = 'Monospace, Courier' + fgcolor = None + bgcolor = None _stylesheet = """ * {{ - background: {self.bgcolor}; - color: {self.fgcolor}; - font-family: {self.font}; + {color[statusbar.bg.__cur__]} + {color[statusbar.fg.__cur__]} + font-family: Monospace, Courier; }} """ def __setattr__(self, name, value): """Update the stylesheet if relevant attributes have been changed""" super().__setattr__(name, value) - if name in ['fgcolor', 'bgcolor', 'font']: - self.setStyleSheet(self._stylesheet.strip().format(self=self)) + if name == 'fgcolor' and value is not None: + config.colordict['statusbar.fg.__cur__'] = value + self.setStyleSheet(config.get_stylesheet(self._stylesheet)) + elif name == 'bgcolor' and value is not None: + config.colordict['statusbar.bg.__cur__'] = value + self.setStyleSheet(config.get_stylesheet(self._stylesheet)) # TODO: the statusbar should be a bit smaller def __init__(self, mainwindow): super().__init__(mainwindow) - self.setStyleSheet(self._stylesheet.strip().format(self=self)) + self.fgcolor = config.colordict.getraw('statusbar.fg') + self.bgcolor = config.colordict.getraw('statusbar.bg') + self.setStyleSheet(config.get_stylesheet(self._stylesheet)) + self.hbox = QHBoxLayout(self) self.hbox.setContentsMargins(0, 0, 0, 0) self.hbox.setSpacing(0) @@ -50,12 +57,14 @@ class StatusBar(QWidget): def disp_error(self, text): """Displays an error in the statusbar""" - self.bgcolor = 'red' + self.bgcolor = config.colordict.getraw('statusbar.bg.error') + self.fgcolor = config.colordict.getraw('statusbar.fg.error') self.txt.error = text def clear_error(self): """Clears a displayed error from the status bar""" - self.bgcolor = 'black' + self.bgcolor = config.colordict.getraw('statusbar.bg') + self.fgcolor = config.colordict.getraw('statusbar.fg') self.txt.error = '' def resizeEvent(self, e): diff --git a/qutebrowser/widgets/statusbar/progress.py b/qutebrowser/widgets/statusbar/progress.py index 3e63b7a13..77db7b89f 100644 --- a/qutebrowser/widgets/statusbar/progress.py +++ b/qutebrowser/widgets/statusbar/progress.py @@ -1,10 +1,12 @@ +import qutebrowser.utils.config as config + from PyQt5.QtWidgets import QProgressBar, QSizePolicy from PyQt5.QtCore import QSize class Progress(QProgressBar): """ The progress bar part of the status bar""" bar = None - color = 'white' + color = None _stylesheet = """ QProgressBar {{ border-radius: 0px; @@ -13,7 +15,7 @@ class Progress(QProgressBar): }} QProgressBar::chunk {{ - background-color: {self.color}; + {color[statusbar.progress.bg.__cur__]} }} """ @@ -23,14 +25,15 @@ class Progress(QProgressBar): self.setSizePolicy(QSizePolicy.Fixed, QSizePolicy.Fixed) self.setTextVisible(False) - self.setStyleSheet(self._stylesheet.strip().format(self=self)) + self.color = config.colordict.getraw('statusbar.progress.bg') self.hide() def __setattr__(self, name, value): """Update the stylesheet if relevant attributes have been changed""" super().__setattr__(name, value) - if name == 'color': - self.setStyleSheet(self._stylesheet.strip().format(self=self)) + if name == 'color' and value is not None: + config.colordict['statusbar.progress.bg.__cur__'] = value + self.setStyleSheet(config.get_stylesheet(self._stylesheet)) def minimumSizeHint(self): status_size = self.bar.size() @@ -45,8 +48,9 @@ class Progress(QProgressBar): if prog == 100: self.setValue(prog) else: - if self.color != 'white': - self.color = 'white' + color = config.colordict.getraw('status.progress.bg') + if self.color != color: + self.color = color self.setValue(prog) self.show() @@ -54,4 +58,5 @@ class Progress(QProgressBar): if ok: self.hide() else: - self.color = 'red' + self.color = config.colordict.getraw('statusbar.progress.bg.error') + diff --git a/qutebrowser/widgets/tabbar.py b/qutebrowser/widgets/tabbar.py index 2184e0533..474998f4e 100644 --- a/qutebrowser/widgets/tabbar.py +++ b/qutebrowser/widgets/tabbar.py @@ -1,6 +1,8 @@ from PyQt5.QtWidgets import QTabWidget from PyQt5.QtCore import Qt +import qutebrowser.utils.config as config + class TabWidget(QTabWidget): """The tabwidget used for TabbedBrowser""" @@ -8,36 +10,36 @@ class TabWidget(QTabWidget): # background-color: grey for QTabBar... _stylesheet = """ - QTabWidget::pane { + QTabWidget::pane {{ position: absolute; top: 0px; - } + }} - QTabBar { + QTabBar {{ font-family: Monospace, Courier; font-size: 8pt; - } + }} - QTabBar::tab { - background-color: grey; - color: white; + QTabBar::tab {{ + {color[tab.bg]} + {color[tab.fg]} padding-left: 5px; padding-right: 5px; padding-top: 0px; padding-bottom: 0px; - } + }} - QTabBar::tab:first, QTabBar::tab:middle { - border-right: 1px solid white; - } + QTabBar::tab:first, QTabBar::tab:middle {{ + border-right: 1px solid {color[tab.seperator]}; + }} - QTabBar::tab:selected { - background-color: black; - } + QTabBar::tab:selected {{ + {color[tab.bg.selected]} + }} """ def __init__(self, parent): super().__init__(parent) - self.setStyleSheet(self._stylesheet.strip()) + self.setStyleSheet(config.get_stylesheet(self._stylesheet)) self.setDocumentMode(True) self.setElideMode(Qt.ElideRight)