diff options
author | Aylur <[email protected]> | 2025-01-16 17:37:00 +0100 |
---|---|---|
committer | Aylur <[email protected]> | 2025-01-16 17:37:04 +0100 |
commit | 9e8634d892c559c5b44565a68bf35b13cbcb5572 (patch) | |
tree | 36a8b911e919959cdf64d3c64646f5066c6a2523 /examples/gtk3/vala/simple-bar/widget/Bar.vala | |
parent | bc796ac226800c43e724e27f53f410c157acaffe (diff) |
add: gtk3 ts popover example
closes #224
closes #157
Diffstat (limited to 'examples/gtk3/vala/simple-bar/widget/Bar.vala')
-rw-r--r-- | examples/gtk3/vala/simple-bar/widget/Bar.vala | 253 |
1 files changed, 253 insertions, 0 deletions
diff --git a/examples/gtk3/vala/simple-bar/widget/Bar.vala b/examples/gtk3/vala/simple-bar/widget/Bar.vala new file mode 100644 index 0000000..28b32ef --- /dev/null +++ b/examples/gtk3/vala/simple-bar/widget/Bar.vala @@ -0,0 +1,253 @@ +class Workspaces : Gtk.Box { + AstalHyprland.Hyprland hypr = AstalHyprland.get_default(); + public Workspaces() { + Astal.widget_set_class_names(this, {"Workspaces"}); + hypr.notify["workspaces"].connect(sync); + sync(); + } + + void sync() { + foreach (var child in get_children()) + child.destroy(); + + foreach (var ws in hypr.workspaces) { + // filter out special workspaces + if (!(ws.id >= -99 && ws.id <= -2)) { + add(button(ws)); + } + } + } + + Gtk.Button button(AstalHyprland.Workspace ws) { + var btn = new Gtk.Button() { + visible = true, + label = ws.id.to_string() + }; + + hypr.notify["focused-workspace"].connect(() => { + var focused = hypr.focused_workspace == ws; + if (focused) { + Astal.widget_set_class_names(btn, {"focused"}); + } else { + Astal.widget_set_class_names(btn, {}); + } + }); + + btn.clicked.connect(ws.focus); + return btn; + } +} + +class FocusedClient : Gtk.Box { + public FocusedClient() { + Astal.widget_set_class_names(this, {"Focused"}); + AstalHyprland.get_default().notify["focused-client"].connect(sync); + sync(); + } + + void sync() { + foreach (var child in get_children()) + child.destroy(); + + var client = AstalHyprland.get_default().focused_client; + if (client == null) + return; + + var label = new Gtk.Label(client.title) { visible = true }; + client.bind_property("title", label, "label", BindingFlags.SYNC_CREATE); + add(label); + } +} + +class Media : Gtk.Box { + AstalMpris.Mpris mpris = AstalMpris.get_default(); + + public Media() { + Astal.widget_set_class_names(this, {"Media"}); + mpris.notify["players"].connect(sync); + sync(); + } + + void sync() { + foreach (var child in get_children()) + child.destroy(); + + if (mpris.players.length() == 0) { + add(new Gtk.Label("Nothing Playing")); + return; + } + + var player = mpris.players.nth_data(0); + var label = new Gtk.Label(null); + var cover = new Gtk.Box(Gtk.Orientation.HORIZONTAL, 0) { + valign = Gtk.Align.CENTER + }; + + Astal.widget_set_class_names(cover, {"Cover"}); + player.bind_property("title", label, "label", BindingFlags.SYNC_CREATE, (_, src, ref trgt) => { + var title = player.title; + var artist = player.artist; + trgt.set_string(@"$artist - $title"); + return true; + }); + + var id = player.notify["cover-art"].connect(() => { + var art = player.cover_art; + Astal.widget_set_css(cover, @"background-image: url('$art')"); + }); + + cover.destroy.connect(() => player.disconnect(id)); + add(cover); + add(label); + } +} + +class SysTray : Gtk.Box { + HashTable<string, Gtk.Widget> items = new HashTable<string, Gtk.Widget>(str_hash, str_equal); + AstalTray.Tray tray = AstalTray.get_default(); + + public SysTray() { + Astal.widget_set_class_names(this, { "SysTray" }); + tray.item_added.connect(add_item); + tray.item_removed.connect(remove_item); + } + + void add_item(string id) { + if (items.contains(id)) + return; + + var item = tray.get_item(id); + var btn = new Gtk.MenuButton() { use_popover = false, visible = true }; + var icon = new Astal.Icon() { visible = true }; + + item.bind_property("tooltip-markup", btn, "tooltip-markup", BindingFlags.SYNC_CREATE); + item.bind_property("gicon", icon, "gicon", BindingFlags.SYNC_CREATE); + item.bind_property("menu-model", btn, "menu-model", BindingFlags.SYNC_CREATE); + btn.insert_action_group("dbusmenu", item.action_group); + item.notify["action-group"].connect(() => { + btn.insert_action_group("dbusmenu", item.action_group); + }); + + btn.add(icon); + add(btn); + items.set(id, btn); + } + + void remove_item(string id) { + if (items.contains(id)) { + items.remove(id); + } + } +} + +class Wifi : Astal.Icon { + public Wifi() { + Astal.widget_set_class_names(this, {"Wifi"}); + var wifi = AstalNetwork.get_default().get_wifi(); + if (wifi != null) { + wifi.bind_property("ssid", this, "tooltip-text", BindingFlags.SYNC_CREATE); + wifi.bind_property("icon-name", this, "icon", BindingFlags.SYNC_CREATE); + } + } +} + +class AudioSlider : Gtk.Box { + Astal.Icon icon = new Astal.Icon(); + Astal.Slider slider = new Astal.Slider() { hexpand = true }; + + public AudioSlider() { + add(icon); + add(slider); + Astal.widget_set_class_names(this, {"AudioSlider"}); + Astal.widget_set_css(this, "min-width: 140px"); + + var speaker = AstalWp.get_default().audio.default_speaker; + speaker.bind_property("volume-icon", icon, "icon", BindingFlags.SYNC_CREATE); + speaker.bind_property("volume", slider, "value", BindingFlags.SYNC_CREATE); + slider.dragged.connect(() => speaker.volume = slider.value); + } +} + +class Battery : Gtk.Box { + Astal.Icon icon = new Astal.Icon(); + Astal.Label label = new Astal.Label(); + + public Battery() { + add(icon); + add(label); + Astal.widget_set_class_names(this, {"Battery"}); + + var bat = AstalBattery.get_default(); + bat.bind_property("is-present", this, "visible", BindingFlags.SYNC_CREATE); + bat.bind_property("battery-icon-name", icon, "icon", BindingFlags.SYNC_CREATE); + bat.bind_property("percentage", label, "label", BindingFlags.SYNC_CREATE, (_, src, ref trgt) => { + var p = Math.floor(src.get_double() * 100); + trgt.set_string(@"$p%"); + return true; + }); + } +} + +class Time : Astal.Label { + string format; + AstalIO.Time interval; + + void sync() { + label = new DateTime.now_local().format(format); + } + + public Time(string format = "%H:%M - %A %e.") { + this.format = format; + interval = AstalIO.Time.interval(1000, null); + interval.now.connect(sync); + destroy.connect(interval.cancel); + Astal.widget_set_class_names(this, {"Time"}); + } +} + +class Left : Gtk.Box { + public Left() { + Object(hexpand: true, halign: Gtk.Align.START); + add(new Workspaces()); + add(new FocusedClient()); + } +} + +class Center : Gtk.Box { + public Center() { + add(new Media()); + } +} + +class Right : Gtk.Box { + public Right() { + Object(hexpand: true, halign: Gtk.Align.END); + add(new SysTray()); + add(new Wifi()); + add(new AudioSlider()); + add(new Battery()); + add(new Time()); + } +} + +class Bar : Astal.Window { + public Bar(Gdk.Monitor monitor) { + Object( + anchor: Astal.WindowAnchor.TOP + | Astal.WindowAnchor.LEFT + | Astal.WindowAnchor.RIGHT, + exclusivity: Astal.Exclusivity.EXCLUSIVE, + gdkmonitor: monitor + ); + + Astal.widget_set_class_names(this, {"Bar"}); + + add(new Astal.CenterBox() { + start_widget = new Left(), + center_widget = new Center(), + end_widget = new Right(), + }); + + show_all(); + } +} |