use crate::anim::Timing;
use crate::shader::ShaderBinding;
use crate::style::StyleProfile;
use super::geometry::{Corners, Sides};
use super::node::{El, FocusRingPlacement};
use super::semantics::SurfaceRole;
use crate::color::Color;
#[cfg(debug_assertions)]
fn warn_once(loc: &'static std::panic::Location<'static>, msg: impl FnOnce() -> String) {
use std::collections::HashSet;
use std::sync::Mutex;
static SEEN: Mutex<Option<HashSet<(&'static str, u32)>>> = Mutex::new(None);
let mut seen = SEEN.lock().unwrap();
if seen
.get_or_insert_with(HashSet::new)
.insert((loc.file(), loc.line()))
{
eprintln!("{}", msg());
}
}
impl El {
pub fn fill(mut self, c: Color) -> Self {
self.fill = Some(c);
self
}
pub fn dim_fill(mut self, c: Color) -> Self {
self.dim_fill = Some(c);
self
}
pub fn stroke(mut self, c: Color) -> Self {
self.stroke = Some(c);
if self.stroke_width == 0.0 {
self.stroke_width = 1.0;
}
self
}
pub fn stroke_width(mut self, w: f32) -> Self {
self.stroke_width = w;
self
}
pub fn radius(mut self, r: impl Into<Corners>) -> Self {
self.radius = r.into();
self.explicit_radius = true;
self
}
pub fn shadow(mut self, s: f32) -> Self {
self.shadow = s;
self
}
pub fn surface_role(mut self, role: SurfaceRole) -> Self {
self.surface_role = role;
self
}
pub fn paint_overflow(mut self, outset: impl Into<Sides>) -> Self {
self.paint_overflow = outset.into();
self
}
pub fn focus_ring_inside(mut self) -> Self {
self.focus_ring_placement = FocusRingPlacement::Inside;
self
}
pub fn focus_ring_outside(mut self) -> Self {
self.focus_ring_placement = FocusRingPlacement::Outside;
self
}
#[track_caller]
pub fn tooltip(mut self, text: impl Into<String>) -> Self {
let text = text.into();
#[cfg(debug_assertions)]
if let Some(prev) = &self.tooltip
&& *prev != text
{
let loc = std::panic::Location::caller();
warn_once(loc, || {
format!(
"damascene: .tooltip({text:?}) at {file}:{line} replaces the earlier \
.tooltip({prev:?}) on the same element — last value wins. If one of \
these belongs on a different node, move it; tooltips are looked up \
by the hovered node's id.",
file = loc.file(),
line = loc.line(),
)
});
}
self.tooltip = Some(text);
self
}
pub fn cursor(mut self, cursor: crate::cursor::Cursor) -> Self {
self.cursor = Some(cursor);
self
}
pub fn cursor_pressed(mut self, cursor: crate::cursor::Cursor) -> Self {
self.cursor_pressed = Some(cursor);
self
}
pub fn opacity(mut self, v: f32) -> Self {
self.opacity = v.clamp(0.0, 1.0);
self
}
pub fn translate(mut self, x: f32, y: f32) -> Self {
self.translate = (x, y);
self
}
pub fn scale(mut self, v: f32) -> Self {
self.scale = v.max(0.0);
self
}
pub fn animate(mut self, timing: Timing) -> Self {
self.animate = Some(timing);
self
}
pub fn shader(mut self, binding: ShaderBinding) -> Self {
self.shader_override = Some(binding);
self
}
pub fn style_profile(mut self, p: StyleProfile) -> Self {
self.style_profile = p;
self
}
pub(crate) fn default_radius(mut self, r: impl Into<Corners>) -> Self {
self.radius = r.into();
self.explicit_radius = false;
self
}
}