[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
This commit is contained in:
tobi-wan-kenobi 2022-09-11 13:12:51 +02:00
parent 910b9a8963
commit 21cbbe685d
3 changed files with 81 additions and 1 deletions

View file

@ -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.

View file

@ -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": ","}

View file

@ -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