diff options
author | Aylur <[email protected]> | 2024-09-26 00:32:03 +0000 |
---|---|---|
committer | Aylur <[email protected]> | 2024-09-26 00:32:03 +0000 |
commit | 00738c9383472b9fd83d65785215c5a97a58159f (patch) | |
tree | d9f91a890f6a01886496a58f4bc761619f5df09d /examples | |
parent | d24e3e39526a88a00ca9e11f168d9c705a21d25a (diff) |
add: python example bar
Diffstat (limited to 'examples')
-rw-r--r-- | examples/js/simple-bar/README.md | 2 | ||||
-rw-r--r-- | examples/lua/simple-bar/README.md | 2 | ||||
-rw-r--r-- | examples/py/simple-bar/README.md | 14 | ||||
-rw-r--r-- | examples/py/simple-bar/__init__.py (renamed from examples/py/starter-bar/__init__.py) | 0 | ||||
-rwxr-xr-x | examples/py/simple-bar/app.py (renamed from examples/py/starter-bar/app.py) | 19 | ||||
-rw-r--r-- | examples/py/simple-bar/style.scss | 88 | ||||
-rw-r--r-- | examples/py/simple-bar/versions.py | 14 | ||||
-rw-r--r-- | examples/py/simple-bar/widget/Bar.py | 257 | ||||
-rw-r--r-- | examples/py/simple-bar/widget/__init__.py (renamed from examples/py/starter-bar/widget/__init__.py) | 0 | ||||
-rw-r--r-- | examples/py/starter-bar/README.md | 7 | ||||
-rw-r--r-- | examples/py/starter-bar/style.css | 4 | ||||
-rw-r--r-- | examples/py/starter-bar/versions.py | 6 | ||||
-rw-r--r-- | examples/py/starter-bar/widget/Bar.py | 48 | ||||
-rw-r--r-- | examples/vala/simple-bar/README.md | 1 | ||||
-rw-r--r-- | examples/vala/simple-bar/app.in.vala | 20 | ||||
-rw-r--r-- | examples/vala/simple-bar/flake.lock | 62 | ||||
-rw-r--r-- | examples/vala/simple-bar/widget/Bar.vala | 7 |
17 files changed, 472 insertions, 79 deletions
diff --git a/examples/js/simple-bar/README.md b/examples/js/simple-bar/README.md index 8f733da..997e4bf 100644 --- a/examples/js/simple-bar/README.md +++ b/examples/js/simple-bar/README.md @@ -9,3 +9,5 @@ A simple bar for Hyprland using - [Hyprland library](https://aylur.github.io/astal/libraries/hyprland). - [Mpris library](https://aylur.github.io/astal/libraries/mpris). - [Network library](https://aylur.github.io/astal/libraries/network). +- [Tray library](https://aylur.github.io/astal/libraries/tray). +- [WirePlumber library](https://aylur.github.io/astal/libraries/wireplumber). diff --git a/examples/lua/simple-bar/README.md b/examples/lua/simple-bar/README.md index 1cebdac..d33e57d 100644 --- a/examples/lua/simple-bar/README.md +++ b/examples/lua/simple-bar/README.md @@ -9,4 +9,6 @@ A simple bar for Hyprland using - [Hyprland library](https://aylur.github.io/astal/libraries/hyprland). - [Mpris library](https://aylur.github.io/astal/libraries/mpris). - [Network library](https://aylur.github.io/astal/libraries/network). +- [Tray library](https://aylur.github.io/astal/libraries/tray). +- [WirePlumber library](https://aylur.github.io/astal/libraries/wireplumber). - [dart-sass](https://sass-lang.com/dart-sass/) as the css precompiler diff --git a/examples/py/simple-bar/README.md b/examples/py/simple-bar/README.md new file mode 100644 index 0000000..d33e57d --- /dev/null +++ b/examples/py/simple-bar/README.md @@ -0,0 +1,14 @@ +# Simple Bar Example + + + +A simple bar for Hyprland using + +- [Audio library](https://aylur.github.io/astal/libraries/audio). +- [Battery library](https://aylur.github.io/astal/libraries/battery). +- [Hyprland library](https://aylur.github.io/astal/libraries/hyprland). +- [Mpris library](https://aylur.github.io/astal/libraries/mpris). +- [Network library](https://aylur.github.io/astal/libraries/network). +- [Tray library](https://aylur.github.io/astal/libraries/tray). +- [WirePlumber library](https://aylur.github.io/astal/libraries/wireplumber). +- [dart-sass](https://sass-lang.com/dart-sass/) as the css precompiler diff --git a/examples/py/starter-bar/__init__.py b/examples/py/simple-bar/__init__.py index e69de29..e69de29 100644 --- a/examples/py/starter-bar/__init__.py +++ b/examples/py/simple-bar/__init__.py diff --git a/examples/py/starter-bar/app.py b/examples/py/simple-bar/app.py index 287d0f8..f5a8a80 100755 --- a/examples/py/starter-bar/app.py +++ b/examples/py/simple-bar/app.py @@ -1,27 +1,32 @@ #!/usr/bin/env python3 +import sys import versions from gi.repository import Astal, Gio from widget.Bar import Bar from pathlib import Path -css = str(Path(__file__).parent.resolve() / "style.css") +scss = str(Path(__file__).parent.resolve() / "style.scss") +css = "/tmp/style.css" class App(Astal.Application): - def __init__(self): - super().__init__() - self.acquire_socket() - self.run(None) - def do_request(self, msg: str, conn: Gio.SocketConnection) -> None: print(msg) Astal.write_sock(conn, "hello") def do_activate(self) -> None: self.hold() + Astal.Process.execv(["sass", scss, css]) self.apply_css(css, True) for mon in self.get_monitors(): self.add_window(Bar(mon)) -App() +instance_name = "simple-bar" +app = App(instance_name=instance_name) + +if __name__ == "__main__": + if app.acquire_socket(): + app.run(None) + else: + print(Astal.Application.send_message(instance_name, "".join(sys.argv[1:]))) diff --git a/examples/py/simple-bar/style.scss b/examples/py/simple-bar/style.scss new file mode 100644 index 0000000..f98286e --- /dev/null +++ b/examples/py/simple-bar/style.scss @@ -0,0 +1,88 @@ +$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; + + button { + all: unset; + background-color: transparent; + + &:hover label { + background-color: transparentize($fg, 0.84); + border-color: transparentize($accent, 0.8); + } + + &:active label { + background-color: transparentize($fg, 0.8) + } + } + + label { + transition: 200ms; + padding: 0 8px; + margin: 2px; + border-radius: $radius; + border: 1pt solid transparent; + } + + .Workspaces .focused label { + color: $accent; + border-color: $accent; + } + + .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: transparentize($fg, 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 new file mode 100644 index 0000000..a8a1ab8 --- /dev/null +++ b/examples/py/simple-bar/versions.py @@ -0,0 +1,14 @@ +import gi + +gi.require_version("Astal", "0.1") +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 new file mode 100644 index 0000000..89581f1 --- /dev/null +++ b/examples/py/simple-bar/widget/Bar.py @@ -0,0 +1,257 @@ +import math +from gi.repository import ( + 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(): + 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__() + 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) + theme = item.get_icon_theme_path() + + if theme is not None: + from app import app + + app.add_icons(theme) + + menu = item.create_menu() + btn = Astal.Button() + icon = Astal.Icon() + + def on_clicked(btn): + if menu: + menu.popup_at_widget(btn, Gdk.Gravity.SOUTH, Gdk.Gravity.NORTH, None) + + def on_destroy(btn): + if menu: + menu.destroy() + + btn.connect("clicked", on_clicked) + btn.connect("destroy", on_destroy) + + item.bind_property("tooltip-markup", btn, "tooltip-markup", SYNC) + item.bind_property("gicon", icon, "gicon", SYNC) + 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() + 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 = Astal.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/starter-bar/widget/__init__.py b/examples/py/simple-bar/widget/__init__.py index e69de29..e69de29 100644 --- a/examples/py/starter-bar/widget/__init__.py +++ b/examples/py/simple-bar/widget/__init__.py diff --git a/examples/py/starter-bar/README.md b/examples/py/starter-bar/README.md deleted file mode 100644 index b3a14ce..0000000 --- a/examples/py/starter-bar/README.md +++ /dev/null @@ -1,7 +0,0 @@ -# Starter Bar Example - -A starter bar that shows a label and the date. - -> [!NOTE] -> This code is not ideal to work with as it requires too much boilerplate compared to AGS. -> If you want to use python try picking up the [python library](https://github.com/Aylur/astal/tree/feat/python/core/python). diff --git a/examples/py/starter-bar/style.css b/examples/py/starter-bar/style.css deleted file mode 100644 index cb8c712..0000000 --- a/examples/py/starter-bar/style.css +++ /dev/null @@ -1,4 +0,0 @@ -window.Bar { - background-color: #212121; - color: white; -} diff --git a/examples/py/starter-bar/versions.py b/examples/py/starter-bar/versions.py deleted file mode 100644 index a5993be..0000000 --- a/examples/py/starter-bar/versions.py +++ /dev/null @@ -1,6 +0,0 @@ -import gi - -gi.require_version("Astal", "0.1") -gi.require_version("Gtk", "3.0") -gi.require_version("Gdk", "3.0") -gi.require_version("Gio", "2.0") diff --git a/examples/py/starter-bar/widget/Bar.py b/examples/py/starter-bar/widget/Bar.py deleted file mode 100644 index 9071169..0000000 --- a/examples/py/starter-bar/widget/Bar.py +++ /dev/null @@ -1,48 +0,0 @@ -from gi.repository import Astal, Gtk, Gdk, GLib - - -class Time(Astal.Label): - def __init__(self, format="%H:%M:%S"): - super().__init__(visible=True) - self.connect("destroy", self.on_destroy) - self.format = format - self.time = Astal.Time.interval(1000, self.on_tick) - - def on_tick(self): - datetime = GLib.DateTime.new_now_local() - assert datetime - time = datetime.format(self.format) - assert time - self.set_label(time) - - def on_destroy(self, *args, **kwargs): - self.time.cancel() - - -class Bar(Astal.Window): - def __init__(self, monitor: Gdk.Monitor): - super().__init__( - visible=True, - gdkmonitor=monitor, - name="Bar" + str(monitor.get_model()), - anchor=Astal.WindowAnchor.LEFT - | Astal.WindowAnchor.RIGHT - | Astal.WindowAnchor.TOP, - exclusivity=Astal.Exclusivity.EXCLUSIVE, - ) - - Astal.widget_set_class_names(self, ["Bar"]) - start_widget = Astal.Box(visible=True, hexpand=True, halign=Gtk.Align.CENTER) - end_widget = Astal.Box(visible=True, hexpand=True, halign=Gtk.Align.CENTER) - - start_widget.set_children([Astal.Label(visible=True, label="Astal in python")]) - - end_widget.set_children([Time()]) - - self.add( - Astal.CenterBox( - visible=True, - start_widget=start_widget, - end_widget=end_widget, - ) - ) diff --git a/examples/vala/simple-bar/README.md b/examples/vala/simple-bar/README.md index 997e4bf..d33e57d 100644 --- a/examples/vala/simple-bar/README.md +++ b/examples/vala/simple-bar/README.md @@ -11,3 +11,4 @@ A simple bar for Hyprland using - [Network library](https://aylur.github.io/astal/libraries/network). - [Tray library](https://aylur.github.io/astal/libraries/tray). - [WirePlumber library](https://aylur.github.io/astal/libraries/wireplumber). +- [dart-sass](https://sass-lang.com/dart-sass/) as the css precompiler diff --git a/examples/vala/simple-bar/app.in.vala b/examples/vala/simple-bar/app.in.vala index 1d61b3a..aece979 100644 --- a/examples/vala/simple-bar/app.in.vala +++ b/examples/vala/simple-bar/app.in.vala @@ -1,6 +1,11 @@ class App : Astal.Application { public static App instance; + public override void request (string msg, SocketConnection conn) { + print(@"$msg\n"); + Astal.write_sock.begin(conn, "hello"); + } + public override void activate () { foreach (var mon in this.monitors) add_window(new Bar(mon)); @@ -8,8 +13,17 @@ class App : Astal.Application { apply_css("@STYLE@"); } - public static int main() { - App.instance = new App(); - return App.instance.run(null); + public static void main(string[] args) { + var instance_name = "simple-bar"; + + App.instance = new App() { + instance_name = instance_name + }; + + if (App.instance.acquire_socket()) { + App.instance.run(null); + } else { + print(Astal.Application.send_message(instance_name, string.joinv(" ", args))); + } } } diff --git a/examples/vala/simple-bar/flake.lock b/examples/vala/simple-bar/flake.lock new file mode 100644 index 0000000..06f572f --- /dev/null +++ b/examples/vala/simple-bar/flake.lock @@ -0,0 +1,62 @@ +{ + "nodes": { + "astal": { + "inputs": { + "nixpkgs": "nixpkgs" + }, + "locked": { + "lastModified": 1727022015, + "narHash": "sha256-ka7aRbReUE6ImjQV8KabMHoojUgb3gtn1/9drMFTtBk=", + "owner": "aylur", + "repo": "astal", + "rev": "8cab7d039e2cf783033a5f1f26cf8be42b0d158e", + "type": "github" + }, + "original": { + "owner": "aylur", + "repo": "astal", + "type": "github" + } + }, + "nixpkgs": { + "locked": { + "lastModified": 1716293225, + "narHash": "sha256-pU9ViBVE3XYb70xZx+jK6SEVphvt7xMTbm6yDIF4xPs=", + "owner": "nixos", + "repo": "nixpkgs", + "rev": "3eaeaeb6b1e08a016380c279f8846e0bd8808916", + "type": "github" + }, + "original": { + "owner": "nixos", + "ref": "nixos-unstable", + "repo": "nixpkgs", + "type": "github" + } + }, + "nixpkgs_2": { + "locked": { + "lastModified": 1726937504, + "narHash": "sha256-bvGoiQBvponpZh8ClUcmJ6QnsNKw0EMrCQJARK3bI1c=", + "owner": "nixos", + "repo": "nixpkgs", + "rev": "9357f4f23713673f310988025d9dc261c20e70c6", + "type": "github" + }, + "original": { + "owner": "nixos", + "ref": "nixos-unstable", + "repo": "nixpkgs", + "type": "github" + } + }, + "root": { + "inputs": { + "astal": "astal", + "nixpkgs": "nixpkgs_2" + } + } + }, + "root": "root", + "version": 7 +} diff --git a/examples/vala/simple-bar/widget/Bar.vala b/examples/vala/simple-bar/widget/Bar.vala index 438e8b7..6e99327 100644 --- a/examples/vala/simple-bar/widget/Bar.vala +++ b/examples/vala/simple-bar/widget/Bar.vala @@ -137,10 +137,9 @@ class SysTray : Gtk.Box { } void remove_item(string id) { - if (!items.contains(id)) - return; - - items.remove(id); + if (items.contains(id)) { + items.remove(id); + } } } |