radar-g/src/widgets/render/predefined/widgets.rs
2024-03-16 12:57:30 +08:00

104 lines
2.7 KiB
Rust

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<V, T>
where
V: num_traits::NumOps + PartialOrd + FromPrimitive + AsPrimitive<f64>,
T: ColorMapper<V>,
{
color_mapper: T,
padding: [f32; 4],
width: f32,
height: f32,
margin: [i32; 4],
color_list: Vec<femtovg::Color>,
phantom: std::marker::PhantomData<V>,
}
impl<V, T> ColorBar<V, T>
where
V: num_traits::NumOps + PartialOrd + FromPrimitive + AsPrimitive<f64>,
T: ColorMapper<V>,
{
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<V, T> WidgetTrait for ColorBar<V, T>
where
V: num_traits::NumOps + PartialOrd + FromPrimitive + AsPrimitive<f64> + Send + Sync,
T: ColorMapper<V> + 'static,
{
fn cairo_render(&self, canvas: &gtk::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]
}
}