[core/theme|output] Add separators

Add a way for themes to specify custom separators. Doing that, make
nicer interfaces for drawing "supplementary" components (separators)
for widgets and generalize the attribute retrieval within the theme.
This commit is contained in:
Tobias Witek 2020-02-22 13:42:44 +01:00
parent d3fc648c08
commit 38410adcb8
6 changed files with 63 additions and 15 deletions

View file

@ -6,6 +6,9 @@ def register(event, callback, *args, **kwargs):
lambda: callback(*args, **kwargs)
)
def clear():
callbacks.clear()
def trigger(event):
for callback in callbacks.get(event, []):
callback()

View file

@ -38,18 +38,41 @@ class i3(object):
def stop(self):
return { 'suffix': '\n]' }
def __separator(self, widget):
if not self._theme.separator():
return []
return [{
'full_text': self._theme.separator(),
'color': self._theme.bg(widget),
'background': self._theme.prev_bg(widget),
'separator': False,
'separator_block_width': self._theme.separator_block_width(),
'border_top': self._theme.border_top(),
'border_left': self._theme.border_left(),
'border_right': self._theme.border_right(),
'border_bottom': self._theme.border_bottom(),
}]
def __main(self, module, widget):
return [{
'full_text': widget.full_text(),
'instance': widget.id(),
'name': module.id(),
'color': self._theme.fg(widget),
'background': self._theme.bg(widget),
'separator': self._theme.default_separators(),
'separator_block_width': self._theme.separator_block_width(),
'border_top': self._theme.border_top(),
'border_left': self._theme.border_left(),
'border_right': self._theme.border_right(),
'border_bottom': self._theme.border_bottom(),
}]
def widgets(self, module):
widgets = []
for widget in module.widgets():
widgets.append({
'full_text': widget.full_text(),
'instance': widget.id(),
'name': module.id(),
'color': self._theme.fg(widget),
'background': self._theme.bg(widget),
'separator': self._theme.default_separators(),
'separator_block_width': self._theme.separator_block_width(),
})
widgets += self.__separator(widget)
widgets += self.__main(module, widget)
core.event.trigger('next-widget')
return widgets
@ -61,7 +84,8 @@ class i3(object):
def statusline(self):
widgets = []
for module in self._modules:
widgets += self._status[module]
if module in self._status:
widgets += self._status[module]
return {
'data': widgets,
'suffix': ','

View file

@ -19,14 +19,18 @@ class Theme(object):
self.__data = raw_data
else:
self.__data = self.load(name)
core.event.register('start', self.__start)
core.event.register('update', self.__start)
core.event.register('next-widget', self.__next_widget)
for attr, default in [
('fg', None), ('bg', None),
('default-separators', True),
('separator-block-width', 0),
('separator', None)
('separator', None),
('border-top', 0),
('border-bottom', 0),
('border-left', 0),
('border-right', 0),
]:
setattr(self, attr.replace('-', '_'), lambda widget=None, default=default, attr=attr: self.__get(widget, attr, default))
@ -41,6 +45,14 @@ class Theme(object):
def __start(self):
self.__widget_count = 0
def prev_bg(self, widget):
if self.__widget_count == 0:
return None
self.__widget_count = self.__widget_count - 1
value = self.bg(widget)
self.__widget_count = self.__widget_count + 1
return value
def __next_widget(self):
self.__widget_count = self.__widget_count + 1

View file

@ -19,6 +19,7 @@
- hide modules if not in warning/error state (-a)
- WAL support
- tkinter / popups
- scrolling decorator (incl. minwidth, alignment)
## Improvements
- pango output (improve - maybe autodetect? see #531)

View file

@ -15,6 +15,8 @@ class i3(unittest.TestCase):
self.someModule = TestModule(widgets=[widget, widget, widget])
def test_start(self):
core.event.clear()
all_data = self.i3.start()
data = all_data['data']
self.assertEqual(1, data['version'], 'i3bar protocol version 1 expected')

View file

@ -1,9 +1,11 @@
import unittest
import core.theme
import core.event
class theme(unittest.TestCase):
def setUp(self):
core.event.clear()
self.invalidThemeName = 'this-theme-does-not-exist'
self.validThemeName = 'default'
self.defaultsTheme = {
@ -34,14 +36,18 @@ class theme(unittest.TestCase):
def test_cycle(self):
theme = core.theme.Theme(raw_data=self.cycleTheme)
self.assertEqual(None, theme.prev_bg(None))
self.assertEqual(self.cycleTheme['cycle'][0]['fg'], theme.fg())
self.assertEqual(self.cycleTheme['cycle'][0]['bg'], theme.bg())
core.event.trigger('next-widget')
self.assertEqual(self.cycleTheme['cycle'][0]['bg'], theme.prev_bg(None))
core.event.trigger('next-widget')
self.assertEqual(self.cycleTheme['cycle'][2]['fg'], theme.fg())
self.assertEqual(self.cycleTheme['cycle'][2]['bg'], theme.bg())
core.event.trigger('start')
self.assertEqual(self.cycleTheme['cycle'][0]['fg'], theme.fg())
self.assertEqual(self.cycleTheme['cycle'][0]['bg'], theme.bg())
with unittest.mock.patch('core.output.sys.stdout'):
core.event.trigger('update')
self.assertEqual(self.cycleTheme['cycle'][0]['fg'], theme.fg())
self.assertEqual(self.cycleTheme['cycle'][0]['bg'], theme.bg())
# vim: tabstop=8 expandtab shiftwidth=4 softtabstop=4