use super::{ super::widget::{Widget as WidgetTrait, WidgetType}, super::Layer, color_mapper::ColorMapper, }; use femtovg::{renderer::OpenGl, Canvas, Color, Paint, Path}; use num_traits::*; #[derive(Debug)] pub struct ColorBar where V: num_traits::NumOps + PartialOrd + FromPrimitive + AsPrimitive, T: ColorMapper, { color_mapper: T, padding: [f32; 4], width: f32, height: f32, margin: [i32; 4], color_list: Vec, phantom: std::marker::PhantomData, } impl ColorBar where V: num_traits::NumOps + PartialOrd + FromPrimitive + AsPrimitive, T: ColorMapper, { pub fn new(color_mapper: T, padding: [f32; 4], size: (f32, f32), margin: [i32; 4]) -> Self { let (l, ll) = color_mapper.min_max(); let invalid = color_mapper.invalid(); let colors = color_mapper.map_min_to_max(); Self { color_list: colors, color_mapper, padding, width: size.0, height: size.1, margin, phantom: std::marker::PhantomData, } } } impl WidgetTrait for ColorBar where V: num_traits::NumOps + PartialOrd + FromPrimitive + AsPrimitive + Send + Sync, T: ColorMapper + 'static, { fn cairo_render(&self, canvas: >k::cairo::Context, w: f32, h: f32) { let bar_width = 10; let bar_height = h - self.padding[0] - self.padding[2]; let (x, y) = (self.padding[3], self.padding[0]); let b_h = bar_height / self.color_list.len() as f32; for ((i, color), label) in self .color_list .iter() .enumerate() .zip(self.color_mapper.labels()) { let y = y + i as f32 * b_h; canvas.set_source_rgba( color.r as f64, color.g as f64, color.b as f64, color.a as f64, ); canvas.rectangle(x as f64, y as f64, bar_width as f64, b_h as f64); canvas.fill(); let extents = canvas.text_extents(&label).unwrap(); canvas.move_to( (x + bar_width as f32 + 5.0) as f64, y as f64 + extents.height() / 2.0 as f64, ); canvas.set_source_rgba(1.0, 1.0, 1.0, 1.0); canvas.show_text(&label); } } fn location(&self) -> (gtk::Align, gtk::Align) { (gtk::Align::End, gtk::Align::End) } fn size(&self) -> (f32, f32) { (self.width, self.height) } fn widget_type(&self) -> WidgetType { WidgetType::Cairo } fn margin(&self) -> [i32; 4] { self.margin } fn padding(&self) -> [i32; 4] { [10, 10, 10, 10] } }