From 9e8634d892c559c5b44565a68bf35b13cbcb5572 Mon Sep 17 00:00:00 2001 From: Aylur Date: Thu, 16 Jan 2025 17:37:00 +0100 Subject: add: gtk3 ts popover example closes #224 closes #157 --- examples/py/.gitignore | 1 - examples/py/simple-bar/README.md | 13 -- examples/py/simple-bar/__init__.py | 0 examples/py/simple-bar/app.py | 36 ----- examples/py/simple-bar/style.scss | 106 ------------- examples/py/simple-bar/versions.py | 15 -- examples/py/simple-bar/widget/Bar.py | 251 ------------------------------ examples/py/simple-bar/widget/__init__.py | 0 8 files changed, 422 deletions(-) delete mode 100644 examples/py/.gitignore delete mode 100644 examples/py/simple-bar/README.md delete mode 100644 examples/py/simple-bar/__init__.py delete mode 100755 examples/py/simple-bar/app.py delete mode 100644 examples/py/simple-bar/style.scss delete mode 100644 examples/py/simple-bar/versions.py delete mode 100644 examples/py/simple-bar/widget/Bar.py delete mode 100644 examples/py/simple-bar/widget/__init__.py (limited to 'examples/py') diff --git a/examples/py/.gitignore b/examples/py/.gitignore deleted file mode 100644 index c18dd8d..0000000 --- a/examples/py/.gitignore +++ /dev/null @@ -1 +0,0 @@ -__pycache__/ diff --git a/examples/py/simple-bar/README.md b/examples/py/simple-bar/README.md deleted file mode 100644 index 48cc27c..0000000 --- a/examples/py/simple-bar/README.md +++ /dev/null @@ -1,13 +0,0 @@ -# Simple Bar Example - -![simple-bar](https://github.com/user-attachments/assets/a306c864-56b7-44c4-8820-81f424f32b9b) - -A simple bar for Hyprland using - -- [Battery library](https://aylur.github.io/astal/guide/libraries/battery). -- [Hyprland library](https://aylur.github.io/astal/guide/libraries/hyprland). -- [Mpris library](https://aylur.github.io/astal/guide/libraries/mpris). -- [Network library](https://aylur.github.io/astal/guide/libraries/network). -- [Tray library](https://aylur.github.io/astal/guide/libraries/tray). -- [WirePlumber library](https://aylur.github.io/astal/guide/libraries/wireplumber). -- [dart-sass](https://sass-lang.com/dart-sass/) as the css precompiler diff --git a/examples/py/simple-bar/__init__.py b/examples/py/simple-bar/__init__.py deleted file mode 100644 index e69de29..0000000 diff --git a/examples/py/simple-bar/app.py b/examples/py/simple-bar/app.py deleted file mode 100755 index d95dc0e..0000000 --- a/examples/py/simple-bar/app.py +++ /dev/null @@ -1,36 +0,0 @@ -#!/usr/bin/env python3 -import sys -import versions -import subprocess -from gi.repository import AstalIO, Astal, Gio -from widget.Bar import Bar -from pathlib import Path - -scss = str(Path(__file__).parent.resolve() / "style.scss") -css = "/tmp/style.css" - - -class App(Astal.Application): - def do_astal_application_request( - self, msg: str, conn: Gio.SocketConnection - ) -> None: - print(msg) - AstalIO.write_sock(conn, "hello") - - def do_activate(self) -> None: - self.hold() - subprocess.run(["sass", scss, css]) - self.apply_css(css, True) - for mon in self.get_monitors(): - self.add_window(Bar(mon)) - - -instance_name = "python" -app = App(instance_name=instance_name) - -if __name__ == "__main__": - try: - app.acquire_socket() - app.run(None) - except Exception as e: - print(AstalIO.send_message(instance_name, "".join(sys.argv[1:]))) diff --git a/examples/py/simple-bar/style.scss b/examples/py/simple-bar/style.scss deleted file mode 100644 index f5f771a..0000000 --- a/examples/py/simple-bar/style.scss +++ /dev/null @@ -1,106 +0,0 @@ -@use "sass:color"; - -$bg: #212223; -$fg: #f1f1f1; -$accent: #378DF7; -$radius: 7px; - -window.Bar { - border: none; - box-shadow: none; - background-color: $bg; - color: $fg; - font-size: 1.1em; - font-weight: bold; - - label { - margin: 0 8px; - } - - .Workspaces { - button { - all: unset; - background-color: transparent; - - &:hover label { - background-color: color.adjust($fg, $alpha: -0.84); - border-color: color.adjust($accent, $alpha: -0.8); - } - - &:active label { - background-color: color.adjust($fg, $alpha: -0.8) - } - } - - label { - transition: 200ms; - padding: 0 8px; - margin: 2px; - border-radius: $radius; - border: 1pt solid transparent; - } - - .focused label { - color: $accent; - border-color: $accent; - } - } - - .SysTray { - margin-right: 8px; - - button { - padding: 0 4px; - } - } - - .FocusedClient { - color: $accent; - } - - .Media .Cover { - min-height: 1.2em; - min-width: 1.2em; - border-radius: $radius; - background-position: center; - background-size: contain; - } - - .Battery label { - padding-left: 0; - margin-left: 0; - } - - .AudioSlider { - * { - all: unset; - } - - icon { - margin-right: .6em; - } - - & { - margin: 0 1em; - } - - trough { - background-color: color.adjust($fg, $alpha: -0.8); - border-radius: $radius; - } - - highlight { - background-color: $accent; - min-height: .8em; - border-radius: $radius; - } - - slider { - background-color: $fg; - border-radius: $radius; - min-height: 1em; - min-width: 1em; - margin: -.2em; - } - } -} diff --git a/examples/py/simple-bar/versions.py b/examples/py/simple-bar/versions.py deleted file mode 100644 index 0e57708..0000000 --- a/examples/py/simple-bar/versions.py +++ /dev/null @@ -1,15 +0,0 @@ -import gi - -gi.require_version("AstalIO", "0.1") -gi.require_version("Astal", "3.0") -gi.require_version("Gtk", "3.0") -gi.require_version("Gdk", "3.0") -gi.require_version("Gio", "2.0") -gi.require_version("GObject", "2.0") - -gi.require_version("AstalBattery", "0.1") -gi.require_version("AstalWp", "0.1") -gi.require_version("AstalNetwork", "0.1") -gi.require_version("AstalTray", "0.1") -gi.require_version("AstalMpris", "0.1") -gi.require_version("AstalHyprland", "0.1") diff --git a/examples/py/simple-bar/widget/Bar.py b/examples/py/simple-bar/widget/Bar.py deleted file mode 100644 index 555ab85..0000000 --- a/examples/py/simple-bar/widget/Bar.py +++ /dev/null @@ -1,251 +0,0 @@ -import math -from gi.repository import ( - AstalIO, - Astal, - Gtk, - Gdk, - GLib, - GObject, - AstalBattery as Battery, - AstalWp as Wp, - AstalNetwork as Network, - AstalTray as Tray, - AstalMpris as Mpris, - AstalHyprland as Hyprland, -) - -SYNC = GObject.BindingFlags.SYNC_CREATE - - -class Workspaces(Gtk.Box): - def __init__(self) -> None: - super().__init__() - Astal.widget_set_class_names(self, ["Workspaces"]) - hypr = Hyprland.get_default() - hypr.connect("notify::workspaces", self.sync) - hypr.connect("notify::focused-workspace", self.sync) - self.sync() - - def sync(self, *_): - hypr = Hyprland.get_default() - for child in self.get_children(): - child.destroy() - - for ws in hypr.get_workspaces(): - if not (ws.get_id() >= -99 and ws.get_id() <= -2): # filter out special workspaces - self.add(self.button(ws)) - - def button(self, ws): - hypr = Hyprland.get_default() - btn = Gtk.Button(visible=True) - btn.add(Gtk.Label(visible=True, label=ws.get_id())) - - if hypr.get_focused_workspace() == ws: - Astal.widget_set_class_names(btn, ["focused"]) - - btn.connect("clicked", lambda *_: ws.focus()) - return btn - - -class FocusedClient(Gtk.Label): - def __init__(self) -> None: - super().__init__() - Astal.widget_set_class_names(self, ["Focused"]) - Hyprland.get_default().connect("notify::focused-client", self.sync) - self.sync() - - def sync(self, *_): - client = Hyprland.get_default().get_focused_client() - if client is None: - return self.set_label("") - - client.bind_property("title", self, "label", SYNC) - - -class Media(Gtk.Box): - def __init__(self) -> None: - super().__init__() - self.players = {} - mpris = Mpris.get_default() - Astal.widget_set_class_names(self, ["Media"]) - mpris.connect("notify::players", self.sync) - self.sync() - - def sync(self): - mpris = Mpris.get_default() - for child in self.get_children(): - child.destroy() - - if len(mpris.get_players()) == 0: - self.add(Gtk.Label(visible=True, label="Nothing Playing")) - return - - player = mpris.get_players()[0] - label = Gtk.Label(visible=True) - cover = Gtk.Box(valign=Gtk.Align.CENTER) - Astal.widget_set_class_names(cover, ["Cover"]) - - self.add(cover) - self.add(label) - - player.bind_property( - "title", - label, - "label", - SYNC, - lambda *_: f"{player.get_artist()} - {player.get_title()}", - ) - - def on_cover_art(*_): - Astal.widget_set_css( - cover, f"background-image: url('{player.get_cover_art()}')" - ) - - id = player.connect("notify::cover-art", on_cover_art) - cover.connect("destroy", lambda _: player.disconnect(id)) - on_cover_art() - - -class SysTray(Gtk.Box): - def __init__(self) -> None: - super().__init__() - Astal.widget_set_class_names(self, ["SysTray"]) - self.items = {} - tray = Tray.get_default() - tray.connect("item_added", self.add_item) - tray.connect("item_removed", self.remove_item) - - def add_item(self, _: Tray.Tray, id: str): - if id in self.items: - return - - item = Tray.get_default().get_item(id) - btn = Gtk.MenuButton(use_popover=False, visible=True) - icon = Astal.Icon(visible=True) - - item.bind_property("tooltip-markup", btn, "tooltip-markup", SYNC) - item.bind_property("gicon", icon, "gicon", SYNC) - item.bind_property("menu-model", btn, "menu-model", SYNC) - btn.insert_action_group("dbusmenu", item.get_action_group()) - - def on_action_group(*args): - btn.insert_action_group("dbusmenu", item.get_action_group()) - - item.connect("notify::action-group", on_action_group) - - btn.add(icon) - self.add(btn) - self.items[id] = btn - - def remove_item(self, _: Tray.Tray, id: str): - if id in self.items: - del self.items[id] - - -class Wifi(Astal.Icon): - def __init__(self) -> None: - super().__init__() - Astal.widget_set_class_names(self, ["Wifi"]) - wifi = Network.get_default().get_wifi() - if wifi: - wifi.bind_property("ssid", self, "tooltip-text", SYNC) - wifi.bind_property("icon-name", self, "icon", SYNC) - - -class AudioSlider(Gtk.Box): - def __init__(self) -> None: - super().__init__() - Astal.widget_set_class_names(self, ["AudioSlider"]) - Astal.widget_set_css(self, "min-width: 140px") - - icon = Astal.Icon() - slider = Astal.Slider(hexpand=True) - - self.add(icon) - self.add(slider) - - speaker = Wp.get_default().get_audio().get_default_speaker() - speaker.bind_property("volume-icon", icon, "icon", SYNC) - speaker.bind_property("volume", slider, "value", SYNC) - slider.connect("dragged", lambda *_: speaker.set_volume(slider.get_value())) - - -class BatteryLevel(Gtk.Box): - def __init__(self) -> None: - super().__init__() - Astal.widget_set_class_names(self, ["Battery"]) - - icon = Astal.Icon() - label = Astal.Label() - - self.add(icon) - self.add(label) - - bat = Battery.get_default() - bat.bind_property("is-present", self, "visible", SYNC) - bat.bind_property("battery-icon-name", icon, "icon", SYNC) - bat.bind_property( - "percentage", - label, - "label", - SYNC, - lambda _, value: f"{math.floor(value * 100)}%", - ) - - -class Time(Astal.Label): - def __init__(self, format="%H:%M - %A %e."): - super().__init__() - self.format = format - self.interval = AstalIO.Time.interval(1000, self.sync) - self.connect("destroy", self.interval.cancel) - Astal.widget_set_class_names(self, ["Time"]) - - def sync(self): - self.set_label(GLib.DateTime.new_now_local().format(self.format)) - - -class Left(Gtk.Box): - def __init__(self) -> None: - super().__init__(hexpand=True, halign=Gtk.Align.START) - self.add(Workspaces()) - self.add(FocusedClient()) - - -class Center(Gtk.Box): - def __init__(self) -> None: - super().__init__() - self.add(Media()) - - -class Right(Gtk.Box): - def __init__(self) -> None: - super().__init__(hexpand=True, halign=Gtk.Align.END) - self.add(SysTray()) - self.add(Wifi()) - self.add(AudioSlider()) - self.add(BatteryLevel()) - self.add(Time()) - - -class Bar(Astal.Window): - def __init__(self, monitor: Gdk.Monitor): - super().__init__( - anchor=Astal.WindowAnchor.LEFT - | Astal.WindowAnchor.RIGHT - | Astal.WindowAnchor.TOP, - gdkmonitor=monitor, - exclusivity=Astal.Exclusivity.EXCLUSIVE, - ) - - Astal.widget_set_class_names(self, ["Bar"]) - - self.add( - Astal.CenterBox( - start_widget=Left(), - center_widget=Center(), - end_widget=Right(), - ) - ) - - self.show_all() diff --git a/examples/py/simple-bar/widget/__init__.py b/examples/py/simple-bar/widget/__init__.py deleted file mode 100644 index e69de29..0000000 -- cgit v1.2.3