1
0
Fork 0
mirror of https://github.com/Zedfrigg/ironbar.git synced 2025-07-03 03:31:03 +02:00

Merge pull request #106 from JakeStanger/feat/custom-dynamic-image

Custom image dynamic src support
This commit is contained in:
Jake Stanger 2023-04-10 20:17:58 +01:00 committed by GitHub
commit 2815cef440
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
6 changed files with 47 additions and 36 deletions

View file

@ -62,8 +62,8 @@ An image or icon from disk or http.
> Type `image` > Type `image`
| Name | Type | Default | Description | | Name | Type | Default | Description |
|--------|-----------|---------|-------------------------------------------------------------| |--------|-----------|---------|---------------------------------------------------------------------------------------------|
| `src` | `image` | `null` | Image source. See [here](images) for information on images. | | `src` | `image` | `null` | Image source. See [here](images) for information on images. Embedded scripts are supported. |
| `size` | `integer` | `null` | Width/height of the image. Aspect ratio is preserved. | | `size` | `integer` | `null` | Width/height of the image. Aspect ratio is preserved. |
#### Slider #### Slider
@ -130,7 +130,7 @@ $progress = {
bar = [ bar = [
{ {
type = "progress" type = "progress"
value = "500:mpc | sed -n 2p | awk '{ print $4 }' | grep -Eo '[0-9]+'" value = "500:mpc | sed -n 2p | awk '{ print $4 }' | grep -Eo '[0-9]+' || echo 0"
label = "{{500:mpc | sed -n 2p | awk '{ print $3 }'}} elapsed" label = "{{500:mpc | sed -n 2p | awk '{ print $3 }'}} elapsed"
length = 200 length = 200
} }

View file

@ -193,7 +193,16 @@ impl<'a> ImageProvider<'a> {
/// Attempts to get `Bytes` from an HTTP resource asynchronously. /// Attempts to get `Bytes` from an HTTP resource asynchronously.
#[cfg(feature = "http")] #[cfg(feature = "http")]
async fn get_bytes_from_http(url: reqwest::Url) -> Result<glib::Bytes> { async fn get_bytes_from_http(url: reqwest::Url) -> Result<glib::Bytes> {
let bytes = reqwest::get(url).await?.bytes().await?; let res = reqwest::get(url).await?;
let status = res.status();
if status.is_success() {
let bytes = res.bytes().await?;
Ok(glib::Bytes::from_owned(bytes)) Ok(glib::Bytes::from_owned(bytes))
} else {
Err(Report::msg(format!(
"Received non-success HTTP code ({status})"
)))
}
} }
} }

View file

@ -21,7 +21,7 @@ impl CustomWidget for BoxWidget {
if let Some(orientation) = self.orientation { if let Some(orientation) = self.orientation {
container.set_orientation( container.set_orientation(
try_get_orientation(&orientation).unwrap_or(Orientation::Horizontal), try_get_orientation(&orientation).unwrap_or(Orientation::Horizontal),
) );
} }
if let Some(widgets) = self.widgets { if let Some(widgets) = self.widgets {

View file

@ -1,5 +1,6 @@
use super::{CustomWidget, CustomWidgetContext}; use super::{CustomWidget, CustomWidgetContext};
use crate::build; use crate::build;
use crate::dynamic_string::DynamicString;
use crate::image::ImageProvider; use crate::image::ImageProvider;
use gtk::prelude::*; use gtk::prelude::*;
use gtk::Image; use gtk::Image;
@ -10,8 +11,13 @@ use tracing::error;
pub struct ImageWidget { pub struct ImageWidget {
name: Option<String>, name: Option<String>,
class: Option<String>, class: Option<String>,
src: Option<String>, src: String,
size: Option<i32>, #[serde(default = "default_size")]
size: i32,
}
const fn default_size() -> i32 {
32
} }
impl CustomWidget for ImageWidget { impl CustomWidget for ImageWidget {
@ -20,13 +26,20 @@ impl CustomWidget for ImageWidget {
fn into_widget(self, context: CustomWidgetContext) -> Self::Widget { fn into_widget(self, context: CustomWidgetContext) -> Self::Widget {
let gtk_image = build!(self, Self::Widget); let gtk_image = build!(self, Self::Widget);
if let Some(src) = self.src {
let size = self.size.unwrap_or(32);
if let Err(err) = ImageProvider::parse(&src, context.icon_theme, size)
.and_then(|image| image.load_into_image(gtk_image.clone()))
{ {
let gtk_image = gtk_image.clone();
let icon_theme = context.icon_theme.clone();
DynamicString::new(&self.src, move |src| {
let res = ImageProvider::parse(&src, &icon_theme, self.size)
.and_then(|image| image.load_into_image(gtk_image.clone()));
if let Err(err) = res {
error!("{err:?}"); error!("{err:?}");
} }
Continue(true)
});
} }
gtk_image gtk_image

View file

@ -109,12 +109,12 @@ impl Widget {
/// Creates this widget and adds it to the parent container /// Creates this widget and adds it to the parent container
fn add_to(self, parent: &gtk::Box, context: CustomWidgetContext) { fn add_to(self, parent: &gtk::Box, context: CustomWidgetContext) {
match self { match self {
Widget::Box(widget) => parent.add(&widget.into_widget(context)), Self::Box(widget) => parent.add(&widget.into_widget(context)),
Widget::Label(widget) => parent.add(&widget.into_widget(context)), Self::Label(widget) => parent.add(&widget.into_widget(context)),
Widget::Button(widget) => parent.add(&widget.into_widget(context)), Self::Button(widget) => parent.add(&widget.into_widget(context)),
Widget::Image(widget) => parent.add(&widget.into_widget(context)), Self::Image(widget) => parent.add(&widget.into_widget(context)),
Widget::Slider(widget) => parent.add(&widget.into_widget(context)), Self::Slider(widget) => parent.add(&widget.into_widget(context)),
Widget::Progress(widget) => parent.add(&widget.into_widget(context)), Self::Progress(widget) => parent.add(&widget.into_widget(context)),
} }
} }
} }
@ -147,7 +147,7 @@ impl Module<gtk::Box> for CustomModule {
debug!("executing command: '{}'", script.cmd); debug!("executing command: '{}'", script.cmd);
let args = event.args.unwrap_or(vec![]); let args = event.args.unwrap_or_default();
if let Err(err) = script.get_output(Some(&args)).await { if let Err(err) = script.get_output(Some(&args)).await {
error!("{err:?}"); error!("{err:?}");

View file

@ -60,7 +60,7 @@ impl CustomWidget for SliderWidget {
scale.connect_change_value(move |scale, _, val| { scale.connect_change_value(move |scale, _, val| {
// GTK will send values outside min/max range // GTK will send values outside min/max range
let val = clamp(val, min, max); let val = val.clamp(min, max);
if val != prev_value.get() { if val != prev_value.get() {
try_send!( try_send!(
@ -106,14 +106,3 @@ impl CustomWidget for SliderWidget {
scale scale
} }
} }
/// Ensures `num` is between `min` and `max` (inclusive).
fn clamp(num: f64, min: f64, max: f64) -> f64 {
if num < min {
min
} else if num > max {
max
} else {
num
}
}