feat: add support for circular-progress widget
This commit is contained in:
@@ -22,6 +22,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/).
|
||||
- `focusable` property to all widget.
|
||||
- `widget_name` property to all widget.
|
||||
- `lifetime` flag for update command.
|
||||
- `circular-progress` widget back.
|
||||
|
||||
### Fixed
|
||||
|
||||
|
||||
@@ -350,7 +350,12 @@ impl<B: DisplayBackend> App<B> {
|
||||
let output = format!("{:#?}", &self.pl_handler_store.read().unwrap());
|
||||
sender.send_success(output)?
|
||||
}
|
||||
DaemonCommand::TriggerUpdateUI { inject_vars, should_preserve_state, lifetime, sender } => {
|
||||
DaemonCommand::TriggerUpdateUI {
|
||||
inject_vars,
|
||||
should_preserve_state,
|
||||
lifetime,
|
||||
sender,
|
||||
} => {
|
||||
match self.trigger_ui_update_with(inject_vars, should_preserve_state, lifetime) {
|
||||
Ok(_) => sender.send_success(String::new())?,
|
||||
Err(e) => sender.send_failure(e.to_string())?,
|
||||
@@ -406,9 +411,7 @@ impl<B: DisplayBackend> App<B> {
|
||||
|
||||
// let scope_index = ewwii_window.scope_index;
|
||||
ewwii_window.close();
|
||||
println!("VAR: {:#?}", self.clear_pl_onclose);
|
||||
if let Some(var_name) = self.clear_pl_onclose.remove(instance_id) {
|
||||
println!("NAME: {}", var_name);
|
||||
self.pl_handler_store.write().unwrap().remove(&var_name);
|
||||
}
|
||||
|
||||
@@ -736,7 +739,7 @@ impl<B: DisplayBackend> App<B> {
|
||||
&mut self,
|
||||
inject_vars: Option<HashMap<String, String>>,
|
||||
should_preserve_state: bool,
|
||||
lifetime: Option<String>
|
||||
lifetime: Option<String>,
|
||||
) -> Result<()> {
|
||||
let compiled_ast = self.ewwii_config.get_owned_compiled_ast();
|
||||
let config_path = self.paths.get_rhai_path();
|
||||
@@ -856,36 +859,34 @@ impl<B: DisplayBackend> App<B> {
|
||||
let cp = self.config_parser.clone();
|
||||
let wgs = self.widget_reg_store.clone();
|
||||
|
||||
let handle_request = move |req: PluginRequest| {
|
||||
match req {
|
||||
PluginRequest::RhaiEngineAct(func) => {
|
||||
cp.borrow_mut().action_with_engine(func);
|
||||
let handle_request = move |req: PluginRequest| match req {
|
||||
PluginRequest::RhaiEngineAct(func) => {
|
||||
cp.borrow_mut().action_with_engine(func);
|
||||
}
|
||||
PluginRequest::RegisterFunc((name, func)) => {
|
||||
if let Err(e) = shared_utils::slib_store::register_functions(name, func) {
|
||||
log::error!("Error registering function: {}", e);
|
||||
}
|
||||
PluginRequest::RegisterFunc((name, func)) => {
|
||||
if let Err(e) = shared_utils::slib_store::register_functions(name, func) {
|
||||
log::error!("Error registering function: {}", e);
|
||||
}
|
||||
}
|
||||
PluginRequest::ListWidgetIds(res_tx) => {
|
||||
let wgs_guard = wgs.lock().unwrap();
|
||||
if let Some(wgs_brw) = wgs_guard.as_ref() {
|
||||
let output: Vec<u64> = wgs_brw.widgets.keys().cloned().collect();
|
||||
let _ = res_tx.send(output);
|
||||
}
|
||||
PluginRequest::ListWidgetIds(res_tx) => {
|
||||
let wgs_guard = wgs.lock().unwrap();
|
||||
if let Some(wgs_brw) = wgs_guard.as_ref() {
|
||||
let output: Vec<u64> = wgs_brw.widgets.keys().cloned().collect();
|
||||
let _ = res_tx.send(output);
|
||||
}
|
||||
}
|
||||
PluginRequest::WidgetRegistryAct(func) => {
|
||||
let mut wgs_guard = wgs.lock().unwrap();
|
||||
if let Some(ref mut registry) = *wgs_guard {
|
||||
let repr_map: HashMap<u64, &mut gtk4::Widget> = registry
|
||||
.widgets
|
||||
.iter_mut()
|
||||
.map(|(id, entry)| (*id, &mut entry.widget))
|
||||
.collect();
|
||||
}
|
||||
PluginRequest::WidgetRegistryAct(func) => {
|
||||
let mut wgs_guard = wgs.lock().unwrap();
|
||||
if let Some(ref mut registry) = *wgs_guard {
|
||||
let repr_map: HashMap<u64, &mut gtk4::Widget> = registry
|
||||
.widgets
|
||||
.iter_mut()
|
||||
.map(|(id, entry)| (*id, &mut entry.widget))
|
||||
.collect();
|
||||
|
||||
func(&mut ewwii_plugin_api::widget_backend::WidgetRegistryRepr {
|
||||
widgets: repr_map,
|
||||
});
|
||||
}
|
||||
func(&mut ewwii_plugin_api::widget_backend::WidgetRegistryRepr {
|
||||
widgets: repr_map,
|
||||
});
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
@@ -50,9 +50,9 @@ fn build_gtk_widget_from_node(
|
||||
WidgetNode::ToolTip { props, children } => {
|
||||
build_tooltip(props, children, widget_reg)?.upcast()
|
||||
}
|
||||
// WidgetNode::CircularProgress { props } => {
|
||||
// build_circular_progress_bar(props, widget_reg)?.upcast()
|
||||
// }
|
||||
WidgetNode::CircularProgress { props } => {
|
||||
build_circular_progress_bar(props, widget_reg)?.upcast()
|
||||
}
|
||||
// WidgetNode::Graph { props } => build_graph(props, widget_reg)?.upcast(),
|
||||
// WidgetNode::Transform { props } => build_transform(props, widget_reg)?.upcast(),
|
||||
WidgetNode::Slider { props } => build_gtk_scale(props, widget_reg)?.upcast(),
|
||||
|
||||
@@ -1,273 +1,199 @@
|
||||
// use anyhow::{anyhow, Result};
|
||||
// use gtk4::glib::{self, object_subclass, prelude::*, wrapper, Properties};
|
||||
// use gtk4::{cairo, gdk, prelude::*, subclass::prelude::*};
|
||||
// use std::cell::RefCell;
|
||||
use glib::Object;
|
||||
use gtk4::glib;
|
||||
use gtk4::prelude::*;
|
||||
use gtk4::subclass::prelude::*;
|
||||
use gtk4::{cairo, gdk, graphene};
|
||||
use std::cell::Cell;
|
||||
|
||||
// use crate::error_handling_ctx;
|
||||
mod imp {
|
||||
use super::*;
|
||||
|
||||
// wrapper! {
|
||||
// pub struct CircProg(ObjectSubclass<CircProgPriv>)
|
||||
// @extends gtk4::Bin, gtk4::Container, gtk4::Widget;
|
||||
// }
|
||||
pub struct CircProg {
|
||||
pub value: Cell<f64>,
|
||||
pub start_at: Cell<f64>,
|
||||
pub thickness: Cell<f64>,
|
||||
pub clockwise: Cell<bool>,
|
||||
pub fg_color: Cell<gdk::RGBA>,
|
||||
pub bg_color: Cell<gdk::RGBA>,
|
||||
}
|
||||
|
||||
// #[derive(Properties)]
|
||||
// #[properties(wrapper_type = CircProg)]
|
||||
// pub struct CircProgPriv {
|
||||
// #[property(
|
||||
// get,
|
||||
// set,
|
||||
// nick = "Starting at",
|
||||
// blurb = "Starting at",
|
||||
// minimum = 0f64,
|
||||
// maximum = 100f64,
|
||||
// default = 0f64
|
||||
// )]
|
||||
// start_at: RefCell<f64>,
|
||||
impl Default for CircProg {
|
||||
fn default() -> Self {
|
||||
Self {
|
||||
value: Cell::new(0.0),
|
||||
start_at: Cell::new(0.0),
|
||||
thickness: Cell::new(8.0),
|
||||
clockwise: Cell::new(true),
|
||||
fg_color: Cell::new(gdk::RGBA::new(1.0, 0.0, 0.0, 1.0)),
|
||||
bg_color: Cell::new(gdk::RGBA::new(0.0, 0.0, 0.0, 0.1)),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// #[property(
|
||||
// get,
|
||||
// set,
|
||||
// nick = "Value",
|
||||
// blurb = "The value",
|
||||
// minimum = 0f64,
|
||||
// maximum = 100f64,
|
||||
// default = 0f64
|
||||
// )]
|
||||
// value: RefCell<f64>,
|
||||
#[glib::object_subclass]
|
||||
impl ObjectSubclass for CircProg {
|
||||
const NAME: &'static str = "CircProg";
|
||||
type Type = super::CircProg;
|
||||
type ParentType = gtk4::Widget;
|
||||
}
|
||||
|
||||
// #[property(
|
||||
// get,
|
||||
// set,
|
||||
// nick = "Thickness",
|
||||
// blurb = "Thickness",
|
||||
// minimum = 0f64,
|
||||
// maximum = 100f64,
|
||||
// default = 1f64
|
||||
// )]
|
||||
// thickness: RefCell<f64>,
|
||||
impl ObjectImpl for CircProg {
|
||||
fn constructed(&self) {
|
||||
self.parent_constructed();
|
||||
|
||||
// #[property(get, set, nick = "Clockwise", blurb = "Clockwise", default = true)]
|
||||
// clockwise: RefCell<bool>,
|
||||
let obj = self.obj();
|
||||
obj.add_css_class("circular-progress");
|
||||
}
|
||||
|
||||
// content: RefCell<Option<gtk4::Widget>>,
|
||||
// }
|
||||
fn properties() -> &'static [glib::ParamSpec] {
|
||||
use once_cell::sync::Lazy;
|
||||
static PROPERTIES: Lazy<Vec<glib::ParamSpec>> = Lazy::new(|| {
|
||||
vec![
|
||||
glib::ParamSpecDouble::builder("value")
|
||||
.minimum(0.0)
|
||||
.maximum(100.0)
|
||||
.default_value(0.0)
|
||||
.build(),
|
||||
glib::ParamSpecDouble::builder("start-at")
|
||||
.minimum(0.0)
|
||||
.maximum(100.0)
|
||||
.default_value(0.0)
|
||||
.build(),
|
||||
glib::ParamSpecDouble::builder("thickness")
|
||||
.minimum(1.0)
|
||||
.maximum(50.0)
|
||||
.default_value(8.0)
|
||||
.build(),
|
||||
glib::ParamSpecBoolean::builder("clockwise").default_value(true).build(),
|
||||
glib::ParamSpecBoxed::builder::<gdk::RGBA>("fg-color").build(),
|
||||
glib::ParamSpecBoxed::builder::<gdk::RGBA>("bg-color").build(),
|
||||
]
|
||||
});
|
||||
PROPERTIES.as_ref()
|
||||
}
|
||||
|
||||
// // This should match the default values from the ParamSpecs
|
||||
// impl Default for CircProgPriv {
|
||||
// fn default() -> Self {
|
||||
// CircProgPriv {
|
||||
// start_at: RefCell::new(0.0),
|
||||
// value: RefCell::new(0.0),
|
||||
// thickness: RefCell::new(1.0),
|
||||
// clockwise: RefCell::new(true),
|
||||
// content: RefCell::new(None),
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
fn set_property(&self, _: usize, value: &glib::Value, pspec: &glib::ParamSpec) {
|
||||
match pspec.name() {
|
||||
"value" => self.value.set(value.get().unwrap()),
|
||||
"start-at" => self.start_at.set(value.get().unwrap()),
|
||||
"thickness" => self.thickness.set(value.get().unwrap()),
|
||||
"clockwise" => self.clockwise.set(value.get().unwrap()),
|
||||
"fg-color" => self.fg_color.set(value.get().unwrap()),
|
||||
"bg-color" => self.bg_color.set(value.get().unwrap()),
|
||||
x => panic!("Tried to set inexistant property of CircProg: {}", x,),
|
||||
}
|
||||
self.obj().queue_draw();
|
||||
}
|
||||
|
||||
// impl ObjectImpl for CircProgPriv {
|
||||
// fn properties() -> &'static [glib::ParamSpec] {
|
||||
// Self::derived_properties()
|
||||
// }
|
||||
fn property(&self, _: usize, pspec: &glib::ParamSpec) -> glib::Value {
|
||||
match pspec.name() {
|
||||
"value" => self.value.get().to_value(),
|
||||
"start-at" => self.start_at.get().to_value(),
|
||||
"thickness" => self.thickness.get().to_value(),
|
||||
"clockwise" => self.clockwise.get().to_value(),
|
||||
"fg-color" => self.fg_color.get().to_value(),
|
||||
"bg-color" => self.bg_color.get().to_value(),
|
||||
x => panic!("Tried to get inexistant property of CircProg: {}", x,),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// fn set_property(&self, _id: usize, value: &glib::Value, pspec: &glib::ParamSpec) {
|
||||
// match pspec.name() {
|
||||
// "value" => {
|
||||
// self.value.replace(value.get().unwrap());
|
||||
// self.obj().queue_draw(); // Queue a draw call with the updated value
|
||||
// }
|
||||
// "thickness" => {
|
||||
// self.thickness.replace(value.get().unwrap());
|
||||
// }
|
||||
// "start-at" => {
|
||||
// self.start_at.replace(value.get().unwrap());
|
||||
// }
|
||||
// "clockwise" => {
|
||||
// self.clockwise.replace(value.get().unwrap());
|
||||
// }
|
||||
// x => panic!("Tried to set inexistant property of CircProg: {}", x,),
|
||||
// }
|
||||
// }
|
||||
impl WidgetImpl for CircProg {
|
||||
fn measure(&self, _orientation: gtk4::Orientation, _for_size: i32) -> (i32, i32, i32, i32) {
|
||||
let min_size = 32;
|
||||
let natural_size = 64;
|
||||
(min_size, natural_size, -1, -1)
|
||||
}
|
||||
|
||||
// fn property(&self, id: usize, pspec: &glib::ParamSpec) -> glib::Value {
|
||||
// self.derived_property(id, pspec)
|
||||
// }
|
||||
// }
|
||||
fn snapshot(&self, snapshot: >k4::Snapshot) {
|
||||
let value = self.value.get();
|
||||
let start_at = self.start_at.get();
|
||||
let thickness = self.thickness.get();
|
||||
let clockwise = self.clockwise.get();
|
||||
let fg_color = self.fg_color.get();
|
||||
let bg_color = self.bg_color.get();
|
||||
|
||||
// #[object_subclass]
|
||||
// impl ObjectSubclass for CircProgPriv {
|
||||
// type ParentType = gtk4::Bin;
|
||||
// type Type = CircProg;
|
||||
let margin_start = self.obj().margin_start() as f64;
|
||||
let margin_end = self.obj().margin_end() as f64;
|
||||
let margin_top = self.obj().margin_top() as f64;
|
||||
let margin_bottom = self.obj().margin_bottom() as f64;
|
||||
// Padding is not supported yet
|
||||
|
||||
// const NAME: &'static str = "CircProg";
|
||||
let (start_angle, end_angle) = if clockwise {
|
||||
(0.0, perc_to_rad(value))
|
||||
} else {
|
||||
(perc_to_rad(100.0 - value), 2f64 * std::f64::consts::PI)
|
||||
};
|
||||
|
||||
// fn class_init(klass: &mut Self::Class) {
|
||||
// klass.set_css_name("circular-progress");
|
||||
// }
|
||||
// }
|
||||
let total_width = self.obj().allocated_width() as f64;
|
||||
let total_height = self.obj().allocated_height() as f64;
|
||||
let center = (total_width / 2.0, total_height / 2.0);
|
||||
|
||||
// impl Default for CircProg {
|
||||
// fn default() -> Self {
|
||||
// Self::new()
|
||||
// }
|
||||
// }
|
||||
let circle_width = total_width - margin_start - margin_end;
|
||||
let circle_height = total_height - margin_top - margin_bottom;
|
||||
let outer_ring = f64::min(circle_width, circle_height) / 2.0;
|
||||
let inner_ring = (f64::min(circle_width, circle_height) / 2.0) - thickness;
|
||||
|
||||
// impl CircProg {
|
||||
// pub fn new() -> Self {
|
||||
// glib::Object::new::<Self>()
|
||||
// }
|
||||
// }
|
||||
// Snapshot Cairo node
|
||||
let cr = snapshot.append_cairo(&graphene::Rect::new(
|
||||
0.0_f32,
|
||||
0.0_f32,
|
||||
total_width as f32,
|
||||
total_height as f32,
|
||||
));
|
||||
|
||||
// impl ContainerImpl for CircProgPriv {
|
||||
// fn add(&self, widget: >k4::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(content);
|
||||
// }
|
||||
// self.parent_add(widget);
|
||||
// self.content.replace(Some(widget.clone()));
|
||||
// }
|
||||
// }
|
||||
cr.save().unwrap();
|
||||
|
||||
// fn calc_widget_lowest_preferred_dimension(widget: >k4::Widget) -> (i32, i32) {
|
||||
// let preferred_width = widget.preferred_width();
|
||||
// let preferred_height = widget.preferred_height();
|
||||
// let min_lowest = i32::min(preferred_width.0, preferred_height.0);
|
||||
// let natural_lowest = i32::min(preferred_width.1, preferred_height.1);
|
||||
// (min_lowest, natural_lowest)
|
||||
// }
|
||||
// Centering
|
||||
cr.translate(center.0, center.1);
|
||||
cr.rotate(perc_to_rad(start_at));
|
||||
cr.translate(-center.0, -center.1);
|
||||
|
||||
// impl BinImpl for CircProgPriv {}
|
||||
// Background Ring
|
||||
cr.move_to(center.0, center.1);
|
||||
cr.arc(center.0, center.1, outer_ring, 0.0, perc_to_rad(100.0));
|
||||
cr.set_source_rgba(
|
||||
bg_color.red().into(),
|
||||
bg_color.green().into(),
|
||||
bg_color.blue().into(),
|
||||
bg_color.alpha().into(),
|
||||
);
|
||||
cr.move_to(center.0, center.1);
|
||||
cr.arc(center.0, center.1, inner_ring, 0.0, perc_to_rad(100.0));
|
||||
cr.set_fill_rule(cairo::FillRule::EvenOdd); // Substract one circle from the other
|
||||
cr.fill().unwrap();
|
||||
|
||||
// impl WidgetImpl for CircProgPriv {
|
||||
// // We overwrite preferred_* so that overflowing content from the children gets cropped
|
||||
// // We return min(child_width, child_height)
|
||||
// fn preferred_width(&self) -> (i32, i32) {
|
||||
// let styles = self.obj().style_context();
|
||||
// let margin = styles.margin(gtk4::StateFlags::NORMAL);
|
||||
// Foreground Ring
|
||||
cr.move_to(center.0, center.1);
|
||||
cr.arc(center.0, center.1, outer_ring, start_angle, end_angle);
|
||||
cr.set_source_rgba(
|
||||
fg_color.red().into(),
|
||||
fg_color.green().into(),
|
||||
fg_color.blue().into(),
|
||||
fg_color.alpha().into(),
|
||||
);
|
||||
cr.move_to(center.0, center.1);
|
||||
cr.arc(center.0, center.1, inner_ring, start_angle, end_angle);
|
||||
cr.set_fill_rule(cairo::FillRule::EvenOdd); // Substract one circle from the other
|
||||
cr.fill().unwrap();
|
||||
|
||||
// if let Some(child) = &*self.content.borrow() {
|
||||
// let (min_child, natural_child) = calc_widget_lowest_preferred_dimension(child);
|
||||
// (
|
||||
// min_child + margin.right as i32 + margin.left as i32,
|
||||
// natural_child + margin.right as i32 + margin.left as i32,
|
||||
// )
|
||||
// } else {
|
||||
// let empty_width =
|
||||
// (2 * *self.thickness.borrow() as i32) + margin.right as i32 + margin.left as i32;
|
||||
// (empty_width, empty_width)
|
||||
// }
|
||||
// }
|
||||
cr.restore().unwrap();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// fn preferred_width_for_height(&self, _height: i32) -> (i32, i32) {
|
||||
// self.preferred_width()
|
||||
// }
|
||||
glib::wrapper! {
|
||||
pub struct CircProg(ObjectSubclass<imp::CircProg>)
|
||||
@extends gtk4::Widget,
|
||||
@implements gtk4::Accessible, gtk4::Actionable, gtk4::Buildable, gtk4::ConstraintTarget;
|
||||
}
|
||||
|
||||
// fn preferred_height(&self) -> (i32, i32) {
|
||||
// let styles = self.obj().style_context();
|
||||
// let margin = styles.margin(gtk4::StateFlags::NORMAL);
|
||||
impl CircProg {
|
||||
pub fn new() -> Self {
|
||||
Object::builder().build()
|
||||
}
|
||||
}
|
||||
|
||||
// if let Some(child) = &*self.content.borrow() {
|
||||
// let (min_child, natural_child) = calc_widget_lowest_preferred_dimension(child);
|
||||
// (
|
||||
// min_child + margin.bottom as i32 + margin.top as i32,
|
||||
// natural_child + margin.bottom as i32 + margin.top as i32,
|
||||
// )
|
||||
// } else {
|
||||
// let empty_height =
|
||||
// (2 * *self.thickness.borrow() as i32) + margin.right as i32 + margin.left as i32;
|
||||
// (empty_height, empty_height)
|
||||
// }
|
||||
// }
|
||||
|
||||
// fn preferred_height_for_width(&self, _width: i32) -> (i32, i32) {
|
||||
// self.preferred_height()
|
||||
// }
|
||||
|
||||
// fn draw(&self, cr: &cairo::Context) -> glib::Propagation {
|
||||
// let res: Result<()> = (|| {
|
||||
// let value = *self.value.borrow();
|
||||
// let start_at = *self.start_at.borrow();
|
||||
// let thickness = *self.thickness.borrow();
|
||||
// let clockwise = *self.clockwise.borrow();
|
||||
|
||||
// let styles = self.obj().style_context();
|
||||
// let margin = styles.margin(gtk4::StateFlags::NORMAL);
|
||||
// // Padding is not supported yet
|
||||
// let fg_color: gdk::RGBA = styles.color(gtk4::StateFlags::NORMAL);
|
||||
// let bg_color: gdk::RGBA = styles
|
||||
// .style_property_for_state("background-color", gtk4::StateFlags::NORMAL)
|
||||
// .get()?;
|
||||
// let (start_angle, end_angle) = if clockwise {
|
||||
// (0.0, perc_to_rad(value))
|
||||
// } else {
|
||||
// (perc_to_rad(100.0 - value), 2f64 * std::f64::consts::PI)
|
||||
// };
|
||||
|
||||
// let total_width = self.obj().allocated_width() as f64;
|
||||
// let total_height = self.obj().allocated_height() as f64;
|
||||
// let center = (total_width / 2.0, total_height / 2.0);
|
||||
|
||||
// let circle_width = total_width - margin.left as f64 - margin.right as f64;
|
||||
// let circle_height = total_height - margin.top as f64 - margin.bottom as f64;
|
||||
// let outer_ring = f64::min(circle_width, circle_height) / 2.0;
|
||||
// let inner_ring = (f64::min(circle_width, circle_height) / 2.0) - thickness;
|
||||
|
||||
// cr.save()?;
|
||||
|
||||
// // Centering
|
||||
// cr.translate(center.0, center.1);
|
||||
// cr.rotate(perc_to_rad(start_at));
|
||||
// cr.translate(-center.0, -center.1);
|
||||
|
||||
// // Background Ring
|
||||
// cr.move_to(center.0, center.1);
|
||||
// cr.arc(center.0, center.1, outer_ring, 0.0, perc_to_rad(100.0));
|
||||
// cr.set_source_rgba(bg_color.red(), bg_color.green(), bg_color.blue(), bg_color.alpha());
|
||||
// cr.move_to(center.0, center.1);
|
||||
// cr.arc(center.0, center.1, inner_ring, 0.0, perc_to_rad(100.0));
|
||||
// cr.set_fill_rule(cairo::FillRule::EvenOdd); // Substract one circle from the other
|
||||
// cr.fill()?;
|
||||
|
||||
// // Foreground Ring
|
||||
// cr.move_to(center.0, center.1);
|
||||
// cr.arc(center.0, center.1, outer_ring, start_angle, end_angle);
|
||||
// cr.set_source_rgba(fg_color.red(), fg_color.green(), fg_color.blue(), fg_color.alpha());
|
||||
// cr.move_to(center.0, center.1);
|
||||
// cr.arc(center.0, center.1, inner_ring, start_angle, end_angle);
|
||||
// cr.set_fill_rule(cairo::FillRule::EvenOdd); // Substract one circle from the other
|
||||
// cr.fill()?;
|
||||
// cr.restore()?;
|
||||
|
||||
// // Draw the children widget, clipping it to the inside
|
||||
// if let Some(child) = &*self.content.borrow() {
|
||||
// cr.save()?;
|
||||
|
||||
// // Center circular clip
|
||||
// cr.arc(center.0, center.1, inner_ring + 1.0, 0.0, perc_to_rad(100.0));
|
||||
// cr.set_source_rgba(bg_color.red(), 0.0, 0.0, bg_color.alpha());
|
||||
// cr.clip();
|
||||
|
||||
// // Children widget
|
||||
// self.obj().propagate_draw(child, cr);
|
||||
|
||||
// cr.reset_clip();
|
||||
// cr.restore()?;
|
||||
// }
|
||||
// Ok(())
|
||||
// })();
|
||||
|
||||
// if let Err(error) = res {
|
||||
// error_handling_ctx::print_error(error)
|
||||
// };
|
||||
|
||||
// glib::Propagation::Proceed
|
||||
// }
|
||||
// }
|
||||
|
||||
// fn perc_to_rad(n: f64) -> f64 {
|
||||
// (n / 100f64) * 2f64 * std::f64::consts::PI
|
||||
// }
|
||||
fn perc_to_rad(n: f64) -> f64 {
|
||||
(n / 100f64) * 2f64 * std::f64::consts::PI
|
||||
}
|
||||
|
||||
@@ -26,6 +26,7 @@ use std::{
|
||||
|
||||
// custom widgets
|
||||
// use crate::widgets::{circular_progressbar::CircProg, transform::Transform};
|
||||
use crate::widgets::circular_progressbar::CircProg;
|
||||
|
||||
/// Connect a gtk signal handler inside of this macro to ensure that when the same code gets run multiple times,
|
||||
/// the previously connected singal handler first gets disconnected.
|
||||
@@ -798,7 +799,7 @@ pub(crate) fn build_gtk_flowbox(
|
||||
|
||||
if let Ok(default_select) = get_i32_prop(&props, "default_select", None) {
|
||||
if let Some(child) = gtk_widget.child_at_index(default_select) {
|
||||
gtk_widget.select_child(&child);
|
||||
gtk_widget.select_child(&child);
|
||||
child.grab_focus();
|
||||
} else {
|
||||
log::error!("Failed to get child at index {} from FlowBox", default_select);
|
||||
@@ -988,54 +989,66 @@ pub(super) fn build_gtk_stack(
|
||||
// Ok(widget)
|
||||
// }
|
||||
|
||||
// pub(super) fn build_circular_progress_bar(
|
||||
// props: &Map,
|
||||
// widget_registry: &mut WidgetRegistry,
|
||||
// ) -> Result<CircProg> {
|
||||
// let widget = CircProg::new();
|
||||
pub(super) fn build_circular_progress_bar(
|
||||
props: &Map,
|
||||
widget_registry: &mut WidgetRegistry,
|
||||
) -> Result<CircProg> {
|
||||
let widget = CircProg::new();
|
||||
|
||||
// let apply_props = |props: &Map, widget: &CircProg| -> Result<()> {
|
||||
// if let Ok(value) = get_f64_prop(&props, "value", None) {
|
||||
// widget.set_property("value", value.clamp(0.0, 100.0));
|
||||
// }
|
||||
let apply_props = |props: &Map, widget: &CircProg| -> Result<()> {
|
||||
if let Ok(value) = get_f64_prop(&props, "value", None) {
|
||||
widget.set_property("value", value.clamp(0.0, 100.0));
|
||||
}
|
||||
|
||||
// if let Ok(start_at) = get_f64_prop(&props, "start_at", None) {
|
||||
// widget.set_property("start-at", start_at.clamp(0.0, 100.0));
|
||||
// }
|
||||
if let Ok(start_at) = get_f64_prop(&props, "start_at", None) {
|
||||
widget.set_property("start-at", start_at.clamp(0.0, 100.0));
|
||||
}
|
||||
|
||||
// if let Ok(thickness) = get_f64_prop(&props, "thickness", None) {
|
||||
// widget.set_property("thickness", thickness);
|
||||
// }
|
||||
if let Ok(thickness) = get_f64_prop(&props, "thickness", None) {
|
||||
widget.set_property("thickness", thickness);
|
||||
}
|
||||
|
||||
// if let Ok(clockwise) = get_f64_prop(&props, "clockwise", None) {
|
||||
// widget.set_property("clockwise", clockwise);
|
||||
// }
|
||||
if let Ok(clockwise) = get_f64_prop(&props, "clockwise", None) {
|
||||
widget.set_property("clockwise", clockwise);
|
||||
}
|
||||
|
||||
// Ok(())
|
||||
// };
|
||||
if let Ok(fg_color_str) = get_string_prop(&props, "fg_color", None) {
|
||||
if let Ok(rgba) = gdk::RGBA::parse(fg_color_str) {
|
||||
widget.set_property("fg-color", rgba);
|
||||
}
|
||||
}
|
||||
|
||||
// apply_props(&props, &widget)?;
|
||||
if let Ok(bg_color_str) = get_string_prop(&props, "bg_color", None) {
|
||||
if let Ok(rgba) = gdk::RGBA::parse(bg_color_str) {
|
||||
widget.set_property("bg-color", rgba);
|
||||
}
|
||||
}
|
||||
|
||||
// let widget_clone = widget.clone();
|
||||
// let update_fn: UpdateFn = Box::new(move |props: &Map| {
|
||||
// let _ = apply_props(props, &widget_clone);
|
||||
Ok(())
|
||||
};
|
||||
|
||||
// // now re-apply generic widget attrs
|
||||
// if let Err(err) =
|
||||
// resolve_rhai_widget_attrs(&widget_clone.clone().upcast::<gtk4::Widget>(), &props)
|
||||
// {
|
||||
// eprintln!("Failed to update widget attrs: {:?}", err);
|
||||
// }
|
||||
// });
|
||||
apply_props(&props, &widget)?;
|
||||
|
||||
// let id = hash_props_and_type(&props, "CircularProgressBar");
|
||||
let widget_clone = widget.clone();
|
||||
let update_fn: UpdateFn = Box::new(move |props: &Map| {
|
||||
let _ = apply_props(props, &widget_clone);
|
||||
|
||||
// widget_registry.widgets.insert(id, WidgetEntry { update_fn, widget: widget.clone().upcast() });
|
||||
// now re-apply generic widget attrs
|
||||
if let Err(err) =
|
||||
resolve_rhai_widget_attrs(&widget_clone.clone().upcast::<gtk4::Widget>(), &props)
|
||||
{
|
||||
eprintln!("Failed to update widget attrs: {:?}", err);
|
||||
}
|
||||
});
|
||||
|
||||
// resolve_rhai_widget_attrs(&widget.clone().upcast::<gtk4::Widget>(), &props)?;
|
||||
let id = hash_props_and_type(&props, "CircularProgressBar");
|
||||
|
||||
// Ok(widget)
|
||||
// }
|
||||
widget_registry.widgets.insert(id, WidgetEntry { update_fn, widget: widget.clone().upcast() });
|
||||
|
||||
resolve_rhai_widget_attrs(&widget.clone().upcast::<gtk4::Widget>(), &props)?;
|
||||
|
||||
Ok(widget)
|
||||
}
|
||||
|
||||
// pub(super) fn build_graph(
|
||||
// props: &Map,
|
||||
@@ -2357,12 +2370,16 @@ pub(super) fn resolve_rhai_widget_attrs(gtk_widget: >k4::Widget, props: &Map)
|
||||
(Some(w), Some(h)) => gtk_widget.set_size_request(w, h),
|
||||
(Some(w), None) => {
|
||||
let h = gtk_widget.allocated_height();
|
||||
if h > 0 { gtk_widget.set_size_request(w, h); }
|
||||
},
|
||||
if h > 0 {
|
||||
gtk_widget.set_size_request(w, h);
|
||||
}
|
||||
}
|
||||
(None, Some(h)) => {
|
||||
let w = gtk_widget.allocated_width();
|
||||
if w > 0 { gtk_widget.set_size_request(w, h); }
|
||||
},
|
||||
if w > 0 {
|
||||
gtk_widget.set_size_request(w, h);
|
||||
}
|
||||
}
|
||||
(None, None) => {}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user