diff --git a/src/modules/volume.rs b/src/modules/volume.rs index 54c536e..172b562 100644 --- a/src/modules/volume.rs +++ b/src/modules/volume.rs @@ -1,7 +1,6 @@ use crate::clients::volume::{self, Event}; use crate::config::CommonConfig; use crate::gtk_helpers::IronbarGtkExt; -use crate::image::ImageProvider; use crate::modules::{ Module, ModuleInfo, ModuleParts, ModulePopup, ModuleUpdateEvent, PopupButton, WidgetContext, }; @@ -9,10 +8,7 @@ use crate::{glib_recv, lock, module_impl, send_async, spawn, try_send}; use glib::Propagation; use gtk::pango::EllipsizeMode; use gtk::prelude::*; -use gtk::{ - Box as GtkBox, Button, CellRendererText, ComboBoxText, Image, Label, Orientation, Scale, - ToggleButton, -}; +use gtk::{Button, CellRendererText, ComboBoxText, Label, Orientation, Scale, ToggleButton}; use serde::Deserialize; use std::collections::HashMap; use tokio::sync::mpsc; @@ -20,6 +16,13 @@ use tokio::sync::mpsc; #[derive(Debug, Clone, Deserialize)] #[cfg_attr(feature = "schema", derive(schemars::JsonSchema))] pub struct VolumeModule { + /// The format string to use for the widget button label. + /// For available tokens, see [below](#formatting-tokens). + /// + /// **Default**: `{icon} {percentage}%` + #[serde(default = "default_format")] + format: String, + /// Maximum value to allow volume sliders to reach. /// Pulse supports values > 100 but this may result in distortion. /// @@ -27,20 +30,88 @@ pub struct VolumeModule { #[serde(default = "default_max_volume")] max_volume: f64, - #[serde(default = "default_icon_size")] - icon_size: i32, + /// Volume state icons. + /// + /// See [icons](#icons). + #[serde(default)] + icons: Icons, /// See [common options](module-level-options#common-options). #[serde(flatten)] pub common: Option, } +fn default_format() -> String { + String::from("{icon} {percentage}%") +} + +#[derive(Debug, Clone, Deserialize)] +#[cfg_attr(feature = "schema", derive(schemars::JsonSchema))] +pub struct Icons { + /// Icon to show for high volume levels. + /// + /// **Default**: `󰕾` + #[serde(default = "default_icon_volume_high")] + volume_high: String, + + /// Icon to show for medium volume levels. + /// + /// **Default**: `󰖀` + #[serde(default = "default_icon_volume_medium")] + volume_medium: String, + + /// Icon to show for low volume levels. + /// + /// **Default**: `󰕿` + #[serde(default = "default_icon_volume_low")] + volume_low: String, + + /// Icon to show for muted outputs. + /// + /// **Default**: `󰝟` + #[serde(default = "default_icon_muted")] + muted: String, +} + +impl Icons { + fn volume_icon(&self, volume_percent: f64) -> &str { + match volume_percent as u32 { + 0..=33 => &self.volume_low, + 34..=66 => &self.volume_medium, + 67.. => &self.volume_high, + } + } +} + +impl Default for Icons { + fn default() -> Self { + Self { + volume_high: default_icon_volume_high(), + volume_medium: default_icon_volume_medium(), + volume_low: default_icon_volume_low(), + muted: default_icon_muted(), + } + } +} + const fn default_max_volume() -> f64 { 100.0 } -const fn default_icon_size() -> i32 { - 24 +fn default_icon_volume_high() -> String { + String::from("󰕾") +} + +fn default_icon_volume_medium() -> String { + String::from("󰖀") +} + +fn default_icon_volume_low() -> String { + String::from("󰕿") +} + +fn default_icon_muted() -> String { + String::from("󰝟") } #[derive(Debug, Clone)] @@ -143,23 +214,22 @@ impl Module