canary-rs/scripts/music-player/src/lib.rs

101 lines
2.5 KiB
Rust

// Copyright (c) 2022 Marceline Cramer
// SPDX-License-Identifier: AGPL-3.0-or-later
#[global_allocator]
static ALLOC: wee_alloc::WeeAlloc = wee_alloc::WeeAlloc::INIT;
use api::*;
use canary_script::*;
canary_script::export_abi!(bind_panel_impl);
pub fn bind_panel_impl(panel: Panel, _protocol: Message, message: Message) -> Box<dyn PanelImpl> {
MusicPlayerPanel::bind(panel, message)
}
const DISPLAY_FONT: &str = "Liberation Sans";
pub struct MusicPlayerPanel {
panel: Panel,
display_font: Font,
label: Label,
}
impl PanelImpl for MusicPlayerPanel {
fn update(&mut self, dt: f32) {}
fn draw(&mut self) {
let ctx = DrawContext::new(self.panel);
let offset = Vec2 { x: 5.0, y: 12.0 };
let size = 8.0;
let color = Color::WHITE;
self.label.draw(&ctx, offset, size, color);
}
fn on_resize(&mut self, new_size: Vec2) {}
fn on_cursor_event(&mut self, kind: CursorEventKind, at: Vec2) {}
fn on_message(&mut self, msg: Message) {
use canary_music_player::{serde_json, InMsg};
let msg = msg.to_vec();
let msg = serde_json::from_slice::<InMsg>(&msg);
self.label.set_text(format!("{:#?}", msg));
}
}
impl MusicPlayerPanel {
pub fn bind(panel: Panel, _message: Message) -> Box<dyn PanelImpl> {
let display_font = Font::new(DISPLAY_FONT);
let label = Label::new(display_font, "Hello, world!".into(), 1.2);
let panel = Self {
panel,
display_font,
label,
};
Box::new(panel)
}
}
pub struct Label {
font: Font,
text: String,
line_height: f32,
layout: Option<Vec<TextLayout>>,
}
impl Label {
pub fn new(font: Font, text: String, line_height: f32) -> Self {
Self {
font,
text,
line_height,
layout: None,
}
}
pub fn draw(&mut self, ctx: &DrawContext, offset: Vec2, size: f32, color: Color) {
let layout = self.layout.get_or_insert_with(|| {
self.text
.lines()
.map(|line| TextLayout::new(&self.font, line))
.collect()
});
for (line, layout) in layout.iter().enumerate() {
let offset = Vec2 {
x: offset.x,
y: self.line_height * size * line as f32 + offset.y,
};
ctx.draw_text_layout(layout, offset.into(), size, color);
}
}
pub fn set_text(&mut self, text: String) {
self.text = text;
self.layout = None;
}
}