use cairo::Context; use gtk::{gdk::RGBA, prelude::*, StyleContext}; use std::f64::consts::PI; #[derive(Clone, Debug)] pub struct Color { pub r: f64, pub g: f64, pub b: f64, } #[derive(Clone, Debug)] pub struct Wedge { pub start_angle: f64, pub end_angle: f64, pub color: Color, } pub struct PieChart { rotation: f64, wedges: Vec<Wedge>, center_x: f64, center_y: f64, radius: f64, border_color: RGBA, } impl PieChart { pub fn new(style_context: &StyleContext) -> Self { Self { rotation: 0., wedges: vec![], center_x: 0., center_y: 0., radius: 0., border_color: style_context.lookup_color("theme_fg_color").unwrap(), } } pub fn rotation(mut self, rotation: f64) -> Self { self.rotation = rotation; self } pub fn wedges(mut self, wedge: impl Iterator<Item = Wedge>) -> Self { let mut wedges: Vec<Wedge> = wedge.collect(); self.wedges.append(&mut wedges); self } pub fn center(mut self, center_x: f64, center_y: f64) -> Self { self.center_x = center_x; self.center_y = center_y; self } pub fn radius(mut self, radius: f64) -> Self { self.radius = radius; self } pub fn draw(self, context: &Context) { context.set_source_rgba(0., 0., 0., 0.); let _ = context.paint(); context.set_line_width(2.); self.wedges.iter().for_each( |Wedge { start_angle, end_angle, color, }| { context.move_to(self.center_x, self.center_y); context.set_source_rgb(color.r, color.g, color.b); context.arc( self.center_x, self.center_y, self.radius, start_angle + self.rotation, end_angle + self.rotation, ); let _ = context.fill(); }, ); context.set_source_rgb( self.border_color.red() as f64, self.border_color.green() as f64, self.border_color.blue() as f64, ); context.arc(self.center_x, self.center_y, self.radius, 0., 2. * PI); let _ = context.stroke(); } }