use crate::event::Rect;
use crate::primitives::button::{Button, ButtonLayout};
pub fn win_button_layout(rect: Rect, button: &Button) -> ButtonLayout {
button.layout(rect)
}
#[cfg(test)]
mod tests {
use super::*;
use crate::primitives::button::{ButtonEvent, ButtonHit, ButtonVariant};
use crate::theme::Theme;
use crate::types::WidgetId;
use crate::win::testing::HeadlessSurface;
use crate::win::text::DWrite;
const W: u32 = 120;
const H: u32 = 20;
fn mk_button(label: &str) -> Button {
Button::new(WidgetId::new("dialog:ok"), label)
}
fn paint(
surface: &HeadlessSurface,
dwrite: &DWrite,
rect: Rect,
button: &Button,
theme: &Theme,
) -> ButtonLayout {
surface
.paint(|target| {
let mut raw = super::super::surface::D2dSurface {
target,
dwrite: Some(dwrite),
};
crate::primitives::button::native_surface_paint::paint(
button,
&mut raw,
theme,
rect,
&crate::style::Style::default(),
);
})
.map(|_| win_button_layout(rect, button))
.expect("paint button")
}
#[test]
fn primary_variant_fills_accent_bg() {
let surface = HeadlessSurface::new(W, H).expect("create surface");
let (dwrite, _, _) = DWrite::new("Segoe UI", 10.0, None).expect("create DWrite");
let button = mk_button("OK");
let rect = Rect::new(0.0, 0.0, W as f32, H as f32);
let theme = Theme::default();
paint(&surface, &dwrite, rect, &button, &theme);
let px = surface.pixel_at(W / 2, H / 2);
assert_eq!(
(px.r, px.g, px.b),
(theme.accent_bg.r, theme.accent_bg.g, theme.accent_bg.b)
);
}
#[test]
fn secondary_variant_fills_surface_bg() {
let surface = HeadlessSurface::new(W, H).expect("create surface");
let (dwrite, _, _) = DWrite::new("Segoe UI", 10.0, None).expect("create DWrite");
let mut button = mk_button("Cancel");
button.variant = ButtonVariant::Secondary;
let rect = Rect::new(0.0, 0.0, W as f32, H as f32);
let theme = Theme::default();
paint(&surface, &dwrite, rect, &button, &theme);
let px = surface.pixel_at(W / 2, H / 2);
assert_eq!(
(px.r, px.g, px.b),
(theme.surface_bg.r, theme.surface_bg.g, theme.surface_bg.b)
);
}
#[test]
fn disabled_button_fills_surface_bg_regardless_of_variant() {
let surface = HeadlessSurface::new(W, H).expect("create surface");
let (dwrite, _, _) = DWrite::new("Segoe UI", 10.0, None).expect("create DWrite");
let mut button = mk_button("OK");
button.disabled = true;
let rect = Rect::new(0.0, 0.0, W as f32, H as f32);
let theme = Theme::default();
paint(&surface, &dwrite, rect, &button, &theme);
let px = surface.pixel_at(W / 2, H / 2);
assert_eq!(
(px.r, px.g, px.b),
(theme.surface_bg.r, theme.surface_bg.g, theme.surface_bg.b)
);
}
fn hit_test_round_trip_at(x: f32, y: f32) {
let rect = Rect::new(x, y, 40.0, 16.0);
let layout = win_button_layout(rect, &mk_button("OK"));
let inside = layout.hit_test(crate::event::Point::new(x + 4.0, y + 4.0));
assert_eq!(inside, ButtonHit::Body);
let outside = layout.hit_test(crate::event::Point::new(x + 400.0, y));
assert_eq!(outside, ButtonHit::Outside);
}
#[test]
fn hit_test_round_trip() {
hit_test_round_trip_at(0.0, 0.0);
}
#[test]
fn hit_test_round_trip_at_nonzero_origin() {
hit_test_round_trip_at(7.0, 13.0);
}
#[test]
fn click_activation_still_works_after_painting() {
let surface = HeadlessSurface::new(W, H).expect("create surface");
let (dwrite, _, _) = DWrite::new("Segoe UI", 10.0, None).expect("create DWrite");
let button = mk_button("OK");
let rect = Rect::new(0.0, 0.0, W as f32, H as f32);
let theme = Theme::default();
let layout = paint(&surface, &dwrite, rect, &button, &theme);
assert_eq!(
layout.hit_test(crate::event::Point::new(2.0, 2.0)),
ButtonHit::Body
);
assert_eq!(
button.click(),
Some(ButtonEvent::Activated { id: button.id })
);
}
#[test]
fn keyboard_activation_requires_focus() {
let mut button = mk_button("OK");
button.focused = true;
let event = button.handle_key(
&crate::event::Key::Named(crate::event::NamedKey::Enter),
&crate::types::Modifiers::default(),
);
assert_eq!(event, Some(ButtonEvent::Activated { id: button.id }));
}
#[test]
fn no_paint_layout_matches_paint_layout() {
let button = mk_button("OK");
let rect = Rect::new(0.0, 0.0, W as f32, H as f32);
let surface = HeadlessSurface::new(W, H).expect("create surface");
let (dwrite, _, _) = DWrite::new("Segoe UI", 10.0, None).expect("create DWrite");
let theme = Theme::default();
let painted = paint(&surface, &dwrite, rect, &button, &theme);
let no_paint = win_button_layout(rect, &button);
assert_eq!(painted, no_paint);
}
}