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