diff --git a/scripts/music-player/Cargo.toml b/scripts/music-player/Cargo.toml index f57dd5f..98fd0c9 100644 --- a/scripts/music-player/Cargo.toml +++ b/scripts/music-player/Cargo.toml @@ -9,4 +9,5 @@ crate-type = ["cdylib"] [dependencies] canary_script = { path = "../../crates/script" } canary-music-player-protocol = { path = "../../crates/music-player-protocol" } +serde_json = "1" wee_alloc = "^0.4" diff --git a/scripts/music-player/src/lib.rs b/scripts/music-player/src/lib.rs index b13533f..56d2bc9 100644 --- a/scripts/music-player/src/lib.rs +++ b/scripts/music-player/src/lib.rs @@ -1,7 +1,10 @@ #[global_allocator] static ALLOC: wee_alloc::WeeAlloc = wee_alloc::WeeAlloc::INIT; -use canary_script::{BindPanel, CursorEventKind, Color, TextLayout, Font, Message, Panel, PanelImpl, Vec2}; +use canary_script::{ + draw::DrawContext, BindPanel, Color, CursorEventKind, Font, Message, Panel, PanelImpl, + TextLayout, Vec2, +}; canary_script::export_abi!(MusicPlayerPanel); @@ -10,14 +13,17 @@ const DISPLAY_FONT: &str = "Liberation Sans"; pub struct MusicPlayerPanel { panel: Panel, display_font: Font, + label: Label, } impl BindPanel for MusicPlayerPanel { fn bind(panel: Panel, message: Message) -> Box { 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) } @@ -27,14 +33,61 @@ impl PanelImpl for MusicPlayerPanel { fn update(&mut self, dt: f32) {} fn draw(&mut self) { - let layout = TextLayout::new(&self.display_font, "Hello world!"); - let offset = Vec2 { x: 100.0, y: 100.0 }; - let scale = 14.0; + let ctx = DrawContext::new(self.panel); + + let offset = Vec2 { x: 5.0, y: 12.0 }; + let size = 8.0; let color = Color::WHITE; - self.panel.draw_text_layout(&layout, offset, scale, color); + self.label.draw(&ctx, offset, size, color); } fn on_cursor_event(&mut self, kind: CursorEventKind, at: Vec2) {} - fn on_message(&mut self, message: Message) {} + fn on_message(&mut self, msg: Message) { + use canary_music_player_protocol::InMsg; + let msg = msg.to_vec(); + let msg = serde_json::from_slice::(&msg); + self.label.set_text(format!("{:#?}", msg)); + } +} + +pub struct Label { + font: Font, + text: String, + line_height: f32, + layout: Option>, +} + +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; + } }