diff --git a/discover_overlay/discover_overlay.py b/discover_overlay/discover_overlay.py index 753591b..e44f067 100755 --- a/discover_overlay/discover_overlay.py +++ b/discover_overlay/discover_overlay.py @@ -22,12 +22,12 @@ import importlib_resources from configparser import ConfigParser from ctypes import CDLL -from ._version import __version__ CDLL("libgtk4-layer-shell.so") import gi +from ._version import __version__ from .overlay import OverlayWindow from .settings_window import Settings from .voice_overlay import VoiceOverlayWindow diff --git a/discover_overlay/glade/settings.xml b/discover_overlay/glade/settings.xml index 94a2761..0cd8af3 100644 --- a/discover_overlay/glade/settings.xml +++ b/discover_overlay/glade/settings.xml @@ -400,11 +400,18 @@ - + voice_talking_foreground 1 1 - + + + Select Color + 1 + 1 + + + 3 1 @@ -412,11 +419,18 @@ - + voice_talking_background 1 1 - + + + Select Color + 1 + 1 + + + 4 1 @@ -424,11 +438,18 @@ - + voice_talking_border 1 1 - + + + Select Color + 1 + 1 + + + 5 1 @@ -436,11 +457,18 @@ - + voice_idle_foreground 1 1 - + + + Select Color + 1 + 1 + + + 3 2 @@ -448,11 +476,18 @@ - + voice_idle_background 1 1 - + + + Select Color + 1 + 1 + + + 4 2 @@ -460,11 +495,18 @@ - + voice_idle_border 1 1 - + + + Select Color + 1 + 1 + + + 5 2 @@ -472,11 +514,18 @@ - + voice_mute_foreground 1 1 - + + + Select Color + 1 + 1 + + + 3 3 @@ -484,11 +533,18 @@ - + voice_mute_background 1 1 - + + + Select Color + 1 + 1 + + + 4 3 @@ -496,11 +552,18 @@ - + voice_avatar_background 1 1 - + + + Select Color + 1 + 1 + + + 4 4 @@ -642,7 +705,7 @@ 5 - 11 + 12 @@ -653,7 +716,7 @@ 0 4 - 11 + 12 @@ -1134,6 +1197,28 @@ + + + voice_text_border_label + Border around text + 0 + + 4 + 5 + + + + + + voice_text_border + 1 + + + 5 + 5 + + + voice_border_width_label @@ -1141,7 +1226,7 @@ 0 4 - 5 + 6 @@ -1155,7 +1240,7 @@ 5 - 5 + 6 @@ -1166,7 +1251,7 @@ 0 4 - 6 + 7 @@ -1179,7 +1264,7 @@ 5 - 6 + 7 @@ -1192,7 +1277,7 @@ 5 - 12 + 14 @@ -1203,7 +1288,7 @@ 0 4 - 7 + 8 @@ -1214,7 +1299,7 @@ 0 4 - 8 + 9 @@ -1225,7 +1310,7 @@ 0 4 - 9 + 10 @@ -1236,7 +1321,7 @@ 0 4 - 10 + 11 @@ -1247,7 +1332,7 @@ 5 - 7 + 8 @@ -1262,7 +1347,7 @@ swapped="no" /> 5 - 8 + 9 @@ -1275,7 +1360,7 @@ 5 - 9 + 10 @@ -1288,7 +1373,7 @@ 5 - 10 + 11 @@ -1429,11 +1514,18 @@ - + text_background_colour 1 1 - + + + Select Color + 1 + 1 + + + 1 8 @@ -1452,11 +1544,18 @@ - + text_colour 1 1 - + + + Select Color + 1 + 1 + + + 1 7 @@ -1858,11 +1957,18 @@ - + notification_text_colour 1 1 - + + + Select Color + 1 + 1 + + + 1 5 @@ -1870,11 +1976,18 @@ - + notification_background_colour 1 1 - + + Select Color + 1 + 1 + + + 1 @@ -2217,4 +2330,4 @@ - \ No newline at end of file + diff --git a/discover_overlay/layout.py b/discover_overlay/layout.py index 90b6214..6e2451c 100644 --- a/discover_overlay/layout.py +++ b/discover_overlay/layout.py @@ -11,6 +11,7 @@ # You should have received a copy of the GNU General Public License # along with this program. If not, see . """Collection of LayoutManagers used throughout""" + import logging from enum import Enum import gi @@ -273,13 +274,23 @@ def do_allocate(self, widget, width, height, _baseline): lbl_alloc.x = lbl_alloc.y = 0 lbl_alloc.width = width - tx = widget.overlay.text_x_align - if tx == "left": + # i hope this isn't needed anymore + # tx = widget.overlay.text_x_align + # if tx == "left": + # widget.label.set_halign(Gtk.Align.START) + # elif tx == "middle": + # widget.label.set_halign(Gtk.Align.CENTER) + # else: + # widget.label.set_halign(Gtk.Align.END) + if direction == Direction.LTR: widget.label.set_halign(Gtk.Align.START) - elif tx == "middle": + elif direction == Direction.TTB: + widget.label.set_halign(Gtk.Align.CENTER) + elif direction == Direction.BTT: widget.label.set_halign(Gtk.Align.CENTER) else: widget.label.set_halign(Gtk.Align.END) + ty = widget.overlay.text_y_align if ty == "top": widget.label.set_valign(Gtk.Align.START) @@ -288,7 +299,7 @@ def do_allocate(self, widget, width, height, _baseline): else: widget.label.set_valign(Gtk.Align.END) - widget.image.size_allocate(img_alloc, -1) + widget.image_wrapper.size_allocate(img_alloc, -1) widget.label.size_allocate(lbl_alloc, -1) widget.mute.size_allocate(img_alloc, -1) widget.deaf.size_allocate(img_alloc, -1) diff --git a/discover_overlay/notification_overlay.py b/discover_overlay/notification_overlay.py index c92ae76..0631208 100644 --- a/discover_overlay/notification_overlay.py +++ b/discover_overlay/notification_overlay.py @@ -11,6 +11,7 @@ # You should have received a copy of the GNU General Public License # along with this program. If not, see . """Notification window for text""" + import logging import json import cairo @@ -92,10 +93,17 @@ def __init__(self, discover): self.text_align = "left" self.align_x = HorzAlign.RIGHT self.align_y = VertAlign.TOP + self.enabled = False self.show() + def set_enabled(self, enabled): + """Set if notifications should be enabled""" + self.enabled = enabled + def add_notification_message(self, data): """Add new message to dataset""" + if not self.enabled: + return if "data" in data: data = data["data"] if "body" in data or "title" in data: @@ -201,6 +209,7 @@ def update_all(self): def set_config(self, config): """Read in config section and set self and children accordingly""" + self.set_enabled(config.getboolean("enabled", fallback=False)) font = config.get("font", fallback=None) self.align_x = get_h_align(config.get("align_x", "right")) self.align_y = get_v_align(config.get("align_y", "top")) diff --git a/discover_overlay/settings_window.py b/discover_overlay/settings_window.py index ddf6024..cd8e6be 100644 --- a/discover_overlay/settings_window.py +++ b/discover_overlay/settings_window.py @@ -533,6 +533,10 @@ def read_config(self): config.getint("main", "order", fallback=0) ) + self.widget["voice_text_border"].set_active( + config.getboolean("main", "text_border", fallback=True) + ) + self.widget["voice_border_width"].set_value( config.getint("main", "border_width", fallback=2) ) @@ -737,7 +741,12 @@ def read_config(self): def make_colour(self, col): """Create a Gdk Color from a col tuple""" col = json.loads(col) - return Gdk.RGBA(col[0], col[1], col[2], col[3]) + rgba = Gdk.RGBA() + rgba.red = col[0] + rgba.green = col[1] + rgba.blue = col[2] + rgba.alpha = col[3] + return rgba def parse_guild_ids(self, guild_ids_str): """Parse the guild_ids from a str and return them in a list""" @@ -886,47 +895,47 @@ def voice_display_speakers_grace_period(self, button): def voice_toggle_test_content(self, button): self.config_set("main", "show_dummy", f"{button.get_active()}") - def voice_talking_foreground_changed(self, button): + def voice_talking_foreground_changed(self, button, _param=None): colour = button.get_rgba() colour = [colour.red, colour.green, colour.blue, colour.alpha] self.config_set("main", "fg_hi_col", json.dumps(colour)) - def voice_talking_background_changed(self, button): + def voice_talking_background_changed(self, button, _param=None): colour = button.get_rgba() colour = [colour.red, colour.green, colour.blue, colour.alpha] self.config_set("main", "hi_col", json.dumps(colour)) - def voice_talking_border_changed(self, button): + def voice_talking_border_changed(self, button, _param=None): colour = button.get_rgba() colour = [colour.red, colour.green, colour.blue, colour.alpha] self.config_set("main", "tk_col", json.dumps(colour)) - def voice_idle_foreground_changed(self, button): + def voice_idle_foreground_changed(self, button, _param=None): colour = button.get_rgba() colour = [colour.red, colour.green, colour.blue, colour.alpha] self.config_set("main", "fg_col", json.dumps(colour)) - def voice_idle_background_changed(self, button): + def voice_idle_background_changed(self, button, _param=None): colour = button.get_rgba() colour = [colour.red, colour.green, colour.blue, colour.alpha] self.config_set("main", "bg_col", json.dumps(colour)) - def voice_idle_border_changed(self, button): + def voice_idle_border_changed(self, button, _param=None): colour = button.get_rgba() colour = [colour.red, colour.green, colour.blue, colour.alpha] self.config_set("main", "bo_col", json.dumps(colour)) - def voice_mute_foreground_changed(self, button): + def voice_mute_foreground_changed(self, button, _param=None): colour = button.get_rgba() colour = [colour.red, colour.green, colour.blue, colour.alpha] self.config_set("main", "mt_col", json.dumps(colour)) - def voice_mute_background_changed(self, button): + def voice_mute_background_changed(self, button, _param=None): colour = button.get_rgba() colour = [colour.red, colour.green, colour.blue, colour.alpha] self.config_set("main", "mt_bg_col", json.dumps(colour)) - def voice_avatar_background_changed(self, button): + def voice_avatar_background_changed(self, button, _param=None): colour = button.get_rgba() colour = [colour.red, colour.green, colour.blue, colour.alpha] self.config_set("main", "avatar_bg_col", json.dumps(colour)) @@ -950,11 +959,14 @@ def voice_fancy_avatar_shapes_changed(self, button): def voice_order_avatars_by_changed(self, button): self.config_set("main", "order", f"{button.get_active()}") + def voice_text_border_changed(self, button): + self.config_set("main", "text_border", f"{button.get_active()}") + def voice_border_width_changed(self, button): self.config_set("main", "border_width", f"{int(button.get_value())}") def voice_avatar_circle_changed(self, button): - self.config_set("main", "square_avatar", f"{ not button.get_active()}") + self.config_set("main", "square_avatar", f"{not button.get_active()}") def voice_show_title_changed(self, button): self.config_set("main", "show_title", f"{button.get_active()}") @@ -1028,12 +1040,12 @@ def text_channel_changed(self, button): def text_font_changed(self, button): self.config_set("text", "font", button.get_font()) - def text_colour_changed(self, button): + def text_colour_changed(self, button, _param=None): colour = button.get_rgba() colour = [colour.red, colour.green, colour.blue, colour.alpha] self.config_set("text", "fg_col", json.dumps(colour)) - def text_background_colour_changed(self, button): + def text_background_colour_changed(self, button, _param=None): colour = button.get_rgba() colour = [colour.red, colour.green, colour.blue, colour.alpha] self.config_set("text", "bg_col", json.dumps(colour)) @@ -1083,12 +1095,12 @@ def notification_limit_popup_width_changed(self, button): def notification_font_changed(self, button): self.config_set("notification", "font", button.get_font()) - def notification_text_colour_changed(self, button): + def notification_text_colour_changed(self, button, _param=None): colour = button.get_rgba() colour = [colour.red, colour.green, colour.blue, colour.alpha] self.config_set("notification", "fg_col", json.dumps(colour)) - def notification_background_colour_changed(self, button): + def notification_background_colour_changed(self, button, _param=None): colour = button.get_rgba() colour = [colour.red, colour.green, colour.blue, colour.alpha] self.config_set("notification", "bg_col", json.dumps(colour)) diff --git a/discover_overlay/text_overlay.py b/discover_overlay/text_overlay.py index b874a98..e8aac2a 100644 --- a/discover_overlay/text_overlay.py +++ b/discover_overlay/text_overlay.py @@ -11,6 +11,7 @@ # You should have received a copy of the GNU General Public License # along with this program. If not, see . """Overlay window for text""" + import logging import gi import cairo @@ -45,8 +46,13 @@ def __init__(self, discover): self.height_limit = 300 self.align_x = HorzAlign.RIGHT self.align_y = VertAlign.BOTTOM + self.enabled = False self.show() + def set_enabled(self, enabled): + """Set if text overlay should be enabled""" + self.enabled = enabled + def set_blank(self): """Set contents blank and redraw""" child = self.get_first_child() @@ -58,6 +64,8 @@ def set_blank(self): def new_line(self, message): """Add a new message to text overlay. Does not sanity check the data""" + if not self.enabled: + return message = Message(self, message) if not message.skip: self.append(message) @@ -104,6 +112,7 @@ def update_all(self): def set_config(self, config): """Set self and children from config""" + self.set_enabled(config.getboolean("enabled", fallback=False)) channel = config.get("channel", fallback="0") guild = config.get("guild", fallback="0") self.discover.connection.set_text_channel(channel, guild) diff --git a/discover_overlay/userbox.py b/discover_overlay/userbox.py index 9a6d211..ee7e05f 100644 --- a/discover_overlay/userbox.py +++ b/discover_overlay/userbox.py @@ -11,6 +11,7 @@ # You should have received a copy of the GNU General Public License # along with this program. If not, see . """A Gtk Box with direction""" + import gettext import logging import gi @@ -55,9 +56,14 @@ def __init__(self, overlay, userid): self.deaf = Gtk.Image() self.image.set_overflow(Gtk.Overflow.HIDDEN) + self.image.add_css_class("usericon-image") + + self.image_wrapper = Gtk.Box() + self.image_wrapper.add_css_class("usericon") + self.image_wrapper.append(self.image) - self.image.add_css_class("usericon") self.label.add_css_class("userlabel") + self.mute.add_css_class("usermute") self.deaf.add_css_class("userdeaf") @@ -69,7 +75,7 @@ def __init__(self, overlay, userid): self.deaf.set_valign(Gtk.Align.CENTER) self.append(self.label) - self.append(self.image) + self.append(self.image_wrapper) self.append(self.mute) self.append(self.deaf) diff --git a/discover_overlay/voice_overlay.py b/discover_overlay/voice_overlay.py index 38f9768..e9008c6 100644 --- a/discover_overlay/voice_overlay.py +++ b/discover_overlay/voice_overlay.py @@ -11,6 +11,7 @@ # You should have received a copy of the GNU General Public License # along with this program. If not, see . """Overlay window for voice""" + import random import gettext import logging @@ -61,6 +62,7 @@ def __init__(self, discover): self.use_dummy = False self.dummy_count = 10 self.border_width = 2 + self.text_border = True self.only_speaking_grace_period = 0 self.text_side = 3 self.rounded_avatar = True @@ -298,7 +300,6 @@ def overlay_fadeout(self): now = perf_counter() time_percent = (now - self.fade_start) / self.inactive_fade_time if time_percent >= 1.0: - fade_opacity = self.fade_out_limit self.fadeout_timeout = None self.set_css("fade-out", ".container { opacity: %2.2f;}" % (fade_opacity)) @@ -356,33 +357,43 @@ def set_overflow_style(self, overflow): def set_borders(self): """Update all border CSS rules based on config""" width = self.border_width + half = width / 2 col = col_to_css(self.border_col) talk_col = col_to_css(self.talk_col) rounded = "border-radius: 50%;" if self.rounded_avatar else "" - - drop_shadow_normal = "" - drop_shadow_talking = "" - for j in range(0, width+1): - drop_shadow_talking += f" drop-shadow(0px 0px {width}px {talk_col})" - drop_shadow_normal += f" drop-shadow(0px 0px {width}px {col})" - # Pile up extra filters to darken the effect... This is such a stupid idea - + text_border = "" + if self.text_border: + text_border = f""" + .userlabel + {{ + outline: {width}px solid {col}; + }} + .talking .userlabel + {{ + outline: {width}px solid {talk_col}; + }} + """ self.set_css( "talking-border", f""" - .talking.user + .talking .usericon {{ - filter: {drop_shadow_talking}; + outline: {width}px solid {talk_col}; + outline-offset: -{half}px; + {rounded} }} - .user + .usericon {{ - filter: {drop_shadow_normal}; + outline: {width}px solid {col}; + outline-offset: -{half}px; + {rounded} }} - .usericon, .usermute, .userdeaf + .usericon-image, .usermute, .userdeaf {{ - {rounded} + {rounded} }} - .container {{ padding: {width*2}px; }} + .container {{ padding: {width}px; }} + {text_border} """, ) @@ -560,12 +571,13 @@ def set_config(self, config): config.getboolean("show_disconnected", fallback=True) ) self.border_width = config.getint("border_width", fallback=2) + self.text_border = config.getboolean("text_border", fallback=True) self.show_avatar = config.getboolean("show_avatar", fallback=True) self.set_css( "icon_transparency", - ".usericon { opacity: %2.2f; }" + ".usericon-image { opacity: %2.2f; }" % (config.getfloat("icon_transparency", fallback=1.0)), ) @@ -594,6 +606,10 @@ def set_config(self, config): self.update_all() + for child in self: + if isinstance(child, UserBox): + child.queue_resize() + def set_css(self, css_id, rule): """Add or replace CSS Rule""" self.get_root().set_css(css_id, rule)