75 lines
2.6 KiB
Rust
75 lines
2.6 KiB
Rust
use std::collections::HashMap;
|
|
use wgpu_glyph::{GlyphBrush, ab_glyph::FontArc, GlyphBrushBuilder, Section, Text};
|
|
use wgpu::util::StagingBelt;
|
|
use futures::executor::LocalPool;
|
|
use futures::task::SpawnExt;
|
|
|
|
const WHITE: [f32; 4] = [1.0, 1.0, 1.0, 1.0];
|
|
const BLUE: [f32; 4] = [0.0, 0.2, 1.0, 1.0];
|
|
const GREEN: [f32; 4] = [0.1, 1.0, 0.0, 1.0];
|
|
|
|
|
|
pub struct UserInterface {
|
|
// Glyph drawing
|
|
staging_belt: StagingBelt,
|
|
local_pool: LocalPool,
|
|
brush: GlyphBrush<()>,
|
|
// Texts
|
|
texts: HashMap<String, Vec<String>>
|
|
}
|
|
|
|
impl UserInterface {
|
|
|
|
pub fn new(device: &mut wgpu::Device, render_format: wgpu::TextureFormat) -> Self {
|
|
let font = FontArc::try_from_slice(include_bytes!("../../assets/font.ttf")).unwrap();
|
|
Self {
|
|
staging_belt: StagingBelt::new(1024),
|
|
local_pool: LocalPool::new(),
|
|
brush: GlyphBrushBuilder::using_font(font).build(device, render_format),
|
|
texts: HashMap::new()
|
|
}
|
|
}
|
|
|
|
fn print(brush: &mut GlyphBrush<()>, line: u32, text: &str, color: [f32; 4]) {
|
|
let t = Text::new(text).with_color(color);
|
|
brush.queue(Section {
|
|
screen_position: (5 as f32, (5 + line*15) as f32),
|
|
bounds: (t.scale.x * t.text.len() as f32, t.scale.y),
|
|
text: vec![t],
|
|
..Section::default()
|
|
});
|
|
}
|
|
|
|
pub fn set_text(&mut self, cat: &str, line: usize, text: String) {
|
|
// Category
|
|
let c = &cat.to_string();
|
|
if !self.texts.contains_key(c) {self.texts.insert(c.clone(), Vec::new());}
|
|
// Texts
|
|
let v = self.texts.get_mut(c).unwrap();
|
|
while v.len() < line+1 { v.push(String::new()); }
|
|
v[line] = text;
|
|
}
|
|
|
|
pub fn render(&mut self, device: &wgpu::Device, encoder: &mut wgpu::CommandEncoder, target: &wgpu::TextureView, width: u32, height: u32) {
|
|
let mut line = 0;
|
|
for (cat, texts) in self.texts.iter_mut() {
|
|
UserInterface::print(&mut self.brush, line, cat, GREEN);
|
|
line += 1;
|
|
for text in texts.iter() {
|
|
UserInterface::print(&mut self.brush, line, text, WHITE);
|
|
line += 1;
|
|
}
|
|
line += 1;
|
|
}
|
|
|
|
// Draw
|
|
self.brush.draw_queued(&device, &mut self.staging_belt, encoder, target, width, height).expect("Draw queued");
|
|
self.staging_belt.finish();
|
|
}
|
|
|
|
pub fn recall(&mut self) {
|
|
// Reset staging belt after drawing
|
|
self.local_pool.spawner().spawn(self.staging_belt.recall()).expect("Recall staging belt");
|
|
self.local_pool.run_until_stalled();
|
|
}
|
|
} |