From 4ffb7d48414ecba9936be1a2dfffce4130dcbdaa Mon Sep 17 00:00:00 2001 From: Pedro Burgos <43417195+druskus20@users.noreply.github.com> Date: Tue, 19 Apr 2022 20:15:25 +0200 Subject: [PATCH] Transform Widget (#348) --- CHANGELOG.md | 1 + crates/eww/src/display_backend.rs | 8 +- crates/eww/src/widgets/mod.rs | 1 + crates/eww/src/widgets/transform.rs | 181 +++++++++++++++++++ crates/eww/src/widgets/widget_definitions.rs | 23 ++- crates/yuck/src/value/coords.rs | 11 +- out.gif | Bin 36688 -> 0 bytes 7 files changed, 218 insertions(+), 7 deletions(-) create mode 100644 crates/eww/src/widgets/transform.rs delete mode 100644 out.gif diff --git a/CHANGELOG.md b/CHANGELOG.md index a67aa71..e002b28 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -29,6 +29,7 @@ All notable changes to eww will be listed here, starting at changes since versio - Add drag and drop functionality to eventbox - Add `search`, `captures`, `stringlength`, `arraylength` and `objectlength` functions for expressions (By: MartinJM, ElKowar) - Add `matches` function +- Add transform widget (By: druskus20) ### Notable Internal changes - Rework state management completely, now making local state and dynamic widget hierarchy changes possible. diff --git a/crates/eww/src/display_backend.rs b/crates/eww/src/display_backend.rs index bfb6d38..a279b57 100644 --- a/crates/eww/src/display_backend.rs +++ b/crates/eww/src/display_backend.rs @@ -69,8 +69,8 @@ mod platform { gtk_layer_shell::set_anchor(&window, gtk_layer_shell::Edge::Top, top); gtk_layer_shell::set_anchor(&window, gtk_layer_shell::Edge::Bottom, bottom); - let xoffset = geometry.offset.x.relative_to(monitor.width); - let yoffset = geometry.offset.y.relative_to(monitor.height); + let xoffset = geometry.offset.x.pixels_relative_to(monitor.width); + let yoffset = geometry.offset.y.pixels_relative_to(monitor.height); if left { gtk_layer_shell::set_margin(&window, gtk_layer_shell::Edge::Left, xoffset); @@ -161,8 +161,8 @@ mod platform { let mon_end_y = (monitor_rect.y + monitor_rect.height) as u32 - 1u32; let dist = match strut_def.side { - Side::Left | Side::Right => strut_def.dist.relative_to(monitor_rect.width) as u32, - Side::Top | Side::Bottom => strut_def.dist.relative_to(monitor_rect.height) as u32, + Side::Left | Side::Right => strut_def.dist.pixels_relative_to(monitor_rect.width) as u32, + Side::Top | Side::Bottom => strut_def.dist.pixels_relative_to(monitor_rect.height) as u32, }; // don't question it,..... diff --git a/crates/eww/src/widgets/mod.rs b/crates/eww/src/widgets/mod.rs index a930332..5da0f78 100644 --- a/crates/eww/src/widgets/mod.rs +++ b/crates/eww/src/widgets/mod.rs @@ -4,6 +4,7 @@ pub mod build_widget; pub mod circular_progressbar; pub mod def_widget_macro; pub mod graph; +pub mod transform; pub mod widget_definitions; /// Run a command that was provided as an attribute. diff --git a/crates/eww/src/widgets/transform.rs b/crates/eww/src/widgets/transform.rs new file mode 100644 index 0000000..87c7b03 --- /dev/null +++ b/crates/eww/src/widgets/transform.rs @@ -0,0 +1,181 @@ +use anyhow::{anyhow, Result}; +use glib::{object_subclass, wrapper}; +use gtk::{prelude::*, subclass::prelude::*}; +use std::{cell::RefCell, str::FromStr}; +use yuck::value::NumWithUnit; + +use crate::error_handling_ctx; + +wrapper! { + pub struct Transform(ObjectSubclass) + @extends gtk::Bin, gtk::Container, gtk::Widget; +} + +pub struct TransformPriv { + rotate: RefCell, + translate_x: RefCell>, + translate_y: RefCell>, + scale_x: RefCell>, + scale_y: RefCell>, + content: RefCell>, +} + +// This should match the default values from the ParamSpecs +impl Default for TransformPriv { + fn default() -> Self { + TransformPriv { + rotate: RefCell::new(0.0), + translate_x: RefCell::new(None), + translate_y: RefCell::new(None), + scale_x: RefCell::new(None), + scale_y: RefCell::new(None), + content: RefCell::new(None), + } + } +} + +impl ObjectImpl for TransformPriv { + fn properties() -> &'static [glib::ParamSpec] { + use once_cell::sync::Lazy; + static PROPERTIES: Lazy> = Lazy::new(|| { + vec![ + glib::ParamSpec::new_double( + "rotate", + "Rotate", + "The Rotation", + f64::MIN, + f64::MAX, + 0f64, + glib::ParamFlags::READWRITE, + ), + glib::ParamSpec::new_string("translate-x", "Translate x", "The X Translation", None, glib::ParamFlags::READWRITE), + glib::ParamSpec::new_string("translate-y", "Translate y", "The Y Translation", None, glib::ParamFlags::READWRITE), + glib::ParamSpec::new_string("scale-x", "Scale x", "The amount to scale in x", None, glib::ParamFlags::READWRITE), + glib::ParamSpec::new_string("scale-y", "Scale y", "The amount to scale in y", None, glib::ParamFlags::READWRITE), + ] + }); + + PROPERTIES.as_ref() + } + + fn set_property(&self, obj: &Self::Type, _id: usize, value: &glib::Value, pspec: &glib::ParamSpec) { + match pspec.name() { + "rotate" => { + self.rotate.replace(value.get().unwrap()); + obj.queue_draw(); // Queue a draw call with the updated value + } + "translate-x" => { + self.translate_x.replace(value.get().unwrap()); + obj.queue_draw(); // Queue a draw call with the updated value + } + "translate-y" => { + self.translate_y.replace(value.get().unwrap()); + obj.queue_draw(); // Queue a draw call with the updated value + } + "scale-x" => { + self.scale_x.replace(value.get().unwrap()); + obj.queue_draw(); // Queue a draw call with the updated value + } + "scale-y" => { + self.scale_y.replace(value.get().unwrap()); + obj.queue_draw(); // Queue a draw call with the updated value + } + x => panic!("Tried to set inexistant property of Transform: {}", x,), + } + } + + fn property(&self, _obj: &Self::Type, _id: usize, pspec: &glib::ParamSpec) -> glib::Value { + match pspec.name() { + "rotate" => self.rotate.borrow().to_value(), + "translate_x" => self.translate_x.borrow().to_value(), + "translate_y" => self.translate_y.borrow().to_value(), + "scale_x" => self.scale_x.borrow().to_value(), + "scale_y" => self.scale_y.borrow().to_value(), + x => panic!("Tried to access inexistant property of Transform: {}", x,), + } + } +} + +#[object_subclass] +impl ObjectSubclass for TransformPriv { + type ParentType = gtk::Bin; + type Type = Transform; + + const NAME: &'static str = "Transform"; + + fn class_init(klass: &mut Self::Class) { + klass.set_css_name("transform"); + } +} + +impl Transform { + pub fn new() -> Self { + glib::Object::new::(&[]).expect("Failed to create Transform Widget") + } +} + +impl ContainerImpl for TransformPriv { + fn add(&self, container: &Self::Type, widget: >k::Widget) { + if let Some(content) = &*self.content.borrow() { + // TODO: Handle this error when populating children widgets instead + error_handling_ctx::print_error(anyhow!("Error, trying to add multiple children to a circular-progress widget")); + self.parent_remove(container, content); + } + self.parent_add(container, widget); + self.content.replace(Some(widget.clone())); + } +} + +impl BinImpl for TransformPriv {} +impl WidgetImpl for TransformPriv { + fn draw(&self, widget: &Self::Type, cr: &cairo::Context) -> Inhibit { + let res: Result<()> = try { + let rotate = *self.rotate.borrow(); + let total_width = widget.allocated_width() as f64; + let total_height = widget.allocated_height() as f64; + + cr.save()?; + + let translate_x = match &*self.translate_x.borrow() { + Some(tx) => NumWithUnit::from_str(&tx)?.pixels_relative_to(total_width as i32) as f64, + None => 0.0, + }; + + let translate_y = match &*self.translate_y.borrow() { + Some(ty) => NumWithUnit::from_str(&ty)?.pixels_relative_to(total_height as i32) as f64, + None => 0.0, + }; + + let scale_x = match &*self.scale_x.borrow() { + Some(sx) => NumWithUnit::from_str(&sx)?.perc_relative_to(total_width as i32) as f64 / 100.0, + None => 1.0, + }; + + let scale_y = match &*self.scale_y.borrow() { + Some(sy) => NumWithUnit::from_str(&sy)?.perc_relative_to(total_height as i32) as f64 / 100.0, + None => 1.0, + }; + + cr.scale(scale_x, scale_y); + cr.rotate(perc_to_rad(rotate)); + cr.translate(translate_x, translate_y); + + // Children widget + if let Some(child) = &*self.content.borrow() { + widget.propagate_draw(child, &cr); + } + + cr.restore()?; + }; + + if let Err(error) = res { + error_handling_ctx::print_error(error) + }; + + gtk::Inhibit(false) + } +} + +fn perc_to_rad(n: f64) -> f64 { + (n / 100f64) * 2f64 * std::f64::consts::PI +} diff --git a/crates/eww/src/widgets/widget_definitions.rs b/crates/eww/src/widgets/widget_definitions.rs index 27c60a0..54949e2 100644 --- a/crates/eww/src/widgets/widget_definitions.rs +++ b/crates/eww/src/widgets/widget_definitions.rs @@ -1,5 +1,5 @@ #![allow(clippy::option_map_unit_fn)] -use super::{build_widget::BuilderArgs, circular_progressbar::*, run_command}; +use super::{build_widget::BuilderArgs, circular_progressbar::*, transform::*, run_command}; use crate::{ def_widget, enum_parse, error::DiagError, @@ -60,6 +60,7 @@ pub(super) fn widget_use_to_gtk_widget(bargs: &mut BuilderArgs) -> Result build_gtk_event_box(bargs)?.upcast(), "circular-progress" => build_circular_progress_bar(bargs)?.upcast(), "graph" => build_graph(bargs)?.upcast(), + "transform" => build_transform(bargs)?.upcast(), "scale" => build_gtk_scale(bargs)?.upcast(), "progress" => build_gtk_progress(bargs)?.upcast(), "image" => build_gtk_image(bargs)?.upcast(), @@ -779,6 +780,26 @@ fn build_gtk_calendar(bargs: &mut BuilderArgs) -> Result { Ok(gtk_widget) } +/// @widget transform +/// @desc A widget that applies transformations to its content. They are applied in the following +/// order: rotate->translate->scale) +fn build_transform(bargs: &mut BuilderArgs) -> Result { + let w = Transform::new(); + def_widget!(bargs, _g, w, { + // @prop rotation - the percentage to rotate + prop(rotate: as_f64) { w.set_property("rotate", rotate)?; }, + // @prop translate-x - the amount to translate in the x direction (px or %) + prop(translate_x: as_string) { w.set_property("translate-x", translate_x)?; }, + // @prop translate-y - the amount to translate in the y direction (px or %) + prop(translate_y: as_string) { w.set_property("translate-y", translate_y)?; }, + // @prop scale_x - the amount to scale in the x direction (px or %) + prop(scale_x: as_string) { w.set_property("scale-x", scale_x)?; }, + // @prop scale_y - the amount to scale in the y direction (px or %) + prop(scale_y: as_string) { w.set_property("scale-y", scale_y)?; }, + }); + Ok(w) +} + /// @widget circular-progress /// @desc A widget that displays a circular progress bar fn build_circular_progress_bar(bargs: &mut BuilderArgs) -> Result { diff --git a/crates/yuck/src/value/coords.rs b/crates/yuck/src/value/coords.rs index cb59663..1c372bf 100644 --- a/crates/yuck/src/value/coords.rs +++ b/crates/yuck/src/value/coords.rs @@ -26,12 +26,19 @@ pub enum NumWithUnit { } impl NumWithUnit { - pub fn relative_to(&self, max: i32) -> i32 { + pub fn pixels_relative_to(&self, max: i32) -> i32 { match *self { NumWithUnit::Percent(n) => ((max as f64 / 100.0) * n as f64) as i32, NumWithUnit::Pixels(n) => n, } } + + pub fn perc_relative_to(&self, max: i32) -> i32 { + match *self { + NumWithUnit::Percent(n) => n, + NumWithUnit::Pixels(n) => ((n as f64 / max as f64) * 100.0) as i32, + } + } } impl FromStr for NumWithUnit { @@ -86,7 +93,7 @@ impl Coords { /// resolve the possibly relative coordinates relative to a given containers size pub fn relative_to(&self, width: i32, height: i32) -> (i32, i32) { - (self.x.relative_to(width), self.y.relative_to(height)) + (self.x.pixels_relative_to(width), self.y.pixels_relative_to(height)) } } diff --git a/out.gif b/out.gif deleted file mode 100644 index d71494a026a0ea5713093c37f0088e1809c30d5c..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 36688 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 ag42=Nq`Li$NhT(OSlCJw{r`TJ*8L9v_j0rV