Add a tab progress indicator

This commit is contained in:
Florian Bruhin 2014-07-16 13:51:16 +02:00
parent bcbdf9090f
commit 52c52e0675
3 changed files with 74 additions and 3 deletions

View File

@ -430,6 +430,14 @@ DATA = OrderedDict([
'20%'),
"The width of the tab bar if it's vertical, in px or as percentage "
"of the window."),
('indicator-width',
SettingValue(types.Int(minval=0), '3'),
"Width of the progress indicator."),
('indicator-space',
SettingValue(types.Int(minval=0), '3'),
"Spacing between tab edge and indicator."),
)),
('storage', sect.KeyValue(
@ -874,6 +882,22 @@ DATA = OrderedDict([
SettingValue(types.Color(), '#555555'),
"Background color of the tabbar."),
('tab.indicator.start',
SettingValue(types.QtColor(), '#0000aa'),
"Color gradient start for the tab indicator."),
('tab.indicator.stop',
SettingValue(types.QtColor(), '#00aa00'),
"Color gradient end for the tab indicator."),
('tab.indicator.error',
SettingValue(types.QtColor(), '#ff0000'),
"Color for the tab indicator on errors.."),
('tab.indicator.system',
SettingValue(types.ColorSystem(), 'rgb'),
"Color gradient interpolation system for the tab indicator."),
('tab.seperator',
SettingValue(types.Color(), '#555555'),
"Color for the tab seperator."),

View File

@ -29,6 +29,7 @@ import qutebrowser.config.config as config
import qutebrowser.commands.utils as cmdutils
import qutebrowser.keyinput.modeman as modeman
import qutebrowser.utils.log as log
import qutebrowser.utils.misc as utils
from qutebrowser.widgets.tabwidget import TabWidget
from qutebrowser.widgets.webview import WebView
from qutebrowser.browser.signalfilter import SignalFilter
@ -181,6 +182,8 @@ class TabbedBrowser(TabWidget):
# misc
tab.titleChanged.connect(partial(self.on_title_changed, tab))
tab.iconChanged.connect(partial(self.on_icon_changed, tab))
tab.loadProgress.connect(partial(self.on_load_progress, tab))
frame.loadFinished.connect(partial(self.on_load_finished, tab))
frame.loadStarted.connect(partial(self.on_load_started, tab))
page.windowCloseRequested.connect(
partial(self.on_window_close_requested, tab))
@ -442,6 +445,27 @@ class TabbedBrowser(TabWidget):
self.current_tab_changed.emit(tab)
self.title_changed.emit('{} - qutebrowser'.format(self.tabText(idx)))
def on_load_progress(self, tab, perc):
"""Adjust tab indicator on load progress."""
idx = self.indexOf(tab)
start = config.get('colors', 'tab.indicator.start')
stop = config.get('colors', 'tab.indicator.stop')
system = config.get('colors', 'tab.indicator.system')
color = utils.interpolate_color(start, stop, perc, system)
self.tabBar().set_tab_indicator_color(idx, color)
def on_load_finished(self, tab, ok):
"""Adjust tab indicator when loading finished."""
idx = self.indexOf(tab)
if ok:
start = config.get('colors', 'tab.indicator.start')
stop = config.get('colors', 'tab.indicator.stop')
system = config.get('colors', 'tab.indicator.system')
color = utils.interpolate_color(start, stop, 100, system)
else:
color = config.get('colors', 'tab.indicator.error')
self.tabBar().set_tab_indicator_color(idx, color)
def resizeEvent(self, e):
"""Extend resizeEvent of QWidget to emit a resized signal afterwards.

View File

@ -26,15 +26,15 @@ Module attributes:
import functools
from PyQt5.QtCore import pyqtSlot, Qt, QSize, QRect
from PyQt5.QtCore import pyqtSlot, Qt, QSize, QRect, QPoint
from PyQt5.QtWidgets import (QTabWidget, QTabBar, QSizePolicy, QCommonStyle,
QStyle, QStylePainter, QStyleOptionTab,
QApplication)
from PyQt5.QtGui import QIcon, QPalette, QColor
import qutebrowser.config.config as config
from qutebrowser.config.style import set_register_stylesheet
from qutebrowser.utils.qt import qt_ensure_valid
import qutebrowser.config.config as config
PM_TabBarPadding = QStyle.PM_CustomBase
@ -125,6 +125,16 @@ class TabBar(QTabBar):
return '<{} with {} tabs>'.format(self.__class__.__name__,
self.count())
def set_tab_indicator_color(self, idx, color):
"""Set the tab indicator color.
Args:
idx: The tab index.
color: A QColor.
"""
self.setTabData(idx, color)
self.update(self.tabRect(idx))
def mousePressEvent(self, e):
"""Override mousePressEvent to close tabs if configured."""
button = config.get('tabbar', 'close-mouse-button')
@ -216,6 +226,10 @@ class TabBar(QTabBar):
tab.palette.setColor(QPalette.Window, QColor(color))
tab.palette.setColor(QPalette.WindowText,
QColor(config.get('colors', 'tab.fg')))
indicator_color = self.tabData(idx)
if indicator_color is None:
indicator_color = QColor()
tab.palette.setColor(QPalette.Base, indicator_color)
if tab.rect.right() < 0 or tab.rect.left() > self.width():
# Don't bother drawing a tab if the entire tab is outside of
# the visible tab bar.
@ -279,11 +293,18 @@ class TabBarStyle(QCommonStyle):
self.drawControl(QStyle.CE_TabBarTabShape, opt, p, widget)
self.drawControl(QStyle.CE_TabBarTabLabel, opt, p, widget)
elif element == QStyle.CE_TabBarTabShape:
p.fillRect(opt.rect, opt.palette.window())
indicator_color = opt.palette.base().color()
indicator_width = config.get('tabbar', 'indicator-width')
if indicator_color.isValid() and indicator_width != 0:
topleft = opt.rect.topLeft()
topleft += QPoint(config.get('tabbar', 'indicator-space'), 2)
p.fillRect(topleft.x(), topleft.y(), indicator_width,
opt.rect.height() - 4, indicator_color)
# We use super() rather than self._style here because we don't want
# any sophisticated drawing.
super().drawControl(QStyle.CE_TabBarTabShape, opt, p, widget)
elif element == QStyle.CE_TabBarTabLabel:
p.fillRect(opt.rect, opt.palette.window())
text_rect, icon_rect = self._tab_layout(opt)
if not opt.icon.isNull():
qt_ensure_valid(icon_rect)
@ -359,6 +380,8 @@ class TabBarStyle(QCommonStyle):
text_rect = QRect(opt.rect)
qt_ensure_valid(text_rect)
text_rect.adjust(padding, 0, 0, 0)
text_rect.adjust(config.get('tabbar', 'indicator-width') +
config.get('tabbar', 'indicator-space'), 0, 0, 0)
if not opt.icon.isNull():
icon_rect = self._get_icon_rect(opt, text_rect)
text_rect.adjust(icon_rect.width() + padding, 0, 0, 0)