mirror of
https://github.com/roc-lang/roc.git
synced 2025-09-29 23:04:49 +00:00
refactored text drawing, fixed color shader bug
This commit is contained in:
parent
80cf1bde54
commit
0d46835135
6 changed files with 321 additions and 254 deletions
|
@ -3,6 +3,7 @@
|
||||||
use crate::rect::Rect;
|
use crate::rect::Rect;
|
||||||
use crate::util::size_of_slice;
|
use crate::util::size_of_slice;
|
||||||
use crate::vertex::Vertex;
|
use crate::vertex::Vertex;
|
||||||
|
use cgmath::Vector3;
|
||||||
use wgpu::util::{BufferInitDescriptor, DeviceExt};
|
use wgpu::util::{BufferInitDescriptor, DeviceExt};
|
||||||
|
|
||||||
pub struct QuadBufferBuilder {
|
pub struct QuadBufferBuilder {
|
||||||
|
@ -27,7 +28,7 @@ impl QuadBufferBuilder {
|
||||||
coords.y - rect.height,
|
coords.y - rect.height,
|
||||||
coords.x + rect.width,
|
coords.x + rect.width,
|
||||||
coords.y,
|
coords.y,
|
||||||
rect.color,
|
rect.color.into(),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -37,7 +38,7 @@ impl QuadBufferBuilder {
|
||||||
min_y: f32,
|
min_y: f32,
|
||||||
max_x: f32,
|
max_x: f32,
|
||||||
max_y: f32,
|
max_y: f32,
|
||||||
color: [f32; 3],
|
color: Vector3<f32>,
|
||||||
) -> Self {
|
) -> Self {
|
||||||
self.vertex_data.extend(&[
|
self.vertex_data.extend(&[
|
||||||
Vertex {
|
Vertex {
|
||||||
|
@ -78,6 +79,71 @@ impl QuadBufferBuilder {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub struct RectBuffers {
|
||||||
|
pub vertex_buffer: wgpu::Buffer,
|
||||||
|
pub index_buffer: wgpu::Buffer,
|
||||||
|
pub num_rects: u32,
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn create_rect_buffers(
|
||||||
|
gpu_device: &wgpu::Device,
|
||||||
|
encoder: &mut wgpu::CommandEncoder,
|
||||||
|
) -> RectBuffers {
|
||||||
|
// Test Rectangles
|
||||||
|
let test_rect_1 = Rect {
|
||||||
|
top_left_coords: (-0.2, 0.6).into(),
|
||||||
|
width: 0.1,
|
||||||
|
height: 0.5,
|
||||||
|
color: [0.0, 0.0, 1.0],
|
||||||
|
};
|
||||||
|
let test_rect_2 = Rect {
|
||||||
|
top_left_coords: (-0.5, 0.0).into(),
|
||||||
|
width: 0.5,
|
||||||
|
height: 0.5,
|
||||||
|
color: [0.0, 1.0, 0.0],
|
||||||
|
};
|
||||||
|
let test_rect_3 = Rect {
|
||||||
|
top_left_coords: (0.3, 0.3).into(),
|
||||||
|
width: 0.6,
|
||||||
|
height: 0.1,
|
||||||
|
color: [1.0, 0.0, 0.0],
|
||||||
|
};
|
||||||
|
|
||||||
|
let vertex_buffer = gpu_device.create_buffer(&wgpu::BufferDescriptor {
|
||||||
|
label: None,
|
||||||
|
size: Vertex::SIZE * 4 * 3,
|
||||||
|
usage: wgpu::BufferUsage::VERTEX | wgpu::BufferUsage::COPY_DST,
|
||||||
|
mapped_at_creation: false,
|
||||||
|
});
|
||||||
|
|
||||||
|
let u32_size = std::mem::size_of::<u32>() as wgpu::BufferAddress;
|
||||||
|
|
||||||
|
let index_buffer = gpu_device.create_buffer(&wgpu::BufferDescriptor {
|
||||||
|
label: None,
|
||||||
|
size: u32_size * 6 * 3,
|
||||||
|
usage: wgpu::BufferUsage::INDEX | wgpu::BufferUsage::COPY_DST,
|
||||||
|
mapped_at_creation: false,
|
||||||
|
});
|
||||||
|
|
||||||
|
let num_rects = {
|
||||||
|
let (stg_vertex, stg_index, num_indices) = QuadBufferBuilder::new()
|
||||||
|
.push_rect(&test_rect_1)
|
||||||
|
.push_rect(&test_rect_2)
|
||||||
|
.push_rect(&test_rect_3)
|
||||||
|
.build(&gpu_device);
|
||||||
|
|
||||||
|
stg_vertex.copy_to_buffer(encoder, &vertex_buffer);
|
||||||
|
stg_index.copy_to_buffer(encoder, &index_buffer);
|
||||||
|
num_indices
|
||||||
|
};
|
||||||
|
|
||||||
|
RectBuffers {
|
||||||
|
vertex_buffer,
|
||||||
|
index_buffer,
|
||||||
|
num_rects,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pub struct StagingBuffer {
|
pub struct StagingBuffer {
|
||||||
buffer: wgpu::Buffer,
|
buffer: wgpu::Buffer,
|
||||||
size: wgpu::BufferAddress,
|
size: wgpu::BufferAddress,
|
||||||
|
|
153
editor/src/keyboard_input.rs
Normal file
153
editor/src/keyboard_input.rs
Normal file
|
@ -0,0 +1,153 @@
|
||||||
|
use winit::event::{ElementState, ModifiersState, VirtualKeyCode};
|
||||||
|
|
||||||
|
pub fn handle_keydown(
|
||||||
|
elem_state: ElementState,
|
||||||
|
virtual_keycode: VirtualKeyCode,
|
||||||
|
_modifiers: ModifiersState,
|
||||||
|
) {
|
||||||
|
use winit::event::VirtualKeyCode::*;
|
||||||
|
|
||||||
|
if let ElementState::Released = elem_state {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
match virtual_keycode {
|
||||||
|
Copy => {
|
||||||
|
todo!("copy");
|
||||||
|
}
|
||||||
|
Paste => {
|
||||||
|
todo!("paste");
|
||||||
|
}
|
||||||
|
Cut => {
|
||||||
|
todo!("cut");
|
||||||
|
}
|
||||||
|
_ => {}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// pub fn handle_text_input(
|
||||||
|
// text_state: &mut String,
|
||||||
|
// elem_state: ElementState,
|
||||||
|
// virtual_keycode: VirtualKeyCode,
|
||||||
|
// _modifiers: ModifiersState,
|
||||||
|
// ) {
|
||||||
|
// use winit::event::VirtualKeyCode::*;
|
||||||
|
|
||||||
|
// if let ElementState::Released = elem_state {
|
||||||
|
// return;
|
||||||
|
// }
|
||||||
|
|
||||||
|
// match virtual_keycode {
|
||||||
|
// Key1 | Numpad1 => text_state.push('1'),
|
||||||
|
// Key2 | Numpad2 => text_state.push('2'),
|
||||||
|
// Key3 | Numpad3 => text_state.push('3'),
|
||||||
|
// Key4 | Numpad4 => text_state.push('4'),
|
||||||
|
// Key5 | Numpad5 => text_state.push('5'),
|
||||||
|
// Key6 | Numpad6 => text_state.push('6'),
|
||||||
|
// Key7 | Numpad7 => text_state.push('7'),
|
||||||
|
// Key8 | Numpad8 => text_state.push('8'),
|
||||||
|
// Key9 | Numpad9 => text_state.push('9'),
|
||||||
|
// Key0 | Numpad0 => text_state.push('0'),
|
||||||
|
// A => text_state.push('a'),
|
||||||
|
// B => text_state.push('b'),
|
||||||
|
// C => text_state.push('c'),
|
||||||
|
// D => text_state.push('d'),
|
||||||
|
// E => text_state.push('e'),
|
||||||
|
// F => text_state.push('f'),
|
||||||
|
// G => text_state.push('g'),
|
||||||
|
// H => text_state.push('h'),
|
||||||
|
// I => text_state.push('i'),
|
||||||
|
// J => text_state.push('j'),
|
||||||
|
// K => text_state.push('k'),
|
||||||
|
// L => text_state.push('l'),
|
||||||
|
// M => text_state.push('m'),
|
||||||
|
// N => text_state.push('n'),
|
||||||
|
// O => text_state.push('o'),
|
||||||
|
// P => text_state.push('p'),
|
||||||
|
// Q => text_state.push('q'),
|
||||||
|
// R => text_state.push('r'),
|
||||||
|
// S => text_state.push('s'),
|
||||||
|
// T => text_state.push('t'),
|
||||||
|
// U => text_state.push('u'),
|
||||||
|
// V => text_state.push('v'),
|
||||||
|
// W => text_state.push('w'),
|
||||||
|
// X => text_state.push('x'),
|
||||||
|
// Y => text_state.push('y'),
|
||||||
|
// Z => text_state.push('z'),
|
||||||
|
// Escape | F1 | F2 | F3 | F4 | F5 | F6 | F7 | F8 | F9 | F10 | F11 | F12 | F13 | F14 | F15
|
||||||
|
// | F16 | F17 | F18 | F19 | F20 | F21 | F22 | F23 | F24 | Snapshot | Scroll | Pause
|
||||||
|
// | Insert | Home | Delete | End | PageDown | PageUp | Left | Up | Right | Down | Compose
|
||||||
|
// | Caret | Numlock | AbntC1 | AbntC2 | Ax | Calculator | Capital | Convert | Kana
|
||||||
|
// | Kanji | LAlt | LBracket | LControl | LShift | LWin | Mail | MediaSelect | PlayPause
|
||||||
|
// | Power | PrevTrack | MediaStop | Mute | MyComputer | NavigateForward
|
||||||
|
// | NavigateBackward | NextTrack | NoConvert | OEM102 | RAlt | Sysrq | RBracket
|
||||||
|
// | RControl | RShift | RWin | Sleep | Stop | Unlabeled | VolumeDown | VolumeUp | Wake
|
||||||
|
// | WebBack | WebFavorites | WebForward | WebHome | WebRefresh | WebSearch | Apps | Tab
|
||||||
|
// | WebStop => {
|
||||||
|
// // TODO handle
|
||||||
|
// }
|
||||||
|
// Back => {
|
||||||
|
// text_state.pop();
|
||||||
|
// }
|
||||||
|
// Return | NumpadEnter => {
|
||||||
|
// text_state.push('\n');
|
||||||
|
// }
|
||||||
|
// Space => {
|
||||||
|
// text_state.push(' ');
|
||||||
|
// }
|
||||||
|
// Comma | NumpadComma => {
|
||||||
|
// text_state.push(',');
|
||||||
|
// }
|
||||||
|
// Add => {
|
||||||
|
// text_state.push('+');
|
||||||
|
// }
|
||||||
|
// Apostrophe => {
|
||||||
|
// text_state.push('\'');
|
||||||
|
// }
|
||||||
|
// At => {
|
||||||
|
// text_state.push('@');
|
||||||
|
// }
|
||||||
|
// Backslash => {
|
||||||
|
// text_state.push('\\');
|
||||||
|
// }
|
||||||
|
// Colon => {
|
||||||
|
// text_state.push(':');
|
||||||
|
// }
|
||||||
|
// Period | Decimal => {
|
||||||
|
// text_state.push('.');
|
||||||
|
// }
|
||||||
|
// Equals | NumpadEquals => {
|
||||||
|
// text_state.push('=');
|
||||||
|
// }
|
||||||
|
// Grave => {
|
||||||
|
// text_state.push('`');
|
||||||
|
// }
|
||||||
|
// Minus | Subtract => {
|
||||||
|
// text_state.push('-');
|
||||||
|
// }
|
||||||
|
// Multiply => {
|
||||||
|
// text_state.push('*');
|
||||||
|
// }
|
||||||
|
// Semicolon => {
|
||||||
|
// text_state.push(';');
|
||||||
|
// }
|
||||||
|
// Slash | Divide => {
|
||||||
|
// text_state.push('/');
|
||||||
|
// }
|
||||||
|
// Underline => {
|
||||||
|
// text_state.push('_');
|
||||||
|
// }
|
||||||
|
// Yen => {
|
||||||
|
// text_state.push('¥');
|
||||||
|
// }
|
||||||
|
// Copy => {
|
||||||
|
// todo!("copy");
|
||||||
|
// }
|
||||||
|
// Paste => {
|
||||||
|
// todo!("paste");
|
||||||
|
// }
|
||||||
|
// Cut => {
|
||||||
|
// todo!("cut");
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// }
|
|
@ -16,22 +16,22 @@
|
||||||
|
|
||||||
// See this link to learn wgpu: https://sotrh.github.io/learn-wgpu/
|
// See this link to learn wgpu: https://sotrh.github.io/learn-wgpu/
|
||||||
|
|
||||||
use crate::buffer::QuadBufferBuilder;
|
use crate::buffer::create_rect_buffers;
|
||||||
use crate::rect::Rect;
|
use crate::text::{build_glyph_brush, Text};
|
||||||
use crate::vertex::Vertex;
|
use crate::vertex::Vertex;
|
||||||
use std::error::Error;
|
use std::error::Error;
|
||||||
use std::io;
|
use std::io;
|
||||||
use std::path::Path;
|
use std::path::Path;
|
||||||
use wgpu_glyph::{ab_glyph, GlyphBrushBuilder, Section, Text};
|
|
||||||
use winit::event;
|
use winit::event;
|
||||||
use winit::event::{ElementState, Event, ModifiersState, VirtualKeyCode};
|
use winit::event::{Event, ModifiersState};
|
||||||
use winit::event_loop::ControlFlow;
|
use winit::event_loop::ControlFlow;
|
||||||
|
|
||||||
pub mod ast;
|
pub mod ast;
|
||||||
mod buffer;
|
mod buffer;
|
||||||
pub mod file;
|
pub mod file;
|
||||||
|
mod keyboard_input;
|
||||||
mod rect;
|
mod rect;
|
||||||
pub mod text_state;
|
pub mod text;
|
||||||
mod util;
|
mod util;
|
||||||
mod vertex;
|
mod vertex;
|
||||||
|
|
||||||
|
@ -104,12 +104,7 @@ fn run_event_loop() -> Result<(), Box<dyn Error>> {
|
||||||
|
|
||||||
let rect_pipeline = make_rect_pipeline(&gpu_device, &swap_chain_descr);
|
let rect_pipeline = make_rect_pipeline(&gpu_device, &swap_chain_descr);
|
||||||
|
|
||||||
// Prepare glyph_brush
|
let mut glyph_brush = build_glyph_brush(&gpu_device, render_format)?;
|
||||||
let inconsolata =
|
|
||||||
ab_glyph::FontArc::try_from_slice(include_bytes!("../Inconsolata-Regular.ttf"))?;
|
|
||||||
|
|
||||||
let mut glyph_brush =
|
|
||||||
GlyphBrushBuilder::using_font(inconsolata).build(&gpu_device, render_format);
|
|
||||||
|
|
||||||
let is_animating = true;
|
let is_animating = true;
|
||||||
let mut text_state = String::new();
|
let mut text_state = String::new();
|
||||||
|
@ -161,7 +156,11 @@ fn run_event_loop() -> Result<(), Box<dyn Error>> {
|
||||||
..
|
..
|
||||||
} => {
|
} => {
|
||||||
if let Some(virtual_keycode) = input.virtual_keycode {
|
if let Some(virtual_keycode) = input.virtual_keycode {
|
||||||
handle_keydown(input.state, virtual_keycode, keyboard_modifiers);
|
keyboard_input::handle_keydown(
|
||||||
|
input.state,
|
||||||
|
virtual_keycode,
|
||||||
|
keyboard_modifiers,
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Event::WindowEvent {
|
Event::WindowEvent {
|
||||||
|
@ -203,7 +202,7 @@ fn run_event_loop() -> Result<(), Box<dyn Error>> {
|
||||||
|
|
||||||
drop(render_pass);
|
drop(render_pass);
|
||||||
|
|
||||||
draw_text(
|
draw_all_text(
|
||||||
&gpu_device,
|
&gpu_device,
|
||||||
&mut staging_belt,
|
&mut staging_belt,
|
||||||
&mut encoder,
|
&mut encoder,
|
||||||
|
@ -294,72 +293,7 @@ fn create_render_pipeline(
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
struct RectBuffers {
|
fn draw_all_text(
|
||||||
vertex_buffer: wgpu::Buffer,
|
|
||||||
index_buffer: wgpu::Buffer,
|
|
||||||
num_rects: u32,
|
|
||||||
}
|
|
||||||
|
|
||||||
fn create_rect_buffers(
|
|
||||||
gpu_device: &wgpu::Device,
|
|
||||||
encoder: &mut wgpu::CommandEncoder,
|
|
||||||
) -> RectBuffers {
|
|
||||||
// Test Rectangles
|
|
||||||
let test_rect_1 = Rect {
|
|
||||||
top_left_coords: (-0.2, 0.6).into(),
|
|
||||||
width: 0.1,
|
|
||||||
height: 0.5,
|
|
||||||
color: [0.0, 0.0, 1.0],
|
|
||||||
};
|
|
||||||
let test_rect_2 = Rect {
|
|
||||||
top_left_coords: (-0.5, 0.0).into(),
|
|
||||||
width: 0.5,
|
|
||||||
height: 0.5,
|
|
||||||
color: [0.0, 1.0, 0.0],
|
|
||||||
};
|
|
||||||
let test_rect_3 = Rect {
|
|
||||||
top_left_coords: (0.3, 0.3).into(),
|
|
||||||
width: 0.6,
|
|
||||||
height: 0.1,
|
|
||||||
color: [0.0, 0.0, 1.0],
|
|
||||||
};
|
|
||||||
|
|
||||||
let vertex_buffer = gpu_device.create_buffer(&wgpu::BufferDescriptor {
|
|
||||||
label: None,
|
|
||||||
size: Vertex::SIZE * 4 * 3,
|
|
||||||
usage: wgpu::BufferUsage::VERTEX | wgpu::BufferUsage::COPY_DST,
|
|
||||||
mapped_at_creation: false,
|
|
||||||
});
|
|
||||||
|
|
||||||
let u32_size = std::mem::size_of::<u32>() as wgpu::BufferAddress;
|
|
||||||
|
|
||||||
let index_buffer = gpu_device.create_buffer(&wgpu::BufferDescriptor {
|
|
||||||
label: None,
|
|
||||||
size: u32_size * 6 * 3,
|
|
||||||
usage: wgpu::BufferUsage::INDEX | wgpu::BufferUsage::COPY_DST,
|
|
||||||
mapped_at_creation: false,
|
|
||||||
});
|
|
||||||
|
|
||||||
let num_rects = {
|
|
||||||
let (stg_vertex, stg_index, num_indices) = QuadBufferBuilder::new()
|
|
||||||
.push_rect(&test_rect_1)
|
|
||||||
.push_rect(&test_rect_2)
|
|
||||||
.push_rect(&test_rect_3)
|
|
||||||
.build(&gpu_device);
|
|
||||||
|
|
||||||
stg_vertex.copy_to_buffer(encoder, &vertex_buffer);
|
|
||||||
stg_index.copy_to_buffer(encoder, &index_buffer);
|
|
||||||
num_indices
|
|
||||||
};
|
|
||||||
|
|
||||||
RectBuffers {
|
|
||||||
vertex_buffer,
|
|
||||||
index_buffer,
|
|
||||||
num_rects,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn draw_text(
|
|
||||||
gpu_device: &wgpu::Device,
|
gpu_device: &wgpu::Device,
|
||||||
staging_belt: &mut wgpu::util::StagingBelt,
|
staging_belt: &mut wgpu::util::StagingBelt,
|
||||||
encoder: &mut wgpu::CommandEncoder,
|
encoder: &mut wgpu::CommandEncoder,
|
||||||
|
@ -368,25 +302,30 @@ fn draw_text(
|
||||||
text_state: &str,
|
text_state: &str,
|
||||||
glyph_brush: &mut wgpu_glyph::GlyphBrush<()>,
|
glyph_brush: &mut wgpu_glyph::GlyphBrush<()>,
|
||||||
) {
|
) {
|
||||||
glyph_brush.queue(Section {
|
let bounds = (size.width as f32, size.height as f32).into();
|
||||||
screen_position: (30.0, 30.0),
|
|
||||||
bounds: (size.width as f32, size.height as f32),
|
|
||||||
text: vec![Text::new("Enter some text:")
|
|
||||||
.with_color([0.4666, 0.2, 1.0, 1.0])
|
|
||||||
.with_scale(40.0)],
|
|
||||||
..Section::default()
|
|
||||||
});
|
|
||||||
|
|
||||||
glyph_brush.queue(Section {
|
let main_label = Text {
|
||||||
screen_position: (30.0, 90.0),
|
position: (30.0, 30.0).into(),
|
||||||
bounds: (size.width as f32, size.height as f32),
|
bounds,
|
||||||
text: vec![Text::new(format!("{}|", text_state).as_str())
|
color: (0.4666, 0.2, 1.0, 1.0).into(),
|
||||||
.with_color([1.0, 1.0, 1.0, 1.0])
|
text: String::from("Enter some text:"),
|
||||||
.with_scale(40.0)],
|
size: 40.0,
|
||||||
..Section::default()
|
..Default::default()
|
||||||
});
|
};
|
||||||
|
|
||||||
|
let code_text = Text {
|
||||||
|
position: (30.0, 90.0).into(),
|
||||||
|
bounds,
|
||||||
|
color: (1.0, 1.0, 1.0, 1.0).into(),
|
||||||
|
text: String::from(format!("{}|", text_state).as_str()),
|
||||||
|
size: 40.0,
|
||||||
|
..Default::default()
|
||||||
|
};
|
||||||
|
|
||||||
|
text::queue_text_draw(&main_label, glyph_brush);
|
||||||
|
|
||||||
|
text::queue_text_draw(&code_text, glyph_brush);
|
||||||
|
|
||||||
// Draw the text!
|
|
||||||
glyph_brush
|
glyph_brush
|
||||||
.draw_queued(
|
.draw_queued(
|
||||||
gpu_device,
|
gpu_device,
|
||||||
|
@ -415,28 +354,3 @@ fn update_text_state(text_state: &mut String, received_char: &char) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn handle_keydown(
|
|
||||||
elem_state: ElementState,
|
|
||||||
virtual_keycode: VirtualKeyCode,
|
|
||||||
_modifiers: ModifiersState,
|
|
||||||
) {
|
|
||||||
use winit::event::VirtualKeyCode::*;
|
|
||||||
|
|
||||||
if let ElementState::Released = elem_state {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
match virtual_keycode {
|
|
||||||
Copy => {
|
|
||||||
todo!("copy");
|
|
||||||
}
|
|
||||||
Paste => {
|
|
||||||
todo!("paste");
|
|
||||||
}
|
|
||||||
Cut => {
|
|
||||||
todo!("cut");
|
|
||||||
}
|
|
||||||
_ => {}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
62
editor/src/text.rs
Normal file
62
editor/src/text.rs
Normal file
|
@ -0,0 +1,62 @@
|
||||||
|
// Adapted from https://github.com/sotrh/learn-wgpu
|
||||||
|
// by Benjamin Hansen, licensed under the MIT license
|
||||||
|
|
||||||
|
use ab_glyph::{FontArc, InvalidFont};
|
||||||
|
use cgmath::{Vector2, Vector4};
|
||||||
|
use wgpu_glyph::{ab_glyph, GlyphBrush, GlyphBrushBuilder, Section};
|
||||||
|
|
||||||
|
#[derive(Debug)]
|
||||||
|
pub struct Text {
|
||||||
|
pub position: Vector2<f32>,
|
||||||
|
pub bounds: Vector2<f32>,
|
||||||
|
pub color: Vector4<f32>,
|
||||||
|
pub text: String,
|
||||||
|
pub size: f32,
|
||||||
|
pub visible: bool,
|
||||||
|
pub centered: bool,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Default for Text {
|
||||||
|
fn default() -> Self {
|
||||||
|
Self {
|
||||||
|
position: (0.0, 0.0).into(),
|
||||||
|
bounds: (std::f32::INFINITY, std::f32::INFINITY).into(),
|
||||||
|
color: (1.0, 1.0, 1.0, 1.0).into(),
|
||||||
|
text: String::new(),
|
||||||
|
size: 16.0,
|
||||||
|
visible: true,
|
||||||
|
centered: false,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn queue_text_draw(text: &Text, glyph_brush: &mut GlyphBrush<()>) {
|
||||||
|
let layout = wgpu_glyph::Layout::default().h_align(if text.centered {
|
||||||
|
wgpu_glyph::HorizontalAlign::Center
|
||||||
|
} else {
|
||||||
|
wgpu_glyph::HorizontalAlign::Left
|
||||||
|
});
|
||||||
|
|
||||||
|
let section = Section {
|
||||||
|
screen_position: text.position.into(),
|
||||||
|
bounds: text.bounds.into(),
|
||||||
|
layout,
|
||||||
|
..Section::default()
|
||||||
|
}
|
||||||
|
.add_text(
|
||||||
|
wgpu_glyph::Text::new(&text.text)
|
||||||
|
.with_color(text.color)
|
||||||
|
.with_scale(text.size),
|
||||||
|
);
|
||||||
|
|
||||||
|
glyph_brush.queue(section);
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn build_glyph_brush(
|
||||||
|
gpu_device: &wgpu::Device,
|
||||||
|
render_format: wgpu::TextureFormat,
|
||||||
|
) -> Result<GlyphBrush<()>, InvalidFont> {
|
||||||
|
let inconsolata = FontArc::try_from_slice(include_bytes!("../Inconsolata-Regular.ttf"))?;
|
||||||
|
|
||||||
|
Ok(GlyphBrushBuilder::using_font(inconsolata).build(&gpu_device, render_format))
|
||||||
|
}
|
|
@ -1,128 +0,0 @@
|
||||||
use winit::event::{ElementState, ModifiersState, VirtualKeyCode};
|
|
||||||
|
|
||||||
pub fn handle_text_input(
|
|
||||||
text_state: &mut String,
|
|
||||||
elem_state: ElementState,
|
|
||||||
virtual_keycode: VirtualKeyCode,
|
|
||||||
_modifiers: ModifiersState,
|
|
||||||
) {
|
|
||||||
use winit::event::VirtualKeyCode::*;
|
|
||||||
|
|
||||||
if let ElementState::Released = elem_state {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
match virtual_keycode {
|
|
||||||
Key1 | Numpad1 => text_state.push('1'),
|
|
||||||
Key2 | Numpad2 => text_state.push('2'),
|
|
||||||
Key3 | Numpad3 => text_state.push('3'),
|
|
||||||
Key4 | Numpad4 => text_state.push('4'),
|
|
||||||
Key5 | Numpad5 => text_state.push('5'),
|
|
||||||
Key6 | Numpad6 => text_state.push('6'),
|
|
||||||
Key7 | Numpad7 => text_state.push('7'),
|
|
||||||
Key8 | Numpad8 => text_state.push('8'),
|
|
||||||
Key9 | Numpad9 => text_state.push('9'),
|
|
||||||
Key0 | Numpad0 => text_state.push('0'),
|
|
||||||
A => text_state.push('a'),
|
|
||||||
B => text_state.push('b'),
|
|
||||||
C => text_state.push('c'),
|
|
||||||
D => text_state.push('d'),
|
|
||||||
E => text_state.push('e'),
|
|
||||||
F => text_state.push('f'),
|
|
||||||
G => text_state.push('g'),
|
|
||||||
H => text_state.push('h'),
|
|
||||||
I => text_state.push('i'),
|
|
||||||
J => text_state.push('j'),
|
|
||||||
K => text_state.push('k'),
|
|
||||||
L => text_state.push('l'),
|
|
||||||
M => text_state.push('m'),
|
|
||||||
N => text_state.push('n'),
|
|
||||||
O => text_state.push('o'),
|
|
||||||
P => text_state.push('p'),
|
|
||||||
Q => text_state.push('q'),
|
|
||||||
R => text_state.push('r'),
|
|
||||||
S => text_state.push('s'),
|
|
||||||
T => text_state.push('t'),
|
|
||||||
U => text_state.push('u'),
|
|
||||||
V => text_state.push('v'),
|
|
||||||
W => text_state.push('w'),
|
|
||||||
X => text_state.push('x'),
|
|
||||||
Y => text_state.push('y'),
|
|
||||||
Z => text_state.push('z'),
|
|
||||||
Escape | F1 | F2 | F3 | F4 | F5 | F6 | F7 | F8 | F9 | F10 | F11 | F12 | F13 | F14 | F15
|
|
||||||
| F16 | F17 | F18 | F19 | F20 | F21 | F22 | F23 | F24 | Snapshot | Scroll | Pause
|
|
||||||
| Insert | Home | Delete | End | PageDown | PageUp | Left | Up | Right | Down | Compose
|
|
||||||
| Caret | Numlock | AbntC1 | AbntC2 | Ax | Calculator | Capital | Convert | Kana
|
|
||||||
| Kanji | LAlt | LBracket | LControl | LShift | LWin | Mail | MediaSelect | PlayPause
|
|
||||||
| Power | PrevTrack | MediaStop | Mute | MyComputer | NavigateForward
|
|
||||||
| NavigateBackward | NextTrack | NoConvert | OEM102 | RAlt | Sysrq | RBracket
|
|
||||||
| RControl | RShift | RWin | Sleep | Stop | Unlabeled | VolumeDown | VolumeUp | Wake
|
|
||||||
| WebBack | WebFavorites | WebForward | WebHome | WebRefresh | WebSearch | Apps | Tab
|
|
||||||
| WebStop => {
|
|
||||||
// TODO handle
|
|
||||||
}
|
|
||||||
Back => {
|
|
||||||
text_state.pop();
|
|
||||||
}
|
|
||||||
Return | NumpadEnter => {
|
|
||||||
text_state.push('\n');
|
|
||||||
}
|
|
||||||
Space => {
|
|
||||||
text_state.push(' ');
|
|
||||||
}
|
|
||||||
Comma | NumpadComma => {
|
|
||||||
text_state.push(',');
|
|
||||||
}
|
|
||||||
Add => {
|
|
||||||
text_state.push('+');
|
|
||||||
}
|
|
||||||
Apostrophe => {
|
|
||||||
text_state.push('\'');
|
|
||||||
}
|
|
||||||
At => {
|
|
||||||
text_state.push('@');
|
|
||||||
}
|
|
||||||
Backslash => {
|
|
||||||
text_state.push('\\');
|
|
||||||
}
|
|
||||||
Colon => {
|
|
||||||
text_state.push(':');
|
|
||||||
}
|
|
||||||
Period | Decimal => {
|
|
||||||
text_state.push('.');
|
|
||||||
}
|
|
||||||
Equals | NumpadEquals => {
|
|
||||||
text_state.push('=');
|
|
||||||
}
|
|
||||||
Grave => {
|
|
||||||
text_state.push('`');
|
|
||||||
}
|
|
||||||
Minus | Subtract => {
|
|
||||||
text_state.push('-');
|
|
||||||
}
|
|
||||||
Multiply => {
|
|
||||||
text_state.push('*');
|
|
||||||
}
|
|
||||||
Semicolon => {
|
|
||||||
text_state.push(';');
|
|
||||||
}
|
|
||||||
Slash | Divide => {
|
|
||||||
text_state.push('/');
|
|
||||||
}
|
|
||||||
Underline => {
|
|
||||||
text_state.push('_');
|
|
||||||
}
|
|
||||||
Yen => {
|
|
||||||
text_state.push('¥');
|
|
||||||
}
|
|
||||||
Copy => {
|
|
||||||
todo!("copy");
|
|
||||||
}
|
|
||||||
Paste => {
|
|
||||||
todo!("paste");
|
|
||||||
}
|
|
||||||
Cut => {
|
|
||||||
todo!("cut");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,12 +1,12 @@
|
||||||
// Taken from https://github.com/sotrh/learn-wgpu
|
// Taken from https://github.com/sotrh/learn-wgpu
|
||||||
// by Benjamin Hansen, licensed under the MIT license
|
// by Benjamin Hansen, licensed under the MIT license
|
||||||
use cgmath::Vector2;
|
use cgmath::{Vector2, Vector3};
|
||||||
|
|
||||||
#[derive(Copy, Clone)]
|
#[derive(Copy, Clone)]
|
||||||
pub struct Vertex {
|
pub struct Vertex {
|
||||||
#[allow(dead_code)]
|
#[allow(dead_code)]
|
||||||
pub position: Vector2<f32>,
|
pub position: Vector2<f32>,
|
||||||
pub color: [f32; 3],
|
pub color: Vector3<f32>,
|
||||||
}
|
}
|
||||||
|
|
||||||
unsafe impl bytemuck::Pod for Vertex {}
|
unsafe impl bytemuck::Pod for Vertex {}
|
||||||
|
@ -26,7 +26,7 @@ impl Vertex {
|
||||||
},
|
},
|
||||||
// color
|
// color
|
||||||
wgpu::VertexAttributeDescriptor {
|
wgpu::VertexAttributeDescriptor {
|
||||||
offset: std::mem::size_of::<[f32; 3]>() as wgpu::BufferAddress,
|
offset: std::mem::size_of::<[f32; 2]>() as wgpu::BufferAddress,
|
||||||
shader_location: 1,
|
shader_location: 1,
|
||||||
format: wgpu::VertexFormat::Float3,
|
format: wgpu::VertexFormat::Float3,
|
||||||
},
|
},
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue