[core/output] Fully switch to i3 block abstraction
According to the unit tests, at least, the old functionality is back again - with the additional i3 block abstraction in output in place. Also, pango support is temporarily removed again and will be re-implemented based on the new architecture.
This commit is contained in:
parent
f5052473fb
commit
37cca1c3b9
2 changed files with 74 additions and 36 deletions
|
@ -6,29 +6,76 @@ import core.theme
|
|||
import core.event
|
||||
|
||||
def dump_json(obj):
|
||||
return obj.__dict__
|
||||
return obj.dict()
|
||||
|
||||
def assign(src, dst, key, src_key=None, default=None):
|
||||
if not src_key:
|
||||
src_key = key.replace('_', '-') # automagically replace - with _
|
||||
|
||||
for k in src_key if isinstance(src_key, list) else [src_key]:
|
||||
if k in src:
|
||||
dst[key] = src[k]
|
||||
return
|
||||
if default is not None:
|
||||
dst[key] = default
|
||||
|
||||
class block(object):
|
||||
__COMMON_THEME_FIELDS = [
|
||||
'separator', 'separator_block_width',
|
||||
'border_top', 'border_left', 'border_right', 'border_bottom',
|
||||
'pango', 'fg', 'bg'
|
||||
'separator', 'separator-block-width', 'default-separators',
|
||||
'border-top', 'border-left', 'border-right', 'border-bottom',
|
||||
'pango', 'fg', 'bg', 'padding', 'prefix', 'suffix'
|
||||
]
|
||||
def __init__(self, theme, module, widget):
|
||||
self.__attributes = {}
|
||||
for key in self.__COMMON_THEME_FIELDS:
|
||||
tmp = theme.get(key, widget)
|
||||
if tmp:
|
||||
if tmp is not None:
|
||||
self.__attributes[key] = tmp
|
||||
|
||||
self.__attributes['name'] = module.id
|
||||
self.__attributes['instance'] = widget.id
|
||||
self.__attributes['prev-bg'] = theme.get('bg', 'previous')
|
||||
|
||||
def set(self, key, value):
|
||||
self.__attributes[key] = value
|
||||
|
||||
def __dict__(self):
|
||||
return {}
|
||||
def dict(self):
|
||||
result = {}
|
||||
|
||||
assign(self.__attributes, result, 'full_text', ['full_text', 'separator'])
|
||||
assign(self.__attributes, result, 'separator', 'default-separators')
|
||||
|
||||
if '_decorator' in self.__attributes:
|
||||
assign(self.__attributes, result, 'color', 'bg')
|
||||
assign(self.__attributes, result, 'background', 'prev-bg')
|
||||
result['_decorator'] = True
|
||||
else:
|
||||
assign(self.__attributes, result, 'color', 'fg')
|
||||
assign(self.__attributes, result, 'background', 'bg')
|
||||
|
||||
if 'full_text' in self.__attributes:
|
||||
result['full_text'] = self.__format(self.__attributes['full_text'])
|
||||
|
||||
for k in [
|
||||
'name', 'instance', 'separator_block_width', 'border', 'border_top',
|
||||
'border_bottom', 'border_left', 'border_right'
|
||||
]:
|
||||
assign(self.__attributes, result, k)
|
||||
|
||||
return result
|
||||
|
||||
def __pad(self, text):
|
||||
padding = self.__attributes.get('padding', '')
|
||||
if not text: return padding
|
||||
return '{}{}{}'.format(padding, text, padding)
|
||||
|
||||
def __format(self, text):
|
||||
if text is None: return None
|
||||
return '{}{}{}'.format(
|
||||
self.__pad(self.__attributes.get('prefix')),
|
||||
text,
|
||||
self.__pad(self.__attributes.get('suffix'))
|
||||
)
|
||||
|
||||
class i3(object):
|
||||
def __init__(self, theme=core.theme.Theme(), config=core.config.Config([])):
|
||||
|
@ -69,29 +116,17 @@ class i3(object):
|
|||
def stop(self):
|
||||
return { 'suffix': '\n]' }
|
||||
|
||||
def __pad(self, module, widget, full_text):
|
||||
padding = self.__theme.padding()
|
||||
if not full_text: return padding
|
||||
return '{}{}{}'.format(padding, full_text, padding)
|
||||
|
||||
def __decorate(self, module, widget, full_text):
|
||||
if full_text is None: return None
|
||||
return '{}{}{}'.format(
|
||||
self.__pad(module, widget, self.__theme.prefix(widget)),
|
||||
full_text,
|
||||
self.__pad(module, widget, self.__theme.suffix(widget))
|
||||
)
|
||||
|
||||
def __separator_block(self, module, widget):
|
||||
if not self.__theme.get('separator'):
|
||||
return []
|
||||
blk = block(self.__theme, module, widget)
|
||||
blk.set('_decorator', True)
|
||||
return blk
|
||||
return [blk]
|
||||
|
||||
def __content_block(self, module, widget):
|
||||
text = self.__content[widget]
|
||||
blk = block(self.__theme, module, widget)
|
||||
blk.set('min_width', self.__decorate(module, widget, widget.get('theme.minwidth')))
|
||||
blk.set('full_text', self.__decorate(module, widget, text))
|
||||
blk.set('min_width', widget.get('theme.minwidth'))
|
||||
blk.set('full_text', self.__content[widget])
|
||||
if self.__config.debug():
|
||||
blk.set('__state', ', '.join(module.state(widget)))
|
||||
return blk
|
||||
|
@ -102,11 +137,12 @@ class i3(object):
|
|||
if widget.module() and self.__config.autohide(widget.module().name()):
|
||||
if not any(state in widget.state() for state in [ 'warning', 'critical']):
|
||||
continue
|
||||
blocks.append(self.__separator_block(module, widget))
|
||||
blocks.extend(self.__separator_block(module, widget))
|
||||
blocks.append(self.__content_block(module, widget))
|
||||
core.event.trigger('next-widget')
|
||||
return blocks
|
||||
|
||||
# TODO: only updates full text, not the state!?
|
||||
def update(self, affected_modules=None):
|
||||
now = time.time()
|
||||
for module in self.__modules:
|
||||
|
|
|
@ -20,14 +20,14 @@ class i3(unittest.TestCase):
|
|||
});
|
||||
self.separator = '***';
|
||||
self.separatorTheme = core.theme.Theme(raw_data = {
|
||||
'defaults': { 'separator': self.separator }
|
||||
'defaults': { 'separator': self.separator, 'fg': 'red', 'bg': 'blue' }
|
||||
});
|
||||
|
||||
def test_start(self):
|
||||
core.event.clear()
|
||||
|
||||
all_data = self.i3.start()
|
||||
data = all_data['data']
|
||||
data = all_data['blocks']
|
||||
self.assertEqual(1, data['version'], 'i3bar protocol version 1 expected')
|
||||
self.assertTrue(data['click_events'], 'click events should be enabled')
|
||||
self.assertEqual('\n[', all_data['suffix'])
|
||||
|
@ -48,37 +48,39 @@ class i3(unittest.TestCase):
|
|||
|
||||
def test_draw_existing_module(self):
|
||||
self.i3.test_draw = unittest.mock.MagicMock(return_value={
|
||||
'data': { 'test': True }, 'suffix': 'end'
|
||||
'blocks': { 'test': True }, 'suffix': 'end'
|
||||
})
|
||||
self.i3.draw('test_draw')
|
||||
self.i3.test_draw.assert_called_once_with()
|
||||
|
||||
def test_empty_status_line(self):
|
||||
data = self.i3.statusline()
|
||||
self.assertEqual([], data['data'], 'expected empty list of status line entries')
|
||||
self.assertEqual([], data['blocks'], 'expected empty list of status line entries')
|
||||
self.assertEqual(',', data['suffix'], 'expected "," as suffix')
|
||||
|
||||
def test_statusline(self):
|
||||
self.i3.modules([ self.someModule, self.someModule, self.someModule ])
|
||||
self.i3.update()
|
||||
data = self.i3.statusline()
|
||||
self.assertEqual(len(self.someModule.widgets())*3, len(data['data']), 'wrong number of widgets')
|
||||
self.assertEqual(len(self.someModule.widgets())*3, len(data['blocks']), 'wrong number of widgets')
|
||||
|
||||
def test_padding(self):
|
||||
self.i3.theme(self.paddedTheme)
|
||||
result = self.i3.__pad(self.someModule, self.someModule.widget(), 'abc')
|
||||
blk = core.output.block(self.i3.theme(), self.someModule, self.someModule.widget())
|
||||
blk.set('full_text', 'abc')
|
||||
result = blk.dict()['full_text']
|
||||
self.assertEqual(' abc ', result)
|
||||
|
||||
def test_no_separator(self):
|
||||
result = self.i3.__separator(self.someModule, self.someModule.widget())
|
||||
result = self.i3.__separator_block(self.someModule, self.someModule.widget())
|
||||
self.assertEqual([], result)
|
||||
|
||||
def test_separator(self):
|
||||
self.i3.theme(self.separatorTheme)
|
||||
result = self.i3.__separator(self.someModule, self.someModule.widget())
|
||||
result = self.i3.__separator_block(self.someModule, self.someModule.widget())
|
||||
self.assertEqual(1, len(result))
|
||||
self.assertEqual('***', result[0]['full_text'])
|
||||
self.assertTrue(result[0].get('_decorator', False))
|
||||
self.assertEqual(self.separatorTheme.bg(self.someModule.widget()), result[0]['color'])
|
||||
self.assertEqual('***', result[0].dict()['full_text'])
|
||||
self.assertTrue(result[0].dict().get('_decorator', False))
|
||||
self.assertEqual(self.separatorTheme.bg(self.someModule.widget()), result[0].dict()['color'])
|
||||
|
||||
# vim: tabstop=8 expandtab shiftwidth=4 softtabstop=4
|
||||
|
|
Loading…
Reference in a new issue