//! Icons drawn procedurally with the egui painter. Original SoundCraft artwork (MIT OR Apache-2.0); //! no image files and nothing derived from any other product's icons. use egui::{Color32, Painter, Pos2, Rect, Shape, Stroke, pos2, vec2}; fn p(r: Rect, x: f32, y: f32) -> Pos2 { pos2(r.min.x + r.width() * x, r.min.y + r.height() * y) } /// Draw icon `name` inside `r` with colour `c`. pub fn draw(painter: &Painter, r: Rect, name: &str, c: Color32) { let s = Stroke::new((r.width() / 14.0).clamp(1.2, 2.4), c); match name { "play" => { painter.add(Shape::convex_polygon(vec![p(r, 0.28, 0.18), p(r, 0.82, 0.5), p(r, 0.28, 0.82)], c, Stroke::NONE)); } "stop" => { painter.rect_filled(Rect::from_min_max(p(r, 0.26, 0.26), p(r, 0.74, 0.74)), 1.0, c); } "record" => { painter.circle_filled(r.center(), r.width() * 0.27, c); } "rtz" => { painter.rect_filled(Rect::from_min_max(p(r, 0.24, 0.26), p(r, 0.34, 0.74)), 0.0, c); painter.add(Shape::convex_polygon(vec![p(r, 0.76, 0.26), p(r, 0.76, 0.74), p(r, 0.36, 0.5)], c, Stroke::NONE)); } "end" => { painter.rect_filled(Rect::from_min_max(p(r, 0.66, 0.26), p(r, 0.76, 0.74)), 0.0, c); painter.add(Shape::convex_polygon(vec![p(r, 0.24, 0.26), p(r, 0.64, 0.5), p(r, 0.24, 0.74)], c, Stroke::NONE)); } "rewind" => { for dx in [0.0, 0.26] { painter.add(Shape::convex_polygon(vec![p(r, 0.5 + dx, 0.28), p(r, 0.5 + dx, 0.72), p(r, 0.22 + dx, 0.5)], c, Stroke::NONE)); } } "ffwd" => { for dx in [0.0, 0.26] { painter.add(Shape::convex_polygon(vec![p(r, 0.24 + dx, 0.28), p(r, 0.52 + dx, 0.5), p(r, 0.24 + dx, 0.72)], c, Stroke::NONE)); } } "loop" => { let rr = Rect::from_min_max(p(r, 0.2, 0.3), p(r, 0.8, 0.7)); painter.rect_stroke(rr, rr.height() * 0.5, s, egui::StrokeKind::Middle); painter.add(Shape::convex_polygon(vec![p(r, 0.55, 0.2), p(r, 0.68, 0.3), p(r, 0.55, 0.4)], c, Stroke::NONE)); } "zoom" => { painter.circle_stroke(p(r, 0.42, 0.4), r.width() * 0.2, s); painter.line_segment([p(r, 0.56, 0.55), p(r, 0.8, 0.8)], Stroke::new(s.width * 1.6, c)); } "zoom_toggle" => { for (x, y, dx, dy) in [(0.18, 0.24, 0.16, 0.14), (0.82, 0.24, -0.16, 0.14), (0.18, 0.76, 0.16, -0.14), (0.82, 0.76, -0.16, -0.14)] { painter.add(Shape::line(vec![p(r, x + dx, y), p(r, x, y), p(r, x, y + dy)], s)); } painter.rect_filled(Rect::from_min_max(p(r, 0.34, 0.41), p(r, 0.66, 0.59)), 1.0, c); } "trim" => { painter.line_segment([p(r, 0.5, 0.2), p(r, 0.5, 0.8)], s); painter.line_segment([p(r, 0.15, 0.5), p(r, 0.85, 0.5)], s); for (a, b, d) in [(0.15, 0.5, 1.0), (0.85, 0.5, -1.0)] { painter.add(Shape::convex_polygon(vec![p(r, a, b), p(r, a + 0.12 * d, b - 0.1), p(r, a + 0.12 * d, b + 0.1)], c, Stroke::NONE)); } } "selector" => { painter.line_segment([p(r, 0.5, 0.2), p(r, 0.5, 0.8)], s); painter.line_segment([p(r, 0.4, 0.2), p(r, 0.6, 0.2)], s); painter.line_segment([p(r, 0.4, 0.8), p(r, 0.6, 0.8)], s); // Waveform hint on either side. for (i, h) in [0.1, 0.22, 0.14, 0.26, 0.12].iter().enumerate() { let x = 0.12 + i as f32 * 0.06; painter.line_segment([p(r, x, 0.5 - h), p(r, x, 0.5 + h)], Stroke::new(s.width * 0.7, c)); let x2 = 0.88 - i as f32 * 0.06; painter.line_segment([p(r, x2, 0.5 - h), p(r, x2, 0.5 + h)], Stroke::new(s.width * 0.7, c)); } } "grabber" => { // A stylised open hand: palm + four fingers + thumb. let palm = Rect::from_min_max(p(r, 0.3, 0.45), p(r, 0.72, 0.82)); painter.rect_stroke(palm, 4.0, s, egui::StrokeKind::Middle); for (i, top) in [0.22, 0.16, 0.18, 0.26].iter().enumerate() { let x = 0.34 + i as f32 * 0.11; painter.line_segment([p(r, x, 0.47), p(r, x, *top)], s); } painter.line_segment([p(r, 0.3, 0.62), p(r, 0.18, 0.48)], s); } "scrubber" => { painter.add(Shape::convex_polygon( vec![p(r, 0.18, 0.4), p(r, 0.3, 0.4), p(r, 0.46, 0.24), p(r, 0.46, 0.76), p(r, 0.3, 0.6), p(r, 0.18, 0.6)], c, Stroke::NONE, )); for (k, rad) in [0.14f32, 0.26].iter().enumerate() { let n = 8; let pts: Vec = (0..=n) .map(|i| { let a = -0.8 + 1.6 * i as f32 / n as f32; let cc = p(r, 0.46, 0.5); pos2(cc.x + a.cos() * r.width() * rad, cc.y + a.sin() * r.height() * rad) }) .collect(); painter.add(Shape::line(pts, Stroke::new(s.width * (1.0 - k as f32 * 0.2), c))); } } "pencil" => { painter.line_segment([p(r, 0.25, 0.75), p(r, 0.72, 0.28)], Stroke::new(s.width * 2.2, c)); painter.add(Shape::convex_polygon(vec![p(r, 0.18, 0.82), p(r, 0.22, 0.66), p(r, 0.34, 0.78)], c, Stroke::NONE)); } "speaker" => { painter.add(Shape::convex_polygon( vec![p(r, 0.2, 0.4), p(r, 0.34, 0.4), p(r, 0.52, 0.22), p(r, 0.52, 0.78), p(r, 0.34, 0.6), p(r, 0.2, 0.6)], c, Stroke::NONE, )); } "click" => { painter.add(Shape::convex_polygon(vec![p(r, 0.5, 0.15), p(r, 0.78, 0.85), p(r, 0.22, 0.85)], Color32::TRANSPARENT, s)); painter.line_segment([p(r, 0.5, 0.7), p(r, 0.7, 0.25)], s); } "link" => { painter.circle_stroke(p(r, 0.38, 0.5), r.width() * 0.16, s); painter.circle_stroke(p(r, 0.62, 0.5), r.width() * 0.16, s); } "plus" => { painter.line_segment([p(r, 0.5, 0.25), p(r, 0.5, 0.75)], s); painter.line_segment([p(r, 0.25, 0.5), p(r, 0.75, 0.5)], s); } "minus" => { painter.line_segment([p(r, 0.25, 0.5), p(r, 0.75, 0.5)], s); } "triangle_down" => { painter.add(Shape::convex_polygon(vec![p(r, 0.25, 0.35), p(r, 0.75, 0.35), p(r, 0.5, 0.68)], c, Stroke::NONE)); } "note" => { painter.circle_filled(p(r, 0.38, 0.72), r.width() * 0.13, c); painter.line_segment([p(r, 0.5, 0.72), p(r, 0.5, 0.2)], s); painter.line_segment([p(r, 0.5, 0.2), p(r, 0.72, 0.32)], s); } "gear" => { painter.circle_stroke(r.center(), r.width() * 0.2, s); for i in 0..8 { let a = i as f32 * std::f32::consts::TAU / 8.0; let c0 = r.center() + vec2(a.cos(), a.sin()) * r.width() * 0.22; let c1 = r.center() + vec2(a.cos(), a.sin()) * r.width() * 0.34; painter.line_segment([c0, c1], Stroke::new(s.width * 1.4, c)); } } "lock" => { painter.rect_filled(Rect::from_min_max(p(r, 0.22, 0.46), p(r, 0.78, 0.88)), r.width() * 0.08, c); let (x, y, w) = (r.center().x, r.min.y + r.height() * 0.46, r.width() * 0.19); let arc: Vec = (0..=12).map(|i| std::f32::consts::PI * i as f32 / 12.0).map(|a| pos2(x - w * a.cos(), y - w * 1.4 * a.sin())).collect(); painter.add(Shape::line(arc, s)); } "wave" => { let n = 24; let pts: Vec = (0..=n) .map(|i| { let t = i as f32 / n as f32; pos2( r.min.x + r.width() * (0.12 + 0.76 * t), r.center().y - (t * 18.0).sin() * r.height() * 0.28 * (1.0 - (t - 0.5).abs() * 1.6).max(0.1), ) }) .collect(); painter.add(Shape::line(pts, s)); } "tab_transient" => { painter.line_segment([p(r, 0.08, 0.5), p(r, 0.3, 0.5)], s); painter.add(Shape::convex_polygon(vec![p(r, 0.42, 0.5), p(r, 0.28, 0.36), p(r, 0.28, 0.64)], c, Stroke::NONE)); painter.line_segment([p(r, 0.5, 0.16), p(r, 0.5, 0.84)], s); for (x, h) in [(0.64, 0.32), (0.78, 0.2), (0.92, 0.1)] { painter.line_segment([p(r, x, 0.5 - h), p(r, x, 0.5 + h)], s); } } _ => { painter.rect_stroke(r.shrink(r.width() * 0.25), 1.0, s, egui::StrokeKind::Middle); } } }