Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: Add orientation support for clock, button, label, and sys_info #530

Merged
merged 5 commits into from
Apr 6, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions docs/modules/Clock.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ Clicking on the widget opens a popup with the time and a calendar.
| `format` | `string` | `%d/%m/%Y %H:%M` | Date/time format string. Pango markup is supported. |
| `format_popup` | `string` | `%H:%M:%S` | Date/time format string to display in the popup header. Pango markup is supported. |
| `locale` | `string` | `$LC_TIME` or `$LANG` or `'POSIX'` | Locale to use (eg `en_GB`). Defaults to the system language (reading from env var). |
| `orientation` | `'horizontal'` or `'vertical'` (shorthand: `'h'` or `'v'`) | `'horizontal'` | Orientation of the time on the clock button. |

> Detail on available tokens can be found here: <https://docs.rs/chrono/latest/chrono/format/strftime/index.html>

Expand Down
2 changes: 2 additions & 0 deletions docs/modules/Custom.md
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,7 @@ A text label. Pango markup is supported.
| Name | Type | Default | Description |
|---------|-------------------------------------------------|---------|---------------------------------------------------------------------|
| `label` | [Dynamic String](dynamic-values#dynamic-string) | `null` | Widget text label. Pango markup and embedded scripts are supported. |
| `orientation` | `'horizontal'` or `'vertical'` (shorthand: `'h'` or `'v'`) | `'horizontal'` | Orientation of the label. |

#### Button

Expand All @@ -69,6 +70,7 @@ A clickable button, which can run a command when clicked.
| `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. |

#### Image

Expand Down
2 changes: 2 additions & 0 deletions docs/modules/Sys-Info.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,8 @@ Pango markup is supported.
| `interval.temps` | `integer` | `5` | Seconds between refreshing temperature data |
| `interval.disks` | `integer` | `5` | Seconds between refreshing disk data |
| `interval.network` | `integer` | `5` | Seconds between refreshing network data |
| `orientation` | `'horizontal'` or `'vertical'` (shorthand: `'h'` or `'v'`) | `'horizontal'` | Orientation of the labels. |
| `direction` | `'horizontal'` or `'vertical'` (shorthand: `'h'` or `'v'`) | `'horizontal'` | How the labels are laid out (not the rotation of an individual label). |

<details>
<summary>JSON</summary>
Expand Down
28 changes: 28 additions & 0 deletions src/config/common.rs
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,34 @@ pub enum TransitionType {
SlideEnd,
}

#[derive(Debug, Default, Deserialize, Clone, Copy)]
#[serde(rename_all = "snake_case")]
pub enum ModuleOrientation {
#[default]
#[serde(alias = "h")]
Horizontal,
#[serde(alias = "v")]
Vertical,
}

impl ModuleOrientation {
pub const fn to_angle(self) -> f64 {
match self {
Self::Horizontal => 0.0,
Self::Vertical => 90.0,
}
}
}

impl From<ModuleOrientation> for Orientation {
fn from(o: ModuleOrientation) -> Self {
match o {
ModuleOrientation::Horizontal => Self::Horizontal,
ModuleOrientation::Vertical => Self::Vertical,
}
}
}

impl TransitionType {
pub const fn to_revealer_transition_type(
&self,
Expand Down
2 changes: 1 addition & 1 deletion src/config/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ use color_eyre::Result;
use serde::Deserialize;
use std::collections::HashMap;

pub use self::common::{CommonConfig, TransitionType};
pub use self::common::{CommonConfig, ModuleOrientation, TransitionType};
pub use self::truncate::TruncateMode;

#[derive(Debug, Deserialize, Clone)]
Expand Down
8 changes: 6 additions & 2 deletions src/modules/clock.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ use serde::Deserialize;
use tokio::sync::{broadcast, mpsc};
use tokio::time::sleep;

use crate::config::CommonConfig;
use crate::config::{CommonConfig, ModuleOrientation};
use crate::gtk_helpers::IronbarGtkExt;
use crate::modules::{
Module, ModuleInfo, ModuleParts, ModulePopup, ModuleUpdateEvent, PopupButton, WidgetContext,
Expand All @@ -31,6 +31,9 @@ pub struct ClockModule {
#[serde(default = "default_locale")]
locale: String,

#[serde(default)]
orientation: ModuleOrientation,

#[serde(flatten)]
pub common: Option<CommonConfig>,
}
Expand All @@ -41,6 +44,7 @@ impl Default for ClockModule {
format: default_format(),
format_popup: default_popup_format(),
locale: default_locale(),
orientation: ModuleOrientation::Horizontal,
common: Some(CommonConfig::default()),
}
}
Expand Down Expand Up @@ -98,7 +102,7 @@ impl Module<Button> for ClockModule {
) -> Result<ModuleParts<Button>> {
let button = Button::new();
let label = Label::builder()
.angle(info.bar_position.get_angle())
.angle(self.orientation.to_angle())
.use_markup(true)
.build();
button.add(&label);
Expand Down
10 changes: 4 additions & 6 deletions src/modules/custom/box.rs
Original file line number Diff line number Diff line change
@@ -1,15 +1,15 @@
use super::{try_get_orientation, CustomWidget, CustomWidgetContext};
use super::{CustomWidget, CustomWidgetContext};
use crate::build;
use crate::config::ModuleOrientation;
use crate::modules::custom::WidgetConfig;
use gtk::prelude::*;
use gtk::Orientation;
use serde::Deserialize;

#[derive(Debug, Deserialize, Clone)]
pub struct BoxWidget {
name: Option<String>,
class: Option<String>,
orientation: Option<String>,
orientation: Option<ModuleOrientation>,
widgets: Option<Vec<WidgetConfig>>,
}

Expand All @@ -20,9 +20,7 @@ impl CustomWidget for BoxWidget {
let container = build!(self, Self::Widget);

if let Some(orientation) = self.orientation {
container.set_orientation(
try_get_orientation(&orientation).unwrap_or(Orientation::Horizontal),
);
container.set_orientation(orientation.into());
}

if let Some(widgets) = self.widgets {
Expand Down
6 changes: 6 additions & 0 deletions src/modules/custom/button.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ use gtk::prelude::*;
use gtk::{Button, Label, Orientation};
use serde::Deserialize;

use crate::config::ModuleOrientation;
use crate::dynamic_value::dynamic_string;
use crate::modules::PopupButton;
use crate::{build, try_send};
Expand All @@ -15,6 +16,8 @@ pub struct ButtonWidget {
label: Option<String>,
on_click: Option<String>,
widgets: Option<Vec<WidgetConfig>>,
#[serde(default)]
orientation: ModuleOrientation,
}

impl CustomWidget for ButtonWidget {
Expand All @@ -35,6 +38,9 @@ impl CustomWidget for ButtonWidget {
} else if let Some(text) = self.label {
let label = Label::new(None);
label.set_use_markup(true);

label.set_angle(self.orientation.to_angle());

button.add(&label);

dynamic_string(&text, move |string| {
Expand Down
5 changes: 5 additions & 0 deletions src/modules/custom/label.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ use gtk::Label;
use serde::Deserialize;

use crate::build;
use crate::config::ModuleOrientation;
use crate::dynamic_value::dynamic_string;

use super::{CustomWidget, CustomWidgetContext};
Expand All @@ -12,6 +13,8 @@ pub struct LabelWidget {
name: Option<String>,
class: Option<String>,
label: String,
#[serde(default)]
orientation: ModuleOrientation,
}

impl CustomWidget for LabelWidget {
Expand All @@ -20,6 +23,8 @@ impl CustomWidget for LabelWidget {
fn into_widget(self, _context: CustomWidgetContext) -> Self::Widget {
let label = build!(self, Self::Widget);

label.set_angle(self.orientation.to_angle());

label.set_use_markup(true);

{
Expand Down
13 changes: 1 addition & 12 deletions src/modules/custom/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ use crate::modules::{
};
use crate::script::Script;
use crate::{module_impl, send_async, spawn};
use color_eyre::{Report, Result};
use color_eyre::Result;
use gtk::prelude::*;
use gtk::{Button, IconTheme, Orientation};
use serde::Deserialize;
Expand Down Expand Up @@ -113,17 +113,6 @@ pub fn set_length<W: WidgetExt>(widget: &W, length: i32, bar_orientation: Orient
};
}

/// Attempts to parse an `Orientation` from `String`.
/// Will accept `horizontal`, `vertical`, `h` or `v`.
/// Ignores case.
fn try_get_orientation(orientation: &str) -> Result<Orientation> {
match orientation.to_lowercase().as_str() {
"horizontal" | "h" => Ok(Orientation::Horizontal),
"vertical" | "v" => Ok(Orientation::Vertical),
_ => Err(Report::msg("Invalid orientation string in config")),
}
}

impl WidgetOrModule {
fn add_to(self, parent: &gtk::Box, context: &CustomWidgetContext, common: CommonConfig) {
match self {
Expand Down
12 changes: 5 additions & 7 deletions src/modules/custom/progress.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,18 +4,20 @@ use serde::Deserialize;
use tokio::sync::mpsc;
use tracing::error;

use crate::config::ModuleOrientation;
use crate::dynamic_value::dynamic_string;
use crate::modules::custom::set_length;
use crate::script::{OutputStream, Script, ScriptInput};
use crate::{build, glib_recv_mpsc, spawn, try_send};

use super::{try_get_orientation, CustomWidget, CustomWidgetContext};
use super::{CustomWidget, CustomWidgetContext};

#[derive(Debug, Deserialize, Clone)]
pub struct ProgressWidget {
name: Option<String>,
class: Option<String>,
orientation: Option<String>,
#[serde(default)]
orientation: ModuleOrientation,
label: Option<String>,
value: Option<ScriptInput>,
#[serde(default = "default_max")]
Expand All @@ -33,11 +35,7 @@ impl CustomWidget for ProgressWidget {
fn into_widget(self, context: CustomWidgetContext) -> Self::Widget {
let progress = build!(self, Self::Widget);

if let Some(orientation) = self.orientation {
progress.set_orientation(
try_get_orientation(&orientation).unwrap_or(context.bar_orientation),
);
}
progress.set_orientation(self.orientation.into());

if let Some(length) = self.length {
set_length(&progress, length, context.bar_orientation);
Expand Down
12 changes: 5 additions & 7 deletions src/modules/custom/slider.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,17 +8,19 @@ use serde::Deserialize;
use tokio::sync::mpsc;
use tracing::error;

use crate::config::ModuleOrientation;
use crate::modules::custom::set_length;
use crate::script::{OutputStream, Script, ScriptInput};
use crate::{build, glib_recv_mpsc, spawn, try_send};

use super::{try_get_orientation, CustomWidget, CustomWidgetContext, ExecEvent};
use super::{CustomWidget, CustomWidgetContext, ExecEvent};

#[derive(Debug, Deserialize, Clone)]
pub struct SliderWidget {
name: Option<String>,
class: Option<String>,
orientation: Option<String>,
#[serde(default)]
orientation: ModuleOrientation,
value: Option<ScriptInput>,
on_change: Option<String>,
#[serde(default = "default_min")]
Expand All @@ -45,11 +47,7 @@ impl CustomWidget for SliderWidget {
fn into_widget(self, context: CustomWidgetContext) -> Self::Widget {
let scale = build!(self, Self::Widget);

if let Some(orientation) = self.orientation {
scale.set_orientation(
try_get_orientation(&orientation).unwrap_or(context.bar_orientation),
);
}
scale.set_orientation(self.orientation.into());

if let Some(length) = self.length {
set_length(&scale, length, context.bar_orientation);
Expand Down
18 changes: 14 additions & 4 deletions src/modules/sysinfo.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use crate::config::CommonConfig;
use crate::config::{CommonConfig, ModuleOrientation};
use crate::gtk_helpers::IronbarGtkExt;
use crate::modules::{Module, ModuleInfo, ModuleParts, ModuleUpdateEvent, WidgetContext};
use crate::{glib_recv, module_impl, send_async, spawn};
Expand All @@ -21,6 +21,11 @@ pub struct SysInfoModule {
#[serde(default = "Interval::default")]
interval: Interval,

#[serde(default)]
orientation: ModuleOrientation,

ClaireNeveu marked this conversation as resolved.
Show resolved Hide resolved
direction: Option<ModuleOrientation>,

#[serde(flatten)]
pub common: Option<CommonConfig>,
}
Expand Down Expand Up @@ -182,19 +187,24 @@ 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 re = Regex::new(r"\{([^}]+)}")?;

let container = gtk::Box::new(info.bar_position.orientation(), 10);
let layout = match self.direction {
Some(orientation) => orientation,
None => self.orientation,
};

let container = gtk::Box::new(layout.into(), 10);

let mut labels = Vec::new();

for format in &self.format {
let label = Label::builder().label(format).use_markup(true).build();

label.add_class("item");
label.set_angle(info.bar_position.get_angle());
label.set_angle(self.orientation.to_angle());

container.add(&label);
labels.push(label);
Expand Down
1 change: 0 additions & 1 deletion src/modules/upower.rs
Original file line number Diff line number Diff line change
Expand Up @@ -181,7 +181,6 @@ impl Module<gtk::Button> for UpowerModule {
try_send!(tx, ModuleUpdateEvent::TogglePopup(button.popup_id()));
});

label.set_angle(info.bar_position.get_angle());
let format = self.format.clone();

let rx = context.subscribe();
Expand Down
Loading
Loading