druid_material_icons/
lib.rs1#[cfg(feature = "druid")]
5use druid::{
6 kurbo::{Affine, PathEl, Point, Rect, Shape, Size},
7 widget::prelude::*,
8 Color, Data,
9};
10#[cfg(not(feature = "druid"))]
11use kurbo::{PathEl, Point, Rect, Shape, Size};
12
13#[derive(Debug, Clone)]
27#[cfg(feature = "druid")]
28pub struct Icon {
29 paths: IconPaths,
30 color: Color,
31}
32
33#[cfg(feature = "druid")]
34impl Icon {
35 #[inline]
36 pub fn new(paths: IconPaths, color: Color) -> Self {
37 Self { paths, color }
38 }
39}
40
41#[cfg(feature = "druid")]
42impl<T: Data> Widget<T> for Icon {
43 fn event(&mut self, _ctx: &mut EventCtx, _event: &Event, _data: &mut T, _env: &Env) {
44 }
46 fn lifecycle(&mut self, _ctx: &mut LifeCycleCtx, _event: &LifeCycle, _data: &T, _env: &Env) {
47 }
49 fn update(&mut self, _ctx: &mut UpdateCtx, _old_data: &T, _data: &T, _env: &Env) {
50 }
52 fn layout(&mut self, _ctx: &mut LayoutCtx, bc: &BoxConstraints, _data: &T, _env: &Env) -> Size {
53 let Size { width, height } = self.paths.size;
54 bc.constrain_aspect_ratio(height / width, width)
55 }
56 fn paint(&mut self, ctx: &mut PaintCtx, _data: &T, _env: &Env) {
57 let Size { width, height } = ctx.size();
58 let Size {
59 width: icon_width,
60 height: icon_height,
61 } = self.paths.size;
62 ctx.transform(Affine::scale_non_uniform(
63 width * icon_width.recip(),
64 height * icon_height.recip(),
65 ));
66 for shape in self.paths.paths {
68 let color = self.color.clone();
69 let (_, _, _, alpha) = color.as_rgba();
70 let color = color.with_alpha(alpha * shape.opacity);
71 let brush = ctx.solid_brush(color);
72 ctx.fill(shape, &brush);
73 }
74 }
75}
76
77#[derive(Debug, Copy, Clone)]
91pub struct IconPaths {
92 pub paths: &'static [IconPath],
93 pub size: Size,
94}
95
96#[cfg(feature = "druid")]
97impl IconPaths {
98 pub fn new(self, color: Color) -> Icon {
99 Icon::new(self, color)
100 }
101}
102
103#[derive(Debug, Copy, Clone)]
104pub struct IconPath {
105 pub els: &'static [PathEl],
106 pub opacity: f64,
107}
108
109impl Shape for IconPath {
110 type PathElementsIter<'a> = std::iter::Copied<std::slice::Iter<'static, PathEl>>;
111 fn path_elements(&self, _tolerance: f64) -> Self::PathElementsIter<'_> {
112 self.els.iter().copied()
113 }
114
115 fn area(&self) -> f64 {
116 self.els.area()
117 }
118
119 fn perimeter(&self, accuracy: f64) -> f64 {
120 self.els.perimeter(accuracy)
121 }
122
123 fn winding(&self, pt: Point) -> i32 {
124 self.els.winding(pt)
125 }
126 fn bounding_box(&self) -> Rect {
127 self.els.bounding_box()
128 }
129
130 fn as_path_slice(&self) -> Option<&[PathEl]> {
131 Some(self.els)
132 }
133}
134
135include!("./icons.rs.in");