use crate::color::Color;
use crate::draw_ctx::DrawCtx;
use crate::event::{Event, EventResult};
use crate::geometry::{Rect, Size};
use crate::widget::Widget;
use super::registry::guides_snapshot;
use super::SnapGuide;
pub struct SnapOverlay {
bounds: Rect,
children: Vec<Box<dyn Widget>>, }
impl SnapOverlay {
pub fn new() -> Self {
Self {
bounds: Rect::default(),
children: Vec::new(),
}
}
fn alignment_color() -> Color {
Color::rgba(0.15, 0.70, 0.95, 0.95)
}
fn spacing_color() -> Color {
Color::rgba(0.95, 0.35, 0.55, 0.95)
}
}
impl Default for SnapOverlay {
fn default() -> Self {
Self::new()
}
}
impl Widget for SnapOverlay {
fn type_name(&self) -> &'static str {
"SnapOverlay"
}
fn bounds(&self) -> Rect {
self.bounds
}
fn set_bounds(&mut self, b: Rect) {
self.bounds = b;
}
fn children(&self) -> &[Box<dyn Widget>] {
&self.children
}
fn children_mut(&mut self) -> &mut Vec<Box<dyn Widget>> {
&mut self.children
}
fn layout(&mut self, available: Size) -> Size {
self.bounds = Rect::new(0.0, 0.0, available.width, available.height);
available
}
fn paint(&mut self, _ctx: &mut dyn DrawCtx) {
}
fn paint_global_overlay(&mut self, ctx: &mut dyn DrawCtx) {
let guides = guides_snapshot();
if guides.is_empty() {
return;
}
ctx.set_line_width(1.0);
for guide in guides {
match guide {
SnapGuide::VLine { x, y0, y1 } => {
ctx.set_stroke_color(Self::alignment_color());
ctx.begin_path();
ctx.move_to(x.round() + 0.5, y0);
ctx.line_to(x.round() + 0.5, y1);
ctx.stroke();
}
SnapGuide::HLine { y, x0, x1 } => {
ctx.set_stroke_color(Self::alignment_color());
ctx.begin_path();
ctx.move_to(x0, y.round() + 0.5);
ctx.line_to(x1, y.round() + 0.5);
ctx.stroke();
}
SnapGuide::HSpacing { y, x0, x1 } => {
ctx.set_stroke_color(Self::spacing_color());
let yy = y.round() + 0.5;
ctx.begin_path();
ctx.move_to(x0, yy);
ctx.line_to(x1, yy);
ctx.stroke();
paint_tick_v(ctx, x0, yy, 4.0);
paint_tick_v(ctx, x1, yy, 4.0);
}
SnapGuide::VSpacing { x, y0, y1 } => {
ctx.set_stroke_color(Self::spacing_color());
let xx = x.round() + 0.5;
ctx.begin_path();
ctx.move_to(xx, y0);
ctx.line_to(xx, y1);
ctx.stroke();
paint_tick_h(ctx, xx, y0, 4.0);
paint_tick_h(ctx, xx, y1, 4.0);
}
}
}
}
fn on_event(&mut self, _event: &Event) -> EventResult {
EventResult::Ignored
}
fn hit_test(&self, _p: crate::geometry::Point) -> bool {
false
}
}
fn paint_tick_v(ctx: &mut dyn DrawCtx, x: f64, y: f64, half: f64) {
ctx.begin_path();
ctx.move_to(x, y - half);
ctx.line_to(x, y + half);
ctx.stroke();
}
fn paint_tick_h(ctx: &mut dyn DrawCtx, x: f64, y: f64, half: f64) {
ctx.begin_path();
ctx.move_to(x - half, y);
ctx.line_to(x + half, y);
ctx.stroke();
}