use super::*;
use crate::widget::paint_subtree;
pub(super) fn paint_window(window: &mut Window, ctx: &mut dyn DrawCtx) {
if !window.is_visible() {
return;
}
let v = ctx.visuals();
let w = window.bounds.width;
let h = window.bounds.height;
let style = super::chrome::ChromeStyle::from_visuals(&v);
super::chrome::paint_chrome_shadow(ctx, w, h, &style);
window.foreground_layer_active.set(false);
if ctx.supports_compositing_layers() {
ctx.push_layer(w, h);
window.foreground_layer_active.set(true);
}
super::chrome::paint_chrome_body(ctx, w, h, &style, window.collapsed);
ctx.set_layer_rounded_clip(0.0, 0.0, w, h, CORNER_R);
{
let mut st = window.title_state.borrow_mut();
st.bar_color = if window.drag_mode == DragMode::Move {
v.window_title_fill_drag
} else {
v.window_title_fill
};
st.title_color = v.window_title_text;
st.collapsed = window.collapsed;
st.maximized = window.maximized;
st.close_hovered = window.close_hovered;
st.maximize_hovered = window.maximize_hovered;
}
let tb_bounds = window.title_bar.bounds();
ctx.save();
ctx.translate(tb_bounds.x, tb_bounds.y);
paint_subtree(&mut window.title_bar, ctx);
ctx.restore();
ctx.set_fill_color(v.window_fill); super::chrome::paint_chrome_border(ctx, w, h, &style);
}
pub(super) fn paint_overlay(window: &mut Window, ctx: &mut dyn DrawCtx) {
if !window.is_visible() || window.collapsed {
return;
}
if !window.resizable || window.auto_size {
return;
}
let v = ctx.visuals();
let w = window.bounds.width;
let h = window.bounds.height;
if window.resizable_h && window.resizable_v {
let is_se_active = matches!(window.drag_mode, DragMode::Resize(ResizeDir::SE));
let is_se_hover = window.hover_dir == Some(ResizeDir::SE);
let grip_color = if is_se_active {
v.window_resize_active
} else if is_se_hover {
v.window_resize_hover
} else {
v.window_stroke
};
ctx.set_stroke_color(grip_color);
ctx.set_line_width(1.5);
let m = 3.0_f64; for i in 1..=3_i32 {
let off = i as f64 * 4.0 + m;
ctx.begin_path();
ctx.move_to(w - off, m);
ctx.line_to(w - m, off);
ctx.stroke();
}
}
let (highlight, is_active) = match window.drag_mode {
DragMode::Resize(d) => (Some(d), true),
DragMode::Move => (None, false), DragMode::None => (window.hover_dir, false),
};
let dir = match highlight {
Some(d) => d,
None => return,
};
let color = if is_active {
v.window_resize_active
} else {
v.window_resize_hover
};
ctx.set_stroke_color(color);
ctx.set_line_width(2.0);
let (top, bottom, left, right) = match dir {
ResizeDir::N => (true, false, false, false),
ResizeDir::S => (false, true, false, false),
ResizeDir::E => (false, false, false, true),
ResizeDir::W => (false, false, true, false),
ResizeDir::NE => (true, false, false, true),
ResizeDir::NW => (true, false, true, false),
ResizeDir::SE => (false, true, false, true),
ResizeDir::SW => (false, true, true, false),
};
let cr = CORNER_R;
if top {
ctx.begin_path();
ctx.move_to(cr, h);
ctx.line_to(w - cr, h);
ctx.stroke();
}
if bottom {
ctx.begin_path();
ctx.move_to(cr, 0.0);
ctx.line_to(w - cr, 0.0);
ctx.stroke();
}
if left {
ctx.begin_path();
ctx.move_to(0.0, cr);
ctx.line_to(0.0, h - cr);
ctx.stroke();
}
if right {
ctx.begin_path();
ctx.move_to(w, cr);
ctx.line_to(w, h - cr);
ctx.stroke();
}
}
pub(super) fn finish_paint(window: &mut Window, ctx: &mut dyn DrawCtx) {
if window.foreground_layer_active.replace(false) {
ctx.pop_layer();
}
}