mirror of
https://github.com/Zedfrigg/ironbar.git
synced 2025-08-16 22:31:03 +02:00
Merge pull request #907 from JakeStanger/feat/widget-rotation
feat: fully implement orientation/justify options
This commit is contained in:
commit
5a7ad5675d
29 changed files with 317 additions and 161 deletions
|
@ -351,7 +351,14 @@ For information on the `Script` type, and embedding scripts in strings, see [her
|
|||
| Name | Type | Default | Description |
|
||||
|-----------|----------|---------|-----------------------------------------------------------------------------------|
|
||||
| `tooltip` | `string` | `null` | Shows this text on hover. Supports embedding scripts between `{{double braces}}`. |
|
||||
| `name` | `string` | `null` | Sets the unique widget name, allowing you to style it using `#name`. |
|
||||
| `class` | `string` | `null` | Sets one or more CSS classes, allowing you to style it using `.class`. |
|
||||
| `name` | `string` | `null` | The unique widget name, allowing you to style it using `#name`. |
|
||||
| `class` | `string` | `null` | One or more CSS classes, allowing you to style it using `.class`. |
|
||||
|
||||
For more information on styling, please see the [styling guide](styling-guide).
|
||||
|
||||
#### Formatting
|
||||
|
||||
| Name | Type | Default | Description |
|
||||
|---------------|--------------------------------------------------------|----------------------------|-------------------------------------------------------------------------------------------------------------------------------------------------|
|
||||
| `orientation` | `horizontal` or `vertical` (shorthand: `'h'` or `'v'`) | `horizontal` or `vertical` | The direction in which the widget and its text are laid out. Some modules additionally provide a `direction` option to provide further control. |
|
||||
| `justify` | `left`, `right`, `center`, `fill` | `left` | The justification (alignment) of the widget text shown on the bar. |
|
||||
|
|
|
@ -71,12 +71,13 @@ A clickable button, which can run a command when clicked.
|
|||
|
||||
> Type `button`
|
||||
|
||||
| Name | Type | Default | Description |
|
||||
|------------|-------------------------------------------------|---------|--------------------------------------------------------------------------------------------------|
|
||||
| `label` | [Dynamic String](dynamic-values#dynamic-string) | `null` | Widget text label. Pango markup and embedded scripts are supported. Ignored if `widgets` is set. |
|
||||
| `widgets` | `(Module or Widget)[]` | `[]` | List of modules/widgets to add to this button. |
|
||||
| `on_click` | `string [command]` | `null` | Command to execute. More on this [below](#commands). |
|
||||
| `orientation` | `'horizontal'` or `'vertical'` (shorthand: `'h'` or `'v'`) | `'horizontal'` | Orientation of the button. |
|
||||
| Name | Type | Default | Description |
|
||||
|---------------|------------------------------------------------------------|----------------|--------------------------------------------------------------------------------------------------|
|
||||
| `label` | [Dynamic String](dynamic-values#dynamic-string) | `null` | Widget text label. Pango markup and embedded scripts are supported. Ignored if `widgets` is set. |
|
||||
| `widgets` | `(Module or Widget)[]` | `[]` | List of modules/widgets to add to this button. |
|
||||
| `on_click` | `string [command]` | `null` | Command to execute. More on this [below](#commands). |
|
||||
| `orientation` | `'horizontal'` or `'vertical'` (shorthand: `'h'` or `'v'`) | `'horizontal'` | Orientation of the label text. |
|
||||
| `justify` | `'left'`, `'right'`, `'center'`, or `'fill'` | `'left'` | Justification (alignment) of the label text. |
|
||||
|
||||
#### Image
|
||||
|
||||
|
|
|
@ -17,6 +17,9 @@ Supports wired ethernet, wifi, cellular data and VPN connections among others.
|
|||
|-------------|-----------|---------|-------------------------|
|
||||
| `icon_size` | `integer` | `24` | Size to render icon at. |
|
||||
|
||||
> [!NOTE]
|
||||
> This module does not support module-level [layout options](module-level-options#layout).
|
||||
|
||||
<details>
|
||||
<summary>JSON</summary>
|
||||
|
||||
|
|
|
@ -21,6 +21,8 @@ Clicking the widget opens the SwayNC panel.
|
|||
| `icons.open_some` | `string` | `` | Icon to show when the panel is open, with notifications. |
|
||||
| `icons.open_dnd` | `string` | `` | Icon to show when the panel is open, with DnD enabled. Takes higher priority than count-based icons. |
|
||||
|
||||
> [!NOTE]
|
||||
> This module does not support module-level [layout options](module-level-options#layout).
|
||||
|
||||
<details>
|
||||
<summary>JSON</summary>
|
||||
|
|
|
@ -77,7 +77,7 @@ impl BarPosition {
|
|||
|
||||
/// Gets the angle that label text should be displayed at
|
||||
/// based on this position.
|
||||
pub const fn get_angle(self) -> f64 {
|
||||
pub const fn angle(self) -> f64 {
|
||||
match self {
|
||||
Self::Top | Self::Bottom => 0.0,
|
||||
Self::Left => 90.0,
|
||||
|
|
37
src/config/layout.rs
Normal file
37
src/config/layout.rs
Normal file
|
@ -0,0 +1,37 @@
|
|||
use crate::config::{ModuleJustification, ModuleOrientation};
|
||||
use crate::modules::ModuleInfo;
|
||||
use serde::Deserialize;
|
||||
|
||||
#[derive(Clone, Debug, Deserialize, Default)]
|
||||
#[cfg_attr(feature = "schema", derive(schemars::JsonSchema))]
|
||||
pub struct LayoutConfig {
|
||||
/// The orientation to display the widget contents.
|
||||
/// Setting to vertical will rotate text 90 degrees.
|
||||
///
|
||||
/// **Valid options**: `horizontal`, `vertical`
|
||||
/// <br>
|
||||
/// **Default**: `horizontal`
|
||||
orientation: Option<ModuleOrientation>,
|
||||
|
||||
/// The justification (alignment) of the widget text shown on the bar.
|
||||
///
|
||||
/// **Valid options**: `left`, `right`, `center`, `fill`
|
||||
/// <br>
|
||||
/// **Default**: `left`
|
||||
#[serde(default)]
|
||||
pub justify: ModuleJustification,
|
||||
}
|
||||
|
||||
impl LayoutConfig {
|
||||
pub fn orientation(&self, info: &ModuleInfo) -> gtk::Orientation {
|
||||
self.orientation
|
||||
.map(ModuleOrientation::into)
|
||||
.unwrap_or(info.bar_position.orientation())
|
||||
}
|
||||
|
||||
pub fn angle(&self, info: &ModuleInfo) -> f64 {
|
||||
self.orientation
|
||||
.map(ModuleOrientation::to_angle)
|
||||
.unwrap_or(info.bar_position.angle())
|
||||
}
|
||||
}
|
|
@ -1,5 +1,6 @@
|
|||
mod common;
|
||||
mod r#impl;
|
||||
mod layout;
|
||||
mod truncate;
|
||||
|
||||
#[cfg(feature = "cairo")]
|
||||
|
@ -46,6 +47,7 @@ use std::collections::HashMap;
|
|||
use schemars::JsonSchema;
|
||||
|
||||
pub use self::common::{CommonConfig, ModuleJustification, ModuleOrientation, TransitionType};
|
||||
pub use self::layout::LayoutConfig;
|
||||
pub use self::truncate::{EllipsizeMode, TruncateMode};
|
||||
|
||||
#[derive(Debug, Deserialize, Clone)]
|
||||
|
|
|
@ -5,30 +5,54 @@ use gtk::{Button, IconTheme, Image, Label, Orientation};
|
|||
use std::ops::Deref;
|
||||
|
||||
#[cfg(any(feature = "music", feature = "workspaces", feature = "clipboard"))]
|
||||
pub fn new_icon_button(input: &str, icon_theme: &IconTheme, size: i32) -> Button {
|
||||
let button = Button::new();
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct IconButton {
|
||||
button: Button,
|
||||
label: Label,
|
||||
}
|
||||
|
||||
if ImageProvider::is_definitely_image_input(input) {
|
||||
#[cfg(any(feature = "music", feature = "workspaces", feature = "clipboard"))]
|
||||
impl IconButton {
|
||||
pub fn new(input: &str, icon_theme: &IconTheme, size: i32) -> Self {
|
||||
let button = Button::new();
|
||||
let image = Image::new();
|
||||
image.add_class("image");
|
||||
image.add_class("icon");
|
||||
let label = Label::new(Some(input));
|
||||
|
||||
match ImageProvider::parse(input, icon_theme, false, size)
|
||||
.map(|provider| provider.load_into_image(&image))
|
||||
{
|
||||
Some(_) => {
|
||||
button.set_image(Some(&image));
|
||||
button.set_always_show_image(true);
|
||||
}
|
||||
None => {
|
||||
button.set_label(input);
|
||||
if ImageProvider::is_definitely_image_input(input) {
|
||||
image.add_class("image");
|
||||
image.add_class("icon");
|
||||
|
||||
match ImageProvider::parse(input, icon_theme, false, size)
|
||||
.map(|provider| provider.load_into_image(&image))
|
||||
{
|
||||
Some(_) => {
|
||||
button.set_image(Some(&image));
|
||||
button.set_always_show_image(true);
|
||||
}
|
||||
None => {
|
||||
button.set_child(Some(&label));
|
||||
label.show();
|
||||
}
|
||||
}
|
||||
} else {
|
||||
button.set_child(Some(&label));
|
||||
label.show();
|
||||
}
|
||||
} else {
|
||||
button.set_label(input);
|
||||
|
||||
Self { button, label }
|
||||
}
|
||||
|
||||
button
|
||||
pub fn label(&self) -> &Label {
|
||||
&self.label
|
||||
}
|
||||
}
|
||||
|
||||
impl Deref for IconButton {
|
||||
type Target = Button;
|
||||
|
||||
fn deref(&self) -> &Self::Target {
|
||||
&self.button
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(any(feature = "music", feature = "keyboard"))]
|
||||
|
@ -98,6 +122,10 @@ impl IconLabel {
|
|||
image.hide();
|
||||
}
|
||||
}
|
||||
|
||||
pub fn label(&self) -> &Label {
|
||||
&self.label
|
||||
}
|
||||
}
|
||||
|
||||
impl Deref for IconLabel {
|
||||
|
|
|
@ -1,8 +1,9 @@
|
|||
use crate::clients::clipboard::{self, ClipboardEvent};
|
||||
use crate::clients::wayland::{ClipboardItem, ClipboardValue};
|
||||
use crate::config::{CommonConfig, TruncateMode};
|
||||
use crate::config::{CommonConfig, LayoutConfig, TruncateMode};
|
||||
use crate::gtk_helpers::IronbarGtkExt;
|
||||
use crate::gtk_helpers::IronbarLabelExt;
|
||||
use crate::image::new_icon_button;
|
||||
use crate::image::IconButton;
|
||||
use crate::modules::{
|
||||
Module, ModuleInfo, ModuleParts, ModulePopup, ModuleUpdateEvent, PopupButton, WidgetContext,
|
||||
};
|
||||
|
@ -14,6 +15,7 @@ use gtk::prelude::*;
|
|||
use gtk::{Button, EventBox, Image, Label, Orientation, RadioButton, Widget};
|
||||
use serde::Deserialize;
|
||||
use std::collections::HashMap;
|
||||
use std::ops::Deref;
|
||||
use tokio::sync::{broadcast, mpsc};
|
||||
use tracing::{debug, error};
|
||||
|
||||
|
@ -47,6 +49,10 @@ pub struct ClipboardModule {
|
|||
/// **Default**: `null`
|
||||
truncate: Option<TruncateMode>,
|
||||
|
||||
/// See [layout options](module-level-options#layout)
|
||||
#[serde(default, flatten)]
|
||||
layout: LayoutConfig,
|
||||
|
||||
/// See [common options](module-level-options#common-options).
|
||||
#[serde(flatten)]
|
||||
pub common: Option<CommonConfig>,
|
||||
|
@ -142,8 +148,11 @@ impl Module<Button> for ClipboardModule {
|
|||
context: WidgetContext<Self::SendMessage, Self::ReceiveMessage>,
|
||||
info: &ModuleInfo,
|
||||
) -> color_eyre::Result<ModuleParts<Button>> {
|
||||
let button = new_icon_button(&self.icon, info.icon_theme, self.icon_size);
|
||||
button.style_context().add_class("btn");
|
||||
let button = IconButton::new(&self.icon, info.icon_theme, self.icon_size);
|
||||
button.label().set_angle(self.layout.angle(info));
|
||||
button.label().set_justify(self.layout.justify.into());
|
||||
|
||||
button.add_class("btn");
|
||||
|
||||
let tx = context.tx.clone();
|
||||
button.connect_clicked(move |button| {
|
||||
|
@ -155,7 +164,7 @@ impl Module<Button> for ClipboardModule {
|
|||
.into_popup(context.controller_tx.clone(), rx, context, info)
|
||||
.into_popup_parts(vec![&button]);
|
||||
|
||||
Ok(ModuleParts::new(button, popup))
|
||||
Ok(ModuleParts::new(button.deref().clone(), popup))
|
||||
}
|
||||
|
||||
fn into_popup(
|
||||
|
|
|
@ -8,7 +8,7 @@ use serde::Deserialize;
|
|||
use tokio::sync::{broadcast, mpsc};
|
||||
use tokio::time::sleep;
|
||||
|
||||
use crate::config::{CommonConfig, ModuleJustification, ModuleOrientation};
|
||||
use crate::config::{CommonConfig, LayoutConfig};
|
||||
use crate::gtk_helpers::IronbarGtkExt;
|
||||
use crate::modules::{
|
||||
Module, ModuleInfo, ModuleParts, ModulePopup, ModuleUpdateEvent, PopupButton, WidgetContext,
|
||||
|
@ -49,22 +49,9 @@ pub struct ClockModule {
|
|||
#[serde(default = "default_locale")]
|
||||
locale: String,
|
||||
|
||||
/// The orientation to display the widget contents.
|
||||
/// Setting to vertical will rotate text 90 degrees.
|
||||
///
|
||||
/// **Valid options**: `horizontal`, `vertical`
|
||||
/// <br>
|
||||
/// **Default**: `horizontal`
|
||||
#[serde(default)]
|
||||
orientation: ModuleOrientation,
|
||||
|
||||
/// The justification (alignment) of the date/time shown on the bar.
|
||||
///
|
||||
/// **Valid options**: `left`, `right`, `center`, `fill`
|
||||
/// <br>
|
||||
/// **Default**: `left`
|
||||
#[serde(default)]
|
||||
justify: ModuleJustification,
|
||||
/// See [layout options](module-level-options#layout)
|
||||
#[serde(default, flatten)]
|
||||
layout: LayoutConfig,
|
||||
|
||||
/// See [common options](module-level-options#common-options).
|
||||
#[serde(flatten)]
|
||||
|
@ -77,9 +64,8 @@ impl Default for ClockModule {
|
|||
format: default_format(),
|
||||
format_popup: default_popup_format(),
|
||||
locale: default_locale(),
|
||||
orientation: ModuleOrientation::Horizontal,
|
||||
layout: LayoutConfig::default(),
|
||||
common: Some(CommonConfig::default()),
|
||||
justify: ModuleJustification::Left,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -136,10 +122,11 @@ impl Module<Button> for ClockModule {
|
|||
) -> Result<ModuleParts<Button>> {
|
||||
let button = Button::new();
|
||||
let label = Label::builder()
|
||||
.angle(self.orientation.to_angle())
|
||||
.angle(self.layout.angle(info))
|
||||
.use_markup(true)
|
||||
.justify(self.justify.into())
|
||||
.justify(self.layout.justify.into())
|
||||
.build();
|
||||
|
||||
button.add(&label);
|
||||
|
||||
let tx = context.tx.clone();
|
||||
|
|
|
@ -1,9 +1,9 @@
|
|||
use gtk::prelude::*;
|
||||
use gtk::{Button, Label, Orientation};
|
||||
use gtk::{Button, Label};
|
||||
use serde::Deserialize;
|
||||
|
||||
use super::{CustomWidget, CustomWidgetContext, ExecEvent, WidgetConfig};
|
||||
use crate::config::ModuleOrientation;
|
||||
use crate::config::LayoutConfig;
|
||||
use crate::dynamic_value::dynamic_string;
|
||||
use crate::gtk_helpers::IronbarLabelExt;
|
||||
use crate::modules::PopupButton;
|
||||
|
@ -37,13 +37,9 @@ pub struct ButtonWidget {
|
|||
/// **Default**: `null`
|
||||
on_click: Option<String>,
|
||||
|
||||
/// Orientation of the button.
|
||||
///
|
||||
/// **Valid options**: `horizontal`, `vertical`, `h`, `v`
|
||||
/// <br />
|
||||
/// **Default**: `horizontal`
|
||||
#[serde(default)]
|
||||
orientation: ModuleOrientation,
|
||||
/// See [layout options](module-level-options#layout)
|
||||
#[serde(default, flatten)]
|
||||
layout: LayoutConfig,
|
||||
|
||||
/// Modules and widgets to add to this box.
|
||||
///
|
||||
|
@ -59,7 +55,7 @@ impl CustomWidget for ButtonWidget {
|
|||
context.popup_buttons.borrow_mut().push(button.clone());
|
||||
|
||||
if let Some(widgets) = self.widgets {
|
||||
let container = gtk::Box::new(Orientation::Horizontal, 0);
|
||||
let container = gtk::Box::new(self.layout.orientation(context.info), 0);
|
||||
|
||||
for widget in widgets {
|
||||
widget.widget.add_to(&container, &context, widget.common);
|
||||
|
@ -70,7 +66,9 @@ impl CustomWidget for ButtonWidget {
|
|||
let label = Label::new(None);
|
||||
label.set_use_markup(true);
|
||||
|
||||
label.set_angle(self.orientation.to_angle());
|
||||
if !context.is_popup {
|
||||
label.set_angle(self.layout.angle(context.info));
|
||||
}
|
||||
|
||||
button.add(&label);
|
||||
|
||||
|
|
|
@ -4,7 +4,7 @@ use serde::Deserialize;
|
|||
|
||||
use super::{CustomWidget, CustomWidgetContext};
|
||||
use crate::build;
|
||||
use crate::config::{ModuleJustification, ModuleOrientation, TruncateMode};
|
||||
use crate::config::{LayoutConfig, TruncateMode};
|
||||
use crate::dynamic_value::dynamic_string;
|
||||
use crate::gtk_helpers::IronbarLabelExt;
|
||||
|
||||
|
@ -28,22 +28,9 @@ pub struct LabelWidget {
|
|||
/// **Required**
|
||||
label: String,
|
||||
|
||||
/// Orientation of the label.
|
||||
/// Setting to vertical will rotate text 90 degrees.
|
||||
///
|
||||
/// **Valid options**: `horizontal`, `vertical`, `h`, `v`
|
||||
/// <br />
|
||||
/// **Default**: `horizontal`
|
||||
#[serde(default)]
|
||||
orientation: ModuleOrientation,
|
||||
|
||||
/// The justification (alignment) of the label text.
|
||||
///
|
||||
/// **Valid options**: `left`, `right`, `center`, `fill`
|
||||
/// <br>
|
||||
/// **Default**: `left`
|
||||
#[serde(default)]
|
||||
justify: ModuleJustification,
|
||||
/// See [layout options](module-level-options#layout)
|
||||
#[serde(default, flatten)]
|
||||
layout: LayoutConfig,
|
||||
|
||||
/// See [truncate options](module-level-options#truncate-mode).
|
||||
///
|
||||
|
@ -54,11 +41,14 @@ pub struct LabelWidget {
|
|||
impl CustomWidget for LabelWidget {
|
||||
type Widget = Label;
|
||||
|
||||
fn into_widget(self, _context: CustomWidgetContext) -> Self::Widget {
|
||||
fn into_widget(self, context: CustomWidgetContext) -> Self::Widget {
|
||||
let label = build!(self, Self::Widget);
|
||||
|
||||
label.set_angle(self.orientation.to_angle());
|
||||
label.set_justify(self.justify.into());
|
||||
if !context.is_popup {
|
||||
label.set_angle(self.layout.angle(context.info));
|
||||
}
|
||||
|
||||
label.set_justify(self.layout.justify.into());
|
||||
label.set_use_markup(true);
|
||||
|
||||
if let Some(truncate) = self.truncate {
|
||||
|
|
|
@ -91,6 +91,7 @@ struct CustomWidgetContext<'a> {
|
|||
info: &'a ModuleInfo<'a>,
|
||||
tx: &'a mpsc::Sender<ExecEvent>,
|
||||
bar_orientation: Orientation,
|
||||
is_popup: bool,
|
||||
icon_theme: &'a IconTheme,
|
||||
popup_buttons: Rc<RefCell<Vec<Button>>>,
|
||||
module_factory: AnyModuleFactory,
|
||||
|
@ -235,6 +236,7 @@ impl Module<gtk::Box> for CustomModule {
|
|||
info,
|
||||
tx: &context.controller_tx,
|
||||
bar_orientation: orientation,
|
||||
is_popup: false,
|
||||
icon_theme: info.icon_theme,
|
||||
popup_buttons: popup_buttons.clone(),
|
||||
module_factory: BarModuleFactory::new(context.ironbar.clone(), context.popup.clone())
|
||||
|
@ -287,7 +289,8 @@ impl Module<gtk::Box> for CustomModule {
|
|||
let custom_context = CustomWidgetContext {
|
||||
info,
|
||||
tx: &tx,
|
||||
bar_orientation: info.bar_position.orientation(),
|
||||
bar_orientation: Orientation::Horizontal,
|
||||
is_popup: true,
|
||||
icon_theme: info.icon_theme,
|
||||
popup_buttons: Rc::new(RefCell::new(vec![])),
|
||||
module_factory: PopupModuleFactory::new(
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
use crate::clients::wayland::{self, ToplevelEvent};
|
||||
use crate::config::{CommonConfig, TruncateMode};
|
||||
use crate::config::{CommonConfig, LayoutConfig, TruncateMode};
|
||||
use crate::gtk_helpers::IronbarGtkExt;
|
||||
use crate::gtk_helpers::IronbarLabelExt;
|
||||
use crate::image::ImageProvider;
|
||||
|
@ -38,6 +38,10 @@ pub struct FocusedModule {
|
|||
/// **Default**: `null`
|
||||
truncate: Option<TruncateMode>,
|
||||
|
||||
/// See [layout options](module-level-options#layout)
|
||||
#[serde(default, flatten)]
|
||||
layout: LayoutConfig,
|
||||
|
||||
/// See [common options](module-level-options#common-options).
|
||||
#[serde(flatten)]
|
||||
pub common: Option<CommonConfig>,
|
||||
|
@ -50,6 +54,7 @@ impl Default for FocusedModule {
|
|||
show_title: crate::config::default_true(),
|
||||
icon_size: default_icon_size(),
|
||||
truncate: None,
|
||||
layout: LayoutConfig::default(),
|
||||
common: Some(CommonConfig::default()),
|
||||
}
|
||||
}
|
||||
|
@ -132,7 +137,7 @@ impl Module<gtk::Box> for FocusedModule {
|
|||
context: WidgetContext<Self::SendMessage, Self::ReceiveMessage>,
|
||||
info: &ModuleInfo,
|
||||
) -> Result<ModuleParts<gtk::Box>> {
|
||||
let container = gtk::Box::new(info.bar_position.orientation(), 5);
|
||||
let container = gtk::Box::new(self.layout.orientation(info), 5);
|
||||
|
||||
let icon = gtk::Image::new();
|
||||
if self.show_icon {
|
||||
|
@ -140,7 +145,11 @@ impl Module<gtk::Box> for FocusedModule {
|
|||
container.add(&icon);
|
||||
}
|
||||
|
||||
let label = Label::new(None);
|
||||
let label = Label::builder()
|
||||
.angle(self.layout.angle(info))
|
||||
.justify(self.layout.justify.into())
|
||||
.build();
|
||||
|
||||
label.add_class("label");
|
||||
|
||||
if let Some(truncate) = self.truncate {
|
||||
|
|
|
@ -2,7 +2,7 @@ use std::collections::HashMap;
|
|||
|
||||
use color_eyre::Result;
|
||||
use color_eyre::eyre::Report;
|
||||
use gtk::{Button, prelude::*};
|
||||
use gtk::prelude::*;
|
||||
use serde::Deserialize;
|
||||
use tokio::sync::mpsc;
|
||||
use tracing::{debug, trace};
|
||||
|
@ -10,9 +10,9 @@ use tracing::{debug, trace};
|
|||
use super::{Module, ModuleInfo, ModuleParts, WidgetContext};
|
||||
use crate::clients::compositor::{self, KeyboardLayoutUpdate};
|
||||
use crate::clients::libinput::{Event, Key, KeyEvent};
|
||||
use crate::config::CommonConfig;
|
||||
use crate::config::{CommonConfig, LayoutConfig};
|
||||
use crate::gtk_helpers::IronbarGtkExt;
|
||||
use crate::image::IconLabel;
|
||||
use crate::image::{IconButton, IconLabel};
|
||||
use crate::{glib_recv, module_impl, module_update, send_async, spawn, try_send};
|
||||
|
||||
#[derive(Debug, Deserialize, Clone)]
|
||||
|
@ -61,6 +61,11 @@ pub struct KeyboardModule {
|
|||
#[serde(default = "default_seat")]
|
||||
seat: String,
|
||||
|
||||
// -- common --
|
||||
/// See [layout options](module-level-options#layout)
|
||||
#[serde(default, flatten)]
|
||||
layout: LayoutConfig,
|
||||
|
||||
/// See [common options](module-level-options#common-options).
|
||||
#[serde(flatten)]
|
||||
pub common: Option<CommonConfig>,
|
||||
|
@ -249,15 +254,22 @@ impl Module<gtk::Box> for KeyboardModule {
|
|||
context: WidgetContext<Self::SendMessage, Self::ReceiveMessage>,
|
||||
info: &ModuleInfo,
|
||||
) -> Result<ModuleParts<gtk::Box>> {
|
||||
let container = gtk::Box::new(info.bar_position.orientation(), 0);
|
||||
let container = gtk::Box::new(self.layout.orientation(info), 0);
|
||||
|
||||
let caps = IconLabel::new(&self.icons.caps_off, info.icon_theme, self.icon_size);
|
||||
let num = IconLabel::new(&self.icons.num_off, info.icon_theme, self.icon_size);
|
||||
let scroll = IconLabel::new(&self.icons.scroll_off, info.icon_theme, self.icon_size);
|
||||
|
||||
let layout_button = Button::new();
|
||||
let layout = IconLabel::new("", info.icon_theme, self.icon_size);
|
||||
layout_button.add(&*layout);
|
||||
caps.label().set_angle(self.layout.angle(info));
|
||||
caps.label().set_justify(self.layout.justify.into());
|
||||
|
||||
num.label().set_angle(self.layout.angle(info));
|
||||
num.label().set_justify(self.layout.justify.into());
|
||||
|
||||
scroll.label().set_angle(self.layout.angle(info));
|
||||
scroll.label().set_justify(self.layout.justify.into());
|
||||
|
||||
let layout_button = IconButton::new("", info.icon_theme, self.icon_size);
|
||||
|
||||
if self.show_caps {
|
||||
caps.add_class("key");
|
||||
|
@ -278,8 +290,8 @@ impl Module<gtk::Box> for KeyboardModule {
|
|||
}
|
||||
|
||||
if self.show_layout {
|
||||
layout.add_class("layout");
|
||||
container.add(&layout_button);
|
||||
layout_button.add_class("layout");
|
||||
container.add(&*layout_button);
|
||||
}
|
||||
|
||||
{
|
||||
|
@ -318,7 +330,7 @@ impl Module<gtk::Box> for KeyboardModule {
|
|||
}
|
||||
KeyboardUpdate::Layout(KeyboardLayoutUpdate(language)) => {
|
||||
let text = icons.layout_map.get(&language).unwrap_or(&language);
|
||||
layout.set_label(Some(text));
|
||||
layout_button.set_label(text);
|
||||
}
|
||||
};
|
||||
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
use crate::config::{CommonConfig, TruncateMode};
|
||||
use crate::config::{CommonConfig, LayoutConfig, TruncateMode};
|
||||
use crate::dynamic_value::dynamic_string;
|
||||
use crate::gtk_helpers::IronbarLabelExt;
|
||||
use crate::modules::{Module, ModuleInfo, ModuleParts, ModuleUpdateEvent, WidgetContext};
|
||||
|
@ -23,6 +23,10 @@ pub struct LabelModule {
|
|||
/// **Default**: `null`
|
||||
truncate: Option<TruncateMode>,
|
||||
|
||||
/// See [layout options](module-level-options#layout)
|
||||
#[serde(default, flatten)]
|
||||
layout: LayoutConfig,
|
||||
|
||||
/// See [common options](module-level-options#common-options).
|
||||
#[serde(flatten)]
|
||||
pub common: Option<CommonConfig>,
|
||||
|
@ -33,6 +37,7 @@ impl LabelModule {
|
|||
Self {
|
||||
label,
|
||||
truncate: None,
|
||||
layout: LayoutConfig::default(),
|
||||
common: Some(CommonConfig::default()),
|
||||
}
|
||||
}
|
||||
|
@ -61,9 +66,13 @@ impl Module<Label> for LabelModule {
|
|||
fn into_widget(
|
||||
self,
|
||||
context: WidgetContext<Self::SendMessage, Self::ReceiveMessage>,
|
||||
_info: &ModuleInfo,
|
||||
info: &ModuleInfo,
|
||||
) -> Result<ModuleParts<Label>> {
|
||||
let label = Label::builder().use_markup(true).build();
|
||||
let label = Label::builder()
|
||||
.use_markup(true)
|
||||
.angle(self.layout.angle(info))
|
||||
.justify(self.layout.justify.into())
|
||||
.build();
|
||||
|
||||
if let Some(truncate) = self.truncate {
|
||||
label.truncate(truncate);
|
||||
|
|
|
@ -9,7 +9,7 @@ use crate::{read_lock, try_send};
|
|||
use glib::Propagation;
|
||||
use gtk::gdk::{BUTTON_MIDDLE, BUTTON_PRIMARY};
|
||||
use gtk::prelude::*;
|
||||
use gtk::{Button, IconTheme, Image, Label, Orientation};
|
||||
use gtk::{Align, Button, IconTheme, Image, Justification, Label, Orientation};
|
||||
use indexmap::IndexMap;
|
||||
use std::ops::Deref;
|
||||
use std::rc::Rc;
|
||||
|
@ -156,6 +156,9 @@ pub struct AppearanceOptions {
|
|||
pub show_icons: bool,
|
||||
pub icon_size: i32,
|
||||
pub truncate: TruncateMode,
|
||||
pub orientation: Orientation,
|
||||
pub angle: f64,
|
||||
pub justify: Justification,
|
||||
}
|
||||
|
||||
impl ItemButton {
|
||||
|
@ -167,11 +170,13 @@ impl ItemButton {
|
|||
tx: &Sender<ModuleUpdateEvent<LauncherUpdate>>,
|
||||
controller_tx: &Sender<ItemEvent>,
|
||||
) -> Self {
|
||||
let button = ImageTextButton::new();
|
||||
let button = ImageTextButton::new(appearance.orientation);
|
||||
|
||||
if appearance.show_names {
|
||||
button.label.set_label(&item.name);
|
||||
button.label.truncate(appearance.truncate);
|
||||
button.label.set_angle(appearance.angle);
|
||||
button.label.set_justify(appearance.justify);
|
||||
}
|
||||
|
||||
if appearance.show_icons {
|
||||
|
@ -329,18 +334,20 @@ pub struct ImageTextButton {
|
|||
}
|
||||
|
||||
impl ImageTextButton {
|
||||
pub(crate) fn new() -> Self {
|
||||
pub(crate) fn new(orientation: Orientation) -> Self {
|
||||
let button = Button::new();
|
||||
let container = gtk::Box::new(Orientation::Horizontal, 0);
|
||||
let container = gtk::Box::new(orientation, 0);
|
||||
|
||||
let label = Label::new(None);
|
||||
let image = Image::new();
|
||||
|
||||
button.add(&container);
|
||||
|
||||
container.add(&image);
|
||||
container.add(&label);
|
||||
|
||||
button.add(&container);
|
||||
container.set_halign(Align::Center);
|
||||
container.set_valign(Align::Center);
|
||||
|
||||
ImageTextButton {
|
||||
button,
|
||||
label,
|
||||
|
|
|
@ -6,7 +6,7 @@ use self::item::{AppearanceOptions, Item, ItemButton, Window};
|
|||
use self::open_state::OpenState;
|
||||
use super::{Module, ModuleInfo, ModuleParts, ModulePopup, ModuleUpdateEvent, WidgetContext};
|
||||
use crate::clients::wayland::{self, ToplevelEvent};
|
||||
use crate::config::{CommonConfig, EllipsizeMode, TruncateMode};
|
||||
use crate::config::{CommonConfig, EllipsizeMode, LayoutConfig, TruncateMode};
|
||||
use crate::desktop_file::find_desktop_file;
|
||||
use crate::gtk_helpers::{IronbarGtkExt, IronbarLabelExt};
|
||||
use crate::modules::launcher::item::ImageTextButton;
|
||||
|
@ -105,6 +105,10 @@ pub struct LauncherModule {
|
|||
#[serde(default = "default_truncate_popup")]
|
||||
truncate_popup: TruncateMode,
|
||||
|
||||
/// See [layout options](module-level-options#layout)
|
||||
#[serde(default, flatten)]
|
||||
layout: LayoutConfig,
|
||||
|
||||
/// See [common options](module-level-options#common-options).
|
||||
#[serde(flatten)]
|
||||
pub common: Option<CommonConfig>,
|
||||
|
@ -451,13 +455,13 @@ impl Module<gtk::Box> for LauncherModule {
|
|||
) -> crate::Result<ModuleParts<gtk::Box>> {
|
||||
let icon_theme = info.icon_theme;
|
||||
|
||||
let container = gtk::Box::new(info.bar_position.orientation(), 0);
|
||||
let container = gtk::Box::new(self.layout.orientation(info), 0);
|
||||
let page_size = self.page_size;
|
||||
|
||||
let pagination = Pagination::new(
|
||||
&container,
|
||||
self.page_size,
|
||||
info.bar_position.orientation(),
|
||||
self.layout.orientation(info),
|
||||
IconContext {
|
||||
icon_back: &self.icons.page_back,
|
||||
icon_fwd: &self.icons.page_forward,
|
||||
|
@ -477,6 +481,9 @@ impl Module<gtk::Box> for LauncherModule {
|
|||
show_icons: self.show_icons,
|
||||
icon_size: self.icon_size,
|
||||
truncate: self.truncate,
|
||||
orientation: self.layout.orientation(info),
|
||||
angle: self.layout.angle(info),
|
||||
justify: self.layout.justify.into(),
|
||||
};
|
||||
|
||||
let show_names = self.show_names;
|
||||
|
@ -636,7 +643,7 @@ impl Module<gtk::Box> for LauncherModule {
|
|||
.into_iter()
|
||||
.map(|(_, win)| {
|
||||
// TODO: Currently has a useless image
|
||||
let button = ImageTextButton::new();
|
||||
let button = ImageTextButton::new(Orientation::Horizontal);
|
||||
button.set_height_request(40);
|
||||
button.label.set_label(&win.name);
|
||||
button.label.truncate(self.truncate_popup);
|
||||
|
@ -662,7 +669,7 @@ impl Module<gtk::Box> for LauncherModule {
|
|||
|
||||
if let Some(buttons) = buttons.get_mut(&app_id) {
|
||||
// TODO: Currently has a useless image
|
||||
let button = ImageTextButton::new();
|
||||
let button = ImageTextButton::new(Orientation::Horizontal);
|
||||
button.set_height_request(40);
|
||||
button.label.set_label(&win.name);
|
||||
button.label.truncate(self.truncate_popup);
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
use crate::gtk_helpers::IronbarGtkExt;
|
||||
use crate::image::new_icon_button;
|
||||
use crate::image::IconButton;
|
||||
use gtk::prelude::*;
|
||||
use gtk::{Button, IconTheme, Orientation};
|
||||
use std::cell::RefCell;
|
||||
|
@ -29,13 +29,13 @@ impl Pagination {
|
|||
) -> Self {
|
||||
let scroll_box = gtk::Box::new(orientation, 0);
|
||||
|
||||
let scroll_back = new_icon_button(
|
||||
let scroll_back = IconButton::new(
|
||||
icon_context.icon_back,
|
||||
icon_context.icon_theme,
|
||||
icon_context.icon_size,
|
||||
);
|
||||
|
||||
let scroll_fwd = new_icon_button(
|
||||
let scroll_fwd = IconButton::new(
|
||||
icon_context.icon_fwd,
|
||||
icon_context.icon_theme,
|
||||
icon_context.icon_size,
|
||||
|
@ -48,8 +48,8 @@ impl Pagination {
|
|||
scroll_back.add_class("btn-back");
|
||||
scroll_fwd.add_class("btn-forward");
|
||||
|
||||
scroll_box.add(&scroll_back);
|
||||
scroll_box.add(&scroll_fwd);
|
||||
scroll_box.add(&*scroll_back);
|
||||
scroll_box.add(&*scroll_fwd);
|
||||
container.add(&scroll_box);
|
||||
|
||||
let offset = Rc::new(RefCell::new(1));
|
||||
|
@ -103,7 +103,7 @@ impl Pagination {
|
|||
offset,
|
||||
|
||||
controls_container: scroll_box,
|
||||
btn_fwd: scroll_fwd,
|
||||
btn_fwd: scroll_fwd.deref().clone(),
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
use crate::config::{CommonConfig, TruncateMode};
|
||||
use crate::config::{CommonConfig, LayoutConfig, TruncateMode};
|
||||
use dirs::{audio_dir, home_dir};
|
||||
use serde::Deserialize;
|
||||
use std::path::PathBuf;
|
||||
|
@ -147,6 +147,10 @@ pub struct MusicModule {
|
|||
/// **Default**: `null`
|
||||
pub(crate) truncate: Option<TruncateMode>,
|
||||
|
||||
/// See [layout options](module-level-options#layout)
|
||||
#[serde(default, flatten)]
|
||||
pub(crate) layout: LayoutConfig,
|
||||
|
||||
/// See [common options](module-level-options#common-options).
|
||||
#[serde(flatten)]
|
||||
pub common: Option<CommonConfig>,
|
||||
|
|
|
@ -17,7 +17,7 @@ use crate::clients::music::{
|
|||
self, MusicClient, PlayerState, PlayerUpdate, ProgressTick, Status, Track,
|
||||
};
|
||||
use crate::gtk_helpers::{IronbarGtkExt, IronbarLabelExt};
|
||||
use crate::image::{IconLabel, ImageProvider, new_icon_button};
|
||||
use crate::image::{IconButton, IconLabel, ImageProvider};
|
||||
use crate::modules::PopupButton;
|
||||
use crate::modules::{
|
||||
Module, ModuleInfo, ModuleParts, ModulePopup, ModuleUpdateEvent, WidgetContext,
|
||||
|
@ -182,7 +182,7 @@ impl Module<Button> for MusicModule {
|
|||
info: &ModuleInfo,
|
||||
) -> Result<ModuleParts<Button>> {
|
||||
let button = Button::new();
|
||||
let button_contents = gtk::Box::new(Orientation::Horizontal, 5);
|
||||
let button_contents = gtk::Box::new(self.layout.orientation(info), 5);
|
||||
button_contents.add_class("contents");
|
||||
|
||||
button.add(&button_contents);
|
||||
|
@ -190,9 +190,16 @@ impl Module<Button> for MusicModule {
|
|||
let icon_play = IconLabel::new(&self.icons.play, info.icon_theme, self.icon_size);
|
||||
let icon_pause = IconLabel::new(&self.icons.pause, info.icon_theme, self.icon_size);
|
||||
|
||||
icon_play.label().set_angle(self.layout.angle(info));
|
||||
icon_play.label().set_justify(self.layout.justify.into());
|
||||
|
||||
icon_pause.label().set_angle(self.layout.angle(info));
|
||||
icon_pause.label().set_justify(self.layout.justify.into());
|
||||
|
||||
let label = Label::builder()
|
||||
.use_markup(true)
|
||||
.angle(info.bar_position.get_angle())
|
||||
.angle(self.layout.angle(info))
|
||||
.justify(self.layout.justify.into())
|
||||
.build();
|
||||
|
||||
if let Some(truncate) = self.truncate {
|
||||
|
@ -297,22 +304,22 @@ impl Module<Button> for MusicModule {
|
|||
let controls_box = gtk::Box::new(Orientation::Horizontal, 0);
|
||||
controls_box.add_class("controls");
|
||||
|
||||
let btn_prev = new_icon_button(&icons.prev, icon_theme, self.icon_size);
|
||||
let btn_prev = IconButton::new(&icons.prev, icon_theme, self.icon_size);
|
||||
btn_prev.add_class("btn-prev");
|
||||
|
||||
let btn_play = new_icon_button(&icons.play, icon_theme, self.icon_size);
|
||||
let btn_play = IconButton::new(&icons.play, icon_theme, self.icon_size);
|
||||
btn_play.add_class("btn-play");
|
||||
|
||||
let btn_pause = new_icon_button(&icons.pause, icon_theme, self.icon_size);
|
||||
let btn_pause = IconButton::new(&icons.pause, icon_theme, self.icon_size);
|
||||
btn_pause.add_class("btn-pause");
|
||||
|
||||
let btn_next = new_icon_button(&icons.next, icon_theme, self.icon_size);
|
||||
let btn_next = IconButton::new(&icons.next, icon_theme, self.icon_size);
|
||||
btn_next.add_class("btn-next");
|
||||
|
||||
controls_box.add(&btn_prev);
|
||||
controls_box.add(&btn_play);
|
||||
controls_box.add(&btn_pause);
|
||||
controls_box.add(&btn_next);
|
||||
controls_box.add(&*btn_prev);
|
||||
controls_box.add(&*btn_play);
|
||||
controls_box.add(&*btn_pause);
|
||||
controls_box.add(&*btn_next);
|
||||
|
||||
info_box.add(&controls_box);
|
||||
|
||||
|
|
|
@ -1,11 +1,10 @@
|
|||
use crate::config::CommonConfig;
|
||||
use crate::config::{CommonConfig, LayoutConfig};
|
||||
use crate::gtk_helpers::IronbarLabelExt;
|
||||
use crate::modules::{Module, ModuleInfo, ModuleParts, ModuleUpdateEvent, WidgetContext};
|
||||
use crate::script::{OutputStream, Script, ScriptMode};
|
||||
use crate::{glib_recv, module_impl, spawn, try_send};
|
||||
use color_eyre::{Help, Report, Result};
|
||||
use gtk::Label;
|
||||
use gtk::prelude::*;
|
||||
use serde::Deserialize;
|
||||
use tokio::sync::mpsc;
|
||||
use tracing::error;
|
||||
|
@ -36,6 +35,11 @@ pub struct ScriptModule {
|
|||
#[serde(default = "default_interval")]
|
||||
interval: u64,
|
||||
|
||||
// -- Common --
|
||||
/// See [layout options](module-level-options#layout)
|
||||
#[serde(default, flatten)]
|
||||
layout: LayoutConfig,
|
||||
|
||||
/// See [common options](module-level-options#common-options).
|
||||
#[serde(flatten)]
|
||||
pub common: Option<CommonConfig>,
|
||||
|
@ -99,8 +103,11 @@ impl Module<Label> for ScriptModule {
|
|||
context: WidgetContext<Self::SendMessage, Self::ReceiveMessage>,
|
||||
info: &ModuleInfo,
|
||||
) -> Result<ModuleParts<Label>> {
|
||||
let label = Label::builder().use_markup(true).build();
|
||||
label.set_angle(info.bar_position.get_angle());
|
||||
let label = Label::builder()
|
||||
.use_markup(true)
|
||||
.angle(self.layout.angle(info))
|
||||
.justify(self.layout.justify.into())
|
||||
.build();
|
||||
|
||||
{
|
||||
let label = label.clone();
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
use crate::config::{CommonConfig, TruncateMode};
|
||||
use crate::config::{CommonConfig, LayoutConfig, TruncateMode};
|
||||
use crate::gtk_helpers::IronbarLabelExt;
|
||||
use crate::modules::{Module, ModuleInfo, ModuleParts, ModuleUpdateEvent, WidgetContext};
|
||||
use crate::{await_sync, glib_recv, module_impl, try_send};
|
||||
|
@ -19,6 +19,10 @@ pub struct SwayModeModule {
|
|||
/// **Default**: `null`
|
||||
pub truncate: Option<TruncateMode>,
|
||||
|
||||
/// See [layout options](module-level-options#layout)
|
||||
#[serde(default, flatten)]
|
||||
layout: LayoutConfig,
|
||||
|
||||
/// See [common options](module-level-options#common-options).
|
||||
#[serde(flatten)]
|
||||
pub common: Option<CommonConfig>,
|
||||
|
@ -57,10 +61,13 @@ impl Module<Label> for SwayModeModule {
|
|||
fn into_widget(
|
||||
self,
|
||||
context: WidgetContext<Self::SendMessage, Self::ReceiveMessage>,
|
||||
_info: &ModuleInfo,
|
||||
info: &ModuleInfo,
|
||||
) -> Result<ModuleParts<Label>> {
|
||||
let label = Label::new(None);
|
||||
label.set_use_markup(true);
|
||||
let label = Label::builder()
|
||||
.use_markup(true)
|
||||
.angle(self.layout.angle(info))
|
||||
.justify(self.layout.justify.into())
|
||||
.build();
|
||||
|
||||
{
|
||||
let label = label.clone();
|
||||
|
|
|
@ -3,7 +3,7 @@ mod renderer;
|
|||
mod token;
|
||||
|
||||
use crate::clients::sysinfo::TokenType;
|
||||
use crate::config::{CommonConfig, ModuleOrientation};
|
||||
use crate::config::{CommonConfig, LayoutConfig, ModuleOrientation};
|
||||
use crate::gtk_helpers::{IronbarGtkExt, IronbarLabelExt};
|
||||
use crate::modules::sysinfo::token::Part;
|
||||
use crate::modules::{Module, ModuleInfo, ModuleParts, ModuleUpdateEvent, WidgetContext};
|
||||
|
@ -34,14 +34,6 @@ pub struct SysInfoModule {
|
|||
#[serde(default = "Interval::default")]
|
||||
interval: Interval,
|
||||
|
||||
/// The orientation of text for the labels.
|
||||
///
|
||||
/// **Valid options**: `horizontal`, `vertical`, `h`, `v`
|
||||
/// <br>
|
||||
/// **Default** : `horizontal`
|
||||
#[serde(default)]
|
||||
orientation: ModuleOrientation,
|
||||
|
||||
/// The orientation by which the labels are laid out.
|
||||
///
|
||||
/// **Valid options**: `horizontal`, `vertical`, `h`, `v`
|
||||
|
@ -49,6 +41,11 @@ pub struct SysInfoModule {
|
|||
/// **Default** : `horizontal`
|
||||
direction: Option<ModuleOrientation>,
|
||||
|
||||
// -- common --
|
||||
/// See [layout options](module-level-options#layout)
|
||||
#[serde(default, flatten)]
|
||||
layout: LayoutConfig,
|
||||
|
||||
/// See [common options](module-level-options#common-options).
|
||||
#[serde(flatten)]
|
||||
pub common: Option<CommonConfig>,
|
||||
|
@ -281,22 +278,25 @@ impl Module<gtk::Box> for SysInfoModule {
|
|||
fn into_widget(
|
||||
self,
|
||||
context: WidgetContext<Self::SendMessage, Self::ReceiveMessage>,
|
||||
_info: &ModuleInfo,
|
||||
info: &ModuleInfo,
|
||||
) -> Result<ModuleParts<gtk::Box>> {
|
||||
let layout = match self.direction {
|
||||
Some(orientation) => orientation,
|
||||
None => self.orientation,
|
||||
Some(orientation) => orientation.into(),
|
||||
None => self.layout.orientation(info),
|
||||
};
|
||||
|
||||
let container = gtk::Box::new(layout.into(), 10);
|
||||
let container = gtk::Box::new(layout, 10);
|
||||
|
||||
let mut labels = Vec::new();
|
||||
|
||||
for _ in &self.format {
|
||||
let label = Label::builder().use_markup(true).build();
|
||||
let label = Label::builder()
|
||||
.use_markup(true)
|
||||
.angle(self.layout.angle(info))
|
||||
.justify(self.layout.justify.into())
|
||||
.build();
|
||||
|
||||
label.add_class("item");
|
||||
label.set_angle(self.orientation.to_angle());
|
||||
|
||||
container.add(&label);
|
||||
labels.push(label);
|
||||
|
|
|
@ -39,6 +39,7 @@ pub struct TrayModule {
|
|||
/// **Default**: `horizontal` for horizontal bars, `vertical` for vertical bars
|
||||
#[serde(default)]
|
||||
direction: Option<ModuleOrientation>,
|
||||
|
||||
/// See [common options](module-level-options#common-options).
|
||||
#[serde(flatten)]
|
||||
pub common: Option<CommonConfig>,
|
||||
|
|
|
@ -8,7 +8,7 @@ use zbus;
|
|||
use zbus::fdo::PropertiesProxy;
|
||||
|
||||
use crate::clients::upower::BatteryState;
|
||||
use crate::config::CommonConfig;
|
||||
use crate::config::{CommonConfig, LayoutConfig};
|
||||
use crate::gtk_helpers::{IronbarGtkExt, IronbarLabelExt};
|
||||
use crate::image::ImageProvider;
|
||||
use crate::modules::PopupButton;
|
||||
|
@ -37,6 +37,11 @@ pub struct UpowerModule {
|
|||
#[serde(default = "default_icon_size")]
|
||||
icon_size: i32,
|
||||
|
||||
// -- Common --
|
||||
/// See [layout options](module-level-options#layout)
|
||||
#[serde(default, flatten)]
|
||||
layout: LayoutConfig,
|
||||
|
||||
/// See [common options](module-level-options#common-options).
|
||||
#[serde(flatten)]
|
||||
pub common: Option<CommonConfig>,
|
||||
|
@ -172,10 +177,13 @@ impl Module<Button> for UpowerModule {
|
|||
let label = Label::builder()
|
||||
.label(&self.format)
|
||||
.use_markup(true)
|
||||
.angle(self.layout.angle(info))
|
||||
.justify(self.layout.justify.into())
|
||||
.build();
|
||||
|
||||
label.add_class("label");
|
||||
|
||||
let container = gtk::Box::new(info.bar_position.orientation(), 5);
|
||||
let container = gtk::Box::new(self.layout.orientation(info), 5);
|
||||
container.add_class("contents");
|
||||
|
||||
let button = Button::new();
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
use crate::clients::volume::{self, Event};
|
||||
use crate::config::CommonConfig;
|
||||
use crate::config::{CommonConfig, LayoutConfig};
|
||||
use crate::gtk_helpers::{IronbarGtkExt, IronbarLabelExt};
|
||||
use crate::modules::{
|
||||
Module, ModuleInfo, ModuleParts, ModulePopup, ModuleUpdateEvent, PopupButton, WidgetContext,
|
||||
|
@ -36,6 +36,11 @@ pub struct VolumeModule {
|
|||
#[serde(default)]
|
||||
icons: Icons,
|
||||
|
||||
// -- Common --
|
||||
/// See [layout options](module-level-options#layout)
|
||||
#[serde(default, flatten)]
|
||||
layout: LayoutConfig,
|
||||
|
||||
/// See [common options](module-level-options#common-options).
|
||||
#[serde(flatten)]
|
||||
pub common: Option<CommonConfig>,
|
||||
|
@ -204,7 +209,8 @@ impl Module<Button> for VolumeModule {
|
|||
{
|
||||
let button_label = Label::builder()
|
||||
.use_markup(true)
|
||||
.angle(info.bar_position.get_angle())
|
||||
.angle(self.layout.angle(info))
|
||||
.justify(self.layout.justify.into())
|
||||
.build();
|
||||
|
||||
let button = Button::new();
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
use super::open_state::OpenState;
|
||||
use crate::gtk_helpers::IronbarGtkExt;
|
||||
use crate::image::new_icon_button;
|
||||
use crate::image::IconButton;
|
||||
use crate::modules::workspaces::WorkspaceItemContext;
|
||||
use crate::try_send;
|
||||
use gtk::Button as GtkButton;
|
||||
|
@ -8,7 +8,7 @@ use gtk::prelude::*;
|
|||
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct Button {
|
||||
button: GtkButton,
|
||||
button: IconButton,
|
||||
workspace_id: i64,
|
||||
}
|
||||
|
||||
|
@ -16,7 +16,7 @@ impl Button {
|
|||
pub fn new(id: i64, name: &str, open_state: OpenState, context: &WorkspaceItemContext) -> Self {
|
||||
let label = context.name_map.get(name).map_or(name, String::as_str);
|
||||
|
||||
let button = new_icon_button(label, &context.icon_theme, context.icon_size);
|
||||
let button = IconButton::new(label, &context.icon_theme, context.icon_size);
|
||||
button.set_widget_name(name);
|
||||
button.add_class("item");
|
||||
|
||||
|
|
|
@ -4,7 +4,7 @@ mod open_state;
|
|||
|
||||
use self::button::Button;
|
||||
use crate::clients::compositor::{Workspace, WorkspaceClient, WorkspaceUpdate};
|
||||
use crate::config::CommonConfig;
|
||||
use crate::config::{CommonConfig, LayoutConfig};
|
||||
use crate::modules::workspaces::button_map::{ButtonMap, Identifier};
|
||||
use crate::modules::workspaces::open_state::OpenState;
|
||||
use crate::modules::{Module, ModuleInfo, ModuleParts, ModuleUpdateEvent, WidgetContext};
|
||||
|
@ -127,6 +127,11 @@ pub struct WorkspacesModule {
|
|||
#[serde(default = "default_icon_size")]
|
||||
icon_size: i32,
|
||||
|
||||
// -- Common --
|
||||
/// See [layout options](module-level-options#layout)
|
||||
#[serde(default, flatten)]
|
||||
layout: LayoutConfig,
|
||||
|
||||
/// See [common options](module-level-options#common-options).
|
||||
#[serde(flatten)]
|
||||
pub common: Option<CommonConfig>,
|
||||
|
@ -228,7 +233,7 @@ impl Module<gtk::Box> for WorkspacesModule {
|
|||
context: WidgetContext<Self::SendMessage, Self::ReceiveMessage>,
|
||||
info: &ModuleInfo,
|
||||
) -> Result<ModuleParts<gtk::Box>> {
|
||||
let container = gtk::Box::new(info.bar_position.orientation(), 0);
|
||||
let container = gtk::Box::new(self.layout.orientation(info), 0);
|
||||
|
||||
let mut button_map = ButtonMap::new();
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue