use super::{color::Rgba, AnimationState};
#[allow(unused)] use super::{DrawRounded, DrawRoundedImpl};
use super::{DrawShared, DrawSharedImpl, ImageId, PassId, PassType, SharedState};
use crate::geom::{Offset, Quad, Rect};
#[allow(unused)] use crate::text::TextApi;
use crate::text::{Effect, TextDisplay};
use std::any::Any;
use std::time::Instant;
pub struct DrawIface<'a, DS: DrawSharedImpl> {
#[cfg_attr(not(feature = "internal_doc"), doc(hidden))]
#[cfg_attr(doc_cfg, doc(cfg(internal_doc)))]
pub draw: &'a mut DS::Draw,
#[cfg_attr(not(feature = "internal_doc"), doc(hidden))]
#[cfg_attr(doc_cfg, doc(cfg(internal_doc)))]
pub shared: &'a mut SharedState<DS>,
#[cfg_attr(not(feature = "internal_doc"), doc(hidden))]
#[cfg_attr(doc_cfg, doc(cfg(internal_doc)))]
pub pass: PassId,
}
impl<'a, DS: DrawSharedImpl> DrawIface<'a, DS> {
pub fn downcast_from(obj: &'a mut dyn Draw) -> Option<Self> {
let pass = obj.get_pass();
let (draw, shared) = obj.get_fields_as_any_mut();
let draw = draw.downcast_mut()?;
let shared = shared.downcast_mut()?;
Some(DrawIface { draw, shared, pass })
}
pub fn re<'b>(&'b mut self) -> DrawIface<'b, DS>
where
'a: 'b,
{
DrawIface {
draw: &mut *self.draw,
shared: &mut *self.shared,
pass: self.pass,
}
}
pub fn new_pass(&mut self, rect: Rect, offset: Offset, class: PassType) -> DrawIface<DS> {
let pass = self.draw.new_pass(self.pass, rect, offset, class);
DrawIface {
draw: &mut *self.draw,
shared: &mut *self.shared,
pass,
}
}
}
pub trait Draw {
fn shared(&mut self) -> &mut dyn DrawShared;
fn animate(&mut self);
fn animate_at(&mut self, time: Instant);
fn get_pass(&self) -> PassId;
#[cfg_attr(not(feature = "internal_doc"), doc(hidden))]
#[cfg_attr(doc_cfg, doc(cfg(internal_doc)))]
fn get_fields_as_any_mut(&mut self) -> (&mut dyn Any, &mut dyn Any);
fn new_dyn_pass<'b>(
&'b mut self,
rect: Rect,
offset: Offset,
class: PassType,
) -> Box<dyn Draw + 'b>;
fn get_clip_rect(&self) -> Rect;
fn rect(&mut self, rect: Quad, col: Rgba);
fn frame(&mut self, outer: Quad, inner: Quad, col: Rgba);
fn image(&mut self, id: ImageId, rect: Quad);
fn text(&mut self, rect: Rect, text: &TextDisplay, col: Rgba);
fn text_effects(&mut self, rect: Rect, text: &TextDisplay, col: Rgba, effects: &[Effect<()>]);
fn text_effects_rgba(&mut self, rect: Rect, text: &TextDisplay, effects: &[Effect<Rgba>]);
}
impl<'a, DS: DrawSharedImpl> Draw for DrawIface<'a, DS> {
fn shared(&mut self) -> &mut dyn DrawShared {
self.shared
}
fn animate(&mut self) {
self.draw.animate();
}
fn animate_at(&mut self, time: Instant) {
self.draw.animate_at(time);
}
fn get_pass(&self) -> PassId {
self.pass
}
fn get_fields_as_any_mut(&mut self) -> (&mut dyn Any, &mut dyn Any) {
(self.draw, self.shared)
}
fn new_dyn_pass<'b>(
&'b mut self,
rect: Rect,
offset: Offset,
class: PassType,
) -> Box<dyn Draw + 'b> {
Box::new(self.new_pass(rect, offset, class))
}
fn get_clip_rect(&self) -> Rect {
self.draw.get_clip_rect(self.pass)
}
fn rect(&mut self, rect: Quad, col: Rgba) {
self.draw.rect(self.pass, rect, col);
}
fn frame(&mut self, outer: Quad, inner: Quad, col: Rgba) {
self.draw.frame(self.pass, outer, inner, col);
}
fn image(&mut self, id: ImageId, rect: Quad) {
self.shared.draw.draw_image(self.draw, self.pass, id, rect);
}
fn text(&mut self, rect: Rect, text: &TextDisplay, col: Rgba) {
self.shared
.draw
.draw_text(self.draw, self.pass, rect, text, col);
}
fn text_effects(&mut self, rect: Rect, text: &TextDisplay, col: Rgba, effects: &[Effect<()>]) {
self.shared
.draw
.draw_text_effects(self.draw, self.pass, rect, text, col, effects);
}
fn text_effects_rgba(&mut self, rect: Rect, text: &TextDisplay, effects: &[Effect<Rgba>]) {
self.shared
.draw
.draw_text_effects_rgba(self.draw, self.pass, rect, text, effects);
}
}
#[cfg_attr(not(feature = "internal_doc"), doc(hidden))]
#[cfg_attr(doc_cfg, doc(cfg(internal_doc)))]
pub trait DrawImpl: Any {
fn animation_mut(&mut self) -> &mut AnimationState;
fn animate(&mut self) {
self.animation_mut().merge_in(AnimationState::Animate);
}
fn animate_at(&mut self, time: Instant) {
self.animation_mut().merge_in(AnimationState::Timed(time));
}
fn new_pass(
&mut self,
parent_pass: PassId,
rect: Rect,
offset: Offset,
class: PassType,
) -> PassId;
fn get_clip_rect(&self, pass: PassId) -> Rect;
fn rect(&mut self, pass: PassId, rect: Quad, col: Rgba);
fn frame(&mut self, pass: PassId, outer: Quad, inner: Quad, col: Rgba);
}