From b86220ae90a54add64976a83a74963011ba4e66d Mon Sep 17 00:00:00 2001 From: Michael Sippel Date: Mon, 6 Sep 2021 00:08:36 +0200 Subject: [PATCH 01/16] first color editor --- Cargo.toml | 1 + nested/src/integer/editor.rs | 13 +++- sdf_editor/Cargo.toml | 18 +++++ sdf_editor/src/main.rs | 124 +++++++++++++++++++++++++++++++++++ 4 files changed, 155 insertions(+), 1 deletion(-) create mode 100644 sdf_editor/Cargo.toml create mode 100644 sdf_editor/src/main.rs diff --git a/Cargo.toml b/Cargo.toml index c3f151d..30c441b 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -4,6 +4,7 @@ members = [ "terminal/display_server", "terminal/ansi_parser", "shell", + "sdf_editor", "math/str2int", "math/int2str", "math/radix_transform", diff --git a/nested/src/integer/editor.rs b/nested/src/integer/editor.rs index 0281a94..72d2678 100644 --- a/nested/src/integer/editor.rs +++ b/nested/src/integer/editor.rs @@ -6,7 +6,7 @@ use { crate::{ core::{ViewPort, OuterViewPort, Observer}, singleton::{SingletonView, SingletonBuffer}, - sequence::{SequenceView}, + sequence::{SequenceView, SequenceViewExt}, vec::VecBuffer, terminal::{TerminalAtom, TerminalStyle, TerminalView, TerminalEvent, TerminalEditor, TerminalEditorResult}, tree_nav::{TreeNav, TreeNavResult, TerminalTreeEditor, TreeCursor}, @@ -102,6 +102,17 @@ impl PosIntEditor { self.digits_editor.get_data_port() .filter_map(move |digit_editor| digit_editor.read().unwrap().data.get()?.to_digit(radix)) } + + pub fn get_value(&self) -> u32 { + let mut value = 0; + let mut weight = 1; + for digit_value in self.get_data_port().get_view().unwrap().iter() { + value += digit_value * weight; + weight *= self.radix; + } + + value + } } impl TreeNav for PosIntEditor { diff --git a/sdf_editor/Cargo.toml b/sdf_editor/Cargo.toml new file mode 100644 index 0000000..44b1df3 --- /dev/null +++ b/sdf_editor/Cargo.toml @@ -0,0 +1,18 @@ +[package] +name = "sdf_editor" +version = "0.1.0" +edition = "2018" + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[dependencies] +nako = {git= "https://gitlab.com/tendsinmende/nako.git"} +nako_std = {git= "https://gitlab.com/tendsinmende/nako.git"} +nakorender = {git="https://gitlab.com/tendsinmende/nako.git", default-features = false} +nested = { path = "../nested" } +cgmath = "*" +termion = "*" + +[dependencies.async-std] +version = "1.9.0" +features = ["unstable", "attributes"] diff --git a/sdf_editor/src/main.rs b/sdf_editor/src/main.rs new file mode 100644 index 0000000..0823b6d --- /dev/null +++ b/sdf_editor/src/main.rs @@ -0,0 +1,124 @@ +use{ + std::sync::{Arc, RwLock}, + cgmath::{Point2, Vector2}, + termion::event::{Event, Key}, + nested::{ + core::{ + View, + ViewPort, + Observer, + OuterViewPort, + port::UpdateTask + }, + singleton::{SingletonBuffer, SingletonView}, + sequence::{SequenceView}, + integer::{PosIntEditor}, + terminal::{Terminal, TerminalCompositor, TerminalEvent, TerminalEditor}, + list::{ListEditor}, + tree_nav::{TreeNav} + } +}; + + +// projects a Sequence of ints to a color tuple +struct ColorCollector { + src_view: Option>>, + color: SingletonBuffer<(u8, u8, u8)> +} + +impl ColorCollector { + fn update(&mut self) { + if let Some(l) = self.src_view.as_ref() { + let r = l.get(&0).unwrap_or(0); + let g = l.get(&1).unwrap_or(0); + let b = l.get(&2).unwrap_or(0); + + self.color.set((r as u8, g as u8, b as u8)); + } + } +} + +impl Observer> for ColorCollector { + fn reset(&mut self, new_view: Option>>) { + self.src_view = new_view; + self.update(); + } + + fn notify(&mut self, idx: &usize) { + self.update(); + } +} + + +#[async_std::main] +async fn main() { + let term_port = ViewPort::new(); + let compositor = TerminalCompositor::new(term_port.inner()); + + let mut term = Terminal::new(term_port.outer()); + let term_writer = term.get_writer(); + + let mut color_editor = ListEditor::new( + || { + Arc::new(RwLock::new(PosIntEditor::new(16))) + }, + nested::list::ListEditorStyle::Clist + ); + + color_editor.goto(nested::tree_nav::TreeCursor { + leaf_mode: nested::list::ListCursorMode::Insert, + tree_addr: vec![ 0 ] + }); + + let color_port = ViewPort::new(); + let color_collector = Arc::new(RwLock::new(ColorCollector { + src_view: None, + color: SingletonBuffer::new((0, 0, 0), color_port.inner()) + })); + + color_editor.get_data_port().map( + |sub_editor| sub_editor.read().unwrap().get_value() + ).add_observer( + color_collector + ); + + compositor.write().unwrap().push(color_editor.get_term_view().offset(Vector2::new(2, 2))); + + async_std::task::spawn( + async move { + loop { + term_port.update(); + match term.next_event().await { + TerminalEvent::Input(Event::Key(Key::Ctrl('c'))) | + TerminalEvent::Input(Event::Key(Key::Ctrl('g'))) | + TerminalEvent::Input(Event::Key(Key::Ctrl('d'))) => break, + + TerminalEvent::Input(Event::Key(Key::Left)) => { + color_editor.pxev(); + } + TerminalEvent::Input(Event::Key(Key::Right)) => { + color_editor.nexd(); + } + TerminalEvent::Input(Event::Key(Key::Up)) => { + color_editor.up(); + } + TerminalEvent::Input(Event::Key(Key::Down)) => { + color_editor.dn(); + } + TerminalEvent::Input(Event::Key(Key::Home)) => { + color_editor.goto_home(); + } + TerminalEvent::Input(Event::Key(Key::End)) => { + color_editor.goto_end(); + } + event => { + color_editor.handle_terminal_event(&event); + } + } + } + } + ); + + term_writer.show().await.expect("output error!"); +} + From 4ce574ea78532fb1c36d7019eddd49246ae6a84e Mon Sep 17 00:00:00 2001 From: Tendsin Mende Date: Mon, 6 Sep 2021 00:56:51 +0200 Subject: [PATCH 02/16] initial sdf output --- sdf_editor/src/main.rs | 82 ++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 79 insertions(+), 3 deletions(-) diff --git a/sdf_editor/src/main.rs b/sdf_editor/src/main.rs index 0823b6d..63b15e2 100644 --- a/sdf_editor/src/main.rs +++ b/sdf_editor/src/main.rs @@ -16,7 +16,16 @@ use{ terminal::{Terminal, TerminalCompositor, TerminalEvent, TerminalEditor}, list::{ListEditor}, tree_nav::{TreeNav} - } + }, + nako::{ + stream::{SecondaryStream2d, PrimaryStream2d}, + glam::{Vec2, Vec3}, + operations::{ + planar::primitives2d::Box2d, + volumetric::{Color, Union, Round}, + }, + }, + nakorender::{backend::{Backend, LayerInfo}, winit, camera::Camera2d} }; @@ -32,7 +41,7 @@ impl ColorCollector { let r = l.get(&0).unwrap_or(0); let g = l.get(&1).unwrap_or(0); let b = l.get(&2).unwrap_or(0); - + println!("Set r: {}", r); self.color.set((r as u8, g as u8, b as u8)); } } @@ -83,11 +92,14 @@ async fn main() { ); compositor.write().unwrap().push(color_editor.get_term_view().offset(Vector2::new(2, 2))); + + let color_view = color_port.outer().get_view(); async_std::task::spawn( async move { loop { term_port.update(); + color_port.update(); match term.next_event().await { TerminalEvent::Input(Event::Key(Key::Ctrl('c'))) | TerminalEvent::Input(Event::Key(Key::Ctrl('g'))) | @@ -118,7 +130,71 @@ async fn main() { } } ); + + async_std::task::spawn(async move { + term_writer.show().await.expect("output error!"); + }); + + + let event_loop = nakorender::winit::event_loop::EventLoop::new(); + let window = nakorender::winit::window::Window::new(&event_loop).unwrap(); + let mut renderer = nakorender::marp::MarpBackend::new(&window, &event_loop); + + let id = renderer.new_layer_2d(); + renderer.set_layer_order(&[id.into()]); + renderer.update_camera_2d(id, Camera2d{ + extent: Vec2::new(2.0, 2.0), + location: Vec2::new(-1.0, -1.0), + rotation: 0.0 + }); - term_writer.show().await.expect("output error!"); + event_loop.run(move |event, _target, control_flow|{ + //Set to polling for now, might be overwritten + //TODO: Maybe we want to use "WAIT" for the ui thread? However, the renderers don't work that hard + //if nothing changes. So should be okay for a alpha style programm. + *control_flow = winit::event_loop::ControlFlow::Poll; + + + + //now check if a rerender was requested, or if we worked on all + //events on that batch + match event{ + winit::event::Event::WindowEvent{window_id: _, event: winit::event::WindowEvent::Resized(newsize)} => { + //update layer to cover whole window again. + renderer.set_layer_info(id.into(), LayerInfo{ + extent: (newsize.width as usize, newsize.height as usize), + location: (0,0) + }); + } + winit::event::Event::MainEventsCleared => { + window.request_redraw(); + } + winit::event::Event::RedrawRequested(_) => { + let new_sdf = sdf_from_color(color_view.get()); + renderer.update_sdf_2d(id, new_sdf); + + renderer.render(&window); + } + _ => {}, + } + + }) } + + +fn sdf_from_color(c: (u8, u8, u8)) -> PrimaryStream2d{ + PrimaryStream2d::new() + .push( + SecondaryStream2d::new( + Union, + Box2d{extent: Vec2::new(0.5, 0.5)} + ).push_mod(Color( + Vec3::new( + (c.0 as f32 / 255.0).clamp(0.0, 1.0), + (c.1 as f32 / 255.0).clamp(0.0, 1.0), + (c.2 as f32 / 255.0).clamp(0.0, 1.0), + ) + )).push_mod(Round{radius: 0.2}).build() + ).build() +} From 859a3f12ff06e775697c32c949dd2fda0966fd31 Mon Sep 17 00:00:00 2001 From: Michael Sippel Date: Mon, 6 Sep 2021 01:22:08 +0200 Subject: [PATCH 03/16] fix color update --- sdf_editor/src/main.rs | 22 ++++++++++++++++------ 1 file changed, 16 insertions(+), 6 deletions(-) diff --git a/sdf_editor/src/main.rs b/sdf_editor/src/main.rs index 63b15e2..d42912c 100644 --- a/sdf_editor/src/main.rs +++ b/sdf_editor/src/main.rs @@ -7,6 +7,7 @@ use{ View, ViewPort, Observer, + ObserverExt, OuterViewPort, port::UpdateTask }, @@ -41,7 +42,7 @@ impl ColorCollector { let r = l.get(&0).unwrap_or(0); let g = l.get(&1).unwrap_or(0); let b = l.get(&2).unwrap_or(0); - println!("Set r: {}", r); + self.color.set((r as u8, g as u8, b as u8)); } } @@ -82,13 +83,15 @@ async fn main() { let color_port = ViewPort::new(); let color_collector = Arc::new(RwLock::new(ColorCollector { src_view: None, - color: SingletonBuffer::new((0, 0, 0), color_port.inner()) + color: SingletonBuffer::new((200, 200, 0), color_port.inner()) })); - color_editor.get_data_port().map( + let col_seq_port = color_editor.get_data_port().map( |sub_editor| sub_editor.read().unwrap().get_value() - ).add_observer( - color_collector + ); + color_port.add_update_hook(Arc::new(col_seq_port.0.clone())); + col_seq_port.add_observer( + color_collector.clone() ); compositor.write().unwrap().push(color_editor.get_term_view().offset(Vector2::new(2, 2))); @@ -98,9 +101,16 @@ async fn main() { async_std::task::spawn( async move { loop { - term_port.update(); color_port.update(); + term_port.update(); match term.next_event().await { + TerminalEvent::Resize(new_size) => { + term_port.inner().get_broadcast().notify_each( + nested::grid::GridWindowIterator::from( + Point2::new(0,0) .. Point2::new(new_size.x, new_size.y) + ) + ); + } TerminalEvent::Input(Event::Key(Key::Ctrl('c'))) | TerminalEvent::Input(Event::Key(Key::Ctrl('g'))) | TerminalEvent::Input(Event::Key(Key::Ctrl('d'))) => break, From d647e45c26b4ae40a44d3fc37df845632451def2 Mon Sep 17 00:00:00 2001 From: Michael Sippel Date: Thu, 9 Sep 2021 18:18:48 +0200 Subject: [PATCH 04/16] sdfs: convert TerminalAtom to SDF --- sdf_editor/src/main.rs | 137 +++++++++++++++++++++++++++++++++-------- 1 file changed, 111 insertions(+), 26 deletions(-) diff --git a/sdf_editor/src/main.rs b/sdf_editor/src/main.rs index d42912c..533412f 100644 --- a/sdf_editor/src/main.rs +++ b/sdf_editor/src/main.rs @@ -14,7 +14,7 @@ use{ singleton::{SingletonBuffer, SingletonView}, sequence::{SequenceView}, integer::{PosIntEditor}, - terminal::{Terminal, TerminalCompositor, TerminalEvent, TerminalEditor}, + terminal::{Terminal, TerminalAtom, TerminalStyle, TerminalCompositor, TerminalEvent, TerminalEditor}, list::{ListEditor}, tree_nav::{TreeNav} }, @@ -26,10 +26,18 @@ use{ volumetric::{Color, Union, Round}, }, }, - nakorender::{backend::{Backend, LayerInfo}, winit, camera::Camera2d} + nakorender::{ + backend::{Backend, LayerId, LayerId2d, LayerInfo}, + marp::MarpBackend, + winit, camera::Camera2d + }, + nako_std::{ + text::Character + }, + std::{fs::File, io::Read, mem::needs_drop, path::Path}, + font_kit::font::Font, }; - // projects a Sequence of ints to a color tuple struct ColorCollector { src_view: Option>>, @@ -60,6 +68,64 @@ impl Observer> for ColorCollector { } +struct TermAtomSDF { + atom: TerminalAtom +} + +impl TermAtomSDF { + fn new(atom: TerminalAtom) -> Self { + TermAtomSDF { + atom + } + } + + fn update_bg(&self, layer_id: LayerId2d, renderer: &mut MarpBackend) { + let (r,g,b) = self.atom.style.bg_color.unwrap_or((0, 0, 0)); + + let stream = PrimaryStream2d::new() + .push( + SecondaryStream2d::new( + Union, + Box2d { + extent: Vec2::new(0.5, 1.0) + } + ).push_mod( + Color( + Vec3::new( + (r as f32 / 255.0).clamp(0.0, 1.0), + (g as f32 / 255.0).clamp(0.0, 1.0), + (b as f32 / 255.0).clamp(0.0, 1.0), + ) + ) + ).build() + ).build(); + + renderer.update_sdf_2d(layer_id, stream); + } + + fn update_ch(&self, layer_id: LayerId2d, renderer: &mut MarpBackend) { + if let Some(c) = self.atom.c { + let font = Font::from_path(Path::new("/usr/share/fonts/TTF/FiraCode-Light.ttf"),0).unwrap(); + let mut ch = Character::from_font(&font, c).with_size(1.0).with_tesselation_factor(0.2); + + let (r,g,b) = self.atom.style.fg_color.unwrap_or((0, 0, 0)); + + ch.color = Vec3::new( + (r as f32 / 255.0).clamp(0.0, 1.0), + (g as f32 / 255.0).clamp(0.0, 1.0), + (b as f32 / 255.0).clamp(0.0, 1.0), + ); + + let mut stream = PrimaryStream2d::new(); + stream = ch.record_character(stream); + renderer.update_sdf_2d(layer_id, stream.build()); + } else { + renderer.update_sdf_2d(layer_id, PrimaryStream2d::new().build()); + } + } +} + + #[async_std::main] async fn main() { let term_port = ViewPort::new(); @@ -126,6 +192,7 @@ async fn main() { } TerminalEvent::Input(Event::Key(Key::Down)) => { color_editor.dn(); + color_editor.goto_home(); } TerminalEvent::Input(Event::Key(Key::Home)) => { color_editor.goto_home(); @@ -144,20 +211,31 @@ async fn main() { async_std::task::spawn(async move { term_writer.show().await.expect("output error!"); }); - - + let event_loop = nakorender::winit::event_loop::EventLoop::new(); let window = nakorender::winit::window::Window::new(&event_loop).unwrap(); let mut renderer = nakorender::marp::MarpBackend::new(&window, &event_loop); - let id = renderer.new_layer_2d(); - renderer.set_layer_order(&[id.into()]); - renderer.update_camera_2d(id, Camera2d{ - extent: Vec2::new(2.0, 2.0), - location: Vec2::new(-1.0, -1.0), + let bg_id = renderer.new_layer_2d(); + renderer.update_camera_2d(bg_id, Camera2d{ + extent: Vec2::new(10.0, 10.0), + location: Vec2::new(0.0, 0.0), rotation: 0.0 }); - + + let ch_id = renderer.new_layer_2d(); + renderer.update_camera_2d(ch_id, Camera2d{ + extent: Vec2::new(10.0, 10.0), + location: Vec2::new(0.0, 0.0), + rotation: 0.0 + }); + + renderer.set_layer_order(&[bg_id.into(), ch_id.into()]); + + let asdf = TermAtomSDF::new(TerminalAtom::new('H', TerminalStyle::fg_color((98, 200, 60)).add(TerminalStyle::bg_color((40,40,40))))); + asdf.update_bg(bg_id, &mut renderer); + asdf.update_ch(ch_id, &mut renderer); + event_loop.run(move |event, _target, control_flow|{ //Set to polling for now, might be overwritten //TODO: Maybe we want to use "WAIT" for the ui thread? However, the renderers don't work that hard @@ -171,7 +249,12 @@ async fn main() { match event{ winit::event::Event::WindowEvent{window_id: _, event: winit::event::WindowEvent::Resized(newsize)} => { //update layer to cover whole window again. - renderer.set_layer_info(id.into(), LayerInfo{ + renderer.set_layer_info(bg_id.into(), LayerInfo{ + extent: (newsize.width as usize, newsize.height as usize), + location: (0,0) + }); + + renderer.set_layer_info(ch_id.into(), LayerInfo{ extent: (newsize.width as usize, newsize.height as usize), location: (0,0) }); @@ -179,10 +262,7 @@ async fn main() { winit::event::Event::MainEventsCleared => { window.request_redraw(); } - winit::event::Event::RedrawRequested(_) => { - let new_sdf = sdf_from_color(color_view.get()); - renderer.update_sdf_2d(id, new_sdf); - + winit::event::Event::RedrawRequested(_) => { renderer.render(&window); } _ => {}, @@ -191,20 +271,25 @@ async fn main() { }) } - - -fn sdf_from_color(c: (u8, u8, u8)) -> PrimaryStream2d{ +fn sdf_from_color(c: (u8, u8, u8)) -> PrimaryStream2d { PrimaryStream2d::new() .push( SecondaryStream2d::new( Union, - Box2d{extent: Vec2::new(0.5, 0.5)} - ).push_mod(Color( - Vec3::new( - (c.0 as f32 / 255.0).clamp(0.0, 1.0), - (c.1 as f32 / 255.0).clamp(0.0, 1.0), - (c.2 as f32 / 255.0).clamp(0.0, 1.0), + Box2d { + extent: Vec2::new(0.5, 0.5) + } + ).push_mod( + Color( + Vec3::new( + (c.0 as f32 / 255.0).clamp(0.0, 1.0), + (c.1 as f32 / 255.0).clamp(0.0, 1.0), + (c.2 as f32 / 255.0).clamp(0.0, 1.0), + ) ) - )).push_mod(Round{radius: 0.2}).build() + ).push_mod( + Round{radius: 0.2} ).build() + ).build() } + From eb2f4c28dd68efa22ffd7944e3251ec9c8cd6b76 Mon Sep 17 00:00:00 2001 From: Michael Sippel Date: Fri, 10 Sep 2021 01:04:00 +0200 Subject: [PATCH 05/16] initial terminal view rendering with sdfs still very whacky --- sdf_editor/src/main.rs | 223 ++++++++++++++++++++++++++--------------- 1 file changed, 144 insertions(+), 79 deletions(-) diff --git a/sdf_editor/src/main.rs b/sdf_editor/src/main.rs index 533412f..cc62e4d 100644 --- a/sdf_editor/src/main.rs +++ b/sdf_editor/src/main.rs @@ -1,5 +1,8 @@ use{ - std::sync::{Arc, RwLock}, + std::{ + sync::{Arc, RwLock, Mutex}, + collections::HashMap + }, cgmath::{Point2, Vector2}, termion::event::{Event, Key}, nested::{ @@ -14,7 +17,7 @@ use{ singleton::{SingletonBuffer, SingletonView}, sequence::{SequenceView}, integer::{PosIntEditor}, - terminal::{Terminal, TerminalAtom, TerminalStyle, TerminalCompositor, TerminalEvent, TerminalEditor}, + terminal::{Terminal, TerminalAtom, TerminalStyle, TerminalView, TerminalCompositor, TerminalEvent, TerminalEditor}, list::{ListEditor}, tree_nav::{TreeNav} }, @@ -80,14 +83,15 @@ impl TermAtomSDF { } fn update_bg(&self, layer_id: LayerId2d, renderer: &mut MarpBackend) { - let (r,g,b) = self.atom.style.bg_color.unwrap_or((0, 0, 0)); - - let stream = PrimaryStream2d::new() - .push( + let mut stream = PrimaryStream2d::new(); + + let (r,g,b) = self.atom.style.bg_color.unwrap_or((0,0,0)); + + stream = stream.push( SecondaryStream2d::new( Union, Box2d { - extent: Vec2::new(0.5, 1.0) + extent: Vec2::new(0.6, 1.0) } ).push_mod( Color( @@ -98,15 +102,17 @@ impl TermAtomSDF { ) ) ).build() - ).build(); + ); - renderer.update_sdf_2d(layer_id, stream); + renderer.update_sdf_2d(layer_id, stream.build()); } fn update_ch(&self, layer_id: LayerId2d, renderer: &mut MarpBackend) { + let mut stream = PrimaryStream2d::new(); + if let Some(c) = self.atom.c { let font = Font::from_path(Path::new("/usr/share/fonts/TTF/FiraCode-Light.ttf"),0).unwrap(); - let mut ch = Character::from_font(&font, c).with_size(1.0).with_tesselation_factor(0.2); + let mut ch = Character::from_font(&font, c).with_size(1.0).with_tesselation_factor(0.01); let (r,g,b) = self.atom.style.fg_color.unwrap_or((0, 0, 0)); @@ -116,16 +122,108 @@ impl TermAtomSDF { (b as f32 / 255.0).clamp(0.0, 1.0), ); - let mut stream = PrimaryStream2d::new(); stream = ch.record_character(stream); - renderer.update_sdf_2d(layer_id, stream.build()); - } else { - renderer.update_sdf_2d(layer_id, PrimaryStream2d::new().build()); } + + renderer.update_sdf_2d(layer_id, stream.build()); } } +struct SdfTerm { + src_view: Arc, + bg_layers: HashMap, LayerId2d>, + ch_layers: HashMap, LayerId2d>, + renderer: Arc> +} +impl SdfTerm { + fn update_order(&mut self) { + self.renderer.lock().unwrap().set_layer_order( + vec![ + self.bg_layers.iter().filter( + |(pt, _)| + if let Some(a) = self.src_view.get(pt) { + a.style.bg_color.is_some() + } else { + false + } + ) + .collect::>() + .into_iter(), + self.ch_layers.iter().filter( + |(pt, _)| + if let Some(a) = self.src_view.get(pt) { + a.c.is_some() + } else { + false + } + ) + .collect::>() + .into_iter() + ] + .into_iter() + .flatten() + .map(|(_,id)| (*id).into()) + .collect::>() + .as_slice() + ); + } + + fn update(&mut self, pt: &Point2) { + if self.bg_layers.get(pt).is_none() { + let id = self.renderer.lock().unwrap().new_layer_2d(); + + self.renderer.lock().unwrap().update_camera_2d( + id.into(), + Camera2d { + extent: Vec2::new(0.5, 1.0), + location: Vec2::new(0.0, 0.0), + rotation: 0.0 + }); + self.renderer.lock().unwrap().set_layer_info( + id.into(), + LayerInfo { + extent: (60, 100), + location: (pt.x as usize * 60, pt.y as usize * 100) + }); + + self.bg_layers.insert(*pt, id); + } + if self.ch_layers.get(pt).is_none() { + let id = self.renderer.lock().unwrap().new_layer_2d(); + + self.renderer.lock().unwrap().update_camera_2d( + id.into(), + Camera2d { + extent: Vec2::new(0.5, 1.0), + location: Vec2::new(0.0, 0.0), + rotation: 0.0 + }); + self.renderer.lock().unwrap().set_layer_info( + id.into(), + LayerInfo { + extent: (60, 100), + location: (pt.x as usize * 60, pt.y as usize * 100) + }); + + self.ch_layers.insert(*pt, id); + } + + if let Some(atom) = self.src_view.get(pt) { + let atom_stream_builder = TermAtomSDF::new(atom); + atom_stream_builder.update_bg(*self.bg_layers.get(pt).unwrap(), &mut *self.renderer.lock().unwrap()); + atom_stream_builder.update_ch(*self.ch_layers.get(pt).unwrap(), &mut *self.renderer.lock().unwrap()); + } + } +} +/* +impl Observer for SdfTerm { + fn notify(&mut self, pt: &Point2) { + self.update(pt); + self.update_order(); + } +} +*/ #[async_std::main] async fn main() { let term_port = ViewPort::new(); @@ -163,19 +261,37 @@ async fn main() { compositor.write().unwrap().push(color_editor.get_term_view().offset(Vector2::new(2, 2))); let color_view = color_port.outer().get_view(); - + + let cp = color_port.clone(); + let tp = term_port.clone(); + + let event_loop = nakorender::winit::event_loop::EventLoop::new(); + let window = nakorender::winit::window::Window::new(&event_loop).unwrap(); + let mut renderer = Arc::new(Mutex::new(nakorender::marp::MarpBackend::new(&window, &event_loop))); + + let mut sdf_term = Arc::new(RwLock::new(SdfTerm { + src_view: term_port.outer().get_view().unwrap(), + bg_layers: HashMap::new(), + ch_layers: HashMap::new(), + renderer: renderer.clone() + })); + //term_port.outer().add_observer(sdf_term.clone()); + async_std::task::spawn( async move { loop { - color_port.update(); - term_port.update(); + cp.update(); + tp.update(); + match term.next_event().await { TerminalEvent::Resize(new_size) => { - term_port.inner().get_broadcast().notify_each( + tp.inner().get_broadcast().notify_each( nested::grid::GridWindowIterator::from( Point2::new(0,0) .. Point2::new(new_size.x, new_size.y) ) ); + + } TerminalEvent::Input(Event::Key(Key::Ctrl('c'))) | TerminalEvent::Input(Event::Key(Key::Ctrl('g'))) | @@ -211,59 +327,30 @@ async fn main() { async_std::task::spawn(async move { term_writer.show().await.expect("output error!"); }); - - let event_loop = nakorender::winit::event_loop::EventLoop::new(); - let window = nakorender::winit::window::Window::new(&event_loop).unwrap(); - let mut renderer = nakorender::marp::MarpBackend::new(&window, &event_loop); - - let bg_id = renderer.new_layer_2d(); - renderer.update_camera_2d(bg_id, Camera2d{ - extent: Vec2::new(10.0, 10.0), - location: Vec2::new(0.0, 0.0), - rotation: 0.0 - }); - - let ch_id = renderer.new_layer_2d(); - renderer.update_camera_2d(ch_id, Camera2d{ - extent: Vec2::new(10.0, 10.0), - location: Vec2::new(0.0, 0.0), - rotation: 0.0 - }); - - renderer.set_layer_order(&[bg_id.into(), ch_id.into()]); - - let asdf = TermAtomSDF::new(TerminalAtom::new('H', TerminalStyle::fg_color((98, 200, 60)).add(TerminalStyle::bg_color((40,40,40))))); - asdf.update_bg(bg_id, &mut renderer); - asdf.update_ch(ch_id, &mut renderer); event_loop.run(move |event, _target, control_flow|{ //Set to polling for now, might be overwritten - //TODO: Maybe we want to use "WAIT" for the ui thread? However, the renderers don't work that hard + //TODO: Maybe we want to use "WAIT" for the ui thread? However, the renderer.lock().unwrap()s don't work that hard //if nothing changes. So should be okay for a alpha style programm. *control_flow = winit::event_loop::ControlFlow::Poll; - - //now check if a rerender was requested, or if we worked on all //events on that batch match event{ winit::event::Event::WindowEvent{window_id: _, event: winit::event::WindowEvent::Resized(newsize)} => { - //update layer to cover whole window again. - renderer.set_layer_info(bg_id.into(), LayerInfo{ - extent: (newsize.width as usize, newsize.height as usize), - location: (0,0) - }); - - renderer.set_layer_info(ch_id.into(), LayerInfo{ - extent: (newsize.width as usize, newsize.height as usize), - location: (0,0) - }); } winit::event::Event::MainEventsCleared => { window.request_redraw(); } - winit::event::Event::RedrawRequested(_) => { - renderer.render(&window); + winit::event::Event::RedrawRequested(_) => { + for pt in nested::grid::GridWindowIterator::from( + Point2::new(0, 0) .. Point2::new(10, 4) + ) { + sdf_term.write().unwrap().update(&pt); + } + sdf_term.write().unwrap().update_order(); + + renderer.lock().unwrap().render(&window); } _ => {}, } @@ -271,25 +358,3 @@ async fn main() { }) } -fn sdf_from_color(c: (u8, u8, u8)) -> PrimaryStream2d { - PrimaryStream2d::new() - .push( - SecondaryStream2d::new( - Union, - Box2d { - extent: Vec2::new(0.5, 0.5) - } - ).push_mod( - Color( - Vec3::new( - (c.0 as f32 / 255.0).clamp(0.0, 1.0), - (c.1 as f32 / 255.0).clamp(0.0, 1.0), - (c.2 as f32 / 255.0).clamp(0.0, 1.0), - ) - ) - ).push_mod( - Round{radius: 0.2} - ).build() - ).build() -} - From ebada704c0886713cd2ee9418a3aa90b7105a2a4 Mon Sep 17 00:00:00 2001 From: Michael Sippel Date: Fri, 10 Sep 2021 01:59:42 +0200 Subject: [PATCH 06/16] preview color in nako window --- sdf_editor/src/main.rs | 121 +++++++++++++++++++++++++++-------------- 1 file changed, 81 insertions(+), 40 deletions(-) diff --git a/sdf_editor/src/main.rs b/sdf_editor/src/main.rs index cc62e4d..7881208 100644 --- a/sdf_editor/src/main.rs +++ b/sdf_editor/src/main.rs @@ -111,7 +111,7 @@ impl TermAtomSDF { let mut stream = PrimaryStream2d::new(); if let Some(c) = self.atom.c { - let font = Font::from_path(Path::new("/usr/share/fonts/TTF/FiraCode-Light.ttf"),0).unwrap(); + let font = Font::from_path(Path::new("/usr/share/fonts/TTF/FiraCode-Medium.ttf"),0).unwrap(); let mut ch = Character::from_font(&font, c).with_size(1.0).with_tesselation_factor(0.01); let (r,g,b) = self.atom.style.fg_color.unwrap_or((0, 0, 0)); @@ -131,42 +131,29 @@ impl TermAtomSDF { struct SdfTerm { src_view: Arc, - bg_layers: HashMap, LayerId2d>, - ch_layers: HashMap, LayerId2d>, + bg_layers: HashMap, (bool, LayerId2d)>, + ch_layers: HashMap, (bool, LayerId2d)>, renderer: Arc> } impl SdfTerm { - fn update_order(&mut self) { - self.renderer.lock().unwrap().set_layer_order( - vec![ - self.bg_layers.iter().filter( - |(pt, _)| - if let Some(a) = self.src_view.get(pt) { - a.style.bg_color.is_some() - } else { - false - } - ) - .collect::>() - .into_iter(), - self.ch_layers.iter().filter( - |(pt, _)| - if let Some(a) = self.src_view.get(pt) { - a.c.is_some() - } else { - false - } - ) - .collect::>() - .into_iter() - ] - .into_iter() - .flatten() - .map(|(_,id)| (*id).into()) + fn get_order(&mut self) -> Vec { + vec![ + self.bg_layers.iter().filter( + |(_pt, (active, _id))| *active + ) .collect::>() - .as_slice() - ); + .into_iter(), + self.ch_layers.iter().filter( + |(_pt, (active, _id))| *active + ) + .collect::>() + .into_iter() + ] + .into_iter() + .flatten() + .map(|(_,(_,id))| (*id).into()) + .collect::>() } fn update(&mut self, pt: &Point2) { @@ -187,7 +174,7 @@ impl SdfTerm { location: (pt.x as usize * 60, pt.y as usize * 100) }); - self.bg_layers.insert(*pt, id); + self.bg_layers.insert(*pt, (false, id)); } if self.ch_layers.get(pt).is_none() { let id = self.renderer.lock().unwrap().new_layer_2d(); @@ -206,13 +193,22 @@ impl SdfTerm { location: (pt.x as usize * 60, pt.y as usize * 100) }); - self.ch_layers.insert(*pt, id); + self.ch_layers.insert(*pt, (false, id)); } if let Some(atom) = self.src_view.get(pt) { let atom_stream_builder = TermAtomSDF::new(atom); - atom_stream_builder.update_bg(*self.bg_layers.get(pt).unwrap(), &mut *self.renderer.lock().unwrap()); - atom_stream_builder.update_ch(*self.ch_layers.get(pt).unwrap(), &mut *self.renderer.lock().unwrap()); + atom_stream_builder.update_bg(self.bg_layers.get(pt).unwrap().1, &mut *self.renderer.lock().unwrap()); + atom_stream_builder.update_ch(self.ch_layers.get(pt).unwrap().1, &mut *self.renderer.lock().unwrap()); + + let has_bg = atom.style.bg_color.is_some(); + let has_fg = atom.c.unwrap_or(' ') != ' '; + + self.bg_layers.get_mut(pt).unwrap().0 = has_bg; + self.ch_layers.get_mut(pt).unwrap().0 = has_fg; + } else { + self.bg_layers.get_mut(pt).unwrap().0 = false; + self.ch_layers.get_mut(pt).unwrap().0 = false; } } } @@ -236,7 +232,7 @@ async fn main() { || { Arc::new(RwLock::new(PosIntEditor::new(16))) }, - nested::list::ListEditorStyle::Clist + nested::list::ListEditorStyle::Path ); color_editor.goto(nested::tree_nav::TreeCursor { @@ -258,7 +254,7 @@ async fn main() { color_collector.clone() ); - compositor.write().unwrap().push(color_editor.get_term_view().offset(Vector2::new(2, 2))); + compositor.write().unwrap().push(color_editor.get_term_view().offset(Vector2::new(0, 0))); let color_view = color_port.outer().get_view(); @@ -328,6 +324,19 @@ async fn main() { term_writer.show().await.expect("output error!"); }); + + + let color_layer_id = renderer.lock().unwrap().new_layer_2d(); + renderer.lock().unwrap().update_camera_2d(color_layer_id, Camera2d{ + extent: Vec2::new(4.0, 4.0), + location: Vec2::new(-2.0, -2.0), + rotation: 0.0 + }); + renderer.lock().unwrap().set_layer_info(color_layer_id.into(), LayerInfo{ + extent: (600, 600), + location: (200,100) + }); + event_loop.run(move |event, _target, control_flow|{ //Set to polling for now, might be overwritten //TODO: Maybe we want to use "WAIT" for the ui thread? However, the renderer.lock().unwrap()s don't work that hard @@ -344,11 +353,43 @@ async fn main() { } winit::event::Event::RedrawRequested(_) => { for pt in nested::grid::GridWindowIterator::from( - Point2::new(0, 0) .. Point2::new(10, 4) + Point2::new(0, 0) .. Point2::new(30, 1) ) { sdf_term.write().unwrap().update(&pt); } - sdf_term.write().unwrap().update_order(); + + let c = color_view.get(); + let color_stream = PrimaryStream2d::new() + .push( + SecondaryStream2d::new( + Union, + Box2d { + extent: Vec2::new(0.5, 0.5) + } + ).push_mod( + Color( + Vec3::new( + (c.0 as f32 / 255.0).clamp(0.0, 1.0), + (c.1 as f32 / 255.0).clamp(0.0, 1.0), + (c.2 as f32 / 255.0).clamp(0.0, 1.0), + ) + ) + ).push_mod( + Round{radius: 0.2} + ).build() + ).build(); + + renderer.lock().unwrap().update_sdf_2d(color_layer_id, color_stream); + renderer.lock().unwrap().set_layer_order( + vec![ + sdf_term.write().unwrap().get_order().into_iter(), + vec![ color_layer_id.into() ].into_iter() + ] + .into_iter() + .flatten() + .collect::>() + .as_slice() + ); renderer.lock().unwrap().render(&window); } From 880610c39dce0f1e4e652c749456d6b3fc607dbd Mon Sep 17 00:00:00 2001 From: Michael Sippel Date: Fri, 10 Sep 2021 02:06:24 +0200 Subject: [PATCH 07/16] IntegerEditor: reverse digit sequence in get_value() to use the more commonplace endiannes as default --- nested/src/integer/editor.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/nested/src/integer/editor.rs b/nested/src/integer/editor.rs index 72d2678..aee6c37 100644 --- a/nested/src/integer/editor.rs +++ b/nested/src/integer/editor.rs @@ -106,7 +106,7 @@ impl PosIntEditor { pub fn get_value(&self) -> u32 { let mut value = 0; let mut weight = 1; - for digit_value in self.get_data_port().get_view().unwrap().iter() { + for digit_value in self.get_data_port().get_view().unwrap().iter().collect::>().into_iter().rev() { value += digit_value * weight; weight *= self.radix; } From d9b52d5fecbed9bcf80545102010ed1994939bf6 Mon Sep 17 00:00:00 2001 From: Michael Sippel Date: Fri, 10 Sep 2021 02:18:26 +0200 Subject: [PATCH 08/16] fix cargo dependencies --- sdf_editor/Cargo.toml | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/sdf_editor/Cargo.toml b/sdf_editor/Cargo.toml index 44b1df3..6394ec7 100644 --- a/sdf_editor/Cargo.toml +++ b/sdf_editor/Cargo.toml @@ -6,12 +6,13 @@ edition = "2018" # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html [dependencies] -nako = {git= "https://gitlab.com/tendsinmende/nako.git"} -nako_std = {git= "https://gitlab.com/tendsinmende/nako.git"} -nakorender = {git="https://gitlab.com/tendsinmende/nako.git", default-features = false} +nako = {git= "https://gitlab.com/senvas/nako.git"} +nako_std = {git= "https://gitlab.com/senvas/nako.git"} +nakorender = {git="https://gitlab.com/senvas/nako.git", default-features = false} nested = { path = "../nested" } cgmath = "*" termion = "*" +font-kit = "*" [dependencies.async-std] version = "1.9.0" From 9633986f6c3b48af8defe49cf702363ec55a7a08 Mon Sep 17 00:00:00 2001 From: Michael Sippel Date: Fri, 10 Sep 2021 10:51:47 +0200 Subject: [PATCH 09/16] cleanup SdfTerm --- sdf_editor/Cargo.toml | 6 +- sdf_editor/src/main.rs | 152 ++++++++++++++++++++--------------------- 2 files changed, 76 insertions(+), 82 deletions(-) diff --git a/sdf_editor/Cargo.toml b/sdf_editor/Cargo.toml index 6394ec7..d0224df 100644 --- a/sdf_editor/Cargo.toml +++ b/sdf_editor/Cargo.toml @@ -6,9 +6,9 @@ edition = "2018" # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html [dependencies] -nako = {git= "https://gitlab.com/senvas/nako.git"} -nako_std = {git= "https://gitlab.com/senvas/nako.git"} -nakorender = {git="https://gitlab.com/senvas/nako.git", default-features = false} +nako = {git= "https://git.exobiont.de/senvas/nako.git"} +nako_std = {git= "https://git.exobiont.de/senvas/nako.git"} +nakorender = {git="https://git.exobiont.de/senvas/nako.git", default-features = false} nested = { path = "../nested" } cgmath = "*" termion = "*" diff --git a/sdf_editor/src/main.rs b/sdf_editor/src/main.rs index 7881208..65b80a9 100644 --- a/sdf_editor/src/main.rs +++ b/sdf_editor/src/main.rs @@ -1,3 +1,4 @@ + use{ std::{ sync::{Arc, RwLock, Mutex}, @@ -70,81 +71,33 @@ impl Observer> for ColorCollector { } } - -struct TermAtomSDF { - atom: TerminalAtom -} - -impl TermAtomSDF { - fn new(atom: TerminalAtom) -> Self { - TermAtomSDF { - atom - } - } - - fn update_bg(&self, layer_id: LayerId2d, renderer: &mut MarpBackend) { - let mut stream = PrimaryStream2d::new(); - - let (r,g,b) = self.atom.style.bg_color.unwrap_or((0,0,0)); - - stream = stream.push( - SecondaryStream2d::new( - Union, - Box2d { - extent: Vec2::new(0.6, 1.0) - } - ).push_mod( - Color( - Vec3::new( - (r as f32 / 255.0).clamp(0.0, 1.0), - (g as f32 / 255.0).clamp(0.0, 1.0), - (b as f32 / 255.0).clamp(0.0, 1.0), - ) - ) - ).build() - ); - - renderer.update_sdf_2d(layer_id, stream.build()); - } - - fn update_ch(&self, layer_id: LayerId2d, renderer: &mut MarpBackend) { - let mut stream = PrimaryStream2d::new(); - - if let Some(c) = self.atom.c { - let font = Font::from_path(Path::new("/usr/share/fonts/TTF/FiraCode-Medium.ttf"),0).unwrap(); - let mut ch = Character::from_font(&font, c).with_size(1.0).with_tesselation_factor(0.01); - - let (r,g,b) = self.atom.style.fg_color.unwrap_or((0, 0, 0)); - - ch.color = Vec3::new( - (r as f32 / 255.0).clamp(0.0, 1.0), - (g as f32 / 255.0).clamp(0.0, 1.0), - (b as f32 / 255.0).clamp(0.0, 1.0), - ); - - stream = ch.record_character(stream); - } - - renderer.update_sdf_2d(layer_id, stream.build()); - } -} - struct SdfTerm { - src_view: Arc, + pub src_view: Option>, bg_layers: HashMap, (bool, LayerId2d)>, - ch_layers: HashMap, (bool, LayerId2d)>, + fg_layers: HashMap, (bool, LayerId2d)>, + font: Font, renderer: Arc> } impl SdfTerm { - fn get_order(&mut self) -> Vec { + pub fn new(renderer: Arc>) -> Self { + SdfTerm { + src_view: None, + bg_layers: HashMap::new(), + fg_layers: HashMap::new(), + font: Font::from_path(Path::new("/usr/share/fonts/TTF/FiraCode-Medium.ttf"),0).unwrap(), + renderer + } + } + + pub fn get_order(&mut self) -> Vec { vec![ self.bg_layers.iter().filter( |(_pt, (active, _id))| *active ) .collect::>() .into_iter(), - self.ch_layers.iter().filter( + self.fg_layers.iter().filter( |(_pt, (active, _id))| *active ) .collect::>() @@ -156,7 +109,7 @@ impl SdfTerm { .collect::>() } - fn update(&mut self, pt: &Point2) { + pub fn update(&mut self, pt: &Point2) { if self.bg_layers.get(pt).is_none() { let id = self.renderer.lock().unwrap().new_layer_2d(); @@ -176,7 +129,7 @@ impl SdfTerm { self.bg_layers.insert(*pt, (false, id)); } - if self.ch_layers.get(pt).is_none() { + if self.fg_layers.get(pt).is_none() { let id = self.renderer.lock().unwrap().new_layer_2d(); self.renderer.lock().unwrap().update_camera_2d( @@ -193,22 +146,68 @@ impl SdfTerm { location: (pt.x as usize * 60, pt.y as usize * 100) }); - self.ch_layers.insert(*pt, (false, id)); + self.fg_layers.insert(*pt, (false, id)); } if let Some(atom) = self.src_view.get(pt) { - let atom_stream_builder = TermAtomSDF::new(atom); - atom_stream_builder.update_bg(self.bg_layers.get(pt).unwrap().1, &mut *self.renderer.lock().unwrap()); - atom_stream_builder.update_ch(self.ch_layers.get(pt).unwrap().1, &mut *self.renderer.lock().unwrap()); + // background layer + if let Some((r,g,b)) = atom.style.bg_color { + let mut stream = PrimaryStream2d::new() + .push( + SecondaryStream2d::new( + Union, + Box2d { + extent: Vec2::new(0.6, 1.0) + } + ).push_mod( + Color( + Vec3::new( + (r as f32 / 255.0).clamp(0.0, 1.0), + (g as f32 / 255.0).clamp(0.0, 1.0), + (b as f32 / 255.0).clamp(0.0, 1.0), + ) + ) + ).build() + ); + + self.renderer.lock().unwrap().update_sdf_2d(self.bg_layers.get(pt).unwrap().1, stream.build()); + self.bg_layers.get_mut(pt).unwrap().0 = true; + } else { + self.bg_layers.get_mut(pt).unwrap().0 = false; + } + + // foreground layer + if let Some(c) = atom.c { + let mut ch = Character::from_font(&self.font, c).with_size(1.0).with_tesselation_factor(0.01); + + let (r,g,b) = atom.style.fg_color.unwrap_or((0, 0, 0)); + + ch.color = Vec3::new( + (r as f32 / 255.0).clamp(0.0, 1.0), + (g as f32 / 255.0).clamp(0.0, 1.0), + (b as f32 / 255.0).clamp(0.0, 1.0), + ); + + let mut stream = PrimaryStream2d::new(); + stream = ch.record_character(stream); + + self.renderer.lock().unwrap().update_sdf_2d(self.fg_layers.get(pt).unwrap().1, stream.build()); + self.fg_layers.get_mut(pt).unwrap().0 = true; + } else { + self.fg_layers.get_mut(pt).unwrap().0 = false; + } + + + let has_bg = atom.style.bg_color.is_some(); let has_fg = atom.c.unwrap_or(' ') != ' '; self.bg_layers.get_mut(pt).unwrap().0 = has_bg; - self.ch_layers.get_mut(pt).unwrap().0 = has_fg; + self.fg_layers.get_mut(pt).unwrap().0 = has_fg; } else { self.bg_layers.get_mut(pt).unwrap().0 = false; - self.ch_layers.get_mut(pt).unwrap().0 = false; + self.fg_layers.get_mut(pt).unwrap().0 = false; } } } @@ -265,12 +264,8 @@ async fn main() { let window = nakorender::winit::window::Window::new(&event_loop).unwrap(); let mut renderer = Arc::new(Mutex::new(nakorender::marp::MarpBackend::new(&window, &event_loop))); - let mut sdf_term = Arc::new(RwLock::new(SdfTerm { - src_view: term_port.outer().get_view().unwrap(), - bg_layers: HashMap::new(), - ch_layers: HashMap::new(), - renderer: renderer.clone() - })); + let mut sdf_term = Arc::new(RwLock::new(SdfTerm::new(renderer.clone()))); + sdf_term.write().unwrap().src_view = term_port.outer().get_view(); //term_port.outer().add_observer(sdf_term.clone()); async_std::task::spawn( @@ -324,7 +319,6 @@ async fn main() { term_writer.show().await.expect("output error!"); }); - let color_layer_id = renderer.lock().unwrap().new_layer_2d(); renderer.lock().unwrap().update_camera_2d(color_layer_id, Camera2d{ @@ -336,7 +330,7 @@ async fn main() { extent: (600, 600), location: (200,100) }); - + event_loop.run(move |event, _target, control_flow|{ //Set to polling for now, might be overwritten //TODO: Maybe we want to use "WAIT" for the ui thread? However, the renderer.lock().unwrap()s don't work that hard From b708545b9696480e26f63544acbb8d4efc24d1b6 Mon Sep 17 00:00:00 2001 From: Michael Sippel Date: Fri, 10 Sep 2021 11:02:35 +0200 Subject: [PATCH 10/16] SdfTerm: remove outdated lines --- sdf_editor/src/main.rs | 7 ------- 1 file changed, 7 deletions(-) diff --git a/sdf_editor/src/main.rs b/sdf_editor/src/main.rs index 65b80a9..e773d58 100644 --- a/sdf_editor/src/main.rs +++ b/sdf_editor/src/main.rs @@ -197,14 +197,7 @@ impl SdfTerm { } else { self.fg_layers.get_mut(pt).unwrap().0 = false; } - - - - let has_bg = atom.style.bg_color.is_some(); - let has_fg = atom.c.unwrap_or(' ') != ' '; - self.bg_layers.get_mut(pt).unwrap().0 = has_bg; - self.fg_layers.get_mut(pt).unwrap().0 = has_fg; } else { self.bg_layers.get_mut(pt).unwrap().0 = false; self.fg_layers.get_mut(pt).unwrap().0 = false; From 83386d5bd9a8a4998ddd24a95dd9ac96f70bba69 Mon Sep 17 00:00:00 2001 From: Michael Sippel Date: Fri, 10 Sep 2021 11:10:05 +0200 Subject: [PATCH 11/16] SdfTerm: simplify get_order() --- sdf_editor/src/main.rs | 22 +++++++++------------- 1 file changed, 9 insertions(+), 13 deletions(-) diff --git a/sdf_editor/src/main.rs b/sdf_editor/src/main.rs index e773d58..de5e7f5 100644 --- a/sdf_editor/src/main.rs +++ b/sdf_editor/src/main.rs @@ -92,20 +92,18 @@ impl SdfTerm { pub fn get_order(&mut self) -> Vec { vec![ - self.bg_layers.iter().filter( - |(_pt, (active, _id))| *active - ) - .collect::>() - .into_iter(), - self.fg_layers.iter().filter( - |(_pt, (active, _id))| *active - ) - .collect::>() - .into_iter() + self.bg_layers.iter(), + self.fg_layers.iter() ] .into_iter() .flatten() - .map(|(_,(_,id))| (*id).into()) + .filter_map( + |(_pt,(active,id))| + if *active { + Some((*id).into()) + } else { + None + }) .collect::>() } @@ -274,8 +272,6 @@ async fn main() { Point2::new(0,0) .. Point2::new(new_size.x, new_size.y) ) ); - - } TerminalEvent::Input(Event::Key(Key::Ctrl('c'))) | TerminalEvent::Input(Event::Key(Key::Ctrl('g'))) | From 6247dcc9f50603ad5339b92ee5f2e3f5347ea172 Mon Sep 17 00:00:00 2001 From: Michael Sippel Date: Fri, 10 Sep 2021 12:53:08 +0200 Subject: [PATCH 12/16] SdfTerm: impl Observer to only update modified layers --- sdf_editor/src/main.rs | 62 ++++++++++++++++++++++-------------------- 1 file changed, 32 insertions(+), 30 deletions(-) diff --git a/sdf_editor/src/main.rs b/sdf_editor/src/main.rs index de5e7f5..c404ec9 100644 --- a/sdf_editor/src/main.rs +++ b/sdf_editor/src/main.rs @@ -75,7 +75,7 @@ struct SdfTerm { pub src_view: Option>, bg_layers: HashMap, (bool, LayerId2d)>, fg_layers: HashMap, (bool, LayerId2d)>, - font: Font, + //font: Arc>, renderer: Arc> } @@ -85,12 +85,12 @@ impl SdfTerm { src_view: None, bg_layers: HashMap::new(), fg_layers: HashMap::new(), - font: Font::from_path(Path::new("/usr/share/fonts/TTF/FiraCode-Medium.ttf"),0).unwrap(), + //font: Arc::new(RwLock::new(Font::from_path(Path::new("/usr/share/fonts/TTF/FiraCode-Medium.ttf"),0).unwrap())), renderer } } - pub fn get_order(&mut self) -> Vec { + pub fn get_order(&self) -> Vec { vec![ self.bg_layers.iter(), self.fg_layers.iter() @@ -177,7 +177,8 @@ impl SdfTerm { // foreground layer if let Some(c) = atom.c { - let mut ch = Character::from_font(&self.font, c).with_size(1.0).with_tesselation_factor(0.01); + let font = Font::from_path(Path::new("/usr/share/fonts/TTF/FiraCode-Medium.ttf"),0).unwrap(); + let mut ch = Character::from_font(&font, c).with_size(1.0).with_tesselation_factor(0.01); let (r,g,b) = atom.style.fg_color.unwrap_or((0, 0, 0)); @@ -202,14 +203,21 @@ impl SdfTerm { } } } -/* + impl Observer for SdfTerm { + fn reset(&mut self, new_view: Option>) { + self.src_view = new_view; + + for pt in self.src_view.area().unwrap_or(vec![]) { + self.notify(&pt); + } + } + fn notify(&mut self, pt: &Point2) { self.update(pt); - self.update_order(); } } -*/ + #[async_std::main] async fn main() { let term_port = ViewPort::new(); @@ -246,33 +254,21 @@ async fn main() { compositor.write().unwrap().push(color_editor.get_term_view().offset(Vector2::new(0, 0))); - let color_view = color_port.outer().get_view(); - - let cp = color_port.clone(); let tp = term_port.clone(); - - let event_loop = nakorender::winit::event_loop::EventLoop::new(); - let window = nakorender::winit::window::Window::new(&event_loop).unwrap(); - let mut renderer = Arc::new(Mutex::new(nakorender::marp::MarpBackend::new(&window, &event_loop))); - - let mut sdf_term = Arc::new(RwLock::new(SdfTerm::new(renderer.clone()))); - sdf_term.write().unwrap().src_view = term_port.outer().get_view(); - //term_port.outer().add_observer(sdf_term.clone()); - async_std::task::spawn( async move { loop { - cp.update(); - tp.update(); - match term.next_event().await { - TerminalEvent::Resize(new_size) => { + TerminalEvent::Resize(mut new_size) => { + new_size.x = 10; + new_size.y = 5; tp.inner().get_broadcast().notify_each( nested::grid::GridWindowIterator::from( Point2::new(0,0) .. Point2::new(new_size.x, new_size.y) ) ); } + TerminalEvent::Input(Event::Key(Key::Ctrl('c'))) | TerminalEvent::Input(Event::Key(Key::Ctrl('g'))) | TerminalEvent::Input(Event::Key(Key::Ctrl('d'))) => break, @@ -308,7 +304,16 @@ async fn main() { term_writer.show().await.expect("output error!"); }); - + let event_loop = nakorender::winit::event_loop::EventLoop::new(); + let window = nakorender::winit::window::Window::new(&event_loop).unwrap(); + let mut renderer = Arc::new(Mutex::new(nakorender::marp::MarpBackend::new(&window, &event_loop))); + + // terminal view + let mut sdf_term = Arc::new(RwLock::new(SdfTerm::new(renderer.clone()))); + term_port.outer().add_observer(sdf_term.clone()); + + // color preview + let color_view = color_port.outer().get_view(); let color_layer_id = renderer.lock().unwrap().new_layer_2d(); renderer.lock().unwrap().update_camera_2d(color_layer_id, Camera2d{ extent: Vec2::new(4.0, 4.0), @@ -335,11 +340,8 @@ async fn main() { window.request_redraw(); } winit::event::Event::RedrawRequested(_) => { - for pt in nested::grid::GridWindowIterator::from( - Point2::new(0, 0) .. Point2::new(30, 1) - ) { - sdf_term.write().unwrap().update(&pt); - } + color_port.update(); + term_port.update(); let c = color_view.get(); let color_stream = PrimaryStream2d::new() @@ -365,7 +367,7 @@ async fn main() { renderer.lock().unwrap().update_sdf_2d(color_layer_id, color_stream); renderer.lock().unwrap().set_layer_order( vec![ - sdf_term.write().unwrap().get_order().into_iter(), + sdf_term.read().unwrap().get_order().into_iter(), vec![ color_layer_id.into() ].into_iter() ] .into_iter() From f393704054e334b1b2f34750d14dcb9fff4f0c9f Mon Sep 17 00:00:00 2001 From: Michael Sippel Date: Fri, 10 Sep 2021 13:26:02 +0200 Subject: [PATCH 13/16] sdf color picker: quick n dirty event handling via winit --- sdf_editor/src/main.rs | 164 ++++++++++++++++++++++++++--------------- 1 file changed, 106 insertions(+), 58 deletions(-) diff --git a/sdf_editor/src/main.rs b/sdf_editor/src/main.rs index c404ec9..624c219 100644 --- a/sdf_editor/src/main.rs +++ b/sdf_editor/src/main.rs @@ -177,7 +177,7 @@ impl SdfTerm { // foreground layer if let Some(c) = atom.c { - let font = Font::from_path(Path::new("/usr/share/fonts/TTF/FiraCode-Medium.ttf"),0).unwrap(); + let font = Font::from_path(Path::new("/usr/share/fonts/TTF/FiraCode-Light.ttf"),0).unwrap(); let mut ch = Character::from_font(&font, c).with_size(1.0).with_tesselation_factor(0.01); let (r,g,b) = atom.style.fg_color.unwrap_or((0, 0, 0)); @@ -223,14 +223,11 @@ async fn main() { let term_port = ViewPort::new(); let compositor = TerminalCompositor::new(term_port.inner()); - let mut term = Terminal::new(term_port.outer()); - let term_writer = term.get_writer(); - let mut color_editor = ListEditor::new( || { Arc::new(RwLock::new(PosIntEditor::new(16))) }, - nested::list::ListEditorStyle::Path + nested::list::ListEditorStyle::HorizontalSexpr ); color_editor.goto(nested::tree_nav::TreeCursor { @@ -254,56 +251,6 @@ async fn main() { compositor.write().unwrap().push(color_editor.get_term_view().offset(Vector2::new(0, 0))); - let tp = term_port.clone(); - async_std::task::spawn( - async move { - loop { - match term.next_event().await { - TerminalEvent::Resize(mut new_size) => { - new_size.x = 10; - new_size.y = 5; - tp.inner().get_broadcast().notify_each( - nested::grid::GridWindowIterator::from( - Point2::new(0,0) .. Point2::new(new_size.x, new_size.y) - ) - ); - } - - TerminalEvent::Input(Event::Key(Key::Ctrl('c'))) | - TerminalEvent::Input(Event::Key(Key::Ctrl('g'))) | - TerminalEvent::Input(Event::Key(Key::Ctrl('d'))) => break, - - TerminalEvent::Input(Event::Key(Key::Left)) => { - color_editor.pxev(); - } - TerminalEvent::Input(Event::Key(Key::Right)) => { - color_editor.nexd(); - } - TerminalEvent::Input(Event::Key(Key::Up)) => { - color_editor.up(); - } - TerminalEvent::Input(Event::Key(Key::Down)) => { - color_editor.dn(); - color_editor.goto_home(); - } - TerminalEvent::Input(Event::Key(Key::Home)) => { - color_editor.goto_home(); - } - TerminalEvent::Input(Event::Key(Key::End)) => { - color_editor.goto_end(); - } - event => { - color_editor.handle_terminal_event(&event); - } - } - } - } - ); - - async_std::task::spawn(async move { - term_writer.show().await.expect("output error!"); - }); - let event_loop = nakorender::winit::event_loop::EventLoop::new(); let window = nakorender::winit::window::Window::new(&event_loop).unwrap(); let mut renderer = Arc::new(Mutex::new(nakorender::marp::MarpBackend::new(&window, &event_loop))); @@ -330,11 +277,112 @@ async fn main() { //TODO: Maybe we want to use "WAIT" for the ui thread? However, the renderer.lock().unwrap()s don't work that hard //if nothing changes. So should be okay for a alpha style programm. *control_flow = winit::event_loop::ControlFlow::Poll; - + //now check if a rerender was requested, or if we worked on all //events on that batch match event{ winit::event::Event::WindowEvent{window_id: _, event: winit::event::WindowEvent::Resized(newsize)} => { + + } + winit::event::Event::WindowEvent{window_id: _, event: winit::event::WindowEvent::KeyboardInput{ device_id, input, is_synthetic }} => { + if input.state == winit::event::ElementState::Pressed { + if let Some(kc) = input.virtual_keycode { + match kc { + winit::event::VirtualKeyCode::Space | + winit::event::VirtualKeyCode::Return => { + color_editor.handle_terminal_event(&TerminalEvent::Input(Event::Key(Key::Char(' ')))); + } + winit::event::VirtualKeyCode::Key0 | + winit::event::VirtualKeyCode::Numpad0 => { + color_editor.handle_terminal_event(&TerminalEvent::Input(Event::Key(Key::Char('0')))); + } + winit::event::VirtualKeyCode::Key1 | + winit::event::VirtualKeyCode::Numpad1 => { + color_editor.handle_terminal_event(&TerminalEvent::Input(Event::Key(Key::Char('1')))); + } + winit::event::VirtualKeyCode::Key2 | + winit::event::VirtualKeyCode::Numpad2 => { + color_editor.handle_terminal_event(&TerminalEvent::Input(Event::Key(Key::Char('2')))); + } + winit::event::VirtualKeyCode::Key3 | + winit::event::VirtualKeyCode::Numpad3 => { + color_editor.handle_terminal_event(&TerminalEvent::Input(Event::Key(Key::Char('3')))); + } + winit::event::VirtualKeyCode::Key4 | + winit::event::VirtualKeyCode::Numpad4 => { + color_editor.handle_terminal_event(&TerminalEvent::Input(Event::Key(Key::Char('4')))); + } + winit::event::VirtualKeyCode::Key5 | + winit::event::VirtualKeyCode::Numpad5 => { + color_editor.handle_terminal_event(&TerminalEvent::Input(Event::Key(Key::Char('5')))); + } + winit::event::VirtualKeyCode::Key6 | + winit::event::VirtualKeyCode::Numpad6 => { + color_editor.handle_terminal_event(&TerminalEvent::Input(Event::Key(Key::Char('6')))); + } + winit::event::VirtualKeyCode::Key7 | + winit::event::VirtualKeyCode::Numpad7 => { + color_editor.handle_terminal_event(&TerminalEvent::Input(Event::Key(Key::Char('7')))); + } + winit::event::VirtualKeyCode::Key8 | + winit::event::VirtualKeyCode::Numpad8 => { + color_editor.handle_terminal_event(&TerminalEvent::Input(Event::Key(Key::Char('8')))); + } + winit::event::VirtualKeyCode::Key9 | + winit::event::VirtualKeyCode::Numpad9 => { + color_editor.handle_terminal_event(&TerminalEvent::Input(Event::Key(Key::Char('9')))); + } + winit::event::VirtualKeyCode::A => { + color_editor.handle_terminal_event(&TerminalEvent::Input(Event::Key(Key::Char('a')))); + } + winit::event::VirtualKeyCode::B => { + color_editor.handle_terminal_event(&TerminalEvent::Input(Event::Key(Key::Char('b')))); + } + winit::event::VirtualKeyCode::C => { + color_editor.handle_terminal_event(&TerminalEvent::Input(Event::Key(Key::Char('c')))); + } + winit::event::VirtualKeyCode::D => { + color_editor.handle_terminal_event(&TerminalEvent::Input(Event::Key(Key::Char('d')))); + } + winit::event::VirtualKeyCode::E => { + color_editor.handle_terminal_event(&TerminalEvent::Input(Event::Key(Key::Char('e')))); + } + winit::event::VirtualKeyCode::F => { + color_editor.handle_terminal_event(&TerminalEvent::Input(Event::Key(Key::Char('f')))); + } + winit::event::VirtualKeyCode::Tab => { + color_editor.handle_terminal_event(&TerminalEvent::Input(Event::Key(Key::Insert))); + } + winit::event::VirtualKeyCode::Delete => { + color_editor.handle_terminal_event(&TerminalEvent::Input(Event::Key(Key::Delete))); + } + winit::event::VirtualKeyCode::Back => { + color_editor.handle_terminal_event(&TerminalEvent::Input(Event::Key(Key::Backspace))); + } + winit::event::VirtualKeyCode::Left => { + color_editor.pxev(); + } + winit::event::VirtualKeyCode::Right => { + color_editor.nexd(); + } + winit::event::VirtualKeyCode::Up => { + color_editor.up(); + } + winit::event::VirtualKeyCode::Down => { + color_editor.dn(); + color_editor.goto_home(); + } + winit::event::VirtualKeyCode::Home => { + color_editor.goto_home(); + } + winit::event::VirtualKeyCode::End => { + color_editor.goto_end(); + } + _ => { + } + } + } + } } winit::event::Event::MainEventsCleared => { window.request_redraw(); @@ -367,8 +415,8 @@ async fn main() { renderer.lock().unwrap().update_sdf_2d(color_layer_id, color_stream); renderer.lock().unwrap().set_layer_order( vec![ - sdf_term.read().unwrap().get_order().into_iter(), - vec![ color_layer_id.into() ].into_iter() + vec![ color_layer_id.into() ].into_iter(), + sdf_term.read().unwrap().get_order().into_iter() ] .into_iter() .flatten() From cdeb0f9bc8ddc20c723ea3b7e891f333977adcf5 Mon Sep 17 00:00:00 2001 From: Michael Sippel Date: Sun, 12 Sep 2021 17:39:24 +0200 Subject: [PATCH 14/16] list editor: fix out of bounds on backspace --- nested/src/list/editor.rs | 40 +++++++++++++++++++++------------------ 1 file changed, 22 insertions(+), 18 deletions(-) diff --git a/nested/src/list/editor.rs b/nested/src/list/editor.rs index f29638b..736d27d 100644 --- a/nested/src/list/editor.rs +++ b/nested/src/list/editor.rs @@ -147,7 +147,7 @@ where ItemEditor: TerminalTreeEditor + ?Sized + Send + Sync + 'static, ); return TreeNavResult::Continue; } - + if i < self.data.len() { match cur.mode { ListCursorMode::Insert => { @@ -327,6 +327,8 @@ where ItemEditor: TerminalTreeEditor + ?Sized + Send + Sync + 'static, } ); } + } else { + self.goto_home(); } TreeNavResult::Continue } @@ -424,7 +426,7 @@ where ItemEditor: TerminalTreeEditor + ?Sized + Send + Sync + 'static, TreeNavResult::Exit => { drop(cur_edit); drop(ce); - self.up(); + self.up(); if i+1 < self.data.len() { @@ -477,10 +479,10 @@ where ItemEditor: TerminalTreeEditor + ?Sized + Send + Sync + 'static, ListCursorMode::Insert => { match event { TerminalEvent::Input(Event::Key(Key::Backspace)) => { - if idx > 0 { - self.data.remove(idx-1); + if idx > 0 && idx <= self.data.len() { cur.idx = Some(idx-1); self.cursor.set(cur); + self.data.remove(idx-1); TerminalEditorResult::Continue } else { TerminalEditorResult::Exit @@ -551,24 +553,26 @@ where ItemEditor: TerminalTreeEditor + ?Sized + Send + Sync + 'static, TerminalEditorResult::Exit => { cur_edit.up(); drop(cur_edit); + drop(ce); match event { - TerminalEvent::Input(Event::Key(Key::Char(' '))) => { - // split.. - self.cursor.set(ListCursor { - mode: ListCursorMode::Insert, - idx: Some(idx+1) - }); - } TerminalEvent::Input(Event::Key(Key::Backspace)) => { + // todo: join instead of remove self.cursor.set(ListCursor { mode: ListCursorMode::Insert, idx: Some(idx) }); - self.data.remove(idx); // todo: join instead of remove + self.data.remove(idx); + } + _ => { + // todo: split + + self.cursor.set(ListCursor { + mode: ListCursorMode::Insert, + idx: Some(idx+1) + }); } - _ => {} } }, TerminalEditorResult::Continue => {} @@ -611,11 +615,11 @@ where ItemEditor: TerminalEditor + ?Sized + Send + Sync + 'static, atom.add_style_front(TerminalStyle::bg_color((90,60,200))) ), ListEditorViewSegment::Modify(sub_view) => { - sub_view.clone()/*.map_item( + sub_view.clone().map_item( |_pt, atom| - atom//.add_style_back(TerminalStyle::bg_color((0,0,0))) + atom.add_style_back(TerminalStyle::bg_color((22,15,50))) //.add_style_back(TerminalStyle::bold(true)) - )*/ + ) }, ListEditorViewSegment::View(sub_view) => sub_view.clone() @@ -624,7 +628,7 @@ where ItemEditor: TerminalEditor + ?Sized + Send + Sync + 'static, } pub fn horizontal_sexpr_view(&self) -> OuterViewPort { - self.get_seg_seq_view().horizontal_sexpr_view(0) + self.get_seg_seq_view().horizontal_sexpr_view(1) } pub fn vertical_sexpr_view(&self) -> OuterViewPort { @@ -664,7 +668,7 @@ where ItemEditor: TerminalEditor + ?Sized + Send + Sync + 'static, .to_grid_horizontal() .flatten() } - + pub fn new(make_item_editor: FnMakeItemEditor, style: ListEditorStyle) -> Self { let cursor_port = ViewPort::new(); let data_port = ViewPort::new(); From 029d2c4e029bd8eb796cbb007a8529d819bf173f Mon Sep 17 00:00:00 2001 From: Michael Sippel Date: Sun, 12 Sep 2021 17:40:03 +0200 Subject: [PATCH 15/16] SdfTerm: calculate layer size & offset with configurable font size --- sdf_editor/src/main.rs | 18 +++++++++++------- 1 file changed, 11 insertions(+), 7 deletions(-) diff --git a/sdf_editor/src/main.rs b/sdf_editor/src/main.rs index 624c219..3181b41 100644 --- a/sdf_editor/src/main.rs +++ b/sdf_editor/src/main.rs @@ -72,10 +72,13 @@ impl Observer> for ColorCollector { } struct SdfTerm { - pub src_view: Option>, + src_view: Option>, bg_layers: HashMap, (bool, LayerId2d)>, fg_layers: HashMap, (bool, LayerId2d)>, - //font: Arc>, + + font_height: usize, + //font: Mutex, + renderer: Arc> } @@ -85,7 +88,8 @@ impl SdfTerm { src_view: None, bg_layers: HashMap::new(), fg_layers: HashMap::new(), - //font: Arc::new(RwLock::new(Font::from_path(Path::new("/usr/share/fonts/TTF/FiraCode-Medium.ttf"),0).unwrap())), + font_height: 60, + //font: Mutex::new(Font::from_path(Path::new("/usr/share/fonts/TTF/FiraCode-Medium.ttf"),0).unwrap()), renderer } } @@ -121,8 +125,8 @@ impl SdfTerm { self.renderer.lock().unwrap().set_layer_info( id.into(), LayerInfo { - extent: (60, 100), - location: (pt.x as usize * 60, pt.y as usize * 100) + extent: (1 + self.font_height / 2, self.font_height), + location: (pt.x as usize * self.font_height / 2, pt.y as usize * self.font_height) }); self.bg_layers.insert(*pt, (false, id)); @@ -140,8 +144,8 @@ impl SdfTerm { self.renderer.lock().unwrap().set_layer_info( id.into(), LayerInfo { - extent: (60, 100), - location: (pt.x as usize * 60, pt.y as usize * 100) + extent: (1 + self.font_height / 2, self.font_height), + location: (pt.x as usize * self.font_height / 2, pt.y as usize * self.font_height) }); self.fg_layers.insert(*pt, (false, id)); From b081c4311fb2a8765f0ac7c23f11f9bf96d5eb22 Mon Sep 17 00:00:00 2001 From: Michael Sippel Date: Sun, 12 Sep 2021 22:57:58 +0200 Subject: [PATCH 16/16] use UVec2 in Layer info --- sdf_editor/src/main.rs | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/sdf_editor/src/main.rs b/sdf_editor/src/main.rs index 3181b41..4cd1609 100644 --- a/sdf_editor/src/main.rs +++ b/sdf_editor/src/main.rs @@ -24,7 +24,7 @@ use{ }, nako::{ stream::{SecondaryStream2d, PrimaryStream2d}, - glam::{Vec2, Vec3}, + glam::{Vec2, Vec3, UVec2}, operations::{ planar::primitives2d::Box2d, volumetric::{Color, Union, Round}, @@ -76,7 +76,7 @@ struct SdfTerm { bg_layers: HashMap, (bool, LayerId2d)>, fg_layers: HashMap, (bool, LayerId2d)>, - font_height: usize, + font_height: u32, //font: Mutex, renderer: Arc> @@ -125,8 +125,8 @@ impl SdfTerm { self.renderer.lock().unwrap().set_layer_info( id.into(), LayerInfo { - extent: (1 + self.font_height / 2, self.font_height), - location: (pt.x as usize * self.font_height / 2, pt.y as usize * self.font_height) + extent: UVec2::new(1 + self.font_height / 2, self.font_height), + location: UVec2::new(pt.x as u32 * self.font_height / 2, pt.y as u32 * self.font_height) }); self.bg_layers.insert(*pt, (false, id)); @@ -144,8 +144,8 @@ impl SdfTerm { self.renderer.lock().unwrap().set_layer_info( id.into(), LayerInfo { - extent: (1 + self.font_height / 2, self.font_height), - location: (pt.x as usize * self.font_height / 2, pt.y as usize * self.font_height) + extent: UVec2::new(1 + self.font_height / 2, self.font_height), + location: UVec2::new(pt.x as u32 * self.font_height / 2, pt.y as u32 * self.font_height) }); self.fg_layers.insert(*pt, (false, id)); @@ -272,8 +272,8 @@ async fn main() { rotation: 0.0 }); renderer.lock().unwrap().set_layer_info(color_layer_id.into(), LayerInfo{ - extent: (600, 600), - location: (200,100) + extent: UVec2::new(600, 600), + location: UVec2::new(200,100) }); event_loop.run(move |event, _target, control_flow|{