diff --git a/bumblebee/output.py b/bumblebee/output.py index de80d90..e582d34 100644 --- a/bumblebee/output.py +++ b/bumblebee/output.py @@ -18,6 +18,9 @@ class Widget(object): pass in the module name in every concrete module implementation""" self.module = module.name + def state(self): + return "state-default" + def full_text(self): """Retrieve the full text to display in the widget""" if callable(self._full_text): diff --git a/bumblebee/theme.py b/bumblebee/theme.py index 196a574..ddcd249 100644 --- a/bumblebee/theme.py +++ b/bumblebee/theme.py @@ -113,10 +113,16 @@ class Theme(object): self._cycle = self._cycles[self._cycle_idx] module_theme = self._theme.get(widget.module, {}) + if name != widget.state(): + # avoid infinite recursion + state_theme = self._get(widget, widget.state(), {}) + else: + state_theme = {} value = self._defaults.get(name, default) value = self._cycle.get(name, value) value = module_theme.get(name, value) + value = state_theme.get(name, value) return value diff --git a/tests/test_theme.py b/tests/test_theme.py index d2220cd..75e7bc6 100644 --- a/tests/test_theme.py +++ b/tests/test_theme.py @@ -10,7 +10,7 @@ class TestTheme(unittest.TestCase): self.nonexistentThemeName = "no-such-theme" self.invalidThemeName = "invalid" self.validThemeName = "test" - self.themedWidget = MockWidget("foo") + self.themedWidget = MockWidget("bla") self.theme = Theme(self.validThemeName) self.cycleTheme = Theme("test_cycle") self.anyWidget = MockWidget("bla") @@ -18,6 +18,7 @@ class TestTheme(unittest.TestCase): data = self.theme.data() self.widgetTheme = "test-widget" + self.themedWidget.module = self.widgetTheme self.defaultColor = data["defaults"]["fg"] self.defaultBgColor = data["defaults"]["bg"] self.widgetColor = data[self.widgetTheme]["fg"] @@ -42,24 +43,23 @@ class TestTheme(unittest.TestCase): Theme(self.invalidThemeName) def test_default_prefix(self): - self.assertEquals(self.theme.prefix(self.themedWidget), self.defaultPrefix) + self.assertEquals(self.theme.prefix(self.anyWidget), self.defaultPrefix) def test_default_suffix(self): - self.assertEquals(self.theme.suffix(self.themedWidget), self.defaultSuffix) + self.assertEquals(self.theme.suffix(self.anyWidget), self.defaultSuffix) def test_widget_prefix(self): - self.themedWidget.module = self.widgetTheme self.assertEquals(self.theme.prefix(self.themedWidget), self.widgetPrefix) def test_widget_fg(self): - self.assertEquals(self.theme.fg(self.themedWidget), self.defaultColor) - self.themedWidget.module = self.widgetTheme - self.assertEquals(self.theme.fg(self.themedWidget), self.widgetColor) + self.assertEquals(self.theme.fg(self.anyWidget), self.defaultColor) + self.anyWidget.module = self.widgetTheme + self.assertEquals(self.theme.fg(self.anyWidget), self.widgetColor) def test_widget_bg(self): - self.assertEquals(self.theme.bg(self.themedWidget), self.defaultBgColor) - self.themedWidget.module = self.widgetTheme - self.assertEquals(self.theme.bg(self.themedWidget), self.widgetBgColor) + self.assertEquals(self.theme.bg(self.anyWidget), self.defaultBgColor) + self.anyWidget.module = self.widgetTheme + self.assertEquals(self.theme.bg(self.anyWidget), self.widgetBgColor) def test_absent_cycle(self): theme = self.theme @@ -94,4 +94,21 @@ class TestTheme(unittest.TestCase): self.assertEquals(theme.separator_fg(self.anotherWidget), theme.bg(self.anotherWidget)) self.assertEquals(theme.separator_bg(self.anotherWidget), prev_bg) + def test_state(self): + theme = self.theme + data = theme.data() + + self.assertEquals(theme.fg(self.anyWidget), data["defaults"]["fg"]) + self.assertEquals(theme.bg(self.anyWidget), data["defaults"]["bg"]) + + self.anyWidget.attr_state = "critical" + self.assertEquals(theme.fg(self.anyWidget), data["defaults"]["critical"]["fg"]) + self.assertEquals(theme.bg(self.anyWidget), data["defaults"]["critical"]["bg"]) + + self.themedWidget.attr_state = "critical" + self.assertEquals(theme.fg(self.themedWidget), data[self.widgetTheme]["critical"]["fg"]) + # if elements are missing in the state theme, they are taken from the + # widget theme instead (i.e. no fallback to a more general state theme) + self.assertEquals(theme.bg(self.themedWidget), data[self.widgetTheme]["bg"]) + # vim: tabstop=8 expandtab shiftwidth=4 softtabstop=4 diff --git a/tests/util.py b/tests/util.py index 314cfa0..ff9249d 100644 --- a/tests/util.py +++ b/tests/util.py @@ -28,10 +28,14 @@ class MockOutput(object): def end(self): pass -class MockWidget(object): +class MockWidget(Widget): def __init__(self, text): self._text = text self.module = None + self.attr_state = "state-default" + + def state(self): + return self.attr_state def update(self, widgets): pass diff --git a/themes/test.json b/themes/test.json index 4640634..401a234 100644 --- a/themes/test.json +++ b/themes/test.json @@ -6,10 +6,17 @@ "fg": "#000000", "bg": "#111111", "separator": " * ", - "separator-block-width": 10 + "separator-block-width": 10, + "critical": { + "fg": "#ffffff", + "bg": "#010101" + } }, "test-widget": { "fg": "#ababab", - "bg": "#222222" + "bg": "#222222", + "critical": { + "fg": "#bababa" + } } }