diff options
Diffstat (limited to 'examples/gtk3/lua/simple-bar/widget')
-rw-r--r-- | examples/gtk3/lua/simple-bar/widget/Bar.lua | 198 |
1 files changed, 198 insertions, 0 deletions
diff --git a/examples/gtk3/lua/simple-bar/widget/Bar.lua b/examples/gtk3/lua/simple-bar/widget/Bar.lua new file mode 100644 index 0000000..155b9b8 --- /dev/null +++ b/examples/gtk3/lua/simple-bar/widget/Bar.lua @@ -0,0 +1,198 @@ +local astal = require("astal") +local Widget = require("astal.gtk3.widget") +local Variable = astal.Variable +local GLib = astal.require("GLib") +local bind = astal.bind +local Mpris = astal.require("AstalMpris") +local Battery = astal.require("AstalBattery") +local Wp = astal.require("AstalWp") +local Network = astal.require("AstalNetwork") +local Tray = astal.require("AstalTray") +local Hyprland = astal.require("AstalHyprland") +local map = require("lib").map + +local function SysTray() + local tray = Tray.get_default() + + return Widget.Box({ + class_name = "SysTray", + bind(tray, "items"):as(function(items) + return map(items, function(item) + return Widget.MenuButton({ + tooltip_markup = bind(item, "tooltip_markup"), + use_popover = false, + menu_model = bind(item, "menu-model"), + action_group = bind(item, "action-group"):as(function(ag) + return { "dbusmenu", ag } + end), + Widget.Icon({ + gicon = bind(item, "gicon"), + }), + }) + end) + end), + }) +end + +local function FocusedClient() + local hypr = Hyprland.get_default() + local focused = bind(hypr, "focused-client") + + return Widget.Box({ + class_name = "Focused", + visible = focused, + focused:as(function(client) + return client and Widget.Label({ + label = bind(client, "title"):as(tostring), + }) + end), + }) +end + +local function Wifi() + local network = Network.get_default() + local wifi = bind(network, "wifi") + + return Widget.Box({ + visible = wifi:as(function(v) + return v ~= nil + end), + wifi:as(function(w) + return Widget.Icon({ + tooltip_text = bind(w, "ssid"):as(tostring), + class_name = "Wifi", + icon = bind(w, "icon-name"), + }) + end), + }) +end + +local function AudioSlider() + local speaker = Wp.get_default().audio.default_speaker + + return Widget.Box({ + class_name = "AudioSlider", + css = "min-width: 140px;", + Widget.Icon({ + icon = bind(speaker, "volume-icon"), + }), + Widget.Slider({ + hexpand = true, + on_dragged = function(self) + speaker.volume = self.value + end, + value = bind(speaker, "volume"), + }), + }) +end + +local function BatteryLevel() + local bat = Battery.get_default() + + return Widget.Box({ + class_name = "Battery", + visible = bind(bat, "is-present"), + Widget.Icon({ + icon = bind(bat, "battery-icon-name"), + }), + Widget.Label({ + label = bind(bat, "percentage"):as(function(p) + return tostring(math.floor(p * 100)) .. " %" + end), + }), + }) +end + +local function Media() + local player = Mpris.Player.new("spotify") + + return Widget.Box({ + class_name = "Media", + visible = bind(player, "available"), + Widget.Box({ + class_name = "Cover", + valign = "CENTER", + css = bind(player, "cover-art"):as(function(cover) + return "background-image: url('" .. (cover or "") .. "');" + end), + }), + Widget.Label({ + label = bind(player, "metadata"):as(function() + return (player.title or "") .. " - " .. (player.artist or "") + end), + }), + }) +end + +local function Workspaces() + local hypr = Hyprland.get_default() + + return Widget.Box({ + class_name = "Workspaces", + bind(hypr, "workspaces"):as(function(wss) + table.sort(wss, function(a, b) + return a.id < b.id + end) + + return map(wss, function(ws) + if not (ws.id >= -99 and ws.id <= -2) then -- filter out special workspaces + return Widget.Button({ + class_name = bind(hypr, "focused-workspace"):as(function(fw) + return fw == ws and "focused" or "" + end), + on_clicked = function() + ws:focus() + end, + label = bind(ws, "id"):as(function(v) + return type(v) == "number" and string.format("%.0f", v) or v + end), + }) + end + end) + end), + }) +end + +local function Time(format) + local time = Variable(""):poll(1000, function() + return GLib.DateTime.new_now_local():format(format) + end) + + return Widget.Label({ + class_name = "Time", + on_destroy = function() + time:drop() + end, + label = time(), + }) +end + +return function(gdkmonitor) + local WindowAnchor = astal.require("Astal", "3.0").WindowAnchor + + return Widget.Window({ + class_name = "Bar", + gdkmonitor = gdkmonitor, + anchor = WindowAnchor.TOP + WindowAnchor.LEFT + WindowAnchor.RIGHT, + exclusivity = "EXCLUSIVE", + + Widget.CenterBox({ + Widget.Box({ + halign = "START", + Workspaces(), + FocusedClient(), + }), + Widget.Box({ + Media(), + }), + Widget.Box({ + halign = "END", + SysTray(), + Wifi(), + AudioSlider(), + BatteryLevel(), + Time("%H:%M - %A %e."), + }), + }), + }) +end |