Add a tab progress indicator
This commit is contained in:
parent
bcbdf9090f
commit
52c52e0675
@ -430,6 +430,14 @@ DATA = OrderedDict([
|
|||||||
'20%'),
|
'20%'),
|
||||||
"The width of the tab bar if it's vertical, in px or as percentage "
|
"The width of the tab bar if it's vertical, in px or as percentage "
|
||||||
"of the window."),
|
"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(
|
('storage', sect.KeyValue(
|
||||||
@ -874,6 +882,22 @@ DATA = OrderedDict([
|
|||||||
SettingValue(types.Color(), '#555555'),
|
SettingValue(types.Color(), '#555555'),
|
||||||
"Background color of the tabbar."),
|
"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',
|
('tab.seperator',
|
||||||
SettingValue(types.Color(), '#555555'),
|
SettingValue(types.Color(), '#555555'),
|
||||||
"Color for the tab seperator."),
|
"Color for the tab seperator."),
|
||||||
|
@ -29,6 +29,7 @@ import qutebrowser.config.config as config
|
|||||||
import qutebrowser.commands.utils as cmdutils
|
import qutebrowser.commands.utils as cmdutils
|
||||||
import qutebrowser.keyinput.modeman as modeman
|
import qutebrowser.keyinput.modeman as modeman
|
||||||
import qutebrowser.utils.log as log
|
import qutebrowser.utils.log as log
|
||||||
|
import qutebrowser.utils.misc as utils
|
||||||
from qutebrowser.widgets.tabwidget import TabWidget
|
from qutebrowser.widgets.tabwidget import TabWidget
|
||||||
from qutebrowser.widgets.webview import WebView
|
from qutebrowser.widgets.webview import WebView
|
||||||
from qutebrowser.browser.signalfilter import SignalFilter
|
from qutebrowser.browser.signalfilter import SignalFilter
|
||||||
@ -181,6 +182,8 @@ class TabbedBrowser(TabWidget):
|
|||||||
# misc
|
# misc
|
||||||
tab.titleChanged.connect(partial(self.on_title_changed, tab))
|
tab.titleChanged.connect(partial(self.on_title_changed, tab))
|
||||||
tab.iconChanged.connect(partial(self.on_icon_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))
|
frame.loadStarted.connect(partial(self.on_load_started, tab))
|
||||||
page.windowCloseRequested.connect(
|
page.windowCloseRequested.connect(
|
||||||
partial(self.on_window_close_requested, tab))
|
partial(self.on_window_close_requested, tab))
|
||||||
@ -442,6 +445,27 @@ class TabbedBrowser(TabWidget):
|
|||||||
self.current_tab_changed.emit(tab)
|
self.current_tab_changed.emit(tab)
|
||||||
self.title_changed.emit('{} - qutebrowser'.format(self.tabText(idx)))
|
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):
|
def resizeEvent(self, e):
|
||||||
"""Extend resizeEvent of QWidget to emit a resized signal afterwards.
|
"""Extend resizeEvent of QWidget to emit a resized signal afterwards.
|
||||||
|
|
||||||
|
@ -26,15 +26,15 @@ Module attributes:
|
|||||||
|
|
||||||
import functools
|
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,
|
from PyQt5.QtWidgets import (QTabWidget, QTabBar, QSizePolicy, QCommonStyle,
|
||||||
QStyle, QStylePainter, QStyleOptionTab,
|
QStyle, QStylePainter, QStyleOptionTab,
|
||||||
QApplication)
|
QApplication)
|
||||||
from PyQt5.QtGui import QIcon, QPalette, QColor
|
from PyQt5.QtGui import QIcon, QPalette, QColor
|
||||||
|
|
||||||
import qutebrowser.config.config as config
|
|
||||||
from qutebrowser.config.style import set_register_stylesheet
|
from qutebrowser.config.style import set_register_stylesheet
|
||||||
from qutebrowser.utils.qt import qt_ensure_valid
|
from qutebrowser.utils.qt import qt_ensure_valid
|
||||||
|
import qutebrowser.config.config as config
|
||||||
|
|
||||||
|
|
||||||
PM_TabBarPadding = QStyle.PM_CustomBase
|
PM_TabBarPadding = QStyle.PM_CustomBase
|
||||||
@ -125,6 +125,16 @@ class TabBar(QTabBar):
|
|||||||
return '<{} with {} tabs>'.format(self.__class__.__name__,
|
return '<{} with {} tabs>'.format(self.__class__.__name__,
|
||||||
self.count())
|
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):
|
def mousePressEvent(self, e):
|
||||||
"""Override mousePressEvent to close tabs if configured."""
|
"""Override mousePressEvent to close tabs if configured."""
|
||||||
button = config.get('tabbar', 'close-mouse-button')
|
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.Window, QColor(color))
|
||||||
tab.palette.setColor(QPalette.WindowText,
|
tab.palette.setColor(QPalette.WindowText,
|
||||||
QColor(config.get('colors', 'tab.fg')))
|
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():
|
if tab.rect.right() < 0 or tab.rect.left() > self.width():
|
||||||
# Don't bother drawing a tab if the entire tab is outside of
|
# Don't bother drawing a tab if the entire tab is outside of
|
||||||
# the visible tab bar.
|
# the visible tab bar.
|
||||||
@ -279,11 +293,18 @@ class TabBarStyle(QCommonStyle):
|
|||||||
self.drawControl(QStyle.CE_TabBarTabShape, opt, p, widget)
|
self.drawControl(QStyle.CE_TabBarTabShape, opt, p, widget)
|
||||||
self.drawControl(QStyle.CE_TabBarTabLabel, opt, p, widget)
|
self.drawControl(QStyle.CE_TabBarTabLabel, opt, p, widget)
|
||||||
elif element == QStyle.CE_TabBarTabShape:
|
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
|
# We use super() rather than self._style here because we don't want
|
||||||
# any sophisticated drawing.
|
# any sophisticated drawing.
|
||||||
super().drawControl(QStyle.CE_TabBarTabShape, opt, p, widget)
|
super().drawControl(QStyle.CE_TabBarTabShape, opt, p, widget)
|
||||||
elif element == QStyle.CE_TabBarTabLabel:
|
elif element == QStyle.CE_TabBarTabLabel:
|
||||||
p.fillRect(opt.rect, opt.palette.window())
|
|
||||||
text_rect, icon_rect = self._tab_layout(opt)
|
text_rect, icon_rect = self._tab_layout(opt)
|
||||||
if not opt.icon.isNull():
|
if not opt.icon.isNull():
|
||||||
qt_ensure_valid(icon_rect)
|
qt_ensure_valid(icon_rect)
|
||||||
@ -359,6 +380,8 @@ class TabBarStyle(QCommonStyle):
|
|||||||
text_rect = QRect(opt.rect)
|
text_rect = QRect(opt.rect)
|
||||||
qt_ensure_valid(text_rect)
|
qt_ensure_valid(text_rect)
|
||||||
text_rect.adjust(padding, 0, 0, 0)
|
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():
|
if not opt.icon.isNull():
|
||||||
icon_rect = self._get_icon_rect(opt, text_rect)
|
icon_rect = self._get_icon_rect(opt, text_rect)
|
||||||
text_rect.adjust(icon_rect.width() + padding, 0, 0, 0)
|
text_rect.adjust(icon_rect.width() + padding, 0, 0, 0)
|
||||||
|
Loading…
Reference in New Issue
Block a user