mirror of
https://gitlab.com/veloren/veloren.git
synced 2024-08-30 18:12:32 +00:00
Get resizing working
This commit is contained in:
parent
bbbede68fc
commit
0305c1979a
@ -10,25 +10,39 @@ pub use renderer::IcedRenderer;
|
||||
pub use widget::image::Image;
|
||||
pub use winit_conversion::window_event;
|
||||
|
||||
use super::graphic::{self, Graphic};
|
||||
use super::{
|
||||
graphic::{self, Graphic},
|
||||
scale::{Scale, ScaleMode},
|
||||
};
|
||||
use crate::{render::Renderer, window::Window, Error};
|
||||
use clipboard::Clipboard;
|
||||
use iced::{Cache, Element, MouseCursor, Size, UserInterface};
|
||||
use vek::*;
|
||||
|
||||
pub struct IcedUi {
|
||||
renderer: IcedRenderer,
|
||||
cache: Option<Cache>,
|
||||
events: Vec<Event>,
|
||||
clipboard: Clipboard,
|
||||
// Scaling of the ui
|
||||
scale: Scale,
|
||||
window_resized: Option<Vec2<u32>>,
|
||||
}
|
||||
impl IcedUi {
|
||||
pub fn new(window: &mut Window) -> Result<Self, Error> {
|
||||
let scale = Scale::new(window, ScaleMode::Absolute(1.0));
|
||||
let renderer = window.renderer_mut();
|
||||
|
||||
let scaled_dims = scale.scaled_window_size().map(|e| e as f32);
|
||||
|
||||
Ok(Self {
|
||||
renderer: IcedRenderer::new(window)?,
|
||||
renderer: IcedRenderer::new(renderer, scaled_dims)?,
|
||||
cache: Some(Cache::new()),
|
||||
events: Vec::new(),
|
||||
// TODO: handle None
|
||||
clipboard: Clipboard::new(window.window()).unwrap(),
|
||||
scale,
|
||||
window_resized: None,
|
||||
})
|
||||
}
|
||||
|
||||
@ -37,8 +51,40 @@ impl IcedUi {
|
||||
self.renderer.add_graphic(graphic)
|
||||
}
|
||||
|
||||
// TODO: handle scaling here
|
||||
pub fn handle_event(&mut self, event: Event) { self.events.push(event); }
|
||||
pub fn handle_event(&mut self, event: Event) {
|
||||
use iced::{input::mouse, window};
|
||||
match event {
|
||||
// Intercept resizing events
|
||||
Event::Window(window::Event::Resized { width, height }) => {
|
||||
self.window_resized = Some(Vec2::new(width, height));
|
||||
},
|
||||
// Scale cursor movement events
|
||||
// Note: in some cases the scaling could be off if a resized event occured in the same
|
||||
// frame, in practice this shouldn't be an issue
|
||||
Event::Mouse(mouse::Event::CursorMoved { x, y }) => {
|
||||
// TODO: return f32 here
|
||||
let scale = self.scale.scale_factor_logical() as f32;
|
||||
self.events.push(Event::Mouse(mouse::Event::CursorMoved {
|
||||
x: x * scale,
|
||||
y: y * scale,
|
||||
}));
|
||||
},
|
||||
// Scale pixel scrolling events
|
||||
Event::Mouse(mouse::Event::WheelScrolled {
|
||||
delta: mouse::ScrollDelta::Pixels { x, y },
|
||||
}) => {
|
||||
// TODO: return f32 here
|
||||
let scale = self.scale.scale_factor_logical() as f32;
|
||||
self.events.push(Event::Mouse(mouse::Event::WheelScrolled {
|
||||
delta: mouse::ScrollDelta::Pixels {
|
||||
x: x * scale,
|
||||
y: y * scale,
|
||||
},
|
||||
}));
|
||||
},
|
||||
event => self.events.push(event),
|
||||
}
|
||||
}
|
||||
|
||||
// TODO: produce root internally???
|
||||
pub fn maintain<'a, M, E: Into<Element<'a, M, IcedRenderer>>>(
|
||||
@ -46,8 +92,33 @@ impl IcedUi {
|
||||
root: E,
|
||||
renderer: &mut Renderer,
|
||||
) -> (Vec<M>, MouseCursor) {
|
||||
// Handle window resizing
|
||||
if let Some(new_dims) = self.window_resized.take() {
|
||||
let old_scaled_dims = self.scale.scaled_window_size();
|
||||
// TODO maybe use u32 in Scale to be consistent with iced
|
||||
self.scale
|
||||
.window_resized(new_dims.map(|e| e as f64), renderer);
|
||||
let scaled_dims = self.scale.scaled_window_size();
|
||||
|
||||
self.events
|
||||
.push(Event::Window(iced::window::Event::Resized {
|
||||
width: scaled_dims.x as u32,
|
||||
height: scaled_dims.y as u32,
|
||||
}));
|
||||
|
||||
// Avoid panic in graphic cache when minimizing.
|
||||
// Avoid resetting cache if window size didn't change
|
||||
// Somewhat inefficient for elements that won't change size after a window
|
||||
// resize
|
||||
let res = renderer.get_resolution();
|
||||
if res.x > 0 && res.y > 0 && scaled_dims != old_scaled_dims {
|
||||
self.renderer
|
||||
.resize(scaled_dims.map(|e| e as f32), renderer);
|
||||
}
|
||||
}
|
||||
|
||||
// TODO: convert to f32 at source
|
||||
let window_size = self.renderer.scaled_window_size().map(|e| e as f32);
|
||||
let window_size = self.scale.scaled_window_size().map(|e| e as f32);
|
||||
|
||||
let mut user_interface = UserInterface::build(
|
||||
root,
|
||||
|
@ -5,7 +5,6 @@ use super::{
|
||||
super::{
|
||||
cache::Cache,
|
||||
graphic::{self, Graphic, TexId},
|
||||
scale::{Scale, ScaleMode},
|
||||
},
|
||||
widget,
|
||||
};
|
||||
@ -13,7 +12,6 @@ use crate::{
|
||||
render::{
|
||||
create_ui_quad, Consts, DynamicModel, Globals, Mesh, Renderer, UiLocals, UiMode, UiPipeline,
|
||||
},
|
||||
window::Window,
|
||||
Error,
|
||||
};
|
||||
//use log::warn;
|
||||
@ -73,13 +71,8 @@ pub struct IcedRenderer {
|
||||
interface_locals: Consts<UiLocals>,
|
||||
default_globals: Consts<Globals>,
|
||||
|
||||
// Window size for updating scaling
|
||||
//window_resized: Option<Vec2<f64>>,
|
||||
// Used to delay cache resizing until after current frame is drawn
|
||||
//need_cache_resize: bool,
|
||||
// Scaling of the ui
|
||||
scale: Scale,
|
||||
|
||||
half_res: Vec2<f32>,
|
||||
// Pixel perfection alignment
|
||||
align: Vec2<f32>,
|
||||
@ -95,16 +88,8 @@ pub struct IcedRenderer {
|
||||
//current_scissor: Aabr<u16>,
|
||||
}
|
||||
impl IcedRenderer {
|
||||
pub fn new(window: &mut Window) -> Result<Self, Error> {
|
||||
let scale = Scale::new(window, ScaleMode::Absolute(1.0));
|
||||
// TODO: looks like we can just get this from scale
|
||||
let win_dims = scale.scaled_window_size().map(|e| e as f32);
|
||||
|
||||
let renderer = window.renderer_mut();
|
||||
let res = renderer.get_resolution();
|
||||
|
||||
let half_res = res.map(|e| e as f32 / 2.0);
|
||||
let align = align(res);
|
||||
pub fn new(renderer: &mut Renderer, scaled_dims: Vec2<f32>) -> Result<Self, Error> {
|
||||
let (half_res, align) = Self::calculate_resolution_dependents(renderer.get_resolution());
|
||||
|
||||
Ok(Self {
|
||||
cache: Cache::new(renderer)?,
|
||||
@ -113,35 +98,32 @@ impl IcedRenderer {
|
||||
interface_locals: renderer.create_consts(&[UiLocals::default()])?,
|
||||
default_globals: renderer.create_consts(&[Globals::default()])?,
|
||||
ingame_locals: Vec::new(),
|
||||
//window_resized: None,
|
||||
//need_cache_resize: false,
|
||||
mesh: Mesh::new(),
|
||||
current_state: State::Plain,
|
||||
scale,
|
||||
half_res,
|
||||
align,
|
||||
win_dims,
|
||||
win_dims: scaled_dims,
|
||||
start: 0,
|
||||
//current_scissor: default_scissor(renderer),
|
||||
})
|
||||
}
|
||||
|
||||
pub fn scaled_window_size(&self) -> Vec2<f64> { self.scale.scaled_window_size() }
|
||||
|
||||
pub fn add_graphic(&mut self, graphic: Graphic) -> graphic::Id {
|
||||
self.cache.add_graphic(graphic)
|
||||
}
|
||||
|
||||
pub fn resize(&mut self, scaled_dims: Vec2<f32>, renderer: &mut Renderer) {
|
||||
self.win_dims = scaled_dims;
|
||||
|
||||
self.update_resolution_dependents(renderer.get_resolution());
|
||||
|
||||
// Resize graphic cache
|
||||
self.cache.resize_graphic_cache(renderer);
|
||||
// Resize glyph cache
|
||||
self.cache.resize_glyph_cache(renderer).unwrap();
|
||||
}
|
||||
|
||||
pub fn draw(&mut self, primitive: Primitive, renderer: &mut Renderer) {
|
||||
/*if self.need_cache_resize {
|
||||
// Resize graphic cache
|
||||
self.cache.resize_graphic_cache(renderer).unwrap();
|
||||
// Resize glyph cache
|
||||
self.cache.resize_glyph_cache(renderer).unwrap();
|
||||
|
||||
self.need_cache_resize = false;
|
||||
}*/
|
||||
|
||||
// Re-use memory
|
||||
self.draw_commands.clear();
|
||||
self.mesh.clear();
|
||||
@ -203,6 +185,20 @@ impl IcedRenderer {
|
||||
}*/
|
||||
}
|
||||
|
||||
// Returns (half_res, align)
|
||||
fn calculate_resolution_dependents(res: Vec2<u16>) -> (Vec2<f32>, Vec2<f32>) {
|
||||
let half_res = res.map(|e| e as f32 / 2.0);
|
||||
let align = align(res);
|
||||
|
||||
(half_res, align)
|
||||
}
|
||||
|
||||
fn update_resolution_dependents(&mut self, res: Vec2<u16>) {
|
||||
let (half_res, align) = Self::calculate_resolution_dependents(res);
|
||||
self.half_res = half_res;
|
||||
self.align = align;
|
||||
}
|
||||
|
||||
fn gl_aabr(&self, bounds: iced::Rectangle) -> Aabr<f32> {
|
||||
/*let (ui_win_w, ui_win_h) = self.win_dims.into_tuple();
|
||||
let (l, b) = aabr.min.into_tuple();
|
||||
@ -360,6 +356,7 @@ impl IcedRenderer {
|
||||
|
||||
// Given the the resolution determines the offset needed to align integer
|
||||
// offsets from the center of the sceen to pixels
|
||||
#[inline(always)]
|
||||
fn align(res: Vec2<u16>) -> Vec2<f32> {
|
||||
// If the resolution is odd then the center of the screen will be within the
|
||||
// middle of a pixel so we need to offset by 0.5 pixels to be on the edge of
|
||||
|
Loading…
Reference in New Issue
Block a user