use gtk::{gdk, glib, prelude::*};
mod imp {
use adw::{prelude::*, subclass::prelude::*};
use gtk::{gdk, glib};
use std::{cell::RefCell, f64::consts::PI};
pub struct ColorCircle {
pub color: RefCell<gdk::RGBA>,
}
#[glib::object_subclass]
impl ObjectSubclass for ColorCircle {
const NAME: &'static str = "HealthColorCircle";
type ParentType = adw::Bin;
type Type = super::ColorCircle;
fn new() -> Self {
Self {
color: RefCell::new(
gdk::RGBA::builder()
.red(0.0)
.green(0.0)
.blue(0.0)
.alpha(0.0)
.build(),
),
}
}
}
impl ObjectImpl for ColorCircle {
fn properties() -> &'static [glib::ParamSpec] {
use once_cell::sync::Lazy;
static PROPERTIES: Lazy<Vec<glib::ParamSpec>> =
Lazy::new(|| vec![glib::ParamSpecBoxed::builder::<gdk::RGBA>("color").build()]);
PROPERTIES.as_ref()
}
fn set_property(&self, _id: usize, value: &glib::Value, pspec: &glib::ParamSpec) {
let obj = self.obj();
match pspec.name() {
"color" => {
self.color.replace(value.get().unwrap());
obj.queue_draw();
}
_ => unimplemented!(),
}
}
fn property(&self, _id: usize, pspec: &glib::ParamSpec) -> glib::Value {
match pspec.name() {
"color" => self.color.borrow().to_value(),
_ => unimplemented!(),
}
}
}
impl WidgetImpl for ColorCircle {
fn snapshot(&self, snapshot: >k::Snapshot) {
let widget = self.obj();
let cr = snapshot.append_cairo(>k::graphene::Rect::new(
0.0,
0.0,
widget.width() as f32,
widget.height() as f32,
));
let width = f64::from(widget.width());
let height = f64::from(widget.height());
let radius = height * 0.3;
cr.set_line_width(2.5);
GdkCairoContextExt::set_source_rgba(&cr, &self.color.borrow());
cr.arc(width / 2.0, height / 2.0, radius, 0.0, 2.0 * PI);
cr.stroke_preserve()
.expect("Couldn't stroke on Cairo Context");
cr.fill().expect("Couldn't fill on Cairo Context");
cr.stroke().expect("Couldn't stroke on Cairo Context");
cr.save().unwrap();
}
}
impl BinImpl for ColorCircle {}
}
glib::wrapper! {
pub struct ColorCircle(ObjectSubclass<imp::ColorCircle>)
@extends gtk::Widget, adw::Bin,
@implements gtk::Accessible, gtk::Buildable, gtk::ConstraintTarget;
}
impl ColorCircle {
pub fn color(&self) -> gdk::RGBA {
self.property("color")
}
pub fn new() -> Self {
glib::Object::new()
}
pub fn set_color(&self, color: gdk::RGBA) {
self.set_property("color", color);
}
}
#[cfg(test)]
mod test {
use super::ColorCircle;
use crate::utils::init_gtk;
#[gtk::test]
fn new() {
init_gtk();
ColorCircle::new();
}
}