From 21cbbe685d14ce2831c1d0f3c07b18427816e563 Mon Sep 17 00:00:00 2001 From: tobi-wan-kenobi Date: Sun, 11 Sep 2022 13:12:51 +0200 Subject: [PATCH] [modules/scroll] add preliminary version of scrolling module add a scrolling module that can be used to scroll the whole bar to an arbitrary number of widgets. its parameter is "width", which determines the number of widgets to display. see #921 --- bumblebee_status/core/module.py | 9 +++++ bumblebee_status/core/output.py | 23 +++++++++++- bumblebee_status/modules/core/scroll.py | 50 +++++++++++++++++++++++++ 3 files changed, 81 insertions(+), 1 deletion(-) create mode 100644 bumblebee_status/modules/core/scroll.py diff --git a/bumblebee_status/core/module.py b/bumblebee_status/core/module.py index 84c3ab5..56070bf 100644 --- a/bumblebee_status/core/module.py +++ b/bumblebee_status/core/module.py @@ -112,6 +112,15 @@ class Module(core.input.Object): def hidden(self): return False + """Override this to show the module even if it normally would be scrolled away + + :return: True if the module should be hidden, False otherwise + :rtype: boolean + """ + + def scroll(self): + return True + """Retrieve CLI/configuration parameters for this module. For example, if the module is called "test" and the user specifies "-p test.x=123" on the commandline, using self.parameter("x") retrieves the value 123. diff --git a/bumblebee_status/core/output.py b/bumblebee_status/core/output.py index 1bd5038..b17811e 100644 --- a/bumblebee_status/core/output.py +++ b/bumblebee_status/core/output.py @@ -146,11 +146,14 @@ class i3(object): self.__content = {} self.__theme = theme self.__config = config + self.__offset = 0 self.__lock = threading.Lock() core.event.register("update", self.update) core.event.register("start", self.draw, "start") core.event.register("draw", self.draw, "statusline") core.event.register("stop", self.draw, "stop") + core.event.register("output.scroll-left", self.scroll_left) + core.event.register("output.scroll-right", self.scroll_right) def content(self): return self.__content @@ -182,7 +185,7 @@ class i3(object): cb = getattr(self, what) data = cb(args) if args else cb() if "blocks" in data: - sys.stdout.write(json.dumps(data["blocks"], default=dump_json)) + sys.stdout.write(json.dumps(data, default=dump_json)) if "suffix" in data: sys.stdout.write(data["suffix"]) sys.stdout.write("\n") @@ -223,13 +226,29 @@ class i3(object): blk.set("__state", state) return blk + def scroll_left(self): + if self.__offset > 0: + self.__offset -= 1 + + def scroll_right(self): + self.__offset += 1 + def blocks(self, module): blocks = [] if module.minimized: blocks.extend(self.separator_block(module, module.widgets()[0])) blocks.append(self.__content_block(module, module.widgets()[0])) + self.__widgetcount += 1 return blocks + + width = self.__config.get("output.width", 0) for widget in module.widgets(): + if module.scroll() == True and width > 0: + self.__widgetcount += 1 + if self.__widgetcount-1 < self.__offset: + continue + if self.__widgetcount-1 >= self.__offset + width: + continue if widget.module and self.__config.autohide(widget.module.name): if not any( state in widget.state() for state in ["warning", "critical", "no-autohide"] @@ -244,6 +263,7 @@ class i3(object): blocks.extend(self.separator_block(module, widget)) blocks.append(self.__content_block(module, widget)) core.event.trigger("next-widget") + core.event.trigger("output.done", self.__offset, self.__widgetcount) return blocks def update(self, affected_modules=None, redraw_only=False, force=False): @@ -274,6 +294,7 @@ class i3(object): def statusline(self): blocks = [] + self.__widgetcount = 0 for module in self.__modules: blocks.extend(self.blocks(module)) return {"blocks": blocks, "suffix": ","} diff --git a/bumblebee_status/modules/core/scroll.py b/bumblebee_status/modules/core/scroll.py new file mode 100644 index 0000000..44f9c5e --- /dev/null +++ b/bumblebee_status/modules/core/scroll.py @@ -0,0 +1,50 @@ +# pylint: disable=C0111,R0903 + +""" +""" + +import core.module +import core.widget +import core.input +import core.event + +import util.format + +class Module(core.module.Module): + def __init__(self, config, theme): + super().__init__(config, theme, []) + self.__offset = 0 + self.__widgetcount = 0 + w = self.add_widget(full_text = "<") + core.input.register(w, button=core.input.LEFT_MOUSE, cmd=self.scroll_left) + w = self.add_widget(full_text = ">") + core.input.register(w, button=core.input.LEFT_MOUSE, cmd=self.scroll_right) + self.__width = util.format.asint(self.parameter("width")) + config.set("output.width", self.__width) + core.event.register("output.done", self.update_done) + + + def scroll_left(self, _): + if self.__offset > 0: + core.event.trigger("output.scroll-left") + + def scroll_right(self, _): + if self.__offset + self.__width < self.__widgetcount: + core.event.trigger("output.scroll-right") + + def update_done(self, offset, widgetcount): + self.__offset = offset + self.__widgetcount = widgetcount + + def scroll(self): + return False + + def state(self, widget): + if widget.id == self.widgets()[0].id: + if self.__offset == 0: + return ["warning"] + if self.__offset + self.__width >= self.__widgetcount: + return ["warning"] + return [] + +# vim: tabstop=8 expandtab shiftwidth=4 softtabstop=4