From 1c7efc4a76c5217248223b0e05b06bf116363ab5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Geoffrey=20=E2=80=9CFrogeye=E2=80=9D=20Preud=27homme?= Date: Wed, 22 Aug 2018 12:04:55 +0200 Subject: [PATCH] Aaaand colors. On a bar also. --- config/lemonbar/bar.py | 4 + config/lemonbar/new.py | 174 +++++++++++++++++++++++++++++++++-------- 2 files changed, 145 insertions(+), 33 deletions(-) diff --git a/config/lemonbar/bar.py b/config/lemonbar/bar.py index edeb089..2b36ad5 100755 --- a/config/lemonbar/bar.py +++ b/config/lemonbar/bar.py @@ -1,5 +1,9 @@ #!/usr/bin/env python3 +""" +Debugging script +""" + import i3ipc import os import psutil diff --git a/config/lemonbar/new.py b/config/lemonbar/new.py index 5a3745f..9b44e67 100755 --- a/config/lemonbar/new.py +++ b/config/lemonbar/new.py @@ -4,12 +4,15 @@ import enum import logging import threading import time +import subprocess # 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) +# TODO Use bytes rather than strings +# TODO Use default colors of lemonbar sometimes class BarGroupType(enum.Enum): @@ -24,18 +27,28 @@ class Bar: One bar for each screen """ - everyone = set() - string = "" + # Constants + FONT = "DejaVu Sans Mono for Powerline" @staticmethod def init(): Section.init() - # Debug - Bar() + cmd = ['lemonbar', '-f', Bar.FONT, '-b'] + Bar.process = subprocess.Popen(cmd, stdin=subprocess.PIPE) - def __init__(self): - self.screen = 0 # TODO + # Debug + # Bar(0) + Bar(1) + + # Class globals + everyone = set() + string = "" + process = None + + def __init__(self, screen): + assert isinstance(screen, int) + self.screen = "%{S" + str(screen) + "}" self.groups = dict() for groupType in BarGroupType: @@ -65,17 +78,25 @@ class Bar: def update(self): if self.childsChanged: - self.string = "" + self.string = self.screen + self.string += self.groups[BarGroupType.LEFT].string + self.string += self.groups[BarGroupType.RIGHT].string self.childsChanged = False @staticmethod def updateAll(): + Bar.string = "" for bar in Bar.everyone: bar.update() + Bar.string += bar.string + # Color for empty sections + Bar.string += BarGroup.color(*Section.EMPTY) - Bar.string = "" + print(Bar.string) + Bar.process.stdin.write(bytes(Bar.string + '\n', 'utf-8')) + Bar.process.stdin.flush() class BarGroup: @@ -94,7 +115,7 @@ class BarGroup: self.sections = list() self.string = '' - self.form = '' + self.parts = [] #: One of the sections that had their theme or visibility changed self.childsThemeChanged = False @@ -108,17 +129,58 @@ class BarGroup: self.sections.append(section) section.parents.add(self) + ALIGNS = {BarGroupType.LEFT: "%{l}", BarGroupType.RIGHT: "%{r}"} + + @staticmethod + def fgColor(color): + return "%{F" + color + "}" + + @staticmethod + def bgColor(color): + return "%{B" + color + "}" + + @staticmethod + def color(fg, bg): + return BarGroup.fgColor(fg) + BarGroup.bgColor(bg) + def update(self): if self.childsThemeChanged: - # TODO - self.form = ">".join([sec.curText for sec in self.sections - if sec.visible]) + parts = [BarGroup.ALIGNS[self.groupType]] + + secs = [sec for sec in self.sections if sec.visible] + lenS = len(secs) + for s in range(lenS): + sec = secs[s] + theme = Section.THEMES[sec.theme] + if self.groupType == BarGroupType.LEFT: + oSec = secs[s + 1] if s < lenS - 1 else None + else: + oSec = secs[s - 1] if s > 1 else None + oTheme = Section.THEMES[oSec.theme] \ + if oSec is not None else Section.EMPTY + + if self.groupType == BarGroupType.LEFT: + if s == 0: + parts.append(BarGroup.bgColor(theme[1])) + parts.append(BarGroup.fgColor(theme[0])) + parts.append(sec) + parts.append(BarGroup.color(theme[1], oTheme[1]) + "") + else: + parts.append(BarGroup.fgColor(theme[1]) + "") + parts.append(BarGroup.color(*theme)) + parts.append(sec) + + + # TODO Concatenate successive strings + self.parts = parts 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.string = "" + for part in self.parts: + if isinstance(part, str): + self.string += part + elif isinstance(part, Section): + self.string += part.curText self.parent.childsChanged = True @@ -128,9 +190,8 @@ class BarGroup: @staticmethod def updateAll(): - print("130") - for group in BarGroup.everyone: + group.update() Bar.updateAll() @@ -147,21 +208,36 @@ class SectionThread(threading.Thread): class Section: + # TODO Update all of that to base16 + COLORS = ['#002b36', '#dc322f', '#859900', '#b58900', '#268bd2', '#6c71c4', + '#2aa198', '#93a1a1', '#657b83', '#dc322f', '#859900', '#b58900', + '#268bd2', '#6c71c4', '#2aa198', '#fdf6e3'] + FGCOLOR = '#93a1a1' + BGCOLOR = '#002b36' + + THEMES = list() + EMPTY = (FGCOLOR, BGCOLOR) + + @staticmethod + def init(): + for t in range(8, 16): + Section.THEMES.append((Section.COLORS[0], Section.COLORS[t])) + + Section.updateThread = SectionThread(daemon=True) + Section.updateThread.start() + #: 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): + def __init__(self, theme=0): #: Displayed section #: Note: A section can be empty and displayed! self.visible = False + self.theme = theme + #: Displayed text self.curText = '' #: Displayed text size @@ -175,6 +251,12 @@ class Section: #: Groups that have this section self.parents = set() + def __str__(self): + return "<{}><{}>{:01d}{}{:02d}/{:02d}" \ + .format(self.curText, self.dstText, + self.theme, "+" if self.visible else "-", + self.curSize, self.dstSize) + def informParentsThemeChanged(self): for parent in self.parents: parent.childsThemeChanged = True @@ -197,6 +279,13 @@ class Section: Section.sizeChanging.add(self) Section.somethingChanged.set() + def updateTheme(self, theme): + assert isinstance(theme, int) + assert theme < len(Section.THEMES) + self.theme = theme + self.informParentsThemeChanged() + Section.somethingChanged.set() + def updateVisibility(self, visibility): assert isinstance(visibility, bool) @@ -237,7 +326,6 @@ class Section: for sizeChanging in Section.sizeChanging.copy(): sizeChanging.update() - # print("{1:3d} |{0}|".format(sizeChanging.curText, sizeChanging.curSize)) BarGroup.updateAll() @@ -246,17 +334,37 @@ class Section: if __name__ == '__main__': Bar.init() - sec = Section() - sec1 = Section() + sec = Section(0) + sech = Section(1) + sec1 = Section(2) + sec2 = Section(3) + sec2h = Section(4) + sec3 = Section(5) Bar.addSectionAll(sec, BarGroupType.LEFT) + Bar.addSectionAll(sech, BarGroupType.LEFT) Bar.addSectionAll(sec1, BarGroupType.LEFT) + Bar.addSectionAll(sec2, BarGroupType.RIGHT) + Bar.addSectionAll(sec2h, BarGroupType.RIGHT) + Bar.addSectionAll(sec3, BarGroupType.RIGHT) + time.sleep(1) + sec.updateText("A") + time.sleep(1) + sec.updateText("") + time.sleep(1) sec.updateText("Hello") - # sec1.updateText("world!") - time.sleep(2) - sec.updateText("Salut") - # sec1.updateText("le monde !") + sec1.updateText("world!") + sec2.updateText("Salut") + sec2h.updateText("le") + sec3.updateText("monde !") + time.sleep(3) + sech.updateText("the") + sec2h.updateText("") time.sleep(2) sec.updateText("") - # sec1.updateText("") - time.sleep(2) + sech.updateText("") + sec1.updateText("") + sec2.updateText("") + sec2h.updateText("") + sec3.updateText("") + time.sleep(5)