mirror of
https://github.com/danbulant/cushy
synced 2026-06-18 14:01:10 +00:00
While this was a workaround for a docs.rs issue (Px/Lp are not linked), I decided having the shorter import path would look better in the examples. It probably wasn't necessary to update all of the references in the internal code, but I decided it was worth the consistency.
80 lines
2 KiB
Rust
80 lines
2 KiB
Rust
use std::fmt::Debug;
|
|
|
|
use figures::units::UPx;
|
|
use figures::Size;
|
|
|
|
use crate::context::{GraphicsContext, LayoutContext};
|
|
use crate::value::Dynamic;
|
|
use crate::widget::Widget;
|
|
use crate::{ConstraintLimit, Tick};
|
|
|
|
/// A 2d drawable surface.
|
|
#[must_use]
|
|
pub struct Canvas {
|
|
render: Box<dyn RenderFunction>,
|
|
tick: Option<Tick>,
|
|
redraw: Dynamic<()>,
|
|
}
|
|
|
|
impl Canvas {
|
|
/// Returns a new canvas that draws its contents by invoking `render`.
|
|
pub fn new<F>(render: F) -> Self
|
|
where
|
|
F: for<'clip, 'gfx, 'pass, 'context, 'window> FnMut(
|
|
&mut GraphicsContext<'context, 'window, 'clip, 'gfx, 'pass>,
|
|
) + Send
|
|
+ 'static,
|
|
{
|
|
Self {
|
|
render: Box::new(render),
|
|
tick: None,
|
|
redraw: Dynamic::new(()),
|
|
}
|
|
}
|
|
|
|
/// Associates a [`Tick`] with this widget and returns self.
|
|
pub fn tick(mut self, tick: Tick) -> Self {
|
|
self.tick = Some(tick);
|
|
self
|
|
}
|
|
}
|
|
|
|
impl Widget for Canvas {
|
|
fn redraw(&mut self, context: &mut GraphicsContext<'_, '_, '_, '_, '_>) {
|
|
context.redraw_when_changed(&self.redraw);
|
|
self.render.render(context);
|
|
if let Some(tick) = &self.tick {
|
|
tick.rendered(context);
|
|
}
|
|
}
|
|
|
|
fn layout(
|
|
&mut self,
|
|
available_space: Size<crate::ConstraintLimit>,
|
|
_context: &mut LayoutContext<'_, '_, '_, '_, '_>,
|
|
) -> Size<UPx> {
|
|
available_space.map(ConstraintLimit::max)
|
|
}
|
|
}
|
|
|
|
impl Debug for Canvas {
|
|
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
|
f.debug_struct("Canvas").finish_non_exhaustive()
|
|
}
|
|
}
|
|
|
|
trait RenderFunction: Send + 'static {
|
|
fn render(&mut self, context: &mut GraphicsContext<'_, '_, '_, '_, '_>);
|
|
}
|
|
|
|
impl<F> RenderFunction for F
|
|
where
|
|
F: for<'clip, 'gfx, 'pass, 'context, 'window> FnMut(
|
|
&mut GraphicsContext<'context, 'window, 'clip, 'gfx, 'pass>,
|
|
) + Send
|
|
+ 'static,
|
|
{
|
|
fn render(&mut self, context: &mut GraphicsContext<'_, '_, '_, '_, '_>) {
|
|
self(context);
|
|
}
|
|
}
|