Expand description
Vector shapes drawn into a plugin’s own surface buffer, in either model.
Shapes is implemented by Surface<Cells> (ink: a
Style; box-drawing and block characters) and by
Surface<Pixels> (ink: an Rgba;
antialiased edges). Coordinates are cells or pixels and may lie outside
the surface: everything is clipped, and only what is drawn is marked
dirty.
ⓘ
//! A stage in the graphics model drawn with the shape helpers: a panel, an
//! orbiting dot, a sweeping line, a progress bar and a label. It animates at
//! the viewer's paced rate on mains power and once a second when saving
//! power, and follows the viewer's theme colours.
//!
//! Manifest surfaces: `[{ "id": "stage", "anchor": "stage", "model": "pixels" }]`.
#![no_std]
use standard_plugin::prelude::*;
use standard_plugin::{Power, libm, view};
#[standard_plugin::ui]
struct ShapesStage {
stage: Surface<Pixels>,
}
impl UiPlugin for ShapesStage {
fn activate(_cx: &mut Context) -> Self {
Self {
stage: Surface::new("stage"),
}
}
fn frame(&mut self, frame: &Frame) {
let (w, h) = self.stage.size();
if w == 0 || h == 0 {
// No pixel geometry yet: a resize will follow.
return;
}
let theme = view::theme();
let (fg, bg, accent) = (
Rgba::hex(theme.fg),
Rgba::hex(theme.bg),
Rgba::hex(theme.accent),
);
let t = (frame.now_ms() % 4000) as f32 / 4000.0;
// A full repaint: nothing is carried forward from the last frame.
self.stage.clear(bg);
let panel = Area::new(8, 8, w.saturating_sub(16), h.saturating_sub(16));
self.stage
.fill_rounded_rect(panel, 12, Rgba::hex(theme.recede_bg));
self.stage
.rounded_rect(panel, 12, Rgba::hex(theme.recede_fg));
let (cx, cy) = (w as f32 / 2.0, h as f32 / 2.0);
let radius = (w.min(h) / 4) as f32;
let angle = t * core::f32::consts::TAU;
// `no_std` has no `f32::sin`: the SDK re-exports `libm`. The dot
// moves between pixels; the shapes antialias it there.
let dot = (
cx + radius * libm::cosf(angle),
cy + radius * libm::sinf(angle),
);
self.stage
.circle((cx, cy), radius, Rgba::hex(theme.recede_fg));
self.stage
.line((cx as i32, cy as i32), (dot.0 as i32, dot.1 as i32), accent);
self.stage.fill_circle(dot, 6.0, accent);
let bar = Area::new(24, h as i32 - 40, w.saturating_sub(48), 8);
self.stage
.bar(bar, t, accent, Rgba::hex(theme.recede_fg).with_alpha(96));
self.stage.label(24, 24, "shapes", fg);
let _ = self.stage.commit();
match frame.power() {
Power::Mains => frame.request_frame(),
Power::SavePower => frame.wake_after(1000),
}
}
}Re-exports§
pub use font::GLYPH_ADVANCE;pub use font::GLYPH_HEIGHT;pub use font::GLYPH_WIDTH;
Modules§
- font
- The built-in 5x7 pixel font for printable ASCII, drawn for this SDK: the
font
Shapes::labelpaints on pixels surfaces. Each glyph is seven rows of five bits, the top row first and the leftmost column in bit 4, so a plugin can draw the same letters its own way (in cells, scaled, masked):
Structs§
- Area
- A rectangle whose origin may lie outside the surface.
- Image
- An RGBA8 image to draw with
Surface::blit_clipped:widthbyheightpixels,width * 4bytes per row, straight alpha.
Traits§
- Shapes
- Shapes both surface models draw.
Inkis what paints: a style for cells, a colour for pixels.