use crate::vector_icon;
use crate::{DrawCtx, Rect};
use super::super::value::RowValue;
use super::enum_buttons::{paint_segment_label, paint_strip_chrome, segment_ink};
const ICON_SIZE: f64 = 16.0;
const ICON_PAD: f64 = 2.0;
pub(crate) fn paint_editor(
ctx: &mut dyn DrawCtx,
editor_area: Rect,
value: RowValue,
variants: &[std::sync::Arc<str>],
icons: &[std::sync::Arc<str>],
scale: f64,
) {
for (i, (r, selected)) in paint_strip_chrome(ctx, editor_area, value, variants, scale)
.into_iter()
.enumerate()
{
let art = icons.get(i).and_then(|id| vector_icon::icon(id));
match art {
Some(icon) => {
let ink = segment_ink(&*ctx, selected);
icon.paint(ctx, icon_rect(r, scale), ink);
}
None => paint_segment_label(ctx, r, &variants[i], selected, scale),
}
}
}
fn icon_rect(segment: Rect, scale: f64) -> Rect {
let side = (ICON_SIZE * scale)
.min(segment.width - ICON_PAD * 2.0 * scale)
.min(segment.height - ICON_PAD * 2.0 * scale)
.max(0.0);
Rect::new(
segment.x + (segment.width - side) * 0.5,
segment.y + (segment.height - side) * 0.5,
side,
side,
)
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn the_icon_is_centred_in_its_segment() {
let seg = Rect::new(100.0, 10.0, 30.0, 18.0);
let r = icon_rect(seg, 1.0);
assert!((r.x + r.width * 0.5 - (seg.x + seg.width * 0.5)).abs() < 1e-9);
assert!((r.y + r.height * 0.5 - (seg.y + seg.height * 0.5)).abs() < 1e-9);
assert!((r.width - r.height).abs() < 1e-9, "icons stay square");
}
#[test]
fn a_short_segment_shrinks_the_icon_instead_of_overflowing() {
let seg = Rect::new(0.0, 0.0, 30.0, 18.0);
let r = icon_rect(seg, 1.0);
assert!(r.height <= seg.height - 2.0 * ICON_PAD);
assert!(r.width <= r.height + 1e-9);
}
#[test]
fn a_narrow_segment_clamps_to_the_width() {
let seg = Rect::new(0.0, 0.0, 8.0, 18.0);
let r = icon_rect(seg, 1.0);
assert!((r.width - 4.0).abs() < 1e-9, "got {}", r.width);
}
#[test]
fn scale_multiplies_the_icon_size() {
let seg = Rect::new(0.0, 0.0, 60.0, 44.0);
assert!((icon_rect(seg, 2.0).width - 32.0).abs() < 1e-9);
}
}