From 23d42f0c96b115e698315f03ecb8307946022b10 Mon Sep 17 00:00:00 2001 From: matt1432 Date: Fri, 8 Sep 2023 15:23:52 -0400 Subject: [PATCH] feat(ags): add volume widget --- config/ags/js/bar/audio.js | 73 ++++++++++++++++++++++++ config/ags/js/bar/bar.js | 5 ++ config/ags/js/bar/current-window.js | 2 - config/ags/scss/widgets/traybuttons.scss | 5 ++ config/ags/style.css | 4 ++ 5 files changed, 87 insertions(+), 2 deletions(-) create mode 100644 config/ags/js/bar/audio.js diff --git a/config/ags/js/bar/audio.js b/config/ags/js/bar/audio.js new file mode 100644 index 0000000..978f0a8 --- /dev/null +++ b/config/ags/js/bar/audio.js @@ -0,0 +1,73 @@ +const { Audio } = ags.Service; +const { Label, Box, Icon, Stack, Button, Slider } = ags.Widget; +import { Separator } from '../common.js'; + +const iconSubstitute = item => { + const substitues = [ + { from: 'audio-headset-bluetooth', to: 'audio-headphones-symbolic' }, + { from: 'audio-card-analog-usb', to: 'audio-speakers-symbolic' }, + { from: 'audio-card-analog-pci', to: 'audio-card-symbolic' }, + ]; + + for (const { from, to } of substitues) { + if (from === item) + return to; + } + return item; +}; + +export const SpeakerIndicator = ({ + items = [ + ['101', Icon('audio-volume-overamplified-symbolic')], + ['67', Icon('audio-volume-high-symbolic')], + ['34', Icon('audio-volume-medium-symbolic')], + ['1', Icon('audio-volume-low-symbolic')], + ['0', Icon('audio-volume-muted-symbolic')], + ], + ...props +} = {}) => Stack({ + ...props, + items, + connections: [[Audio, stack => { + if (!Audio.speaker) + return; + + if (Audio.speaker.isMuted) + return stack.shown = '0'; + + const vol = Audio.speaker.volume * 100; + for (const threshold of [100, 66, 33, 0, -1]) { + if (vol > threshold + 1) + return stack.shown = `${threshold + 1}`; + } + }, 'speaker-changed']], +}); + +export const SpeakerTypeIndicator = props => Icon({ + ...props, + connections: [[Audio, icon => { + if (Audio.speaker) + icon.icon = iconSubstitute(Audio.speaker.iconName); + }]], +}); + +export const SpeakerPercentLabel = props => Label({ + ...props, + connections: [[Audio, label => { + if (!Audio.speaker) + return; + + label.label = `${Math.floor(Audio.speaker.volume * 100)}%`; + }, 'speaker-changed']], +}); + +const AudioModule = () => Box({ + className: 'toggle-off audio', + children: [ + SpeakerIndicator(), + Separator(5), + SpeakerPercentLabel(), + ], +}); + +export const AudioIndicator = AudioModule(); diff --git a/config/ags/js/bar/bar.js b/config/ags/js/bar/bar.js index efe0fe6..930f411 100644 --- a/config/ags/js/bar/bar.js +++ b/config/ags/js/bar/bar.js @@ -12,6 +12,7 @@ import { Clock } from './clock.js'; import { SysTray } from './systray.js'; import { Batt } from './battery.js'; import { Brightness } from './brightness.js'; +import { AudioIndicator } from './audio.js'; export const Bar = Window({ name: 'bar', @@ -45,6 +46,10 @@ export const Bar = Window({ Separator(12), + AudioIndicator, + + Separator(12), + Brightness, Separator(12), diff --git a/config/ags/js/bar/current-window.js b/config/ags/js/bar/current-window.js index 94e7b1d..20a6f67 100644 --- a/config/ags/js/bar/current-window.js +++ b/config/ags/js/bar/current-window.js @@ -1,5 +1,3 @@ -// https://github.com/Aylur/ags/wiki/Widgets - const { Hyprland } = ags.Service; const { Label } = ags.Widget; const { Gtk } = imports.gi; diff --git a/config/ags/scss/widgets/traybuttons.scss b/config/ags/scss/widgets/traybuttons.scss index 083decd..0da740f 100644 --- a/config/ags/scss/widgets/traybuttons.scss +++ b/config/ags/scss/widgets/traybuttons.scss @@ -61,6 +61,11 @@ min-width: 230px; } +.audio { + padding: 0 10px 0 10px; + font-size: 20px; +} + .battery { padding: 0 10px 0 10px; font-size: 20px; diff --git a/config/ags/style.css b/config/ags/style.css index bded014..8c11207 100644 --- a/config/ags/style.css +++ b/config/ags/style.css @@ -89,6 +89,10 @@ padding-right: 10px; min-width: 230px; } +.audio { + padding: 0 10px 0 10px; + font-size: 20px; } + .battery { padding: 0 10px 0 10px; font-size: 20px; }