dotfiles/config/lemonbar/new.py

263 lines
6.5 KiB
Python
Raw Normal View History

2018-08-21 19:50:44 +00:00
#!/usr/bin/env python3
import enum
import logging
import threading
import time
# TODO Update strategies (periodic, inotify file)
# TODO Section order (priority system maybe ?)
# TODO Allow deletion of Bar, BarGroup and Section for screen changes
# TODO Optimize to use write() calls instead of string concatenation (writing
# BarGroup strings should be a good compromise)
class BarGroupType(enum.Enum):
LEFT = 0
RIGHT = 1
# MID_LEFT = 2
# MID_RIGHT = 3
class Bar:
"""
One bar for each screen
"""
everyone = set()
string = ""
@staticmethod
def init():
Section.init()
# Debug
Bar()
def __init__(self):
self.screen = 0 # TODO
self.groups = dict()
for groupType in BarGroupType:
group = BarGroup(groupType, self)
self.groups[groupType] = group
self.childsChanged = False
self.everyone.add(self)
@staticmethod
def addSectionAll(section, group, screens=None):
"""
.. note::
Add the section before updating it for the first time.
"""
assert isinstance(section, Section)
assert isinstance(group, BarGroupType)
# TODO screens selection
for bar in Bar.everyone:
bar.addSection(section, group=group)
def addSection(self, section, group):
assert isinstance(section, Section)
assert isinstance(group, BarGroupType)
self.groups[group].addSection(section)
def update(self):
if self.childsChanged:
self.string = ""
self.childsChanged = False
@staticmethod
def updateAll():
for bar in Bar.everyone:
bar.update()
Bar.string = ""
class BarGroup:
"""
One for each group of each bar
"""
everyone = set()
def __init__(self, groupType, parent):
assert isinstance(groupType, BarGroupType)
assert isinstance(parent, Bar)
self.groupType = groupType
self.parent = parent
self.sections = list()
self.string = ''
self.form = ''
#: One of the sections that had their theme or visibility changed
self.childsThemeChanged = False
#: One of the sections that had their text (maybe their size) changed
self.childsTextChanged = False
BarGroup.everyone.add(self)
def addSection(self, section):
self.sections.append(section)
section.parents.add(self)
def update(self):
if self.childsThemeChanged:
# TODO
self.form = ">".join([sec.curText for sec in self.sections
if sec.visible])
if self.childsTextChanged or self.childsThemeChanged:
print("118")
self.string = ">".join([sec.curText for sec in self.sections
if sec.visible])
print("|{0}|".format(self.string))
self.parent.childsChanged = True
self.childsThemeChanged = False
self.childsTextChanged = False
@staticmethod
def updateAll():
print("130")
for group in BarGroup.everyone:
group.update()
Bar.updateAll()
class SectionThread(threading.Thread):
def run(self):
while Section.somethingChanged.wait():
Section.updateAll()
while len(Section.sizeChanging) > 0:
time.sleep(0.1)
Section.updateAll()
class Section:
#: Sections that do not have their destination size
sizeChanging = set()
somethingChanged = threading.Event()
updateThread = None
@staticmethod
def init():
Section.updateThread = SectionThread(daemon=True)
Section.updateThread.start()
def __init__(self):
#: Displayed section
#: Note: A section can be empty and displayed!
self.visible = False
#: Displayed text
self.curText = ''
#: Displayed text size
self.curSize = 0
#: Destination text
self.dstText = ''
#: Destination size
self.dstSize = 0
#: Groups that have this section
self.parents = set()
def informParentsThemeChanged(self):
for parent in self.parents:
parent.childsThemeChanged = True
def informParentsTextChanged(self):
for parent in self.parents:
parent.childsTextChanged = True
def updateText(self, text):
if len(text):
self.dstText = ' {} '.format(text)
self.dstSize = len(self.dstText)
else:
self.dstSize = 0
if self.curSize == self.dstSize:
self.curText = self.dstText
self.informParentsTextChanged()
else:
Section.sizeChanging.add(self)
Section.somethingChanged.set()
def updateVisibility(self, visibility):
assert isinstance(visibility, bool)
self.visible = visibility
self.informParentsThemeChanged()
Section.somethingChanged.set()
@staticmethod
def fit(text, size):
t = len(text)
return text[:size] if t >= size else text + " " * (size - t)
def update(self):
# TODO Might profit of a better logic
if not self.visible:
self.updateVisibility(True)
return
if self.dstSize > self.curSize:
self.curSize += 1
elif self.dstSize < self.curSize:
self.curSize -= 1
else:
# Visibility toggling must be done one step after curSize = 0
if self.dstSize == 0:
self.updateVisibility(False)
Section.sizeChanging.remove(self)
return
self.curText = Section.fit(self.dstText, self.curSize)
self.informParentsTextChanged()
@staticmethod
def updateAll():
"""
Process all sections for text size changes
"""
for sizeChanging in Section.sizeChanging.copy():
sizeChanging.update()
# print("{1:3d} |{0}|".format(sizeChanging.curText, sizeChanging.curSize))
BarGroup.updateAll()
Section.somethingChanged.clear()
if __name__ == '__main__':
Bar.init()
sec = Section()
sec1 = Section()
Bar.addSectionAll(sec, BarGroupType.LEFT)
Bar.addSectionAll(sec1, BarGroupType.LEFT)
sec.updateText("Hello")
# sec1.updateText("world!")
time.sleep(2)
sec.updateText("Salut")
# sec1.updateText("le monde !")
time.sleep(2)
sec.updateText("")
# sec1.updateText("")
time.sleep(2)