[all] Refactor module <-> output communication
Modules now return "bumblebee.output.Widget" objects, so that they can actually define a list of items to be drawn in the bar.
This commit is contained in:
parent
7f91b8298f
commit
bab7821607
6 changed files with 223 additions and 131 deletions
|
@ -43,18 +43,15 @@ class Engine:
|
|||
self.register_event(e)
|
||||
|
||||
def run(self):
|
||||
print self._output.start()
|
||||
self._output.start()
|
||||
|
||||
while True:
|
||||
# improve this
|
||||
self._theme.reset()
|
||||
self._theme.begin()
|
||||
for m in self._modules:
|
||||
self._output.add(m, self._theme)
|
||||
self._theme.next()
|
||||
print self._output.get()
|
||||
sys.stdout.flush()
|
||||
self._output.wait(self._args.interval)
|
||||
self._output.draw(m.widgets(), self._theme)
|
||||
self._output.flush()
|
||||
self._output.wait()
|
||||
|
||||
print self._output.stop()
|
||||
self._output.stop()
|
||||
|
||||
# vim: tabstop=8 expandtab shiftwidth=4 softtabstop=4
|
||||
|
|
|
@ -31,7 +31,11 @@ class Module(bumblebee.module.Module):
|
|||
param_name = "{}.format".format(module)
|
||||
self._fmt = config.parameter(param_name, default)
|
||||
|
||||
def data(self):
|
||||
return datetime.datetime.now().strftime(self._fmt)
|
||||
def widgets(self):
|
||||
return [
|
||||
bumblebee.output.Widget(
|
||||
datetime.datetime.now().strftime(self._fmt)
|
||||
)
|
||||
]
|
||||
|
||||
# vim: tabstop=8 expandtab shiftwidth=4 softtabstop=4
|
||||
|
|
|
@ -1,11 +1,39 @@
|
|||
import inspect
|
||||
import threading
|
||||
|
||||
def output(args):
|
||||
import bumblebee.outputs.i3
|
||||
return bumblebee.outputs.i3.Output(args)
|
||||
|
||||
class Widget(object):
|
||||
def __init__(self, text, warning=False, critical=False, state=None):
|
||||
self._name = inspect.getmodule(inspect.stack()[1][0]).__name__
|
||||
self._text = text
|
||||
self._warning = warning
|
||||
self._critical = critical
|
||||
self._state = state
|
||||
|
||||
def state(self):
|
||||
return self._state
|
||||
|
||||
def warning(self):
|
||||
return self._warning
|
||||
|
||||
def critical(self):
|
||||
return self._critical
|
||||
|
||||
def module(self):
|
||||
return self._name.split(".")[-1]
|
||||
|
||||
def name(self):
|
||||
return self._name
|
||||
|
||||
def text(self):
|
||||
return self._text
|
||||
|
||||
class Output(object):
|
||||
def __init__(self, args):
|
||||
def __init__(self, config):
|
||||
self._config = config
|
||||
self._callbacks = {}
|
||||
self._wait = threading.Condition()
|
||||
self._wait.acquire()
|
||||
|
@ -35,16 +63,16 @@ class Output(object):
|
|||
), None)
|
||||
return cb
|
||||
|
||||
def wait(self, interval):
|
||||
self._wait.wait(interval)
|
||||
def wait(self):
|
||||
self._wait.wait(self._config.parameter("interval", 1))
|
||||
|
||||
def start(self):
|
||||
pass
|
||||
|
||||
def add(self, obj, theme):
|
||||
def draw(self, widgets, theme):
|
||||
pass
|
||||
|
||||
def get(self):
|
||||
def flush(self):
|
||||
pass
|
||||
|
||||
def stop(self):
|
||||
|
|
|
@ -32,51 +32,47 @@ class Output(bumblebee.output.Output):
|
|||
super(Output, self).__init__(args)
|
||||
self._data = []
|
||||
|
||||
self.add_callback("i3-msg workspace prev_on_output", 4)
|
||||
self.add_callback("i3-msg workspace next_on_output", 5)
|
||||
# TODO
|
||||
# self.add_callback("i3-msg workspace prev_on_output", 4)
|
||||
# self.add_callback("i3-msg workspace next_on_output", 5)
|
||||
|
||||
self._thread = threading.Thread(target=read_input, args=(self,))
|
||||
self._thread.start()
|
||||
# self._thread = threading.Thread(target=read_input, args=(self,))
|
||||
# self._thread.start()
|
||||
|
||||
def start(self):
|
||||
return json.dumps({ "version": 1, "click_events": True }) + "["
|
||||
print json.dumps({ "version": 1, "click_events": True }) + "["
|
||||
|
||||
def add(self, obj, theme):
|
||||
|
||||
while True:
|
||||
d = obj.data()
|
||||
data = {
|
||||
u"full_text": "{}{}{}".format(theme.prefix(obj), d, theme.suffix(obj)),
|
||||
"color": theme.color(obj),
|
||||
"background": theme.background(obj),
|
||||
"name": obj.__module__.replace("bumblebee.modules.",""),
|
||||
"instance": obj.instance() if hasattr(obj, "instance") else None,
|
||||
}
|
||||
|
||||
if theme.urgent(obj) and obj.critical():
|
||||
data["urgent"] = True
|
||||
|
||||
if theme.default_separators(obj) == False:
|
||||
data["separator"] = False
|
||||
data["separator_block_width"] = 0
|
||||
if theme.separator(obj):
|
||||
def draw(self, widgets, theme):
|
||||
for widget in widgets:
|
||||
if theme.separator(widget):
|
||||
self._data.append({
|
||||
u"full_text": theme.separator(obj),
|
||||
"color": theme.background(obj),
|
||||
"background": theme.previous_background(),
|
||||
"color": theme.separator_color(obj),
|
||||
"background": theme.separator_background(),
|
||||
"separator": False,
|
||||
"separator_block_width": 0,
|
||||
})
|
||||
|
||||
self._data.append(data)
|
||||
if obj.next() == False:
|
||||
break
|
||||
theme.next()
|
||||
self._data.append({
|
||||
u"full_text": "{}{}{}".format(
|
||||
theme.prefix(widget),
|
||||
widget.text(),
|
||||
theme.suffix(widget)
|
||||
),
|
||||
"color": theme.color(widget),
|
||||
"background": theme.background(widget),
|
||||
"name": widget.name(),
|
||||
"instance": getattr(widget, "instance", None),
|
||||
"separator": theme.default_separators(widget),
|
||||
"separator_block_width": theme.separator_block_width(widget),
|
||||
})
|
||||
theme.next_widget()
|
||||
|
||||
def get(self):
|
||||
def flush(self):
|
||||
data = json.dumps(self._data)
|
||||
self._data = []
|
||||
return data + ","
|
||||
print(data + ",")
|
||||
sys.stdout.flush()
|
||||
|
||||
def stop(self):
|
||||
return "]"
|
||||
|
|
|
@ -10,96 +10,162 @@ def themes():
|
|||
return [ os.path.basename(f).replace(".json", "") for f in glob.iglob("{}/*.json".format(d)) ]
|
||||
|
||||
class Theme:
|
||||
_cycle_index = 0
|
||||
_cycle = None
|
||||
# TODO: cycle handling
|
||||
def __init__(self, config):
|
||||
self._data = None
|
||||
path = os.path.dirname(os.path.realpath(__file__))
|
||||
with open("{}/{}.json".format(getpath(), config.theme())) as f:
|
||||
self._data = json.load(f)
|
||||
self._defaults = self._data.get("defaults", {})
|
||||
self._cycle = self._defaults.get("cycle", [])
|
||||
self._modules = {}
|
||||
self._cycle = {}
|
||||
|
||||
self.reset()
|
||||
def begin(self):
|
||||
pass
|
||||
|
||||
def _gettheme(self, obj, key):
|
||||
module = obj.__module__.split(".")[-1]
|
||||
def next_widget(self):
|
||||
pass
|
||||
|
||||
def prefix(self, widget):
|
||||
pass
|
||||
|
||||
def suffix(self, widget):
|
||||
pass
|
||||
|
||||
def color(self, widget):
|
||||
result = self._get(widget, "fg")
|
||||
if widget.warning():
|
||||
result = self._get(widget, "fg-warning")
|
||||
if widget.critical():
|
||||
result = self._get(widget, "fg-critical")
|
||||
return result
|
||||
|
||||
def background(self, widget):
|
||||
pass
|
||||
|
||||
def separator(self, widget):
|
||||
pass
|
||||
|
||||
def separator_color(self, widget):
|
||||
pass
|
||||
|
||||
def separator_background(self, widget):
|
||||
pass
|
||||
|
||||
def default_separators(self, widget):
|
||||
pass
|
||||
|
||||
def separator_block_width(self, widget):
|
||||
pass
|
||||
|
||||
def _get(self, widget, name):
|
||||
module = widget.module()
|
||||
state = widget.state()
|
||||
module_theme = self._data.get(module, {})
|
||||
|
||||
value = getattr(obj, key)() if hasattr(obj, key) else None
|
||||
value = self._defaults.get(key, value)
|
||||
if len(self._cycle) > 0:
|
||||
value = self._defaults["cycle"][self._cycle_index].get(key, value)
|
||||
value = module_theme.get(key, value)
|
||||
|
||||
if hasattr(obj, "state"):
|
||||
state = getattr(obj, "state")()
|
||||
state_theme = module_theme.get("states", {}).get(state, {})
|
||||
|
||||
value = state_theme.get(key, value)
|
||||
value = None
|
||||
value = self._defaults.get(name, value)
|
||||
value = self._cycle.get(name, value)
|
||||
value = module_theme.get(name, value)
|
||||
value = state_theme.get(name, value)
|
||||
|
||||
if type(value) is list:
|
||||
# cycle through the values
|
||||
if not obj in self._modules:
|
||||
self._modules[obj] = { "idx": 0 }
|
||||
else:
|
||||
self._modules[obj]["idx"] += 1
|
||||
if self._modules[obj]["idx"] >= len(value):
|
||||
self._modules[obj]["idx"] = 0
|
||||
value = value[self._modules[obj]["idx"]]
|
||||
# if the value is a list, cycle through it
|
||||
# TODO
|
||||
pass
|
||||
|
||||
return value
|
||||
|
||||
def reset(self):
|
||||
self._cycle_index = 0
|
||||
self._previous_background = None
|
||||
self._background = None
|
||||
|
||||
def urgent(self, obj):
|
||||
self._gettheme(obj, "urgent")
|
||||
|
||||
def next(self):
|
||||
self._cycle_index += 1
|
||||
self._previous_background = self._background
|
||||
if self._cycle_index >= len(self._cycle):
|
||||
self._cycle_index = 0
|
||||
|
||||
def color(self, obj):
|
||||
fg = None
|
||||
if obj.warning():
|
||||
fg = self._gettheme(obj, "fg-warning")
|
||||
if obj.critical():
|
||||
fg = self._gettheme(obj, "fg-critical")
|
||||
if fg == None:
|
||||
fg = self._gettheme(obj, "fg")
|
||||
return fg
|
||||
|
||||
def background(self, obj):
|
||||
self._background = None
|
||||
if obj.warning():
|
||||
self._background = self._gettheme(obj, "bg-warning")
|
||||
if obj.critical():
|
||||
self._background = self._gettheme(obj, "bg-critical")
|
||||
|
||||
if self._background == None:
|
||||
self._background = self._gettheme(obj, "bg")
|
||||
|
||||
return self._background
|
||||
|
||||
def previous_background(self):
|
||||
return self._previous_background
|
||||
|
||||
def separator(self, obj):
|
||||
return self._gettheme(obj, "separator")
|
||||
|
||||
def default_separators(self, obj):
|
||||
return self._gettheme(obj, "default_separators")
|
||||
|
||||
def prefix(self, obj):
|
||||
return self._gettheme(obj, "prefix")
|
||||
|
||||
def suffix(self, obj):
|
||||
return self._gettheme(obj, "suffix")
|
||||
#class Theme:
|
||||
# _cycle_index = 0
|
||||
# _cycle = None
|
||||
# def __init__(self, config):
|
||||
# self._data = None
|
||||
# path = os.path.dirname(os.path.realpath(__file__))
|
||||
# with open("{}/{}.json".format(getpath(), config.theme())) as f:
|
||||
# self._data = json.load(f)
|
||||
# self._defaults = self._data.get("defaults", {})
|
||||
# self._cycle = self._defaults.get("cycle", [])
|
||||
# self._modules = {}
|
||||
#
|
||||
# self.reset()
|
||||
#
|
||||
# def _gettheme(self, obj, key):
|
||||
# module = obj.__module__.split(".")[-1]
|
||||
# module_theme = self._data.get(module, {})
|
||||
#
|
||||
# value = getattr(obj, key)() if hasattr(obj, key) else None
|
||||
# value = self._defaults.get(key, value)
|
||||
# if len(self._cycle) > 0:
|
||||
# value = self._defaults["cycle"][self._cycle_index].get(key, value)
|
||||
# value = module_theme.get(key, value)
|
||||
#
|
||||
# if hasattr(obj, "state"):
|
||||
# state = getattr(obj, "state")()
|
||||
# state_theme = module_theme.get("states", {}).get(state, {})
|
||||
#
|
||||
# value = state_theme.get(key, value)
|
||||
#
|
||||
# if type(value) is list:
|
||||
# # cycle through the values
|
||||
# if not obj in self._modules:
|
||||
# self._modules[obj] = { "idx": 0 }
|
||||
# else:
|
||||
# self._modules[obj]["idx"] += 1
|
||||
# if self._modules[obj]["idx"] >= len(value):
|
||||
# self._modules[obj]["idx"] = 0
|
||||
# value = value[self._modules[obj]["idx"]]
|
||||
#
|
||||
# return value
|
||||
#
|
||||
# def reset(self):
|
||||
# self._cycle_index = 0
|
||||
# self._previous_background = None
|
||||
# self._background = None
|
||||
#
|
||||
# def urgent(self, obj):
|
||||
# self._gettheme(obj, "urgent")
|
||||
#
|
||||
# def next(self):
|
||||
# self._cycle_index += 1
|
||||
# self._previous_background = self._background
|
||||
# if self._cycle_index >= len(self._cycle):
|
||||
# self._cycle_index = 0
|
||||
#
|
||||
# def color(self, obj):
|
||||
# fg = None
|
||||
# if obj.warning():
|
||||
# fg = self._gettheme(obj, "fg-warning")
|
||||
# if obj.critical():
|
||||
# fg = self._gettheme(obj, "fg-critical")
|
||||
# if fg == None:
|
||||
# fg = self._gettheme(obj, "fg")
|
||||
# return fg
|
||||
#
|
||||
# def background(self, obj):
|
||||
# self._background = None
|
||||
# if obj.warning():
|
||||
# self._background = self._gettheme(obj, "bg-warning")
|
||||
# if obj.critical():
|
||||
# self._background = self._gettheme(obj, "bg-critical")
|
||||
#
|
||||
# if self._background == None:
|
||||
# self._background = self._gettheme(obj, "bg")
|
||||
#
|
||||
# return self._background
|
||||
#
|
||||
# def previous_background(self):
|
||||
# return self._previous_background
|
||||
#
|
||||
# def separator(self, obj):
|
||||
# return self._gettheme(obj, "separator")
|
||||
#
|
||||
# def default_separators(self, obj):
|
||||
# return self._gettheme(obj, "default_separators")
|
||||
#
|
||||
# def prefix(self, obj):
|
||||
# return self._gettheme(obj, "prefix")
|
||||
#
|
||||
# def suffix(self, obj):
|
||||
# return self._gettheme(obj, "suffix")
|
||||
|
||||
# vim: tabstop=8 expandtab shiftwidth=4 softtabstop=4
|
||||
|
|
|
@ -2,7 +2,8 @@
|
|||
"defaults": {
|
||||
"prefix": " ",
|
||||
"suffix" : " ",
|
||||
"urgent": true
|
||||
"urgent": true,
|
||||
"fg": "#aabbcc"
|
||||
},
|
||||
"date": {
|
||||
"prefix": " "
|
||||
|
|
Loading…
Reference in a new issue