diff --git a/procedural/src/prototype/window.rs b/procedural/src/prototype/window.rs index 288428f0..15b06a6f 100644 --- a/procedural/src/prototype/window.rs +++ b/procedural/src/prototype/window.rs @@ -24,7 +24,7 @@ pub fn derive_prototype_window_struct( #window_class_ref_option } - fn to_window(&self, window_cache: &crate::interface::WindowCache, interface_settings: &crate::interface::InterfaceSettings, available_space: crate::interface::Size) -> crate::interface::Window { + fn to_window(&self, window_cache: &crate::interface::WindowCache, interface_settings: &crate::interface::InterfaceSettings, available_space: crate::interface::ScreenSize) -> crate::interface::Window { let scroll_view = crate::interface::ScrollView::new(vec![#(#initializers),*], constraint!(100%, ?)); let elements: Vec<crate::interface::ElementCell> = vec![std::rc::Rc::new(std::cell::RefCell::new(scroll_view))]; diff --git a/src/graphics/cameras/debug.rs b/src/graphics/cameras/debug.rs index a3ad040d..c7d56056 100644 --- a/src/graphics/cameras/debug.rs +++ b/src/graphics/cameras/debug.rs @@ -4,6 +4,7 @@ use cgmath::{Array, EuclideanSpace, InnerSpace, Matrix4, MetricSpace, Point3, Ra use super::Camera; use crate::graphics::Transform; +use crate::interface::{ScreenPosition, ScreenSize}; const LOOK_AROUND_SPEED: f32 = 0.005; const FLY_SPEED_FAST: f32 = 1000.0; @@ -165,12 +166,18 @@ impl Camera for DebugCamera { (top_left_position, bottom_right_position) } - fn screen_position_size(&self, top_left_position: Vector4<f32>, bottom_right_position: Vector4<f32>) -> (Vector2<f32>, Vector2<f32>) { + fn screen_position_size(&self, top_left_position: Vector4<f32>, bottom_right_position: Vector4<f32>) -> (ScreenPosition, ScreenSize) { let top_left_position = self.clip_to_screen_space(top_left_position); let bottom_right_position = self.clip_to_screen_space(bottom_right_position); - let screen_position = top_left_position; - let screen_size = bottom_right_position - top_left_position; + let screen_position = ScreenPosition { + left: top_left_position.x, + top: top_left_position.y, + }; + let screen_size = ScreenSize { + width: bottom_right_position.x - top_left_position.x, + height: bottom_right_position.y - top_left_position.y, + }; (screen_position, screen_size) } diff --git a/src/graphics/cameras/mod.rs b/src/graphics/cameras/mod.rs index 78c503d9..8732c41a 100644 --- a/src/graphics/cameras/mod.rs +++ b/src/graphics/cameras/mod.rs @@ -12,6 +12,7 @@ pub use self::player::PlayerCamera; pub use self::shadow::ShadowCamera; pub use self::start::StartCamera; use crate::graphics::{SmoothedValue, Transform}; +use crate::interface::{ScreenPosition, ScreenSize}; fn direction(vector: Vector2<f32>) -> usize { let inverted = false; @@ -34,7 +35,7 @@ pub trait Camera { fn billboard_coordinates(&self, position: Vector3<f32>, size: f32) -> (Vector4<f32>, Vector4<f32>); - fn screen_position_size(&self, top_left_position: Vector4<f32>, bottom_right_position: Vector4<f32>) -> (Vector2<f32>, Vector2<f32>); + fn screen_position_size(&self, top_left_position: Vector4<f32>, bottom_right_position: Vector4<f32>) -> (ScreenPosition, ScreenSize); fn distance_to(&self, position: Vector3<f32>) -> f32; diff --git a/src/graphics/cameras/player.rs b/src/graphics/cameras/player.rs index cef7722c..4b28eb7b 100644 --- a/src/graphics/cameras/player.rs +++ b/src/graphics/cameras/player.rs @@ -4,6 +4,7 @@ use cgmath::{Array, EuclideanSpace, InnerSpace, Matrix4, MetricSpace, Point3, Ra use super::{Camera, SmoothedValue}; use crate::graphics::Transform; +use crate::interface::{ScreenPosition, ScreenSize}; const ZOOM_SPEED: f32 = 2.0; const ROTATION_SPEED: f32 = 0.02; @@ -162,12 +163,18 @@ impl Camera for PlayerCamera { (top_left_position, bottom_right_position) } - fn screen_position_size(&self, top_left_position: Vector4<f32>, bottom_right_position: Vector4<f32>) -> (Vector2<f32>, Vector2<f32>) { + fn screen_position_size(&self, top_left_position: Vector4<f32>, bottom_right_position: Vector4<f32>) -> (ScreenPosition, ScreenSize) { let top_left_position = self.clip_to_screen_space(top_left_position); let bottom_right_position = self.clip_to_screen_space(bottom_right_position); - let screen_position = top_left_position; - let screen_size = bottom_right_position - top_left_position; + let screen_position = ScreenPosition { + left: top_left_position.x, + top: top_left_position.y, + }; + let screen_size = ScreenSize { + width: bottom_right_position.x - top_left_position.x, + height: bottom_right_position.y - top_left_position.y, + }; (screen_position, screen_size) } diff --git a/src/graphics/cameras/shadow.rs b/src/graphics/cameras/shadow.rs index e316cb9f..6cdcde1e 100644 --- a/src/graphics/cameras/shadow.rs +++ b/src/graphics/cameras/shadow.rs @@ -2,6 +2,7 @@ use cgmath::{Array, EuclideanSpace, InnerSpace, Matrix4, MetricSpace, Point3, Sq use super::Camera; use crate::graphics::Transform; +use crate::interface::{ScreenPosition, ScreenSize}; pub struct ShadowCamera { focus_point: Point3<f32>, @@ -120,12 +121,18 @@ impl Camera for ShadowCamera { (top_left_position, bottom_right_position) } - fn screen_position_size(&self, top_left_position: Vector4<f32>, bottom_right_position: Vector4<f32>) -> (Vector2<f32>, Vector2<f32>) { + fn screen_position_size(&self, top_left_position: Vector4<f32>, bottom_right_position: Vector4<f32>) -> (ScreenPosition, ScreenSize) { let top_left_position = self.clip_to_screen_space(top_left_position); let bottom_right_position = self.clip_to_screen_space(bottom_right_position); - let screen_position = top_left_position; - let screen_size = bottom_right_position - top_left_position; + let screen_position = ScreenPosition { + left: top_left_position.x, + top: top_left_position.y, + }; + let screen_size = ScreenSize { + width: bottom_right_position.x - top_left_position.x, + height: bottom_right_position.y - top_left_position.y, + }; (screen_position, screen_size) } diff --git a/src/graphics/cameras/start.rs b/src/graphics/cameras/start.rs index 3cf03c86..427be54a 100644 --- a/src/graphics/cameras/start.rs +++ b/src/graphics/cameras/start.rs @@ -4,6 +4,7 @@ use cgmath::{Array, EuclideanSpace, InnerSpace, Matrix4, MetricSpace, Point3, Ra use super::Camera; use crate::graphics::Transform; +use crate::interface::{ScreenPosition, ScreenSize}; const DEFAULT_ZOOM: f32 = 150.0; const ROTATION_SPEED: f32 = 0.03; @@ -132,12 +133,18 @@ impl Camera for StartCamera { (top_left_position, bottom_right_position) } - fn screen_position_size(&self, top_left_position: Vector4<f32>, bottom_right_position: Vector4<f32>) -> (Vector2<f32>, Vector2<f32>) { + fn screen_position_size(&self, top_left_position: Vector4<f32>, bottom_right_position: Vector4<f32>) -> (ScreenPosition, ScreenSize) { let top_left_position = self.clip_to_screen_space(top_left_position); let bottom_right_position = self.clip_to_screen_space(bottom_right_position); - let screen_position = top_left_position; - let screen_size = bottom_right_position - top_left_position; + let screen_position = ScreenPosition { + left: top_left_position.x, + top: top_left_position.y, + }; + let screen_size = ScreenSize { + width: bottom_right_position.x - top_left_position.x, + height: bottom_right_position.y - top_left_position.y, + }; (screen_position, screen_size) } diff --git a/src/graphics/color.rs b/src/graphics/color.rs index 60de257f..b8b7078c 100644 --- a/src/graphics/color.rs +++ b/src/graphics/color.rs @@ -106,6 +106,18 @@ impl Color { } } +impl From<Color> for [f32; 3] { + fn from(val: Color) -> Self { + [val.red_f32(), val.green_f32(), val.blue_f32()] + } +} + +impl From<Color> for [f32; 4] { + fn from(val: Color) -> Self { + [val.red_f32(), val.green_f32(), val.blue_f32(), val.alpha_f32()] + } +} + #[allow(dead_code)] #[derive(Clone, Debug, Named, ByteConvertable, PrototypeElement)] pub struct ColorBGRA { diff --git a/src/graphics/particles/mod.rs b/src/graphics/particles/mod.rs index 93105b55..9c2f5031 100644 --- a/src/graphics/particles/mod.rs +++ b/src/graphics/particles/mod.rs @@ -1,11 +1,12 @@ use std::collections::HashMap; -use cgmath::{Array, Vector2, Vector3, Vector4, Zero}; +use cgmath::{Vector2, Vector3}; use derive_new::new; use procedural::profile; use rand::{thread_rng, Rng}; use crate::graphics::*; +use crate::interface::{ScreenClip, ScreenPosition, ScreenSize}; use crate::loaders::{GameFileLoader, TextureLoader}; use crate::network::{EntityId, QuestColor, QuestEffectPacket}; use crate::world::*; @@ -18,7 +19,7 @@ pub trait Particle { render_target: &mut <DeferredRenderer as Renderer>::Target, renderer: &DeferredRenderer, camera: &dyn Camera, - window_size: Vector2<f32>, + window_size: ScreenSize, ); } @@ -53,7 +54,7 @@ impl Particle for DamageNumber { render_target: &mut <DeferredRenderer as Renderer>::Target, renderer: &DeferredRenderer, camera: &dyn Camera, - window_size: Vector2<f32>, + window_size: ScreenSize, ) { let (view_matrix, projection_matrix) = camera.view_projection_matrices(); let clip_space_position = (projection_matrix * view_matrix) * self.position.extend(1.0); @@ -62,7 +63,10 @@ impl Particle for DamageNumber { clip_space_position.y / clip_space_position.w + 1.0, ); let screen_position = screen_position / 2.0; - let final_position = Vector2::new(screen_position.x * window_size.x, screen_position.y * window_size.y); + let final_position = ScreenPosition { + left: screen_position.x * window_size.width, + top: screen_position.y * window_size.height, + }; renderer.render_damage_text(render_target, &self.damage_amount, final_position, Color::monochrome(255), 16.0); } @@ -93,7 +97,7 @@ impl Particle for HealNumber { render_target: &mut <DeferredRenderer as Renderer>::Target, renderer: &DeferredRenderer, camera: &dyn Camera, - window_size: Vector2<f32>, + window_size: ScreenSize, ) { let (view_matrix, projection_matrix) = camera.view_projection_matrices(); let clip_space_position = (projection_matrix * view_matrix) * self.position.extend(1.0); @@ -102,7 +106,10 @@ impl Particle for HealNumber { clip_space_position.y / clip_space_position.w + 1.0, ); let screen_position = screen_position / 2.0; - let final_position = Vector2::new(screen_position.x * window_size.x, screen_position.y * window_size.y); + let final_position = ScreenPosition { + left: screen_position.x * window_size.width, + top: screen_position.y * window_size.height, + }; renderer.render_damage_text(render_target, &self.heal_amount, final_position, Color::rgb(30, 255, 30), 16.0); } @@ -144,7 +151,7 @@ impl QuestIcon { render_target: &mut <DeferredRenderer as Renderer>::Target, renderer: &DeferredRenderer, camera: &dyn Camera, - window_size: Vector2<f32>, + window_size: ScreenSize, ) { let (view_matrix, projection_matrix) = camera.view_projection_matrices(); let clip_space_position = (projection_matrix * view_matrix) * self.position.extend(1.0); @@ -153,14 +160,17 @@ impl QuestIcon { clip_space_position.y / clip_space_position.w + 1.0, ); let screen_position = screen_position / 2.0; - let final_position = Vector2::new(screen_position.x * window_size.x, screen_position.y * window_size.y); + let final_position = ScreenPosition { + left: screen_position.x * window_size.width, + top: screen_position.y * window_size.height, + }; renderer.render_sprite( render_target, self.texture.clone(), - final_position - Vector2::from_value(15.0), - Vector2::from_value(30.0), - Vector4::zero(), + final_position - ScreenSize::uniform(15.0), + ScreenSize::uniform(30.0), + ScreenClip::default(), self.color, true, ); @@ -211,7 +221,7 @@ impl ParticleHolder { render_target: &mut <DeferredRenderer as Renderer>::Target, renderer: &DeferredRenderer, camera: &dyn Camera, - window_size: Vector2<f32>, + window_size: ScreenSize, entities: &[Entity], ) { self.particles diff --git a/src/graphics/renderers/deferred/ambient/mod.rs b/src/graphics/renderers/deferred/ambient/mod.rs index e2918c48..5b379d82 100644 --- a/src/graphics/renderers/deferred/ambient/mod.rs +++ b/src/graphics/renderers/deferred/ambient/mod.rs @@ -77,9 +77,7 @@ impl AmbientLightRenderer { WriteDescriptorSet::image_view(1, render_target.normal_image.clone()), ]); - let constants = Constants { - color: [color.red_f32(), color.green_f32(), color.blue_f32()], - }; + let constants = Constants { color: color.into() }; render_target .state diff --git a/src/graphics/renderers/deferred/box/mod.rs b/src/graphics/renderers/deferred/box/mod.rs index 486e0e92..4214a88a 100644 --- a/src/graphics/renderers/deferred/box/mod.rs +++ b/src/graphics/renderers/deferred/box/mod.rs @@ -139,7 +139,7 @@ impl BoxRenderer { let constants = Constants { world: world_matrix.into(), - color: [color.red_f32(), color.green_f32(), color.blue_f32()], + color: color.into(), }; render_target diff --git a/src/graphics/renderers/deferred/directional/mod.rs b/src/graphics/renderers/deferred/directional/mod.rs index 7b944a1a..2b678c42 100644 --- a/src/graphics/renderers/deferred/directional/mod.rs +++ b/src/graphics/renderers/deferred/directional/mod.rs @@ -104,7 +104,7 @@ impl DirectionalLightRenderer { ]); let constants = Constants { - direction: Padded([direction.x, direction.y, direction.z]), + direction: Padded(direction.into()), color: [ color.red_f32() * intensity, color.green_f32() * intensity, diff --git a/src/graphics/renderers/deferred/effect/mod.rs b/src/graphics/renderers/deferred/effect/mod.rs index 59b360a6..03c36eba 100644 --- a/src/graphics/renderers/deferred/effect/mod.rs +++ b/src/graphics/renderers/deferred/effect/mod.rs @@ -18,6 +18,7 @@ use super::DeferredSubrenderer; use crate::graphics::renderers::pipeline::PipelineBuilder; use crate::graphics::renderers::sampler::{create_new_sampler, SamplerType}; use crate::graphics::*; +use crate::interface::ScreenSize; pub struct EffectRenderer { memory_allocator: Arc<MemoryAllocator>, @@ -76,7 +77,7 @@ impl EffectRenderer { &self, render_target: &mut <DeferredRenderer as Renderer>::Target, texture: Arc<ImageView>, - window_size: Vector2<usize>, + window_size: ScreenSize, mut screen_positions: [Vector2<f32>; 4], texture_coordinates: [Vector2<f32>; 4], screen_space_position: Vector2<f32>, @@ -90,7 +91,7 @@ impl EffectRenderer { self.bind_pipeline(render_target); } - let half_screen = Vector2::new(window_size.x as f32 / 2.0, window_size.y as f32 / 2.0); + let half_screen = Vector2::new(window_size.width / 2.0, window_size.height / 2.0); // TODO: move this calculation to the loading let rotation_matrix = Matrix2::from_angle(cgmath::Deg(angle / (1024.0 / 360.0))); @@ -122,7 +123,7 @@ impl EffectRenderer { t_bottom_left: texture_coordinates[3], t_top_right: texture_coordinates[1], t_bottom_right: texture_coordinates[0], - color: [color.red_f32(), color.green_f32(), color.blue_f32(), color.alpha_f32()], + color: color.into(), }; render_target diff --git a/src/graphics/renderers/deferred/entity/mod.rs b/src/graphics/renderers/deferred/entity/mod.rs index 963afbab..06f0606a 100644 --- a/src/graphics/renderers/deferred/entity/mod.rs +++ b/src/graphics/renderers/deferred/entity/mod.rs @@ -122,8 +122,8 @@ impl EntityRenderer { let constants = Constants { world: world_matrix.into(), - texture_position: [texture_position.x, texture_position.y], - texture_size: [texture_size.x, texture_size.y], + texture_position: texture_position.into(), + texture_size: texture_size.into(), depth_offset, curvature, mirror: mirror as u32, diff --git a/src/graphics/renderers/deferred/indicator/mod.rs b/src/graphics/renderers/deferred/indicator/mod.rs index e023de6c..a00b526f 100644 --- a/src/graphics/renderers/deferred/indicator/mod.rs +++ b/src/graphics/renderers/deferred/indicator/mod.rs @@ -109,7 +109,7 @@ impl IndicatorRenderer { ]); let constants = Constants { - color: Padded([color.red_f32(), color.green_f32(), color.blue_f32()]), + color: Padded(color.into()), upper_left: Padded(upper_left.into()), upper_right: Padded(upper_right.into()), lower_left: Padded(lower_left.into()), diff --git a/src/graphics/renderers/deferred/mod.rs b/src/graphics/renderers/deferred/mod.rs index dcc46f31..85f3c6b9 100644 --- a/src/graphics/renderers/deferred/mod.rs +++ b/src/graphics/renderers/deferred/mod.rs @@ -19,7 +19,7 @@ use std::sync::Arc; #[cfg(feature = "debug")] use cgmath::SquareMatrix; -use cgmath::{Matrix4, Vector2, Vector3, Vector4}; +use cgmath::{Matrix4, Vector2, Vector3}; use procedural::profile; use vulkano::device::{DeviceOwned, Queue}; use vulkano::format::Format; @@ -49,6 +49,7 @@ use crate::graphics::{ EntityRenderer as EntityRendererTrait, GeometryRenderer as GeometryRendererTrait, IndicatorRenderer as IndicatorRendererTrait, SpriteRenderer as SpriteRendererTrait, *, }; +use crate::interface::{ScreenClip, ScreenPosition, ScreenSize}; use crate::loaders::{GameFileLoader, TextureLoader}; use crate::network::EntityId; #[cfg(feature = "debug")] @@ -344,29 +345,38 @@ impl DeferredRenderer { self.overlay_renderer.render(render_target, interface_image); } + fn get_window_size(&self) -> ScreenSize { + ScreenSize { + width: self.dimensions[0] as f32, + height: self.dimensions[1] as f32, + } + } + pub fn render_rectangle( &self, render_target: &mut <Self as Renderer>::Target, - position: Vector2<f32>, - size: Vector2<f32>, + position: ScreenPosition, + size: ScreenSize, color: Color, ) { - let window_size = Vector2::new(self.dimensions[0] as usize, self.dimensions[1] as usize); - - self.rectangle_renderer.render(render_target, window_size, position, size, color); + self.rectangle_renderer + .render(render_target, self.get_window_size(), position, size, color); } pub fn render_bar( &self, render_target: &mut <Self as Renderer>::Target, - position: Vector2<f32>, - size: Vector2<f32>, + position: ScreenPosition, + size: ScreenSize, color: Color, maximum: f32, current: f32, ) { - let bar_offset = Vector2::new(size.x / 2.0, 0.0); - let bar_size = Vector2::new((size.x / maximum) * current, size.y); + let bar_offset = ScreenSize::only_width(size.width / 2.0); + let bar_size = ScreenSize { + width: (size.width / maximum) * current, + height: size.height, + }; self.render_rectangle(render_target, position - bar_offset, bar_size, color); } @@ -375,11 +385,11 @@ impl DeferredRenderer { &self, render_target: &mut <Self as Renderer>::Target, text: &str, - mut position: Vector2<f32>, + mut position: ScreenPosition, color: Color, font_size: f32, ) { - let window_size = Vector2::new(self.dimensions[0] as usize, self.dimensions[1] as usize); + let window_size = self.get_window_size(); for character in text.as_bytes() { let index = (*character as usize).saturating_sub(31); @@ -388,13 +398,13 @@ impl DeferredRenderer { self.font_map.clone(), window_size, position, - Vector2::new(font_size, font_size), + ScreenSize::uniform(font_size), color, 10, index, true, ); - position.x += font_size / 2.0; + position.left += font_size / 2.0; } } @@ -402,11 +412,11 @@ impl DeferredRenderer { &self, render_target: &mut <Self as Renderer>::Target, text: &str, - mut position: Vector2<f32>, + mut position: ScreenPosition, color: Color, font_size: f32, ) { - let window_size = Vector2::new(self.dimensions[0] as usize, self.dimensions[1] as usize); + let window_size = self.get_window_size(); for character in text.as_bytes() { let index = (*character as usize).saturating_sub(31); @@ -415,13 +425,13 @@ impl DeferredRenderer { self.font_map.clone(), window_size, position, - Vector2::new(font_size, font_size), + ScreenSize::uniform(font_size), color, 10, index, true, ); - position.x += font_size / 2.0; + position.left += font_size / 2.0; } } @@ -436,7 +446,7 @@ impl DeferredRenderer { angle: f32, color: Color, ) { - let window_size = Vector2::new(self.dimensions[0] as usize, self.dimensions[1] as usize); + let window_size = self.get_window_size(); self.effect_renderer.render( render_target, @@ -552,18 +562,25 @@ impl SpriteRendererTrait for DeferredRenderer { &self, render_target: &mut <Self as Renderer>::Target, texture: Arc<ImageView>, - position: Vector2<f32>, - size: Vector2<f32>, - _clip_size: Vector4<f32>, + position: ScreenPosition, + size: ScreenSize, + _screen_clip: ScreenClip, color: Color, smooth: bool, ) where Self: Renderer, { - let window_size = Vector2::new(self.dimensions[0] as usize, self.dimensions[1] as usize); - - self.sprite_renderer - .render_indexed(render_target, texture, window_size, position, size, color, 1, 0, smooth); + self.sprite_renderer.render_indexed( + render_target, + texture, + self.get_window_size(), + position, + size, + color, + 1, + 0, + smooth, + ); } } diff --git a/src/graphics/renderers/deferred/point/mod.rs b/src/graphics/renderers/deferred/point/mod.rs index 0116a9be..24d78975 100644 --- a/src/graphics/renderers/deferred/point/mod.rs +++ b/src/graphics/renderers/deferred/point/mod.rs @@ -108,10 +108,10 @@ impl PointLightRenderer { let (screen_position, screen_size) = camera.screen_position_size(top_left_position, bottom_right_position); let constants = Constants { - screen_position: [screen_position.x, screen_position.y], - screen_size: [screen_size.x, screen_size.y], - position: Padded([position.x, position.y, position.z]), - color: [color.red_f32(), color.green_f32(), color.blue_f32()], + screen_position: screen_position.into(), + screen_size: screen_size.into(), + position: Padded(position.into()), + color: color.into(), range, }; diff --git a/src/graphics/renderers/deferred/rectangle/mod.rs b/src/graphics/renderers/deferred/rectangle/mod.rs index c071fd9d..55f0ecd5 100644 --- a/src/graphics/renderers/deferred/rectangle/mod.rs +++ b/src/graphics/renderers/deferred/rectangle/mod.rs @@ -3,7 +3,6 @@ fragment_shader!("src/graphics/renderers/deferred/rectangle/fragment_shader.glsl use std::sync::Arc; -use cgmath::Vector2; use procedural::profile; use vulkano::device::{Device, DeviceOwned}; use vulkano::pipeline::graphics::viewport::Viewport; @@ -15,6 +14,7 @@ use self::vertex_shader::Constants; use super::DeferredSubrenderer; use crate::graphics::renderers::pipeline::PipelineBuilder; use crate::graphics::*; +use crate::interface::{ScreenPosition, ScreenSize}; pub struct RectangleRenderer { vertex_shader: EntryPoint, @@ -67,9 +67,9 @@ impl RectangleRenderer { pub fn render( &self, render_target: &mut <DeferredRenderer as Renderer>::Target, - window_size: Vector2<usize>, - screen_position: Vector2<f32>, - screen_size: Vector2<f32>, + window_size: ScreenSize, + screen_position: ScreenPosition, + screen_size: ScreenSize, color: Color, ) { if render_target.bind_subrenderer(DeferredSubrenderer::Rectangle) { @@ -78,14 +78,14 @@ impl RectangleRenderer { let layout = self.pipeline.layout().clone(); - let half_screen = Vector2::new(window_size.x as f32 / 2.0, window_size.y as f32 / 2.0); - let screen_position = Vector2::new(screen_position.x / half_screen.x, screen_position.y / half_screen.y); - let screen_size = Vector2::new(screen_size.x / half_screen.x, screen_size.y / half_screen.y); + let half_screen = window_size / 2.0; + let screen_position = screen_position / half_screen; + let screen_size = screen_size / half_screen; let constants = Constants { screen_position: screen_position.into(), screen_size: screen_size.into(), - color: [color.red_f32(), color.green_f32(), color.blue_f32(), color.alpha_f32()], + color: color.into(), }; render_target diff --git a/src/graphics/renderers/deferred/sprite/mod.rs b/src/graphics/renderers/deferred/sprite/mod.rs index 4b424fab..72b93205 100644 --- a/src/graphics/renderers/deferred/sprite/mod.rs +++ b/src/graphics/renderers/deferred/sprite/mod.rs @@ -18,6 +18,7 @@ use super::DeferredSubrenderer; use crate::graphics::renderers::pipeline::PipelineBuilder; use crate::graphics::renderers::sampler::{create_new_sampler, SamplerType}; use crate::graphics::*; +use crate::interface::{ScreenPosition, ScreenSize}; #[cfg(feature = "debug")] use crate::loaders::{GameFileLoader, TextureLoader}; #[cfg(feature = "debug")] @@ -120,8 +121,8 @@ impl SpriteRenderer { &self, render_target: &mut <DeferredRenderer as Renderer>::Target, texture: Arc<ImageView>, - screen_position: Vector2<f32>, - screen_size: Vector2<f32>, + screen_position: ScreenPosition, + screen_size: ScreenSize, texture_position: Vector2<f32>, texture_size: Vector2<f32>, color: Color, @@ -141,11 +142,11 @@ impl SpriteRenderer { ]); let constants = Constants { - screen_position: [screen_position.x, screen_position.y], - screen_size: [screen_size.x, screen_size.y], - texture_position: [texture_position.x, texture_position.y], - texture_size: [texture_size.x, texture_size.y], - color: [color.red_f32(), color.green_f32(), color.blue_f32(), color.alpha_f32()], + screen_position: screen_position.into(), + screen_size: screen_size.into(), + texture_position: texture_position.into(), + texture_size: texture_size.into(), + color: color.into(), }; render_target @@ -164,17 +165,26 @@ impl SpriteRenderer { &self, render_target: &mut <DeferredRenderer as Renderer>::Target, texture: Arc<ImageView>, - window_size: Vector2<usize>, - screen_position: Vector2<f32>, - screen_size: Vector2<f32>, + window_size: ScreenSize, + screen_position: ScreenPosition, + screen_size: ScreenSize, color: Color, column_count: usize, cell_index: usize, smooth: bool, ) { - let half_screen = Vector2::new(window_size.x as f32 / 2.0, window_size.y as f32 / 2.0); - let screen_position = Vector2::new(screen_position.x / half_screen.x, screen_position.y / half_screen.y); - let screen_size = Vector2::new(screen_size.x / half_screen.x, screen_size.y / half_screen.y); + let half_screen = ScreenSize { + width: window_size.width as f32 / 2.0, + height: window_size.height as f32 / 2.0, + }; + let screen_position = ScreenPosition { + left: screen_position.left / half_screen.width, + top: screen_position.top / half_screen.height, + }; + let screen_size = ScreenSize { + width: screen_size.width / half_screen.width, + height: screen_size.height / half_screen.height, + }; let unit = 1.0 / column_count as f32; let offset_x = unit * (cell_index % column_count) as f32; @@ -198,8 +208,8 @@ impl SpriteRenderer { &self, render_target: &mut <DeferredRenderer as Renderer>::Target, marker_identifier: MarkerIdentifier, - screen_position: Vector2<f32>, - screen_size: Vector2<f32>, + screen_position: ScreenPosition, + screen_size: ScreenSize, hovered: bool, ) { let (texture, color) = match marker_identifier { diff --git a/src/graphics/renderers/interface/mod.rs b/src/graphics/renderers/interface/mod.rs index b75f0d36..22b3419d 100644 --- a/src/graphics/renderers/interface/mod.rs +++ b/src/graphics/renderers/interface/mod.rs @@ -6,7 +6,7 @@ use std::cell::RefCell; use std::rc::Rc; use std::sync::Arc; -use cgmath::{Vector2, Vector4}; +use cgmath::Vector2; use procedural::profile; use vulkano::device::{DeviceOwned, Queue}; use vulkano::format::{ClearColorValue, Format}; @@ -20,6 +20,7 @@ use self::sprite::SpriteRenderer; use self::text::TextRenderer; use super::{IntoFormat, SubpassAttachments}; use crate::graphics::{Color, MemoryAllocator, Renderer, SingleRenderTarget, SpriteRenderer as SpriteRendererTrait}; +use crate::interface::{CornerRadius, ScreenClip, ScreenPosition, ScreenSize}; use crate::loaders::{FontLoader, GameFileLoader, TextureLoader}; #[derive(PartialEq, Eq)] @@ -132,26 +133,39 @@ impl InterfaceRenderer { ) } + fn get_window_size(&self) -> ScreenSize { + ScreenSize { + width: self.dimensions[0] as f32, + height: self.dimensions[1] as f32, + } + } + pub fn render_rectangle( &self, render_target: &mut <InterfaceRenderer as Renderer>::Target, - position: Vector2<f32>, - size: Vector2<f32>, - clip_size: Vector4<f32>, - corner_radius: Vector4<f32>, + position: ScreenPosition, + size: ScreenSize, + screen_clip: ScreenClip, + corner_radius: CornerRadius, color: Color, ) { - let window_size = Vector2::new(self.dimensions[0] as usize, self.dimensions[1] as usize); - self.rectangle_renderer - .render(render_target, window_size, position, size, clip_size, corner_radius, color); + self.rectangle_renderer.render( + render_target, + self.get_window_size(), + position, + size, + screen_clip, + corner_radius, + color, + ); } pub fn render_checkbox( &self, render_target: &mut <InterfaceRenderer as Renderer>::Target, - position: Vector2<f32>, - size: Vector2<f32>, - clip_size: Vector4<f32>, + position: ScreenPosition, + size: ScreenSize, + screen_clip: ScreenClip, color: Color, checked: bool, ) { @@ -160,15 +174,15 @@ impl InterfaceRenderer { false => self.unchecked_box_texture.clone(), }; - self.render_sprite(render_target, texture, position, size, clip_size, color, true); + self.render_sprite(render_target, texture, position, size, screen_clip, color, true); } pub fn render_expand_arrow( &self, render_target: &mut <InterfaceRenderer as Renderer>::Target, - position: Vector2<f32>, - size: Vector2<f32>, - clip_size: Vector4<f32>, + position: ScreenPosition, + size: ScreenSize, + screen_clip: ScreenClip, color: Color, expanded: bool, ) { @@ -177,21 +191,27 @@ impl InterfaceRenderer { false => self.collapsed_arrow_texture.clone(), }; - self.render_sprite(render_target, texture, position, size, clip_size, color, true); + self.render_sprite(render_target, texture, position, size, screen_clip, color, true); } pub fn render_text( &self, render_target: &mut <InterfaceRenderer as Renderer>::Target, text: &str, - position: Vector2<f32>, - clip_size: Vector4<f32>, + position: ScreenPosition, + screen_clip: ScreenClip, color: Color, font_size: f32, ) -> f32 { - let window_size = Vector2::new(self.dimensions[0] as usize, self.dimensions[1] as usize); - self.text_renderer - .render(render_target, text, window_size, position, clip_size, color, font_size) + self.text_renderer.render( + render_target, + text, + self.get_window_size(), + position, + screen_clip, + color, + font_size, + ) } } @@ -212,17 +232,23 @@ impl SpriteRendererTrait for InterfaceRenderer { &self, render_target: &mut <Self as Renderer>::Target, texture: Arc<ImageView>, - position: Vector2<f32>, - size: Vector2<f32>, - clip_size: Vector4<f32>, + position: ScreenPosition, + size: ScreenSize, + screen_clip: ScreenClip, color: Color, smooth: bool, ) where Self: Renderer, { - let window_size = Vector2::new(self.dimensions[0] as usize, self.dimensions[1] as usize); - - self.sprite_renderer - .render(render_target, texture, window_size, position, size, clip_size, color, smooth); + self.sprite_renderer.render( + render_target, + texture, + self.get_window_size(), + position, + size, + screen_clip, + color, + smooth, + ); } } diff --git a/src/graphics/renderers/interface/rectangle/fragment_shader.glsl b/src/graphics/renderers/interface/rectangle/fragment_shader.glsl index aca8fdc9..08917fd0 100644 --- a/src/graphics/renderers/interface/rectangle/fragment_shader.glsl +++ b/src/graphics/renderers/interface/rectangle/fragment_shader.glsl @@ -7,7 +7,7 @@ layout(location = 0) out vec4 fragment_color; layout(push_constant) uniform Constants { vec2 screen_position; vec2 screen_size; - vec4 clip_size; + vec4 screen_clip; vec4 corner_radius; vec4 color; float aspect_ratio; @@ -45,7 +45,7 @@ void main() { discard; } - if (gl_FragCoord.x < constants.clip_size.x || gl_FragCoord.y < constants.clip_size.y || gl_FragCoord.x > constants.clip_size.z || gl_FragCoord.y > constants.clip_size.w) { + if (gl_FragCoord.x < constants.screen_clip.x || gl_FragCoord.y < constants.screen_clip.y || gl_FragCoord.x > constants.screen_clip.z || gl_FragCoord.y > constants.screen_clip.w) { discard; } diff --git a/src/graphics/renderers/interface/rectangle/mod.rs b/src/graphics/renderers/interface/rectangle/mod.rs index 8309e616..4d7cf9ca 100644 --- a/src/graphics/renderers/interface/rectangle/mod.rs +++ b/src/graphics/renderers/interface/rectangle/mod.rs @@ -3,7 +3,6 @@ fragment_shader!("src/graphics/renderers/interface/rectangle/fragment_shader.gls use std::sync::Arc; -use cgmath::{Vector2, Vector4}; use procedural::profile; use vulkano::device::{Device, DeviceOwned}; use vulkano::image::SampleCount; @@ -16,6 +15,7 @@ use self::vertex_shader::Constants; use super::InterfaceSubrenderer; use crate::graphics::renderers::pipeline::PipelineBuilder; use crate::graphics::*; +use crate::interface::{CornerRadius, ScreenClip, ScreenPosition, ScreenSize}; pub struct RectangleRenderer { vertex_shader: EntryPoint, @@ -69,11 +69,11 @@ impl RectangleRenderer { pub fn render( &self, render_target: &mut <InterfaceRenderer as Renderer>::Target, - window_size: Vector2<usize>, - screen_position: Vector2<f32>, - screen_size: Vector2<f32>, - clip_size: Vector4<f32>, - corner_radius: Vector4<f32>, + window_size: ScreenSize, + screen_position: ScreenPosition, + screen_size: ScreenSize, + screen_clip: ScreenClip, + corner_radius: CornerRadius, color: Color, ) { if render_target.bind_subrenderer(InterfaceSubrenderer::Rectangle) { @@ -82,25 +82,20 @@ impl RectangleRenderer { let layout = self.pipeline.layout().clone(); - let half_screen = Vector2::new(window_size.x as f32 / 2.0, window_size.y as f32 / 2.0); - let screen_position = Vector2::new(screen_position.x / half_screen.x, screen_position.y / half_screen.y); - let screen_size = Vector2::new(screen_size.x / half_screen.x, screen_size.y / half_screen.y); + let half_screen = window_size / 2.0; + let screen_position = screen_position / half_screen; + let screen_size = screen_size / half_screen; - let pixel_size = 1.0 / window_size.y as f32; - let corner_radius = Vector4::new( - corner_radius.x * pixel_size, - corner_radius.y * pixel_size, - corner_radius.z * pixel_size, - corner_radius.w * pixel_size, - ); + let pixel_size = 1.0 / window_size.height; + let corner_radius = corner_radius * pixel_size; let constants = Constants { screen_position: screen_position.into(), screen_size: screen_size.into(), - clip_size: clip_size.into(), + screen_clip: screen_clip.into(), corner_radius: corner_radius.into(), - color: [color.red_f32(), color.green_f32(), color.blue_f32(), color.alpha_f32()], - aspect_ratio: window_size.y as f32 / window_size.x as f32, + color: color.into(), + aspect_ratio: window_size.height / window_size.width, }; render_target diff --git a/src/graphics/renderers/interface/rectangle/vertex_shader.glsl b/src/graphics/renderers/interface/rectangle/vertex_shader.glsl index 3ab6e46c..f23b6eaa 100644 --- a/src/graphics/renderers/interface/rectangle/vertex_shader.glsl +++ b/src/graphics/renderers/interface/rectangle/vertex_shader.glsl @@ -5,7 +5,7 @@ layout(location = 0) out vec2 position_out; layout(push_constant) uniform Constants { vec2 screen_position; vec2 screen_size; - vec4 clip_size; + vec4 screen_clip; vec4 corner_radius; vec4 color; float aspect_ratio; diff --git a/src/graphics/renderers/interface/sprite/fragment_shader.glsl b/src/graphics/renderers/interface/sprite/fragment_shader.glsl index 5096de73..59b61bc3 100644 --- a/src/graphics/renderers/interface/sprite/fragment_shader.glsl +++ b/src/graphics/renderers/interface/sprite/fragment_shader.glsl @@ -9,13 +9,13 @@ layout (set = 0, binding = 0) uniform sampler2D sprite_texture; layout(push_constant) uniform Constants { vec2 screen_position; vec2 screen_size; - vec4 clip_size; + vec4 screen_clip; vec4 color; } constants; void main() { - if (gl_FragCoord.x < constants.clip_size.x || gl_FragCoord.y < constants.clip_size.y || gl_FragCoord.x > constants.clip_size.z || gl_FragCoord.y > constants.clip_size.w) { + if (gl_FragCoord.x < constants.screen_clip.x || gl_FragCoord.y < constants.screen_clip.y || gl_FragCoord.x > constants.screen_clip.z || gl_FragCoord.y > constants.screen_clip.w) { discard; } diff --git a/src/graphics/renderers/interface/sprite/mod.rs b/src/graphics/renderers/interface/sprite/mod.rs index 117ada4d..f9bec5e1 100644 --- a/src/graphics/renderers/interface/sprite/mod.rs +++ b/src/graphics/renderers/interface/sprite/mod.rs @@ -3,7 +3,6 @@ fragment_shader!("src/graphics/renderers/interface/sprite/fragment_shader.glsl") use std::sync::Arc; -use cgmath::{Vector2, Vector4}; use procedural::profile; use vulkano::descriptor_set::WriteDescriptorSet; use vulkano::device::{Device, DeviceOwned}; @@ -19,6 +18,7 @@ use super::InterfaceSubrenderer; use crate::graphics::renderers::pipeline::PipelineBuilder; use crate::graphics::renderers::sampler::{create_new_sampler, SamplerType}; use crate::graphics::*; +use crate::interface::{ScreenClip, ScreenPosition, ScreenSize}; pub struct SpriteRenderer { memory_allocator: Arc<MemoryAllocator>, @@ -81,10 +81,10 @@ impl SpriteRenderer { &self, render_target: &mut <InterfaceRenderer as Renderer>::Target, texture: Arc<ImageView>, - window_size: Vector2<usize>, - screen_position: Vector2<f32>, - screen_size: Vector2<f32>, - clip_size: Vector4<f32>, + window_size: ScreenSize, + screen_position: ScreenPosition, + screen_size: ScreenSize, + screen_clip: ScreenClip, color: Color, smooth: bool, ) { @@ -92,9 +92,9 @@ impl SpriteRenderer { self.bind_pipeline(render_target); } - let half_screen = Vector2::new(window_size.x as f32 / 2.0, window_size.y as f32 / 2.0); - let screen_position = Vector2::new(screen_position.x / half_screen.x, screen_position.y / half_screen.y); - let screen_size = Vector2::new(screen_size.x / half_screen.x, screen_size.y / half_screen.y); + let half_screen = window_size / 2.0; + let screen_position = screen_position / half_screen; + let screen_size = screen_size / half_screen; let sampler = match smooth { true => self.linear_sampler.clone(), @@ -108,8 +108,8 @@ impl SpriteRenderer { let constants = Constants { screen_position: screen_position.into(), screen_size: screen_size.into(), - clip_size: clip_size.into(), - color: [color.red_f32(), color.green_f32(), color.blue_f32(), color.alpha_f32()], + screen_clip: screen_clip.into(), + color: color.into(), }; render_target diff --git a/src/graphics/renderers/interface/sprite/vertex_shader.glsl b/src/graphics/renderers/interface/sprite/vertex_shader.glsl index 0ece11b1..f692b825 100644 --- a/src/graphics/renderers/interface/sprite/vertex_shader.glsl +++ b/src/graphics/renderers/interface/sprite/vertex_shader.glsl @@ -5,7 +5,7 @@ layout(location = 0) out vec2 texture_coordinates; layout(push_constant) uniform Constants { vec2 screen_position; vec2 screen_size; - vec4 clip_size; + vec4 screen_clip; vec4 color; } constants; diff --git a/src/graphics/renderers/interface/text/fragment_shader.glsl b/src/graphics/renderers/interface/text/fragment_shader.glsl index 61858c84..c5722489 100644 --- a/src/graphics/renderers/interface/text/fragment_shader.glsl +++ b/src/graphics/renderers/interface/text/fragment_shader.glsl @@ -9,7 +9,7 @@ layout (set = 0, binding = 0) uniform sampler2D sprite_texture; layout(push_constant) uniform Constants { vec2 screen_position; vec2 screen_size; - vec4 clip_size; + vec4 screen_clip; vec2 texture_position; vec2 texture_size; vec4 color; @@ -17,7 +17,7 @@ layout(push_constant) uniform Constants { void main() { - if (gl_FragCoord.x < constants.clip_size.x || gl_FragCoord.y < constants.clip_size.y || gl_FragCoord.x > constants.clip_size.z || gl_FragCoord.y > constants.clip_size.w) { + if (gl_FragCoord.x < constants.screen_clip.x || gl_FragCoord.y < constants.screen_clip.y || gl_FragCoord.x > constants.screen_clip.z || gl_FragCoord.y > constants.screen_clip.w) { discard; } diff --git a/src/graphics/renderers/interface/text/mod.rs b/src/graphics/renderers/interface/text/mod.rs index 359bd973..b08fdf89 100644 --- a/src/graphics/renderers/interface/text/mod.rs +++ b/src/graphics/renderers/interface/text/mod.rs @@ -5,7 +5,6 @@ use std::cell::RefCell; use std::rc::Rc; use std::sync::Arc; -use cgmath::{Vector2, Vector4}; use procedural::profile; use vulkano::descriptor_set::WriteDescriptorSet; use vulkano::device::{Device, DeviceOwned}; @@ -21,6 +20,7 @@ use super::InterfaceSubrenderer; use crate::graphics::renderers::pipeline::PipelineBuilder; use crate::graphics::renderers::sampler::{create_new_sampler, SamplerType}; use crate::graphics::*; +use crate::interface::{ScreenClip, ScreenPosition, ScreenSize}; use crate::loaders::FontLoader; pub struct TextRenderer { @@ -83,9 +83,9 @@ impl TextRenderer { &self, render_target: &mut <InterfaceRenderer as Renderer>::Target, text: &str, - window_size: Vector2<usize>, - screen_position: Vector2<f32>, - clip_size: Vector4<f32>, + window_size: ScreenSize, + screen_position: ScreenPosition, + screen_clip: ScreenClip, color: Color, font_size: f32, ) -> f32 { @@ -95,8 +95,8 @@ impl TextRenderer { let mut font_loader = self.font_loader.borrow_mut(); let texture = font_loader.get_font_atlas(); - let (character_layout, heigth) = font_loader.get(text, color, font_size, clip_size.z - screen_position.x); - let half_screen = Vector2::new(window_size.x as f32 / 2.0, window_size.y as f32 / 2.0); + let (character_layout, heigth) = font_loader.get(text, color, font_size, screen_clip.right - screen_position.left); + let half_screen = window_size / 2.0; let (layout, set, set_id) = allocate_descriptor_set(&self.pipeline, &self.memory_allocator, 0, [ WriteDescriptorSet::image_view_sampler(0, texture, self.nearest_sampler.clone()), @@ -109,15 +109,15 @@ impl TextRenderer { .unwrap(); character_layout.iter().for_each(|(texture_coordinates, position, color)| { - let screen_position = Vector2::new( - (screen_position.x + position.min.x as f32) / half_screen.x, - (screen_position.y + position.min.y as f32) / half_screen.y, - ); + let screen_position = ScreenPosition { + left: screen_position.left + position.min.x as f32, + top: screen_position.top + position.min.y as f32, + } / half_screen; - let screen_size = Vector2::new( - position.width() as f32 / half_screen.x, - position.height() as f32 / half_screen.y, - ); + let screen_size = ScreenSize { + width: position.width() as f32, + height: position.height() as f32, + } / half_screen; let texture_position = texture_coordinates.min; let texture_size = texture_coordinates.max - texture_coordinates.min; // TODO: use absolute instead @@ -125,10 +125,10 @@ impl TextRenderer { let constants = Constants { screen_position: screen_position.into(), screen_size: screen_size.into(), - clip_size: clip_size.into(), + screen_clip: screen_clip.into(), texture_position: [texture_position.x, texture_position.y], texture_size: [texture_size.x, texture_size.y], - color: [color.red_f32(), color.green_f32(), color.blue_f32(), color.alpha_f32()], + color: (*color).into(), }; render_target diff --git a/src/graphics/renderers/interface/text/vertex_shader.glsl b/src/graphics/renderers/interface/text/vertex_shader.glsl index 9aea46ed..1e8a4fd0 100644 --- a/src/graphics/renderers/interface/text/vertex_shader.glsl +++ b/src/graphics/renderers/interface/text/vertex_shader.glsl @@ -5,7 +5,7 @@ layout(location = 0) out vec2 texture_coordinates; layout(push_constant) uniform Constants { vec2 screen_position; vec2 screen_size; - vec4 clip_size; + vec4 screen_clip; vec2 texture_position; vec2 texture_size; vec4 color; diff --git a/src/graphics/renderers/mod.rs b/src/graphics/renderers/mod.rs index 4e79d99d..721bc7ec 100644 --- a/src/graphics/renderers/mod.rs +++ b/src/graphics/renderers/mod.rs @@ -42,7 +42,7 @@ mod swapchain; use std::marker::{ConstParamTy, PhantomData}; use std::sync::Arc; -use cgmath::{Matrix4, Vector2, Vector3, Vector4}; +use cgmath::{Matrix4, Vector2, Vector3}; use option_ext::OptionExt; use procedural::profile; use vulkano::buffer::{Buffer, BufferUsage, Subbuffer}; @@ -76,6 +76,7 @@ use super::{Color, MemoryAllocator, ModelVertex}; #[cfg(feature = "debug")] use crate::debug::*; use crate::graphics::Camera; +use crate::interface::{ScreenClip, ScreenPosition, ScreenSize}; use crate::network::EntityId; #[cfg(feature = "debug")] use crate::world::MarkerIdentifier; @@ -177,9 +178,9 @@ pub trait SpriteRenderer { &self, render_target: &mut <Self as Renderer>::Target, texture: Arc<ImageView>, - position: Vector2<f32>, - size: Vector2<f32>, - clip_size: Vector4<f32>, + position: ScreenPosition, + size: ScreenSize, + screen_clip: ScreenClip, color: Color, smooth: bool, ) where diff --git a/src/graphics/renderers/picker/entity/mod.rs b/src/graphics/renderers/picker/entity/mod.rs index 3244b9f1..e7a0dfa5 100644 --- a/src/graphics/renderers/picker/entity/mod.rs +++ b/src/graphics/renderers/picker/entity/mod.rs @@ -124,8 +124,8 @@ impl EntityRenderer { let constants = Constants { world: world_matrix.into(), - texture_position: [texture_position.x, texture_position.y], - texture_size: [texture_size.x, texture_size.y], + texture_position: texture_position.into(), + texture_size: texture_size.into(), identifier: picker_target.into(), mirror: mirror as u32, }; diff --git a/src/graphics/renderers/picker/marker/mod.rs b/src/graphics/renderers/picker/marker/mod.rs index d972e357..8f4d85ec 100644 --- a/src/graphics/renderers/picker/marker/mod.rs +++ b/src/graphics/renderers/picker/marker/mod.rs @@ -3,7 +3,6 @@ fragment_shader!("src/graphics/renderers/picker/marker/fragment_shader.glsl"); use std::sync::Arc; -use cgmath::Vector2; use procedural::profile; use vulkano::device::{Device, DeviceOwned}; use vulkano::pipeline::graphics::viewport::Viewport; @@ -15,6 +14,7 @@ use self::vertex_shader::Constants; use super::PickerSubrenderer; use crate::graphics::renderers::pipeline::PipelineBuilder; use crate::graphics::*; +use crate::interface::{ScreenPosition, ScreenSize}; use crate::world::MarkerIdentifier; pub struct MarkerRenderer { @@ -67,8 +67,8 @@ impl MarkerRenderer { pub fn render( &self, render_target: &mut <PickerRenderer as Renderer>::Target, - screen_position: Vector2<f32>, - screen_size: Vector2<f32>, + screen_position: ScreenPosition, + screen_size: ScreenSize, marker_identifier: MarkerIdentifier, ) { if render_target.bind_subrenderer(PickerSubrenderer::Marker) { diff --git a/src/graphics/renderers/shadow/entity/mod.rs b/src/graphics/renderers/shadow/entity/mod.rs index 58838723..bae7b3aa 100644 --- a/src/graphics/renderers/shadow/entity/mod.rs +++ b/src/graphics/renderers/shadow/entity/mod.rs @@ -118,8 +118,8 @@ impl EntityRenderer { let constants = Constants { world: world_matrix.into(), - texture_position: [texture_position.x, texture_position.y], - texture_size: [texture_size.x, texture_size.y], + texture_position: texture_position.into(), + texture_size: texture_size.into(), depth_offset, curvature, mirror: mirror as u32, diff --git a/src/graphics/renderers/swapchain.rs b/src/graphics/renderers/swapchain.rs index a798499e..3519fa86 100644 --- a/src/graphics/renderers/swapchain.rs +++ b/src/graphics/renderers/swapchain.rs @@ -14,6 +14,7 @@ use winit::window::Window; #[cfg(feature = "debug")] use crate::debug::*; +use crate::interface::ScreenSize; #[derive(Debug, Clone, Copy)] pub struct PresentModeInfo { @@ -206,7 +207,10 @@ impl SwapchainHolder { self.window_size } - pub fn window_size_f32(&self) -> Vector2<f32> { - self.window_size.map(|component| component as f32).into() + pub fn window_screen_size(&self) -> ScreenSize { + ScreenSize { + width: self.window_size[0] as f32, + height: self.window_size[1] as f32, + } } } diff --git a/src/input/mod.rs b/src/input/mod.rs index cf0e9699..12335660 100644 --- a/src/input/mod.rs +++ b/src/input/mod.rs @@ -16,7 +16,7 @@ pub use self::mode::{Grabbed, MouseInputMode}; #[cfg(feature = "debug")] use crate::graphics::RenderSettings; use crate::graphics::{PickerRenderTarget, PickerTarget}; -use crate::interface::{ClickAction, ElementCell, Focus, Interface, MouseCursorState, WeakElementCell}; +use crate::interface::{ClickAction, ElementCell, Focus, Interface, MouseCursorState, ScreenPosition, ScreenSize, WeakElementCell}; use crate::network::ClientTick; const MOUSE_SCOLL_MULTIPLIER: f32 = 30.0; @@ -102,9 +102,9 @@ impl FocusState { } pub struct InputSystem { - previous_mouse_position: Vector2<f32>, - new_mouse_position: Vector2<f32>, - mouse_delta: Vector2<f32>, + previous_mouse_position: ScreenPosition, + new_mouse_position: ScreenPosition, + mouse_delta: ScreenSize, previous_scroll_position: f32, new_scroll_position: f32, scroll_delta: f32, @@ -117,9 +117,9 @@ pub struct InputSystem { impl InputSystem { pub fn new() -> Self { - let previous_mouse_position = Vector2::new(0.0, 0.0); - let new_mouse_position = Vector2::new(0.0, 0.0); - let mouse_delta = Vector2::new(0.0, 0.0); + let previous_mouse_position = ScreenPosition::default(); + let new_mouse_position = ScreenPosition::default(); + let mouse_delta = ScreenSize::default(); let previous_scroll_position = 0.0; let new_scroll_position = 0.0; @@ -155,7 +155,10 @@ impl InputSystem { } pub fn update_mouse_position(&mut self, position: PhysicalPosition<f64>) { - self.new_mouse_position = Vector2::new(position.x as f32, position.y as f32); + self.new_mouse_position = ScreenPosition { + left: position.x as f32, + top: position.y as f32, + }; } pub fn update_mouse_buttons(&mut self, button: MouseButton, state: ElementState) { @@ -361,7 +364,7 @@ impl InputSystem { if self.right_mouse_button.down() && !self.right_mouse_button.pressed() && self.mouse_input_mode.is_none() - && self.mouse_delta.x != 0.0 + && self.mouse_delta.width != 0.0 && !lock_actions { self.mouse_input_mode = MouseInputMode::RotateCamera; @@ -369,24 +372,24 @@ impl InputSystem { match &self.mouse_input_mode { MouseInputMode::DragElement((element, window_index)) => { - if self.mouse_delta != Vector2::new(0.0, 0.0) { - interface.drag_element(element, *window_index, self.mouse_delta); + if self.mouse_delta != ScreenSize::default() { + interface.drag_element(element, *window_index, ScreenPosition::from_size(self.mouse_delta)); } interface.set_mouse_cursor_state(MouseCursorState::Grab, client_tick); } MouseInputMode::MoveInterface(identifier) => { - if self.mouse_delta != Vector2::new(0.0, 0.0) { - interface.move_window(*identifier, self.mouse_delta); + if self.mouse_delta != ScreenSize::default() { + interface.move_window(*identifier, ScreenPosition::from_size(self.mouse_delta)); } interface.set_mouse_cursor_state(MouseCursorState::Grab, client_tick); } MouseInputMode::ResizeInterface(identifier) => { - if self.mouse_delta != Vector2::new(0.0, 0.0) { + if self.mouse_delta != ScreenSize::default() { interface.resize_window(*identifier, self.mouse_delta); } } MouseInputMode::RotateCamera => { - events.push(UserEvent::CameraRotate(self.mouse_delta.x)); + events.push(UserEvent::CameraRotate(self.mouse_delta.width)); interface.set_mouse_cursor_state(MouseCursorState::RotateCamera, client_tick); } MouseInputMode::ClickInterface => interface.set_mouse_cursor_state(MouseCursorState::Click, client_tick), @@ -573,7 +576,10 @@ impl InputSystem { && self.mouse_input_mode.is_none() && render_settings.use_debug_camera { - events.push(UserEvent::CameraLookAround(-self.mouse_delta)); + events.push(UserEvent::CameraLookAround(-Vector2::new( + self.mouse_delta.width, + self.mouse_delta.height, + ))); } #[cfg(feature = "debug")] @@ -607,7 +613,7 @@ impl InputSystem { fence.wait(None).unwrap(); } - let sample_index = self.new_mouse_position.x as usize + self.new_mouse_position.y as usize * window_size.x; + let sample_index = self.new_mouse_position.left as usize + self.new_mouse_position.top as usize * window_size.x; let lock = picker_target.buffer.read().unwrap(); if sample_index < lock.len() { @@ -680,7 +686,7 @@ impl InputSystem { (events, hovered_element, focused_element, mouse_target) } - pub fn get_mouse_position(&self) -> Vector2<f32> { + pub fn get_mouse_position(&self) -> ScreenPosition { self.new_mouse_position } diff --git a/src/interface/cursor/mod.rs b/src/interface/cursor/mod.rs index 77011746..46f223e7 100644 --- a/src/interface/cursor/mod.rs +++ b/src/interface/cursor/mod.rs @@ -1,8 +1,6 @@ use std::sync::Arc; -use cgmath::{Array, Vector2, Vector4, Zero}; - -use super::InterfaceSettings; +use super::{InterfaceSettings, ScreenClip, ScreenPosition, ScreenSize}; use crate::graphics::{Color, DeferredRenderer, Renderer, SpriteRenderer}; use crate::input::Grabbed; use crate::loaders::{ActionLoader, Actions, AnimationState, GameFileLoader, Sprite, SpriteLoader}; @@ -70,7 +68,7 @@ impl MouseCursor { &self, render_target: &mut <DeferredRenderer as Renderer>::Target, renderer: &DeferredRenderer, - mouse_position: Vector2<f32>, + mouse_position: ScreenPosition, grabbed: Option<Grabbed>, color: Color, interface_settings: &InterfaceSettings, @@ -80,9 +78,9 @@ impl MouseCursor { Grabbed::Texture(texture) => renderer.render_sprite( render_target, texture, - mouse_position - Vector2::from_value(15.0 * *interface_settings.scaling), - Vector2::from_value(30.0 * *interface_settings.scaling), - Vector4::zero(), + mouse_position - ScreenSize::uniform(15.0 * *interface_settings.scaling), + ScreenSize::uniform(30.0 * *interface_settings.scaling), + ScreenClip::default(), Color::monochrome(255), false, ), diff --git a/src/interface/elements/base.rs b/src/interface/elements/base.rs index 6a1610c8..7cd34598 100644 --- a/src/interface/elements/base.rs +++ b/src/interface/elements/base.rs @@ -2,7 +2,7 @@ use std::cell::{Cell, RefCell}; use std::rc::{Rc, Weak}; use std::sync::Arc; -use cgmath::{Vector2, Vector4, Zero}; +use cgmath::Vector2; use vulkano::image::view::ImageView; use crate::graphics::{Color, InterfaceRenderer, Renderer, SpriteRenderer}; @@ -30,13 +30,13 @@ pub struct ElementRenderer<'a> { pub render_target: &'a mut <InterfaceRenderer as Renderer>::Target, pub renderer: &'a InterfaceRenderer, pub interface_settings: &'a InterfaceSettings, - pub position: Position, - pub size: Size, - pub clip_size: ClipSize, + pub position: ScreenPosition, + pub size: ScreenSize, + pub screen_clip: ScreenClip, } impl<'a> ElementRenderer<'a> { - pub fn get_position(&self) -> Position { + pub fn get_position(&self) -> ScreenPosition { self.position } @@ -46,71 +46,71 @@ impl<'a> ElementRenderer<'a> { } pub fn set_scroll(&mut self, scroll: f32) { - self.position.y -= scroll; + self.position.top -= scroll; } - pub fn render_background(&mut self, border_radius: Vector4<f32>, color: Color) { + pub fn render_background(&mut self, corner_radius: CornerRadius, color: Color) { self.renderer.render_rectangle( self.render_target, self.position, self.size, - self.clip_size, - border_radius * *self.interface_settings.scaling, + self.screen_clip, + corner_radius * *self.interface_settings.scaling, color, ); } - pub fn render_rectangle(&mut self, position: Position, size: Size, border_radius: Vector4<f32>, color: Color) { + pub fn render_rectangle(&mut self, position: ScreenPosition, size: ScreenSize, corner_radius: CornerRadius, color: Color) { self.renderer.render_rectangle( self.render_target, self.position + position, size, - self.clip_size, - border_radius * *self.interface_settings.scaling, + self.screen_clip, + corner_radius * *self.interface_settings.scaling, color, ); } - pub fn render_text(&mut self, text: &str, offset: Position, foreground_color: Color, font_size: f32) -> f32 { + pub fn render_text(&mut self, text: &str, offset: ScreenPosition, foreground_color: Color, font_size: f32) -> f32 { self.renderer.render_text( self.render_target, text, self.position + offset * *self.interface_settings.scaling, - self.clip_size, + self.screen_clip, foreground_color, font_size * *self.interface_settings.scaling, ) } - pub fn render_checkbox(&mut self, offset: Position, size: Size, color: Color, checked: bool) { + pub fn render_checkbox(&mut self, offset: ScreenPosition, size: ScreenSize, color: Color, checked: bool) { self.renderer.render_checkbox( self.render_target, self.position + offset * *self.interface_settings.scaling, size * *self.interface_settings.scaling, - self.clip_size, + self.screen_clip, color, checked, ); } - pub fn render_expand_arrow(&mut self, offset: Position, size: Size, color: Color, expanded: bool) { + pub fn render_expand_arrow(&mut self, offset: ScreenPosition, size: ScreenSize, color: Color, expanded: bool) { self.renderer.render_expand_arrow( self.render_target, self.position + offset * *self.interface_settings.scaling, size * *self.interface_settings.scaling, - self.clip_size, + self.screen_clip, color, expanded, ); } - pub fn render_sprite(&mut self, texture: Arc<ImageView>, offset: Position, size: Size, color: Color) { + pub fn render_sprite(&mut self, texture: Arc<ImageView>, offset: ScreenPosition, size: ScreenSize, color: Color) { self.renderer.render_sprite( self.render_target, texture, self.position + offset * *self.interface_settings.scaling, size * *self.interface_settings.scaling, - self.clip_size, + self.screen_clip, color, false, ); @@ -134,7 +134,7 @@ impl<'a> ElementRenderer<'a> { interface_settings, theme, self.position, - self.clip_size, + self.screen_clip, hovered_element, focused_element, mouse_mode, @@ -143,24 +143,13 @@ impl<'a> ElementRenderer<'a> { } } +#[derive(Default)] pub struct ElementState { - pub cached_size: Size, - pub cached_position: Position, + pub cached_size: ScreenSize, + pub cached_position: ScreenPosition, pub self_element: Option<WeakElementCell>, pub parent_element: Option<WeakElementCell>, - pub mouse_position: Cell<Position>, -} - -impl Default for ElementState { - fn default() -> Self { - Self { - cached_size: Size::zero(), - cached_position: Position::zero(), - self_element: None, - parent_element: None, - mouse_position: Cell::new(Position::zero()), - } - } + pub mouse_position: Cell<ScreenPosition>, } impl ElementState { @@ -175,13 +164,13 @@ impl ElementState { self.cached_position = position; } - pub fn hovered_element(&self, mouse_position: Position) -> HoverInformation { - let absolute_position = mouse_position - self.cached_position; + pub fn hovered_element(&self, mouse_position: ScreenPosition) -> HoverInformation { + let absolute_position = ScreenPosition::from_size(mouse_position - self.cached_position); - if absolute_position.x >= 0.0 - && absolute_position.y >= 0.0 - && absolute_position.x <= self.cached_size.x - && absolute_position.y <= self.cached_size.y + if absolute_position.left >= 0.0 + && absolute_position.top >= 0.0 + && absolute_position.left <= self.cached_size.width + && absolute_position.top <= self.cached_size.height { self.mouse_position.replace(absolute_position); return HoverInformation::Hovered; @@ -195,18 +184,18 @@ impl ElementState { render_target: &'a mut <InterfaceRenderer as Renderer>::Target, renderer: &'a InterfaceRenderer, interface_settings: &'a InterfaceSettings, - parent_position: Position, - clip_size: ClipSize, + parent_position: ScreenPosition, + screen_clip: ScreenClip, ) -> ElementRenderer<'a> { let position = parent_position + self.cached_position; let size = self.cached_size; - let clip_size = Vector4::new( - clip_size.x.max(position.x), - clip_size.y.max(position.y), - clip_size.z.min(position.x + self.cached_size.x), - clip_size.w.min(position.y + self.cached_size.y), - ); + let screen_clip = ScreenClip { + left: screen_clip.left.max(position.left), + top: screen_clip.top.max(position.top), + right: screen_clip.right.min(position.left + self.cached_size.width), + bottom: screen_clip.bottom.min(position.top + self.cached_size.height), + }; ElementRenderer { render_target, @@ -214,7 +203,7 @@ impl ElementState { interface_settings, position, size, - clip_size, + screen_clip, } } } @@ -301,7 +290,7 @@ pub trait Element { matches!(element, Some(reference) if std::ptr::eq(reference as *const _ as *const (), self as *const _ as *const ())) } - fn hovered_element(&self, _mouse_position: Vector2<f32>, _mouse_mode: &MouseInputMode) -> HoverInformation { + fn hovered_element(&self, _mouse_position: ScreenPosition, _mouse_mode: &MouseInputMode) -> HoverInformation { HoverInformation::Missed } @@ -313,7 +302,7 @@ pub trait Element { Vec::new() } - fn drag(&mut self, _mouse_delta: Position) -> Option<ChangeEvent> { + fn drag(&mut self, _mouse_delta: ScreenPosition) -> Option<ChangeEvent> { None } @@ -346,8 +335,8 @@ pub trait Element { state_provider: &StateProvider, interface_settings: &InterfaceSettings, theme: &InterfaceTheme, - parent_position: Position, - clip_size: ClipSize, + parent_position: ScreenPosition, + screen_clip: ScreenClip, hovered_element: Option<&dyn Element>, focused_element: Option<&dyn Element>, mouse_mode: &MouseInputMode, diff --git a/src/interface/elements/buttons/close.rs b/src/interface/elements/buttons/close.rs index 7f2180e7..745091b5 100644 --- a/src/interface/elements/buttons/close.rs +++ b/src/interface/elements/buttons/close.rs @@ -26,7 +26,7 @@ impl Element for CloseButton { false } - fn hovered_element(&self, mouse_position: Position, mouse_mode: &MouseInputMode) -> HoverInformation { + fn hovered_element(&self, mouse_position: ScreenPosition, mouse_mode: &MouseInputMode) -> HoverInformation { match mouse_mode { MouseInputMode::None => self.state.hovered_element(mouse_position), _ => HoverInformation::Missed, @@ -44,8 +44,8 @@ impl Element for CloseButton { _state_provider: &StateProvider, interface_settings: &InterfaceSettings, theme: &InterfaceTheme, - parent_position: Position, - clip_size: ClipSize, + parent_position: ScreenPosition, + screen_clip: ScreenClip, hovered_element: Option<&dyn Element>, focused_element: Option<&dyn Element>, _mouse_mode: &MouseInputMode, @@ -53,18 +53,23 @@ impl Element for CloseButton { ) { let mut renderer = self .state - .element_renderer(render_target, renderer, interface_settings, parent_position, clip_size); + .element_renderer(render_target, renderer, interface_settings, parent_position, screen_clip); let background_color = match self.is_element_self(hovered_element) || self.is_element_self(focused_element) { true => *theme.close_button.hovered_background_color, false => *theme.close_button.background_color, }; - renderer.render_background(*theme.close_button.border_radius, background_color); + renderer.render_background((*theme.close_button.corner_radius).into(), background_color); + + let text_position = ScreenPosition { + left: theme.close_button.text_offset.x, + top: theme.close_button.text_offset.y, + }; renderer.render_text( "X", - *theme.close_button.text_offset, + text_position, *theme.close_button.foreground_color, *theme.close_button.font_size, ); diff --git a/src/interface/elements/buttons/default.rs b/src/interface/elements/buttons/default.rs index 3272ed17..dae6ec06 100644 --- a/src/interface/elements/buttons/default.rs +++ b/src/interface/elements/buttons/default.rs @@ -101,7 +101,7 @@ impl<T: AsRef<str> + 'static, E: ElementEvent> Element for Button<T, E> { self.state.resolve(placement_resolver, &size_constraint); } - fn hovered_element(&self, mouse_position: Position, mouse_mode: &MouseInputMode) -> HoverInformation { + fn hovered_element(&self, mouse_position: ScreenPosition, mouse_mode: &MouseInputMode) -> HoverInformation { match mouse_mode { MouseInputMode::None => self.state.hovered_element(mouse_position), _ => HoverInformation::Missed, @@ -123,8 +123,8 @@ impl<T: AsRef<str> + 'static, E: ElementEvent> Element for Button<T, E> { _state_provider: &StateProvider, interface_settings: &InterfaceSettings, theme: &InterfaceTheme, - parent_position: Position, - clip_size: ClipSize, + parent_position: ScreenPosition, + screen_clip: ScreenClip, hovered_element: Option<&dyn Element>, focused_element: Option<&dyn Element>, _mouse_mode: &MouseInputMode, @@ -132,7 +132,7 @@ impl<T: AsRef<str> + 'static, E: ElementEvent> Element for Button<T, E> { ) { let mut renderer = self .state - .element_renderer(render_target, renderer, interface_settings, parent_position, clip_size); + .element_renderer(render_target, renderer, interface_settings, parent_position, screen_clip); let disabled = self.is_disabled(); let background_color = match self.is_element_self(hovered_element) || self.is_element_self(focused_element) { @@ -142,7 +142,7 @@ impl<T: AsRef<str> + 'static, E: ElementEvent> Element for Button<T, E> { false => *theme.button.background_color, }; - renderer.render_background(*theme.button.border_radius, background_color); + renderer.render_background((*theme.button.corner_radius).into(), background_color); if let Some(text) = &self.text { let foreground_color = if disabled { @@ -154,12 +154,12 @@ impl<T: AsRef<str> + 'static, E: ElementEvent> Element for Button<T, E> { .unwrap_or(*theme.button.foreground_color) }; - renderer.render_text( - text.as_ref(), - *theme.button.text_offset, - foreground_color, - *theme.button.font_size, - ); + let text_position = ScreenPosition { + left: theme.button.text_offset.x, + top: theme.button.text_offset.y, + }; + + renderer.render_text(text.as_ref(), text_position, foreground_color, *theme.button.font_size); } } } diff --git a/src/interface/elements/buttons/drag.rs b/src/interface/elements/buttons/drag.rs index 6ac02aba..36616292 100644 --- a/src/interface/elements/buttons/drag.rs +++ b/src/interface/elements/buttons/drag.rs @@ -31,7 +31,7 @@ impl Element for DragButton { false } - fn hovered_element(&self, mouse_position: Position, mouse_mode: &MouseInputMode) -> HoverInformation { + fn hovered_element(&self, mouse_position: ScreenPosition, mouse_mode: &MouseInputMode) -> HoverInformation { match mouse_mode { MouseInputMode::None => self.state.hovered_element(mouse_position), MouseInputMode::DragElement((element, _)) if self.is_element_self(Some(&*element.borrow())) => HoverInformation::Hovered, @@ -50,8 +50,8 @@ impl Element for DragButton { _state_provider: &StateProvider, interface_settings: &InterfaceSettings, theme: &InterfaceTheme, - parent_position: Position, - clip_size: ClipSize, + parent_position: ScreenPosition, + screen_clip: ScreenClip, hovered_element: Option<&dyn Element>, _focused_element: Option<&dyn Element>, _mouse_mode: &MouseInputMode, @@ -59,15 +59,20 @@ impl Element for DragButton { ) { let mut renderer = self .state - .element_renderer(render_target, renderer, interface_settings, parent_position, clip_size); + .element_renderer(render_target, renderer, interface_settings, parent_position, screen_clip); if self.is_element_self(hovered_element) { - renderer.render_background(*theme.window.title_border_radius, *theme.window.title_background_color); + renderer.render_background((*theme.window.title_corner_radius).into(), *theme.window.title_background_color); } + let text_position = ScreenPosition { + left: theme.window.text_offset.x, + top: theme.window.text_offset.y, + }; + renderer.render_text( &self.window_title, - *theme.window.text_offset, + text_position, *theme.window.foreground_color, *theme.window.font_size, ); diff --git a/src/interface/elements/buttons/state.rs b/src/interface/elements/buttons/state.rs index 3509f9e7..d88e0a74 100644 --- a/src/interface/elements/buttons/state.rs +++ b/src/interface/elements/buttons/state.rs @@ -91,7 +91,7 @@ where self.state.resolve(placement_resolver, &size_constraint); } - fn hovered_element(&self, mouse_position: Position, mouse_mode: &MouseInputMode) -> HoverInformation { + fn hovered_element(&self, mouse_position: ScreenPosition, mouse_mode: &MouseInputMode) -> HoverInformation { match mouse_mode { MouseInputMode::None => self.state.hovered_element(mouse_position), _ => HoverInformation::Missed, @@ -109,8 +109,8 @@ where state_provider: &StateProvider, interface_settings: &InterfaceSettings, theme: &InterfaceTheme, - parent_position: Position, - clip_size: ClipSize, + parent_position: ScreenPosition, + screen_clip: ScreenClip, hovered_element: Option<&dyn Element>, focused_element: Option<&dyn Element>, _mouse_mode: &MouseInputMode, @@ -118,7 +118,7 @@ where ) { let mut renderer = self .state - .element_renderer(render_target, renderer, interface_settings, parent_position, clip_size); + .element_renderer(render_target, renderer, interface_settings, parent_position, screen_clip); let highlighted = self.is_element_self(hovered_element) || self.is_element_self(focused_element); @@ -128,7 +128,7 @@ where false => *theme.button.background_color, }; - renderer.render_background(*theme.button.border_radius, background_color); + renderer.render_background((*theme.button.corner_radius).into(), background_color); } let foreground_color = match self.transparent_background && highlighted { @@ -136,20 +136,30 @@ where false => *theme.button.foreground_color, }; + let box_position = ScreenPosition { + left: theme.button.icon_offset.x, + top: theme.button.icon_offset.y, + }; + + let box_size = ScreenSize { + width: theme.button.icon_size.x, + height: theme.button.icon_size.y, + }; + renderer.render_checkbox( - *theme.button.icon_offset, - *theme.button.icon_size, + box_position, + box_size, foreground_color, (self.selector.as_ref().unwrap())(state_provider), ); if let Some(text) = &self.text { - renderer.render_text( - text.as_ref(), - *theme.button.icon_text_offset, - foreground_color, - *theme.button.font_size, - ); + let text_position = ScreenPosition { + left: theme.button.icon_text_offset.x, + top: theme.button.icon_text_offset.y, + }; + + renderer.render_text(text.as_ref(), text_position, foreground_color, *theme.button.font_size); } } } diff --git a/src/interface/elements/containers/character.rs b/src/interface/elements/containers/character.rs index c181e739..21e8aae7 100644 --- a/src/interface/elements/containers/character.rs +++ b/src/interface/elements/containers/character.rs @@ -1,7 +1,6 @@ use std::cell::RefCell; use std::rc::Weak; -use cgmath::Array; use procedural::*; use crate::graphics::{Color, InterfaceRenderer, Renderer}; @@ -112,7 +111,7 @@ impl Element for CharacterPreview { interface_settings, theme, size_constraint, - Vector2::from_value(4.0), + ScreenSize::uniform(4.0), ); } @@ -154,7 +153,7 @@ impl Element for CharacterPreview { vec![ClickAction::Event(event)] } - fn hovered_element(&self, mouse_position: Position, mouse_mode: &MouseInputMode) -> HoverInformation { + fn hovered_element(&self, mouse_position: ScreenPosition, mouse_mode: &MouseInputMode) -> HoverInformation { match mouse_mode { MouseInputMode::None => self.state.hovered_element(mouse_position, mouse_mode, true), _ => HoverInformation::Missed, @@ -168,8 +167,8 @@ impl Element for CharacterPreview { state_provider: &StateProvider, interface_settings: &InterfaceSettings, theme: &InterfaceTheme, - parent_position: Position, - clip_size: ClipSize, + parent_position: ScreenPosition, + screen_clip: ScreenClip, hovered_element: Option<&dyn Element>, focused_element: Option<&dyn Element>, mouse_mode: &MouseInputMode, @@ -178,14 +177,14 @@ impl Element for CharacterPreview { let mut renderer = self .state .state - .element_renderer(render_target, renderer, interface_settings, parent_position, clip_size); + .element_renderer(render_target, renderer, interface_settings, parent_position, screen_clip); let background_color = match self.is_element_self(hovered_element) || self.is_element_self(focused_element) { true => *theme.button.hovered_background_color, false => *theme.button.background_color, }; - renderer.render_background(*theme.button.border_radius, background_color); + renderer.render_background((*theme.button.corner_radius).into(), background_color); self.state.render( &mut renderer, diff --git a/src/interface/elements/containers/default.rs b/src/interface/elements/containers/default.rs index 9aafe595..fa19698d 100644 --- a/src/interface/elements/containers/default.rs +++ b/src/interface/elements/containers/default.rs @@ -1,6 +1,5 @@ use std::rc::Weak; -use cgmath::Zero; use procedural::*; use crate::graphics::{InterfaceRenderer, Renderer}; @@ -9,7 +8,7 @@ use crate::interface::{Element, *}; pub struct Container { size_constraint: Option<SizeConstraint>, - border_size: Option<Vector2<f32>>, + border_size: Option<ScreenSize>, state: ContainerState, } @@ -56,7 +55,7 @@ impl Element for Container { fn resolve(&mut self, placement_resolver: &mut PlacementResolver, interface_settings: &InterfaceSettings, theme: &InterfaceTheme) { let size_constraint = self.size_constraint.as_ref().unwrap_or(&constraint!(100%, ?)); - let border = self.border_size.unwrap_or_else(Vector2::zero); + let border = self.border_size.unwrap_or_default(); self.state .resolve(placement_resolver, interface_settings, theme, size_constraint, border); @@ -66,7 +65,7 @@ impl Element for Container { self.state.update() } - fn hovered_element(&self, mouse_position: Position, mouse_mode: &MouseInputMode) -> HoverInformation { + fn hovered_element(&self, mouse_position: ScreenPosition, mouse_mode: &MouseInputMode) -> HoverInformation { self.state.hovered_element(mouse_position, mouse_mode, false) } @@ -77,8 +76,8 @@ impl Element for Container { state_provider: &StateProvider, interface_settings: &InterfaceSettings, theme: &InterfaceTheme, - parent_position: Position, - clip_size: ClipSize, + parent_position: ScreenPosition, + screen_clip: ScreenClip, hovered_element: Option<&dyn Element>, focused_element: Option<&dyn Element>, mouse_mode: &MouseInputMode, @@ -87,7 +86,7 @@ impl Element for Container { let mut renderer = self .state .state - .element_renderer(render_target, renderer, interface_settings, parent_position, clip_size); + .element_renderer(render_target, renderer, interface_settings, parent_position, screen_clip); self.state.render( &mut renderer, diff --git a/src/interface/elements/containers/dialog.rs b/src/interface/elements/containers/dialog.rs index 19b82ed9..bcf2d81b 100644 --- a/src/interface/elements/containers/dialog.rs +++ b/src/interface/elements/containers/dialog.rs @@ -1,4 +1,3 @@ -use cgmath::Array; use procedural::*; use crate::graphics::{Color, InterfaceRenderer, Renderer}; @@ -77,7 +76,7 @@ impl Element for DialogContainer { interface_settings, theme, size_constraint, - Vector2::from_value(3.0), + ScreenSize::uniform(3.0), ); } @@ -93,7 +92,7 @@ impl Element for DialogContainer { None } - fn hovered_element(&self, mouse_position: Position, mouse_mode: &MouseInputMode) -> HoverInformation { + fn hovered_element(&self, mouse_position: ScreenPosition, mouse_mode: &MouseInputMode) -> HoverInformation { self.state.hovered_element(mouse_position, mouse_mode, false) } @@ -104,8 +103,8 @@ impl Element for DialogContainer { state_provider: &StateProvider, interface_settings: &InterfaceSettings, theme: &InterfaceTheme, - parent_position: Position, - clip_size: ClipSize, + parent_position: ScreenPosition, + screen_clip: ScreenClip, hovered_element: Option<&dyn Element>, focused_element: Option<&dyn Element>, mouse_mode: &MouseInputMode, @@ -114,7 +113,7 @@ impl Element for DialogContainer { let mut renderer = self .state .state - .element_renderer(render_target, renderer, interface_settings, parent_position, clip_size); + .element_renderer(render_target, renderer, interface_settings, parent_position, screen_clip); self.state.render( &mut renderer, diff --git a/src/interface/elements/containers/equipment.rs b/src/interface/elements/containers/equipment.rs index 2be6c88e..eb11ee17 100644 --- a/src/interface/elements/containers/equipment.rs +++ b/src/interface/elements/containers/equipment.rs @@ -1,4 +1,3 @@ -use cgmath::Array; use procedural::*; use crate::graphics::{InterfaceRenderer, Renderer}; @@ -93,7 +92,7 @@ impl Element for EquipmentContainer { interface_settings, theme, size_constraint, - Vector2::from_value(3.0), + ScreenSize::uniform(3.0), ); } @@ -113,7 +112,7 @@ impl Element for EquipmentContainer { None } - fn hovered_element(&self, mouse_position: Position, mouse_mode: &MouseInputMode) -> HoverInformation { + fn hovered_element(&self, mouse_position: ScreenPosition, mouse_mode: &MouseInputMode) -> HoverInformation { match mouse_mode { MouseInputMode::MoveItem(..) | MouseInputMode::None => self.state.hovered_element(mouse_position, mouse_mode, false), _ => HoverInformation::Missed, @@ -127,8 +126,8 @@ impl Element for EquipmentContainer { state_provider: &StateProvider, interface_settings: &InterfaceSettings, theme: &InterfaceTheme, - parent_position: Position, - clip_size: ClipSize, + parent_position: ScreenPosition, + screen_clip: ScreenClip, hovered_element: Option<&dyn Element>, focused_element: Option<&dyn Element>, mouse_mode: &MouseInputMode, @@ -137,7 +136,7 @@ impl Element for EquipmentContainer { let mut renderer = self .state .state - .element_renderer(render_target, renderer, interface_settings, parent_position, clip_size); + .element_renderer(render_target, renderer, interface_settings, parent_position, screen_clip); self.state.render( &mut renderer, diff --git a/src/interface/elements/containers/expandable.rs b/src/interface/elements/containers/expandable.rs index 804dbd6d..aaafcf22 100644 --- a/src/interface/elements/containers/expandable.rs +++ b/src/interface/elements/containers/expandable.rs @@ -1,6 +1,5 @@ use std::rc::Weak; -use num::Zero; use procedural::*; use crate::graphics::{InterfaceRenderer, Renderer}; @@ -12,7 +11,7 @@ pub struct Expandable { expanded: bool, open_size_constraint: SizeConstraint, closed_size_constraint: SizeConstraint, - cached_closed_size: Size, + cached_closed_size: ScreenSize, state: ContainerState, } @@ -25,7 +24,7 @@ impl Expandable { expanded, open_size_constraint: constraint!(100%, ?), closed_size_constraint: constraint!(100%, 18), - cached_closed_size: Size::zero(), + cached_closed_size: ScreenSize::default(), state, } } @@ -73,12 +72,22 @@ impl Element for Expandable { }; if self.expanded && !self.state.elements.is_empty() { - let mut inner_placement_resolver = placement_resolver.derive( - size, - Position::new(0.0, closed_size.y) + *theme.expandable.element_offset * *interface_settings.scaling, - *theme.expandable.border_size, - ); - inner_placement_resolver.set_gaps(*theme.expandable.gaps); + let screen_position = ScreenPosition::only_top(closed_size.height) + + ScreenPosition { + left: theme.expandable.element_offset.x, + top: theme.expandable.element_offset.y, + } * *interface_settings.scaling; + + let screen_size = ScreenSize { + width: theme.expandable.border_size.x, + height: theme.expandable.border_size.y, + }; + + let mut inner_placement_resolver = placement_resolver.derive(size, screen_position, screen_size); + inner_placement_resolver.set_gaps(ScreenSize { + width: theme.expandable.gaps.x, + height: theme.expandable.gaps.y, + }); self.state.elements.iter_mut().for_each(|element| { element @@ -88,16 +97,18 @@ impl Element for Expandable { if self.open_size_constraint.height.is_flexible() { let final_height = inner_placement_resolver.final_height() - + closed_size.y + + closed_size.height + theme.expandable.element_offset.y * *interface_settings.scaling + theme.expandable.border_size.y * *interface_settings.scaling * 2.0; + let final_height = self.open_size_constraint.validated_height( final_height, - placement_resolver.get_available().y, - placement_resolver.get_available().y, + placement_resolver.get_available().height, + placement_resolver.get_available().height, *interface_settings.scaling, ); - size.y = Some(final_height); + + size.height = Some(final_height); placement_resolver.register_height(final_height); } } @@ -115,13 +126,13 @@ impl Element for Expandable { self.state.update() } - fn hovered_element(&self, mouse_position: Position, mouse_mode: &MouseInputMode) -> HoverInformation { - let absolute_position = mouse_position - self.state.state.cached_position; + fn hovered_element(&self, mouse_position: ScreenPosition, mouse_mode: &MouseInputMode) -> HoverInformation { + let absolute_position = ScreenPosition::from_size(mouse_position - self.state.state.cached_position); - if absolute_position.x >= 0.0 - && absolute_position.y >= 0.0 - && absolute_position.x <= self.state.state.cached_size.x - && absolute_position.y <= self.state.state.cached_size.y + if absolute_position.left >= 0.0 + && absolute_position.top >= 0.0 + && absolute_position.left <= self.state.state.cached_size.width + && absolute_position.top <= self.state.state.cached_size.height { if self.expanded && !self.state.elements.is_empty() { for element in &self.state.elements { @@ -154,8 +165,8 @@ impl Element for Expandable { state_provider: &StateProvider, interface_settings: &InterfaceSettings, theme: &InterfaceTheme, - parent_position: Position, - clip_size: ClipSize, + parent_position: ScreenPosition, + screen_clip: ScreenClip, hovered_element: Option<&dyn Element>, focused_element: Option<&dyn Element>, mouse_mode: &MouseInputMode, @@ -164,33 +175,38 @@ impl Element for Expandable { let mut renderer = self .state .state - .element_renderer(render_target, renderer, interface_settings, parent_position, clip_size); + .element_renderer(render_target, renderer, interface_settings, parent_position, screen_clip); let background_color = match second_theme { true => *theme.expandable.second_background_color, false => *theme.expandable.background_color, }; - renderer.render_background(*theme.button.border_radius, background_color); + renderer.render_background((*theme.button.corner_radius).into(), background_color); + + let arrow_position = ScreenPosition { + left: theme.expandable.icon_offset.x, + top: theme.expandable.icon_offset.y, + }; + + let arrow_size = ScreenSize { + width: theme.expandable.icon_size.x, + height: theme.expandable.icon_size.y, + }; - renderer.render_expand_arrow( - *theme.expandable.icon_offset, - *theme.expandable.icon_size, - *theme.expandable.foreground_color, - self.expanded, - ); + renderer.render_expand_arrow(arrow_position, arrow_size, *theme.expandable.foreground_color, self.expanded); let foreground_color = match self.is_element_self(hovered_element) || self.is_element_self(focused_element) { true => *theme.expandable.hovered_foreground_color, false => *theme.expandable.foreground_color, }; - renderer.render_text( - &self.display, - *theme.expandable.text_offset, - foreground_color, - *theme.expandable.font_size, - ); + let text_position = ScreenPosition { + left: theme.expandable.text_offset.x, + top: theme.expandable.text_offset.y, + }; + + renderer.render_text(&self.display, text_position, foreground_color, *theme.expandable.font_size); if self.expanded && !self.state.elements.is_empty() { self.state.render( diff --git a/src/interface/elements/containers/friends.rs b/src/interface/elements/containers/friends.rs index 37706853..aaacf27f 100644 --- a/src/interface/elements/containers/friends.rs +++ b/src/interface/elements/containers/friends.rs @@ -1,7 +1,6 @@ use std::cell::UnsafeCell; use std::rc::Weak; -use cgmath::Zero; use procedural::*; use crate::graphics::{InterfaceRenderer, Renderer}; @@ -81,7 +80,7 @@ impl Element for FriendView { interface_settings, theme, &constraint!(100%, ?), - Vector2::zero(), + ScreenSize::default(), ); } @@ -126,7 +125,7 @@ impl Element for FriendView { } } - fn hovered_element(&self, mouse_position: Position, mouse_mode: &MouseInputMode) -> HoverInformation { + fn hovered_element(&self, mouse_position: ScreenPosition, mouse_mode: &MouseInputMode) -> HoverInformation { match mouse_mode { MouseInputMode::None => self.state.hovered_element(mouse_position, mouse_mode, false), _ => HoverInformation::Missed, @@ -140,8 +139,8 @@ impl Element for FriendView { state_provider: &StateProvider, interface_settings: &InterfaceSettings, theme: &InterfaceTheme, - parent_position: Position, - clip_size: ClipSize, + parent_position: ScreenPosition, + screen_clip: ScreenClip, hovered_element: Option<&dyn Element>, focused_element: Option<&dyn Element>, mouse_mode: &MouseInputMode, @@ -150,7 +149,7 @@ impl Element for FriendView { let mut renderer = self .state .state - .element_renderer(render_target, renderer, interface_settings, parent_position, clip_size); + .element_renderer(render_target, renderer, interface_settings, parent_position, screen_clip); self.state.render( &mut renderer, diff --git a/src/interface/elements/containers/hotbar.rs b/src/interface/elements/containers/hotbar.rs index 8515e84a..7797fcbe 100644 --- a/src/interface/elements/containers/hotbar.rs +++ b/src/interface/elements/containers/hotbar.rs @@ -1,4 +1,3 @@ -use cgmath::Array; use procedural::*; use crate::graphics::{InterfaceRenderer, Renderer}; @@ -71,7 +70,7 @@ impl Element for HotbarContainer { interface_settings, theme, size_constraint, - Vector2::from_value(3.0), + ScreenSize::uniform(3.0), ); } @@ -91,7 +90,7 @@ impl Element for HotbarContainer { None } - fn hovered_element(&self, mouse_position: Position, mouse_mode: &MouseInputMode) -> HoverInformation { + fn hovered_element(&self, mouse_position: ScreenPosition, mouse_mode: &MouseInputMode) -> HoverInformation { match mouse_mode { MouseInputMode::MoveSkill(..) | MouseInputMode::None => self.state.hovered_element(mouse_position, mouse_mode, false), _ => HoverInformation::Missed, @@ -105,8 +104,8 @@ impl Element for HotbarContainer { state_provider: &StateProvider, interface_settings: &InterfaceSettings, theme: &InterfaceTheme, - parent_position: Position, - clip_size: ClipSize, + parent_position: ScreenPosition, + screen_clip: ScreenClip, hovered_element: Option<&dyn Element>, focused_element: Option<&dyn Element>, mouse_mode: &MouseInputMode, @@ -115,7 +114,7 @@ impl Element for HotbarContainer { let mut renderer = self .state .state - .element_renderer(render_target, renderer, interface_settings, parent_position, clip_size); + .element_renderer(render_target, renderer, interface_settings, parent_position, screen_clip); self.state.render( &mut renderer, diff --git a/src/interface/elements/containers/inventory.rs b/src/interface/elements/containers/inventory.rs index 4f4670eb..44820ff0 100644 --- a/src/interface/elements/containers/inventory.rs +++ b/src/interface/elements/containers/inventory.rs @@ -1,4 +1,3 @@ -use cgmath::{Array, Vector4}; use procedural::*; use crate::graphics::{InterfaceRenderer, Renderer}; @@ -64,7 +63,7 @@ impl Element for InventoryContainer { interface_settings, theme, size_constraint, - Vector2::from_value(3.0), + ScreenSize::uniform(3.0), ); } @@ -84,7 +83,7 @@ impl Element for InventoryContainer { None } - fn hovered_element(&self, mouse_position: Position, mouse_mode: &MouseInputMode) -> HoverInformation { + fn hovered_element(&self, mouse_position: ScreenPosition, mouse_mode: &MouseInputMode) -> HoverInformation { match mouse_mode { MouseInputMode::MoveItem(..) => self.state.state.hovered_element(mouse_position), MouseInputMode::None => self.state.hovered_element(mouse_position, mouse_mode, false), @@ -107,8 +106,8 @@ impl Element for InventoryContainer { state_provider: &StateProvider, interface_settings: &InterfaceSettings, theme: &InterfaceTheme, - parent_position: Position, - clip_size: ClipSize, + parent_position: ScreenPosition, + screen_clip: ScreenClip, hovered_element: Option<&dyn Element>, focused_element: Option<&dyn Element>, mouse_mode: &MouseInputMode, @@ -117,7 +116,7 @@ impl Element for InventoryContainer { let mut renderer = self .state .state - .element_renderer(render_target, renderer, interface_settings, parent_position, clip_size); + .element_renderer(render_target, renderer, interface_settings, parent_position, screen_clip); self.state.render( &mut renderer, @@ -132,8 +131,8 @@ impl Element for InventoryContainer { if matches!(mouse_mode, MouseInputMode::MoveItem(..)) { match self.is_element_self(hovered_element) { - true => renderer.render_background(Vector4::from_value(5.0), Color::rgba(60, 160, 160, 160)), - false => renderer.render_background(Vector4::from_value(5.0), Color::rgba(160, 160, 60, 160)), + true => renderer.render_background(CornerRadius::uniform(5.0), Color::rgba(60, 160, 160, 160)), + false => renderer.render_background(CornerRadius::uniform(5.0), Color::rgba(160, 160, 60, 160)), } } } diff --git a/src/interface/elements/containers/mod.rs b/src/interface/elements/containers/mod.rs index 1de3035b..49dfa764 100644 --- a/src/interface/elements/containers/mod.rs +++ b/src/interface/elements/containers/mod.rs @@ -15,7 +15,6 @@ use std::cell::Cell; use std::ops::Add; use std::rc::Weak; -use cgmath::Zero; use derive_new::new; pub use self::character::CharacterPreview; @@ -57,10 +56,10 @@ impl ContainerState { interface_settings: &InterfaceSettings, theme: &InterfaceTheme, size_constraint: &SizeConstraint, - border: Vector2<f32>, + border: ScreenSize, ) { let (mut size, position) = placement_resolver.allocate(size_constraint); - let mut inner_placement_resolver = placement_resolver.derive(size, Position::zero(), border); + let mut inner_placement_resolver = placement_resolver.derive(size, ScreenPosition::default(), border); // TODO: add ability to pass this in (by calling .with_gaps(..) on the // container) inner_placement_resolver.set_gaps(Size::new(5.0, 3.0)); @@ -75,11 +74,11 @@ impl ContainerState { let final_height = inner_placement_resolver.final_height(); let final_height = size_constraint.validated_height( final_height, - placement_resolver.get_available().y, - placement_resolver.get_available().y, + placement_resolver.get_available().height, + placement_resolver.get_available().height, *interface_settings.scaling, ); - size.y = Some(final_height); + size.height = Some(final_height); placement_resolver.register_height(final_height); } @@ -270,13 +269,13 @@ impl ContainerState { }) } - pub fn hovered_element(&self, mouse_position: Position, mouse_mode: &MouseInputMode, hoverable: bool) -> HoverInformation { - let absolute_position = mouse_position - self.state.cached_position; + pub fn hovered_element(&self, mouse_position: ScreenPosition, mouse_mode: &MouseInputMode, hoverable: bool) -> HoverInformation { + let absolute_position = ScreenPosition::from_size(mouse_position - self.state.cached_position); - if absolute_position.x >= 0.0 - && absolute_position.y >= 0.0 - && absolute_position.x <= self.state.cached_size.x - && absolute_position.y <= self.state.cached_size.y + if absolute_position.left >= 0.0 + && absolute_position.top >= 0.0 + && absolute_position.left <= self.state.cached_size.width + && absolute_position.top <= self.state.cached_size.height { for element in &self.elements { match element.borrow().hovered_element(absolute_position, mouse_mode) { diff --git a/src/interface/elements/containers/packet.rs b/src/interface/elements/containers/packet.rs index 728046ad..7756c2d8 100644 --- a/src/interface/elements/containers/packet.rs +++ b/src/interface/elements/containers/packet.rs @@ -2,7 +2,6 @@ use std::cell::UnsafeCell; use std::fmt::{Display, Formatter, Result}; use std::rc::Weak; -use cgmath::Zero; use procedural::*; use crate::graphics::{InterfaceRenderer, Renderer}; @@ -31,8 +30,8 @@ impl Element for HiddenElement { _state_provider: &StateProvider, _interface_settings: &InterfaceSettings, _theme: &InterfaceTheme, - _parent_position: Position, - _clip_size: ClipSize, + _parent_position: ScreenPosition, + _screen_clip: ScreenClip, _hovered_element: Option<&dyn Element>, _focused_element: Option<&dyn Element>, _mouse_mode: &MouseInputMode, @@ -165,7 +164,7 @@ impl<const N: usize> Element for PacketView<N> { interface_settings, theme, &constraint!(100%, ?), - Vector2::zero(), + ScreenSize::default(), ); } @@ -265,7 +264,7 @@ impl<const N: usize> Element for PacketView<N> { } } - fn hovered_element(&self, mouse_position: Position, mouse_mode: &MouseInputMode) -> HoverInformation { + fn hovered_element(&self, mouse_position: ScreenPosition, mouse_mode: &MouseInputMode) -> HoverInformation { match mouse_mode { MouseInputMode::None => self.state.hovered_element(mouse_position, mouse_mode, false), _ => HoverInformation::Missed, @@ -279,8 +278,8 @@ impl<const N: usize> Element for PacketView<N> { state_provider: &StateProvider, interface_settings: &InterfaceSettings, theme: &InterfaceTheme, - parent_position: Position, - clip_size: ClipSize, + parent_position: ScreenPosition, + screen_clip: ScreenClip, hovered_element: Option<&dyn Element>, focused_element: Option<&dyn Element>, mouse_mode: &MouseInputMode, @@ -289,7 +288,7 @@ impl<const N: usize> Element for PacketView<N> { let mut renderer = self .state .state - .element_renderer(render_target, renderer, interface_settings, parent_position, clip_size); + .element_renderer(render_target, renderer, interface_settings, parent_position, screen_clip); self.state.render( &mut renderer, diff --git a/src/interface/elements/containers/scroll.rs b/src/interface/elements/containers/scroll.rs index e894c3ce..2153d536 100644 --- a/src/interface/elements/containers/scroll.rs +++ b/src/interface/elements/containers/scroll.rs @@ -1,7 +1,5 @@ use std::rc::Weak; -use cgmath::Zero; - use crate::graphics::{InterfaceRenderer, Renderer}; use crate::input::MouseInputMode; use crate::interface::{Element, *}; @@ -66,7 +64,7 @@ impl Element for ScrollView { interface_settings, theme, &self.size_constraint, - Vector2::zero(), + ScreenSize::default(), ); } @@ -74,9 +72,9 @@ impl Element for ScrollView { self.state.update() } - fn hovered_element(&self, mouse_position: Position, mouse_mode: &MouseInputMode) -> HoverInformation { + fn hovered_element(&self, mouse_position: ScreenPosition, mouse_mode: &MouseInputMode) -> HoverInformation { self.state.hovered_element( - mouse_position + Vector2::new(0.0, self.scroll), + mouse_position + ScreenPosition::only_top(self.scroll), mouse_mode, mouse_mode.is_none(), ) @@ -95,8 +93,8 @@ impl Element for ScrollView { state_provider: &StateProvider, interface_settings: &InterfaceSettings, theme: &InterfaceTheme, - parent_position: Position, - clip_size: ClipSize, + parent_position: ScreenPosition, + screen_clip: ScreenClip, hovered_element: Option<&dyn Element>, focused_element: Option<&dyn Element>, mouse_mode: &MouseInputMode, @@ -105,7 +103,7 @@ impl Element for ScrollView { let mut renderer = self .state .state - .element_renderer(render_target, renderer, interface_settings, parent_position, clip_size); + .element_renderer(render_target, renderer, interface_settings, parent_position, screen_clip); if let Some(color_selector) = &self.background_color { renderer.render_background((*theme.button.corner_radius).into(), color_selector(theme)); diff --git a/src/interface/elements/containers/skill_tree.rs b/src/interface/elements/containers/skill_tree.rs index d0f451b2..7c5d8604 100644 --- a/src/interface/elements/containers/skill_tree.rs +++ b/src/interface/elements/containers/skill_tree.rs @@ -1,4 +1,3 @@ -use cgmath::Array; use procedural::*; use crate::graphics::{InterfaceRenderer, Renderer}; @@ -64,7 +63,7 @@ impl Element for SkillTreeContainer { interface_settings, theme, size_constraint, - Vector2::from_value(3.0), + ScreenSize::uniform(3.0), ); } @@ -84,7 +83,7 @@ impl Element for SkillTreeContainer { None } - fn hovered_element(&self, mouse_position: Position, mouse_mode: &MouseInputMode) -> HoverInformation { + fn hovered_element(&self, mouse_position: ScreenPosition, mouse_mode: &MouseInputMode) -> HoverInformation { match mouse_mode { MouseInputMode::MoveItem(..) => self.state.state.hovered_element(mouse_position), MouseInputMode::None => self.state.hovered_element(mouse_position, mouse_mode, false), @@ -107,8 +106,8 @@ impl Element for SkillTreeContainer { state_provider: &StateProvider, interface_settings: &InterfaceSettings, theme: &InterfaceTheme, - parent_position: Position, - clip_size: ClipSize, + parent_position: ScreenPosition, + screen_clip: ScreenClip, hovered_element: Option<&dyn Element>, focused_element: Option<&dyn Element>, mouse_mode: &MouseInputMode, @@ -117,7 +116,7 @@ impl Element for SkillTreeContainer { let mut renderer = self .state .state - .element_renderer(render_target, renderer, interface_settings, parent_position, clip_size); + .element_renderer(render_target, renderer, interface_settings, parent_position, screen_clip); self.state.render( &mut renderer, diff --git a/src/interface/elements/miscellanious/chat.rs b/src/interface/elements/miscellanious/chat.rs index 7cec8850..460aded3 100644 --- a/src/interface/elements/miscellanious/chat.rs +++ b/src/interface/elements/miscellanious/chat.rs @@ -1,4 +1,3 @@ -use cgmath::Array; use procedural::*; use crate::graphics::{InterfaceRenderer, Renderer}; @@ -57,7 +56,7 @@ impl Element for Chat { .get_text_dimensions( message.stamped_text(self.stamp), *theme.chat.font_size * *interface_settings.scaling, - placement_resolver.get_available().x, + placement_resolver.get_available().width, ) .y; } @@ -84,8 +83,8 @@ impl Element for Chat { _state_provider: &StateProvider, interface_settings: &InterfaceSettings, theme: &InterfaceTheme, - parent_position: Position, - clip_size: ClipSize, + parent_position: ScreenPosition, + screen_clip: ScreenClip, _hovered_element: Option<&dyn Element>, _focused_element: Option<&dyn Element>, _mouse_mode: &MouseInputMode, @@ -93,7 +92,7 @@ impl Element for Chat { ) { let mut renderer = self .state - .element_renderer(render_target, renderer, interface_settings, parent_position, clip_size); + .element_renderer(render_target, renderer, interface_settings, parent_position, screen_clip); let mut offset = 0.0; @@ -102,12 +101,15 @@ impl Element for Chat { renderer.render_text( text, - Vector2::new(0.0, offset) + Vector2::from_value(0.2), + ScreenPosition { + left: 0.2, + top: offset + 0.2, + }, Color::monochrome(0), *theme.chat.font_size, ); - offset += renderer.render_text(text, Vector2::new(0.0, offset), message.color, *theme.chat.font_size); + offset += renderer.render_text(text, ScreenPosition::only_top(offset), message.color, *theme.chat.font_size); } } } diff --git a/src/interface/elements/miscellanious/headline.rs b/src/interface/elements/miscellanious/headline.rs index 61723575..294a9543 100644 --- a/src/interface/elements/miscellanious/headline.rs +++ b/src/interface/elements/miscellanious/headline.rs @@ -40,8 +40,8 @@ impl Element for Headline { _state_provider: &StateProvider, interface_settings: &InterfaceSettings, theme: &InterfaceTheme, - parent_position: Position, - clip_size: ClipSize, + parent_position: ScreenPosition, + screen_clip: ScreenClip, _hovered_element: Option<&dyn Element>, _focused_element: Option<&dyn Element>, _mouse_mode: &MouseInputMode, @@ -49,11 +49,16 @@ impl Element for Headline { ) { let mut renderer = self .state - .element_renderer(render_target, renderer, interface_settings, parent_position, clip_size); + .element_renderer(render_target, renderer, interface_settings, parent_position, screen_clip); + + let text_position = ScreenPosition { + left: theme.label.text_offset.x, + top: theme.label.text_offset.y, + }; renderer.render_text( &self.display, - *theme.label.text_offset, + text_position, *theme.label.foreground_color, *theme.label.font_size, ); diff --git a/src/interface/elements/miscellanious/input.rs b/src/interface/elements/miscellanious/input.rs index 2599217c..4dfca7f2 100644 --- a/src/interface/elements/miscellanious/input.rs +++ b/src/interface/elements/miscellanious/input.rs @@ -1,7 +1,6 @@ use std::cell::RefCell; use std::rc::Rc; -use cgmath::{Array, Vector2, Vector4}; use derive_new::new; use crate::graphics::{InterfaceRenderer, Renderer}; @@ -56,7 +55,7 @@ impl<const LENGTH: usize, const HIDDEN: bool> Element for InputField<LENGTH, HID self.state.resolve(placement_resolver, &size_constraint); } - fn hovered_element(&self, mouse_position: Position, mouse_mode: &MouseInputMode) -> HoverInformation { + fn hovered_element(&self, mouse_position: ScreenPosition, mouse_mode: &MouseInputMode) -> HoverInformation { match mouse_mode { MouseInputMode::None => self.state.hovered_element(mouse_position), _ => HoverInformation::Missed, @@ -82,8 +81,8 @@ impl<const LENGTH: usize, const HIDDEN: bool> Element for InputField<LENGTH, HID _state_provider: &StateProvider, interface_settings: &InterfaceSettings, theme: &InterfaceTheme, - parent_position: Position, - clip_size: ClipSize, + parent_position: ScreenPosition, + screen_clip: ScreenClip, hovered_element: Option<&dyn Element>, focused_element: Option<&dyn Element>, _mouse_mode: &MouseInputMode, @@ -91,7 +90,7 @@ impl<const LENGTH: usize, const HIDDEN: bool> Element for InputField<LENGTH, HID ) { let mut renderer = self .state - .element_renderer(render_target, renderer, interface_settings, parent_position, clip_size); + .element_renderer(render_target, renderer, interface_settings, parent_position, screen_clip); let display: &String = &RefCell::borrow(&self.display); let is_hovererd = self.is_element_self(hovered_element); @@ -122,18 +121,33 @@ impl<const LENGTH: usize, const HIDDEN: bool> Element for InputField<LENGTH, HID *theme.input.text_color }; - renderer.render_background(*theme.input.border_radius, background_color); - renderer.render_text(&text, text_offset, text_color, *theme.input.font_size); + let text_position = ScreenPosition { + left: text_offset.x, + top: text_offset.y, + }; + + renderer.render_background((*theme.input.corner_radius).into(), background_color); + renderer.render_text(&text, text_position, text_color, *theme.input.font_size); if is_focused { let cursor_offset = text_offset.x + *theme.input.cursor_offset * *interface_settings.scaling + renderer.get_text_dimensions(&text, *theme.input.font_size, f32::MAX).x; + let cursor_position = ScreenPosition { + left: cursor_offset, + top: 0.0, + }; + + let cursor_size = ScreenSize { + width: *theme.input.cursor_width, + height: self.state.cached_size.height, + }; + renderer.render_rectangle( - Vector2::new(cursor_offset, 0.0), - Vector2::new(*theme.input.cursor_width, self.state.cached_size.y), - Vector4::from_value(0.0), + cursor_position, + cursor_size, + CornerRadius::uniform(0.0), *theme.input.text_color, ); } diff --git a/src/interface/elements/miscellanious/item.rs b/src/interface/elements/miscellanious/item.rs index 47c71b8b..08a9c475 100644 --- a/src/interface/elements/miscellanious/item.rs +++ b/src/interface/elements/miscellanious/item.rs @@ -1,4 +1,3 @@ -use cgmath::{Array, Vector4, Zero}; use derive_new::new; use procedural::*; @@ -33,7 +32,7 @@ impl Element for ItemBox { self.state.resolve(placement_resolver, &constraint!(30, 30)); } - fn hovered_element(&self, mouse_position: Position, mouse_mode: &MouseInputMode) -> HoverInformation { + fn hovered_element(&self, mouse_position: ScreenPosition, mouse_mode: &MouseInputMode) -> HoverInformation { match self.item.is_some() || matches!(mouse_mode, MouseInputMode::MoveItem(..)) { true => self.state.hovered_element(mouse_position), false => HoverInformation::Missed, @@ -63,8 +62,8 @@ impl Element for ItemBox { _state_provider: &StateProvider, interface_settings: &InterfaceSettings, theme: &InterfaceTheme, - parent_position: Position, - clip_size: ClipSize, + parent_position: ScreenPosition, + screen_clip: ScreenClip, hovered_element: Option<&dyn Element>, focused_element: Option<&dyn Element>, mouse_mode: &MouseInputMode, @@ -72,7 +71,7 @@ impl Element for ItemBox { ) { let mut renderer = self .state - .element_renderer(render_target, renderer, interface_settings, parent_position, clip_size); + .element_renderer(render_target, renderer, interface_settings, parent_position, screen_clip); let highlight = (self.highlight)(mouse_mode); let background_color = match self.is_element_self(hovered_element) || self.is_element_self(focused_element) { @@ -82,20 +81,20 @@ impl Element for ItemBox { _ => *theme.button.background_color, }; - renderer.render_background(Vector4::from_value(5.0), background_color); + renderer.render_background(CornerRadius::uniform(5.0), background_color); if let Some(item) = &self.item { renderer.render_sprite( item.texture.clone(), - Vector2::zero(), - Vector2::from_value(30.0), + ScreenPosition::default(), + ScreenSize::uniform(30.0), Color::monochrome(255), ); renderer.render_text( //&format!("{}", self.item.amount), "1", - Vector2::zero(), + ScreenPosition::default(), *theme.button.foreground_color, 8.0, ); diff --git a/src/interface/elements/miscellanious/picklist.rs b/src/interface/elements/miscellanious/picklist.rs index 8b9c358b..7ef29ccf 100644 --- a/src/interface/elements/miscellanious/picklist.rs +++ b/src/interface/elements/miscellanious/picklist.rs @@ -15,8 +15,8 @@ where event: Option<E>, width_constraint: Option<DimensionConstraint>, state: ElementState, - latest_position: Rc<RefCell<Position>>, - latest_size: Rc<RefCell<Size>>, + latest_position: Rc<RefCell<ScreenPosition>>, + latest_size: Rc<RefCell<ScreenSize>>, } // HACK: Workaround for Rust incorrect trait bounds when deriving Option<T> @@ -34,8 +34,8 @@ where event: Default::default(), width_constraint: Default::default(), state: Default::default(), - latest_position: Rc::new(RefCell::new(Position::new(0.0, 0.0))), - latest_size: Rc::new(RefCell::new(Size::new(0.0, 0.0))), + latest_position: Rc::new(RefCell::new(ScreenPosition::default())), + latest_size: Rc::new(RefCell::new(ScreenSize::default())), } } } @@ -93,7 +93,7 @@ where *self.latest_size.borrow_mut() = self.state.cached_size; } - fn hovered_element(&self, mouse_position: Position, mouse_mode: &MouseInputMode) -> HoverInformation { + fn hovered_element(&self, mouse_position: ScreenPosition, mouse_mode: &MouseInputMode) -> HoverInformation { match mouse_mode { MouseInputMode::None => self.state.hovered_element(mouse_position), _ => HoverInformation::Missed, @@ -154,8 +154,8 @@ where _state_provider: &StateProvider, interface_settings: &InterfaceSettings, theme: &InterfaceTheme, - parent_position: Position, - clip_size: ClipSize, + parent_position: ScreenPosition, + screen_clip: ScreenClip, hovered_element: Option<&dyn Element>, focused_element: Option<&dyn Element>, _mouse_mode: &MouseInputMode, @@ -163,7 +163,7 @@ where ) { let mut renderer = self .state - .element_renderer(render_target, renderer, interface_settings, parent_position, clip_size); + .element_renderer(render_target, renderer, interface_settings, parent_position, screen_clip); let highlighted = self.is_element_self(hovered_element) || self.is_element_self(focused_element); let background_color = match highlighted { @@ -171,7 +171,7 @@ where false => *theme.button.background_color, }; - renderer.render_background(*theme.button.border_radius, background_color); + renderer.render_background((*theme.button.corner_radius).into(), background_color); *self.latest_position.borrow_mut() = renderer.get_position(); @@ -184,12 +184,12 @@ where let current_state = self.selected.as_ref().map(|state| state.get()).unwrap(); if let Some((text, _)) = self.options.iter().find(|(_, value)| *value == current_state) { - renderer.render_text( - text.as_ref(), - *theme.button.text_offset, - foreground_color, - *theme.button.font_size, - ); + let text_position = ScreenPosition { + left: theme.button.text_offset.x, + top: theme.button.text_offset.y, + }; + + renderer.render_text(text.as_ref(), text_position, foreground_color, *theme.button.font_size); } } } diff --git a/src/interface/elements/miscellanious/skill.rs b/src/interface/elements/miscellanious/skill.rs index e21c5ebd..ac4ae5b4 100644 --- a/src/interface/elements/miscellanious/skill.rs +++ b/src/interface/elements/miscellanious/skill.rs @@ -1,4 +1,3 @@ -use cgmath::{Array, Vector4, Zero}; use derive_new::new; use procedural::*; @@ -33,7 +32,7 @@ impl Element for SkillBox { self.state.resolve(placement_resolver, &constraint!(30, 30)); } - fn hovered_element(&self, mouse_position: Position, mouse_mode: &MouseInputMode) -> HoverInformation { + fn hovered_element(&self, mouse_position: ScreenPosition, mouse_mode: &MouseInputMode) -> HoverInformation { match self.skill.is_some() || matches!(mouse_mode, MouseInputMode::MoveSkill(..)) { true => self.state.hovered_element(mouse_position), false => HoverInformation::Missed, @@ -63,8 +62,8 @@ impl Element for SkillBox { _state_provider: &StateProvider, interface_settings: &InterfaceSettings, theme: &InterfaceTheme, - parent_position: Position, - clip_size: ClipSize, + parent_position: ScreenPosition, + screen_clip: ScreenClip, hovered_element: Option<&dyn Element>, focused_element: Option<&dyn Element>, mouse_mode: &MouseInputMode, @@ -72,7 +71,7 @@ impl Element for SkillBox { ) { let mut renderer = self .state - .element_renderer(render_target, renderer, interface_settings, parent_position, clip_size); + .element_renderer(render_target, renderer, interface_settings, parent_position, screen_clip); let highlight = (self.highlight)(mouse_mode); let background_color = match self.is_element_self(hovered_element) || self.is_element_self(focused_element) { @@ -82,7 +81,7 @@ impl Element for SkillBox { _ => *theme.button.background_color, }; - renderer.render_background(Vector4::from_value(5.0), background_color); + renderer.render_background(CornerRadius::uniform(5.0), background_color); if let Some(skill) = &self.skill { skill.actions.render2( @@ -90,7 +89,7 @@ impl Element for SkillBox { renderer.renderer, &skill.sprite, &skill.animation_state, - renderer.position + Vector2::from_value(15.0 * *interface_settings.scaling), + renderer.position + ScreenPosition::uniform(15.0 * *interface_settings.scaling), 0, Color::monochrome(255), interface_settings, @@ -98,13 +97,13 @@ impl Element for SkillBox { renderer.render_text( &format!("{}", skill.skill_level.0), - Vector2::from_value(1.0), + ScreenPosition::uniform(1.0), Color::monochrome(0), 15.0, ); renderer.render_text( &format!("{}", skill.skill_level.0), - Vector2::zero(), + ScreenPosition::default(), Color::monochrome(255), 15.0, ); diff --git a/src/interface/elements/miscellanious/slider.rs b/src/interface/elements/miscellanious/slider.rs index 335f29a0..9874bd0f 100644 --- a/src/interface/elements/miscellanious/slider.rs +++ b/src/interface/elements/miscellanious/slider.rs @@ -1,6 +1,5 @@ use std::cmp::PartialOrd; -use cgmath::{Array, Vector4}; use derive_new::new; use num::traits::NumOps; use num::{clamp, NumCast, Zero}; @@ -45,7 +44,7 @@ impl<T: Zero + NumOps + NumCast + Copy + PartialOrd> Element for Slider<T> { None } - fn hovered_element(&self, mouse_position: Position, mouse_mode: &MouseInputMode) -> HoverInformation { + fn hovered_element(&self, mouse_position: ScreenPosition, mouse_mode: &MouseInputMode) -> HoverInformation { match mouse_mode { MouseInputMode::None => self.state.hovered_element(mouse_position), MouseInputMode::DragElement((element, _)) if self.is_element_self(Some(&*element.borrow())) => HoverInformation::Hovered, @@ -57,9 +56,9 @@ impl<T: Zero + NumOps + NumCast + Copy + PartialOrd> Element for Slider<T> { vec![ClickAction::DragElement] } - fn drag(&mut self, mouse_delta: Position) -> Option<ChangeEvent> { + fn drag(&mut self, mouse_delta: ScreenPosition) -> Option<ChangeEvent> { let total_range = self.maximum_value.to_f32().unwrap() - self.minimum_value.to_f32().unwrap(); - let raw_value = self.cached_value.to_f32().unwrap() + (mouse_delta.x * total_range * 0.005); + let raw_value = self.cached_value.to_f32().unwrap() + (mouse_delta.left * total_range * 0.005); let new_value = clamp( raw_value, self.minimum_value.to_f32().unwrap(), @@ -79,8 +78,8 @@ impl<T: Zero + NumOps + NumCast + Copy + PartialOrd> Element for Slider<T> { _state_provider: &StateProvider, interface_settings: &InterfaceSettings, theme: &InterfaceTheme, - parent_position: Position, - clip_size: ClipSize, + parent_position: ScreenPosition, + screen_clip: ScreenClip, hovered_element: Option<&dyn Element>, _focused_element: Option<&dyn Element>, _mouse_mode: &MouseInputMode, @@ -88,25 +87,31 @@ impl<T: Zero + NumOps + NumCast + Copy + PartialOrd> Element for Slider<T> { ) { let mut renderer = self .state - .element_renderer(render_target, renderer, interface_settings, parent_position, clip_size); + .element_renderer(render_target, renderer, interface_settings, parent_position, screen_clip); if self.is_element_self(hovered_element) { - renderer.render_background(*theme.button.border_radius, *theme.slider.background_color); + renderer.render_background((*theme.button.corner_radius).into(), *theme.slider.background_color); } - let bar_size = Size::new(self.state.cached_size.x * 0.9, self.state.cached_size.y / 4.0); - let offset = (self.state.cached_size - bar_size) / 2.0; + let bar_size = ScreenSize { + width: self.state.cached_size.width * 0.9, + height: self.state.cached_size.height / 4.0, + }; + let offset = ScreenPosition::from_size((self.state.cached_size - bar_size) / 2.0); - renderer.render_rectangle(offset, bar_size, Vector4::from_value(0.5), *theme.slider.rail_color); + renderer.render_rectangle(offset, bar_size, CornerRadius::uniform(0.5), *theme.slider.rail_color); - let knob_size = Size::new(20.0 * *interface_settings.scaling, self.state.cached_size.y * 0.8); + let knob_size = ScreenSize { + width: 20.0 * *interface_settings.scaling, + height: self.state.cached_size.height * 0.8, + }; let total_range = self.maximum_value - self.minimum_value; - let offset = Position::new( - (self.state.cached_size.x - knob_size.x) / total_range.to_f32().unwrap() + let offset = ScreenPosition { + left: (self.state.cached_size.width - knob_size.width) / total_range.to_f32().unwrap() * (self.cached_value.to_f32().unwrap() - self.minimum_value.to_f32().unwrap()), - (self.state.cached_size.y - knob_size.y) / 2.0, - ); + top: (self.state.cached_size.height - knob_size.height) / 2.0, + }; - renderer.render_rectangle(offset, knob_size, Vector4::from_value(4.0), *theme.slider.knob_color); + renderer.render_rectangle(offset, knob_size, CornerRadius::uniform(4.0), *theme.slider.knob_color); } } diff --git a/src/interface/elements/miscellanious/static_label.rs b/src/interface/elements/miscellanious/static_label.rs index 7576d31e..a03750ab 100644 --- a/src/interface/elements/miscellanious/static_label.rs +++ b/src/interface/elements/miscellanious/static_label.rs @@ -27,7 +27,7 @@ impl Element for StaticLabel { *theme.label.font_size, *theme.label.text_offset, *interface_settings.scaling, - placement_resolver.get_available().x / 2.0, // TODO: make better + placement_resolver.get_available().width / 2.0, // TODO: make better ); size_constraint.height = Dimension::Absolute(f32::max(size.y / *interface_settings.scaling, 14.0)); // TODO: make better @@ -42,8 +42,8 @@ impl Element for StaticLabel { _state_provider: &StateProvider, interface_settings: &InterfaceSettings, theme: &InterfaceTheme, - parent_position: Position, - clip_size: ClipSize, + parent_position: ScreenPosition, + screen_clip: ScreenClip, _hovered_element: Option<&dyn Element>, _focused_element: Option<&dyn Element>, _mouse_mode: &MouseInputMode, @@ -51,15 +51,15 @@ impl Element for StaticLabel { ) { let mut renderer = self .state - .element_renderer(render_target, renderer, interface_settings, parent_position, clip_size); + .element_renderer(render_target, renderer, interface_settings, parent_position, screen_clip); - renderer.render_background(*theme.label.border_radius, *theme.label.background_color); + renderer.render_background((*theme.label.corner_radius).into(), *theme.label.background_color); - renderer.render_text( - &self.label, - *theme.label.text_offset, - *theme.label.foreground_color, - *theme.label.font_size, - ); + let text_size = ScreenPosition { + left: theme.label.text_offset.x, + top: theme.label.text_offset.y, + }; + + renderer.render_text(&self.label, text_size, *theme.label.foreground_color, *theme.label.font_size); } } diff --git a/src/interface/elements/miscellanious/text.rs b/src/interface/elements/miscellanious/text.rs index 58ed71f4..7f4dffbd 100644 --- a/src/interface/elements/miscellanious/text.rs +++ b/src/interface/elements/miscellanious/text.rs @@ -1,4 +1,3 @@ -use num::Zero; use procedural::dimension; use crate::graphics::{Color, InterfaceRenderer, Renderer}; @@ -78,8 +77,8 @@ impl<T: AsRef<str> + 'static> Element for Text<T> { _state_provider: &StateProvider, interface_settings: &InterfaceSettings, theme: &InterfaceTheme, - parent_position: Position, - clip_size: ClipSize, + parent_position: ScreenPosition, + screen_clip: ScreenClip, _hovered_element: Option<&dyn Element>, _focused_element: Option<&dyn Element>, _mouse_mode: &MouseInputMode, @@ -87,7 +86,7 @@ impl<T: AsRef<str> + 'static> Element for Text<T> { ) { let mut renderer = self .state - .element_renderer(render_target, renderer, interface_settings, parent_position, clip_size); + .element_renderer(render_target, renderer, interface_settings, parent_position, screen_clip); let foreground_color = self .foreground_color @@ -96,6 +95,11 @@ impl<T: AsRef<str> + 'static> Element for Text<T> { .unwrap_or(*theme.button.foreground_color); let text = self.text.as_ref().unwrap(); - renderer.render_text(text.as_ref(), Vector2::zero(), foreground_color, self.get_font_size(theme)); + renderer.render_text( + text.as_ref(), + ScreenPosition::default(), + foreground_color, + self.get_font_size(theme), + ); } } diff --git a/src/interface/elements/profiler/frame.rs b/src/interface/elements/profiler/frame.rs index aeb43a64..10c5a7d4 100644 --- a/src/interface/elements/profiler/frame.rs +++ b/src/interface/elements/profiler/frame.rs @@ -52,7 +52,7 @@ impl Element for FrameView { None } - fn hovered_element(&self, mouse_position: Position, mouse_mode: &MouseInputMode) -> HoverInformation { + fn hovered_element(&self, mouse_position: ScreenPosition, mouse_mode: &MouseInputMode) -> HoverInformation { match mouse_mode { MouseInputMode::None => self.state.hovered_element(mouse_position), _ => HoverInformation::Missed, @@ -64,8 +64,8 @@ impl Element for FrameView { let mouse_position = self.state.mouse_position.get(); let number_of_frames = get_number_of_saved_frames(visible_thread); - let bar_width = self.state.cached_size.x / number_of_frames as f32; - let clicked_frame = (mouse_position.x / bar_width) as usize; + let bar_width = self.state.cached_size.width / number_of_frames as f32; + let clicked_frame = (mouse_position.left / bar_width) as usize; let measurement = get_frame_by_index(visible_thread, clicked_frame); vec![ClickAction::OpenWindow(Box::new(FrameInspectorWindow::new(measurement)))] @@ -78,8 +78,8 @@ impl Element for FrameView { _state_provider: &StateProvider, interface_settings: &InterfaceSettings, _theme: &InterfaceTheme, - parent_position: Position, - clip_size: ClipSize, + parent_position: ScreenPosition, + screen_clip: ScreenClip, _hovered_element: Option<&dyn Element>, _focused_element: Option<&dyn Element>, _mouse_mode: &MouseInputMode, @@ -87,39 +87,46 @@ impl Element for FrameView { ) { let mut renderer = self .state - .element_renderer(render_target, renderer, interface_settings, parent_position, clip_size); + .element_renderer(render_target, renderer, interface_settings, parent_position, screen_clip); let (entries, statistics_map, longest_frame) = get_statistics_data(*self.visible_thread.borrow()); - let bar_width = (self.state.cached_size.x - 50.0) / entries.len() as f32; + let bar_width = (self.state.cached_size.width - 50.0) / entries.len() as f32; let gap_width = 50.0 / entries.len() as f32; - let height_unit = self.state.cached_size.y / longest_frame.as_secs_f32(); + let height_unit = self.state.cached_size.height / longest_frame.as_secs_f32(); let mut x_position = 0.0; let mut color_lookup = super::ColorLookup::default(); for entry in entries { - let mut y_position = self.state.cached_size.y; + let mut y_position = self.state.cached_size.height; let bar_height = height_unit * entry.total_time.as_secs_f32(); + let bar_position = ScreenPosition { + left: x_position, + top: y_position - bar_height, + }; + let bar_size = ScreenSize { + width: bar_width, + height: bar_height, + }; - renderer.render_rectangle( - Position::new(x_position, y_position - bar_height), - Size::new(bar_width, bar_height), - cgmath::Vector4::new(0.0, 0.0, 0.0, 0.0), - Color::monochrome(80), - ); + renderer.render_rectangle(bar_position, bar_size, CornerRadius::default(), Color::monochrome(80)); for (name, duration) in entry.frame_times { let color = color_lookup.get_color(name); let bar_height = height_unit * duration.as_secs_f32(); y_position -= bar_height; - renderer.render_rectangle( - Position::new(x_position, y_position), - Size::new(bar_width, bar_height), - cgmath::Vector4::new(0.0, 0.0, 0.0, 0.0), - color, - ); + let bar_position = ScreenPosition { + left: x_position, + top: y_position, + }; + let bar_size = ScreenSize { + width: bar_width, + height: bar_height, + }; + + renderer.render_rectangle(bar_position, bar_size, CornerRadius::default(), color); } x_position += bar_width + gap_width; @@ -130,10 +137,16 @@ impl Element for FrameView { let statistics = statistics_map.get(name).unwrap(); let text = format!("{} {:?} (SD {:.1})", name, statistics.mean, statistics.standard_deviation); + let text_position = ScreenPosition { + left: 3.0, + top: y_position, + }; + let shadow_position = text_position + ScreenSize::uniform(1.0); + // Drop shadow. - renderer.render_text(&text, Position::new(4.0, y_position + 1.0), Color::monochrome(0), 14.0); + renderer.render_text(&text, shadow_position, Color::monochrome(0), 14.0); // Colored text. - renderer.render_text(&text, Position::new(3.0, y_position), color, 14.0); + renderer.render_text(&text, text_position, color, 14.0); y_position += 14.0; } diff --git a/src/interface/elements/profiler/inspector.rs b/src/interface/elements/profiler/inspector.rs index cfcaf9eb..37104267 100644 --- a/src/interface/elements/profiler/inspector.rs +++ b/src/interface/elements/profiler/inspector.rs @@ -1,6 +1,5 @@ use std::time::{Duration, Instant}; -use cgmath::{Vector4, Zero}; use procedural::*; use crate::debug::*; @@ -45,31 +44,35 @@ impl FrameInspectorView { text_width: f32, mut x_position: f32, distance: f32, - size: Size, + size: ScreenSize, alpha: f32, render_numbers: bool, ) { let color = theme.profiler.line_color.multiply_alpha_f32(alpha); - while x_position < size.x { - renderer.render_rectangle( - Position::new(x_position, 0.0), - Size::new(*theme.profiler.line_width * *renderer.interface_settings.scaling, size.y), - Vector4::zero(), - color, - ); + while x_position < size.width { + let line_position = ScreenPosition { + left: x_position, + top: 0.0, + }; + let line_size = ScreenSize { + width: *theme.profiler.line_width * *renderer.interface_settings.scaling, + height: size.height, + }; + + renderer.render_rectangle(line_position, line_size, CornerRadius::default(), color); if render_numbers { - let offset = Position::new( - x_position + (distance - text_width) / 2.0, - size.y - *theme.profiler.distance_text_offset * *renderer.interface_settings.scaling, - ); + let offset = ScreenPosition { + left: x_position + (distance - text_width) / 2.0, + top: size.height - *theme.profiler.distance_text_offset * *renderer.interface_settings.scaling, + }; renderer.renderer.render_text( renderer.render_target, text, renderer.position + offset, - renderer.clip_size, + renderer.screen_clip, *theme.profiler.line_color, *theme.profiler.distance_text_size * *renderer.interface_settings.scaling, ); @@ -96,7 +99,10 @@ impl FrameInspectorView { let scaled_bar_gap = theme.profiler.bar_gap.x * *renderer.interface_settings.scaling; let color = color_lookup.get_color(measurement.name); - let text_offset = *theme.profiler.bar_text_offset * *renderer.interface_settings.scaling; + let text_offset = ScreenPosition { + left: theme.profiler.bar_text_offset.x * *renderer.interface_settings.scaling, + top: theme.profiler.bar_text_offset.y * *renderer.interface_settings.scaling, + }; let x_position = measurement.start_time.saturating_duration_since(start_time).as_secs_f32() * unit + scaled_bar_gap; let x_size = measurement.end_time.saturating_duration_since(start_time).as_secs_f32() * unit - x_position - scaled_bar_gap; let x_size = x_size.min(total_width - x_position - scaled_bar_gap); @@ -107,10 +113,19 @@ impl FrameInspectorView { return; } + let block_position = ScreenPosition { + left: x_position, + top: y_position, + }; + let block_size = ScreenSize { + width: x_size, + height: y_size, + }; + renderer.render_rectangle( - Position::new(x_position, y_position), - Size::new(x_size, y_size), - *theme.profiler.bar_border_radius, + block_position, + block_size, + (*theme.profiler.bar_corner_radius).into(), color.multiply_alpha_f32(alpha), ); @@ -122,18 +137,25 @@ impl FrameInspectorView { if alpha > VISIBILITY_THRESHHOLD { let text = format!("{} ({:?})", measurement.name, measurement.end_time - measurement.start_time); - let clip_size = ClipSize::new( - renderer.clip_size.x + x_position, - renderer.clip_size.y + y_position, - renderer.clip_size.x + x_position + x_size, - renderer.clip_size.y + y_position + y_size, - ); + let screen_clip = ScreenClip { + left: renderer.screen_clip.left + x_position, + top: renderer.screen_clip.top + y_position, + right: renderer.screen_clip.left + x_position + x_size, + bottom: renderer.screen_clip.top + y_position + y_size, + }; + + let text_position = renderer.position + + ScreenPosition { + left: x_position, + top: y_position, + } + + text_offset; renderer.renderer.render_text( renderer.render_target, &text, - renderer.position + Position::new(x_position, y_position) + text_offset, - clip_size, + text_position, + screen_clip, theme.profiler.bar_text_color.multiply_alpha_f32(alpha), *theme.profiler.bar_text_size * *renderer.interface_settings.scaling, ); @@ -173,7 +195,7 @@ impl Element for FrameInspectorView { self.state.resolve(placement_resolver, size_constraint); } - fn hovered_element(&self, mouse_position: Position, mouse_mode: &MouseInputMode) -> HoverInformation { + fn hovered_element(&self, mouse_position: ScreenPosition, mouse_mode: &MouseInputMode) -> HoverInformation { match mouse_mode { MouseInputMode::None => self.state.hovered_element(mouse_position), _ => HoverInformation::Missed, @@ -184,7 +206,7 @@ impl Element for FrameInspectorView { const ZOOM_SPEED: f32 = 0.004; let viewed_duration = self.measurement.total_time_taken() - (self.start_offset + self.end_offset); - let side_bias = (1.0 / self.state.cached_size.x) * self.state.mouse_position.get().x; + let side_bias = (1.0 / self.state.cached_size.width) * self.state.mouse_position.get().left; let total_offset = viewed_duration.mul_f32(delta.abs() * ZOOM_SPEED); if delta.is_sign_negative() { @@ -205,8 +227,8 @@ impl Element for FrameInspectorView { _state_provider: &StateProvider, interface_settings: &InterfaceSettings, theme: &InterfaceTheme, - parent_position: Position, - clip_size: ClipSize, + parent_position: ScreenPosition, + screen_clip: ScreenClip, _hovered_element: Option<&dyn Element>, _focused_element: Option<&dyn Element>, _mouse_mode: &MouseInputMode, @@ -218,9 +240,9 @@ impl Element for FrameInspectorView { let mut renderer = self .state - .element_renderer(render_target, renderer, interface_settings, parent_position, clip_size); + .element_renderer(render_target, renderer, interface_settings, parent_position, screen_clip); - renderer.render_background(*theme.profiler.border_radius, *theme.profiler.background_color); + renderer.render_background((*theme.profiler.corner_radius).into(), *theme.profiler.background_color); let mut colors = super::ColorLookup::default(); @@ -240,7 +262,7 @@ impl Element for FrameInspectorView { let visibility = Self::interpolate_alpha_smoothed($max, $min, viewed_duration.$alpha_function() as f32); if visibility > VISIBILITY_THRESHHOLD { - let distance = $duration.div_duration_f32(viewed_duration) * self.state.cached_size.x; + let distance = $duration.div_duration_f32(viewed_duration) * self.state.cached_size.width; let offset = ((self.start_offset.$div_function() as f32 / $divider) * -distance) % distance; let text_width = renderer @@ -283,8 +305,8 @@ impl Element for FrameInspectorView { theme, &self.measurement, start_time, - self.state.cached_size.x, - self.state.cached_size.x / viewed_duration.as_secs_f32(), + self.state.cached_size.width, + self.state.cached_size.width / viewed_duration.as_secs_f32(), theme.profiler.bar_gap.y * *interface_settings.scaling, ); } diff --git a/src/interface/elements/values/color.rs b/src/interface/elements/values/color.rs index ab424f84..39e2c99c 100644 --- a/src/interface/elements/values/color.rs +++ b/src/interface/elements/values/color.rs @@ -36,8 +36,8 @@ impl Element for ColorValue { _state_provider: &StateProvider, interface_settings: &InterfaceSettings, theme: &InterfaceTheme, - parent_position: Position, - clip_size: ClipSize, + parent_position: ScreenPosition, + screen_clip: ScreenClip, _hovered_element: Option<&dyn Element>, _focused_element: Option<&dyn Element>, _mouse_mode: &MouseInputMode, @@ -45,15 +45,15 @@ impl Element for ColorValue { ) { let mut renderer = self .state - .element_renderer(render_target, renderer, interface_settings, parent_position, clip_size); + .element_renderer(render_target, renderer, interface_settings, parent_position, screen_clip); - renderer.render_background(*theme.value.border_radius, self.color); + renderer.render_background((*theme.value.corner_radius).into(), self.color); - renderer.render_text( - &self.display, - *theme.value.text_offset, - self.color.invert(), - *theme.value.font_size, - ); + let text_position = ScreenPosition { + left: theme.value.text_offset.x, + top: theme.value.text_offset.y, + }; + + renderer.render_text(&self.display, text_position, self.color.invert(), *theme.value.font_size); } } diff --git a/src/interface/elements/values/mutable/color.rs b/src/interface/elements/values/mutable/color.rs index c04f323c..3099c5ba 100644 --- a/src/interface/elements/values/mutable/color.rs +++ b/src/interface/elements/values/mutable/color.rs @@ -59,7 +59,7 @@ impl Element for MutableColorValue { None } - fn hovered_element(&self, mouse_position: Position, mouse_mode: &MouseInputMode) -> HoverInformation { + fn hovered_element(&self, mouse_position: ScreenPosition, mouse_mode: &MouseInputMode) -> HoverInformation { match mouse_mode { MouseInputMode::None => self.state.hovered_element(mouse_position), _ => HoverInformation::Missed, @@ -81,8 +81,8 @@ impl Element for MutableColorValue { _state_provider: &StateProvider, interface_settings: &InterfaceSettings, theme: &InterfaceTheme, - parent_position: Position, - clip_size: ClipSize, + parent_position: ScreenPosition, + screen_clip: ScreenClip, hovered_element: Option<&dyn Element>, _focused_element: Option<&dyn Element>, _mouse_mode: &MouseInputMode, @@ -90,18 +90,23 @@ impl Element for MutableColorValue { ) { let mut renderer = self .state - .element_renderer(render_target, renderer, interface_settings, parent_position, clip_size); + .element_renderer(render_target, renderer, interface_settings, parent_position, screen_clip); let background_color = match self.is_element_self(hovered_element) { true => self.cached_color.shade(), false => self.cached_color, }; - renderer.render_background(*theme.value.border_radius, background_color); + renderer.render_background((*theme.value.corner_radius).into(), background_color); + + let text_position = ScreenPosition { + left: theme.value.text_offset.x, + top: theme.value.text_offset.y, + }; renderer.render_text( &self.cached_values, - *theme.value.text_offset, + text_position, self.cached_color.invert(), *theme.value.font_size, ); diff --git a/src/interface/elements/values/mutable/number.rs b/src/interface/elements/values/mutable/number.rs index f17c6005..4234d858 100644 --- a/src/interface/elements/values/mutable/number.rs +++ b/src/interface/elements/values/mutable/number.rs @@ -63,7 +63,7 @@ impl<T: Zero + NumOps + NumCast + Copy + PartialOrd + Display + 'static> Element None } - fn hovered_element(&self, mouse_position: Position, mouse_mode: &MouseInputMode) -> HoverInformation { + fn hovered_element(&self, mouse_position: ScreenPosition, mouse_mode: &MouseInputMode) -> HoverInformation { match mouse_mode { MouseInputMode::None => self.state.hovered_element(mouse_position), _ => HoverInformation::Missed, @@ -87,8 +87,8 @@ impl<T: Zero + NumOps + NumCast + Copy + PartialOrd + Display + 'static> Element _state_provider: &StateProvider, interface_settings: &InterfaceSettings, theme: &InterfaceTheme, - parent_position: Position, - clip_size: ClipSize, + parent_position: ScreenPosition, + screen_clip: ScreenClip, hovered_element: Option<&dyn Element>, _focused_element: Option<&dyn Element>, _mouse_mode: &MouseInputMode, @@ -96,18 +96,23 @@ impl<T: Zero + NumOps + NumCast + Copy + PartialOrd + Display + 'static> Element ) { let mut renderer = self .state - .element_renderer(render_target, renderer, interface_settings, parent_position, clip_size); + .element_renderer(render_target, renderer, interface_settings, parent_position, screen_clip); let background_color = match self.is_element_self(hovered_element) { true => *theme.value.hovered_background_color, false => *theme.value.background_color, }; - renderer.render_background(*theme.value.border_radius, background_color); + renderer.render_background((*theme.value.corner_radius).into(), background_color); + + let text_position = ScreenPosition { + left: theme.value.text_offset.x, + top: theme.value.text_offset.y, + }; renderer.render_text( &self.cached_values, - *theme.value.text_offset, + text_position, *theme.value.foreground_color, *theme.value.font_size, ); diff --git a/src/interface/elements/values/mutable/vector.rs b/src/interface/elements/values/mutable/vector.rs index c56ea7f4..a4cff54c 100644 --- a/src/interface/elements/values/mutable/vector.rs +++ b/src/interface/elements/values/mutable/vector.rs @@ -76,7 +76,7 @@ where None } - fn hovered_element(&self, mouse_position: Position, mouse_mode: &MouseInputMode) -> HoverInformation { + fn hovered_element(&self, mouse_position: ScreenPosition, mouse_mode: &MouseInputMode) -> HoverInformation { match mouse_mode { MouseInputMode::None => self.state.hovered_element(mouse_position), _ => HoverInformation::Missed, @@ -102,8 +102,8 @@ where _state_provider: &StateProvider, interface_settings: &InterfaceSettings, theme: &InterfaceTheme, - parent_position: Position, - clip_size: ClipSize, + parent_position: ScreenPosition, + screen_clip: ScreenClip, hovered_element: Option<&dyn Element>, _focused_element: Option<&dyn Element>, _mouse_mode: &MouseInputMode, @@ -111,18 +111,23 @@ where ) { let mut renderer = self .state - .element_renderer(render_target, renderer, interface_settings, parent_position, clip_size); + .element_renderer(render_target, renderer, interface_settings, parent_position, screen_clip); let background_color = match self.is_element_self(hovered_element) { true => *theme.value.hovered_background_color, false => *theme.value.background_color, }; - renderer.render_background(*theme.value.border_radius, background_color); + renderer.render_background((*theme.value.corner_radius).into(), background_color); + + let text_position = ScreenPosition { + left: theme.value.text_offset.x, + top: theme.value.text_offset.y, + }; renderer.render_text( &self.cached_values, - *theme.value.text_offset, + text_position, *theme.value.foreground_color, *theme.value.font_size, ); diff --git a/src/interface/elements/values/quaternion.rs b/src/interface/elements/values/quaternion.rs index 3d433b34..03bcfe8c 100644 --- a/src/interface/elements/values/quaternion.rs +++ b/src/interface/elements/values/quaternion.rs @@ -47,7 +47,7 @@ impl<T: Display> Element for QuaternionValue<T> { interface_settings: &InterfaceSettings, theme: &Theme, parent_position: Position, - clip_size: ClipSize, + screen_clip: ClipSize, _hovered_element: Option<&dyn Element>, _focused_element: Option<&dyn Element>, _second_theme: bool, @@ -55,9 +55,9 @@ impl<T: Display> Element for QuaternionValue<T> { let mut renderer = self .state - .element_renderer(render_target, renderer, interface_settings, parent_position, clip_size); + .element_renderer(render_target, renderer, interface_settings, parent_position, screen_clip); - renderer.render_background(*theme.value.border_radius, *theme.value.hovered_background_color); + renderer.render_background(*theme.value.corner_radius, *theme.value.hovered_background_color); renderer.render_text( &self.display, diff --git a/src/interface/elements/values/string.rs b/src/interface/elements/values/string.rs index 021f74b3..75e80809 100644 --- a/src/interface/elements/values/string.rs +++ b/src/interface/elements/values/string.rs @@ -30,8 +30,8 @@ impl Element for StringValue { _state_provider: &StateProvider, interface_settings: &InterfaceSettings, theme: &InterfaceTheme, - parent_position: Position, - clip_size: ClipSize, + parent_position: ScreenPosition, + screen_clip: ScreenClip, _hovered_element: Option<&dyn Element>, _focused_element: Option<&dyn Element>, _mouse_mode: &MouseInputMode, @@ -39,13 +39,18 @@ impl Element for StringValue { ) { let mut renderer = self .state - .element_renderer(render_target, renderer, interface_settings, parent_position, clip_size); + .element_renderer(render_target, renderer, interface_settings, parent_position, screen_clip); - renderer.render_background(*theme.value.border_radius, *theme.value.hovered_background_color); + renderer.render_background((*theme.value.corner_radius).into(), *theme.value.hovered_background_color); + + let text_position = ScreenPosition { + left: theme.value.text_offset.x, + top: theme.value.text_offset.y, + }; renderer.render_text( &self.value, - *theme.value.text_offset, + text_position, *theme.value.foreground_color, *theme.value.font_size, ); diff --git a/src/interface/elements/values/vector.rs b/src/interface/elements/values/vector.rs index 24ae68e9..4e95dde7 100644 --- a/src/interface/elements/values/vector.rs +++ b/src/interface/elements/values/vector.rs @@ -61,7 +61,7 @@ where interface_settings: &InterfaceSettings, theme: &Theme, parent_position: Position, - clip_size: ClipSize, + screen_clip: ClipSize, _hovered_element: Option<&dyn Element>, _focused_element: Option<&dyn Element>, _second_theme: bool, @@ -69,9 +69,9 @@ where let mut renderer = self .state - .element_renderer(render_target, renderer, interface_settings, parent_position, clip_size); + .element_renderer(render_target, renderer, interface_settings, parent_position, screen_clip); - renderer.render_background(*theme.value.border_radius, *theme.value.hovered_background_color); + renderer.render_background(*theme.value.corner_radius, *theme.value.hovered_background_color); renderer.render_text( &self.display, diff --git a/src/interface/event/action.rs b/src/interface/event/action.rs index 8f7d1526..7e33a7e8 100644 --- a/src/interface/event/action.rs +++ b/src/interface/event/action.rs @@ -1,6 +1,6 @@ use super::{ItemSource, SkillSource}; use crate::input::UserEvent; -use crate::interface::{ChangeEvent, ElementCell, FocusMode, Position, PrototypeWindow, Size, Tracker}; +use crate::interface::{ChangeEvent, ElementCell, FocusMode, PrototypeWindow, ScreenPosition, ScreenSize, Tracker}; use crate::inventory::{Item, Skill}; pub enum ClickAction { @@ -16,8 +16,8 @@ pub enum ClickAction { CloseWindow, OpenPopup { element: ElementCell, - position_tracker: Tracker<Position>, - size_tracker: Tracker<Size>, + position_tracker: Tracker<ScreenPosition>, + size_tracker: Tracker<ScreenSize>, }, ClosePopup, } diff --git a/src/interface/layout/constraint.rs b/src/interface/layout/constraint.rs index 93ab7bd8..388f8b93 100644 --- a/src/interface/layout/constraint.rs +++ b/src/interface/layout/constraint.rs @@ -2,7 +2,7 @@ use derive_new::new; use procedural::constraint; use serde::{Deserialize, Serialize}; -use crate::interface::{Dimension, PartialSize, Position, Size}; +use crate::interface::{Dimension, PartialScreenSize, ScreenPosition, ScreenSize}; #[derive(Copy, Clone, Serialize, Deserialize, new)] pub struct DimensionConstraint { @@ -35,28 +35,30 @@ pub struct SizeConstraint { } impl SizeConstraint { - pub fn resolve(&self, available: Size, remaining: Size, scaling: f32) -> PartialSize { - let width = self.width.resolve_width(available.x, remaining.x, scaling); - let width = self.validated_width(width, available.x, remaining.x, scaling); + pub fn resolve(&self, available: ScreenSize, remaining: ScreenSize, scaling: f32) -> PartialScreenSize { + let width = self.width.resolve_width(available.width, remaining.width, scaling); + let width = self.validated_width(width, available.width, remaining.width, scaling); - let mut height = self.height.resolve_height(available.y.into(), remaining.y.into(), scaling); + let mut height = self + .height + .resolve_height(available.height.into(), remaining.height.into(), scaling); if let Some(height) = &mut height { - *height = self.validated_height(*height, available.y.into(), remaining.y.into(), scaling); + *height = self.validated_height(*height, available.height.into(), remaining.height.into(), scaling); } - PartialSize::new(width, height) + PartialScreenSize::new(width, height) } - pub fn resolve_partial(&self, available: PartialSize, remaining: PartialSize, scaling: f32) -> PartialSize { - let width = self.width.resolve_width(available.x, remaining.x, scaling); - let width = self.validated_width(width, available.x, remaining.x, scaling); + pub fn resolve_partial(&self, available: PartialScreenSize, remaining: PartialScreenSize, scaling: f32) -> PartialScreenSize { + let width = self.width.resolve_width(available.width, remaining.width, scaling); + let width = self.validated_width(width, available.width, remaining.width, scaling); - let mut height = self.height.resolve_height(available.y, remaining.y, scaling); + let mut height = self.height.resolve_height(available.height, remaining.height, scaling); if let Some(height) = &mut height { - *height = self.validated_height(*height, available.y, remaining.y, scaling); + *height = self.validated_height(*height, available.height, remaining.height, scaling); } - PartialSize::new(width, height) + PartialScreenSize::new(width, height) } fn validated_width(&self, mut width: f32, available: f32, remaining: f32, scaling: f32) -> f32 { @@ -87,17 +89,19 @@ impl SizeConstraint { height } - pub fn validated_size(&self, size: Size, available: Size, scaling: f32) -> Size { - let width = self.validated_width(size.x, available.x, available.x, scaling); - let height = self.validated_height(size.y, available.y.into(), available.y.into(), scaling); - Size::new(width, height) + pub fn validated_size(&self, size: ScreenSize, available: ScreenSize, scaling: f32) -> ScreenSize { + let width = self.validated_width(size.width, available.width, available.width, scaling); + let height = self.validated_height(size.height, available.height.into(), available.height.into(), scaling); + + ScreenSize { width, height } } - pub fn validated_position(&self, position: Position, size: Size, available: Size) -> Position { + pub fn validated_position(&self, position: ScreenPosition, size: ScreenSize, available: ScreenSize) -> ScreenPosition { let half_size = size / 2.0; - let x = f32::clamp(position.x, -half_size.x, available.x - half_size.x); - let y = f32::clamp(position.y, 0.0, available.y - 30.0); - Position::new(x, y) + let left = f32::clamp(position.left, -half_size.width, available.width - half_size.width); + let top = f32::clamp(position.top, 0.0, available.height - 30.0); + + ScreenPosition { left, top } } } diff --git a/src/interface/layout/mod.rs b/src/interface/layout/mod.rs index f83254ba..1803428c 100644 --- a/src/interface/layout/mod.rs +++ b/src/interface/layout/mod.rs @@ -6,4 +6,4 @@ mod size; pub use self::constraint::{DimensionConstraint, SizeConstraint}; pub use self::dimension::Dimension; pub use self::resolver::PlacementResolver; -pub use self::size::{ClipSize, PartialSize, Position, Size}; +pub use self::size::{CornerRadius, PartialScreenSize, ScreenClip, ScreenPosition, ScreenSize}; diff --git a/src/interface/layout/resolver.rs b/src/interface/layout/resolver.rs index 8a4b33bd..773c2e6d 100644 --- a/src/interface/layout/resolver.rs +++ b/src/interface/layout/resolver.rs @@ -3,7 +3,7 @@ use std::rc::Rc; use cgmath::Vector2; -use crate::interface::{PartialSize, Position, Size, SizeConstraint}; +use crate::interface::{PartialScreenSize, ScreenPosition, ScreenSize, SizeConstraint}; use crate::loaders::FontLoader; const ELEMENT_THRESHHOLD: f32 = 1.0000; @@ -11,22 +11,28 @@ const REMAINDER_THRESHHOLD: f32 = 0.0001; pub struct PlacementResolver { font_loader: Rc<RefCell<FontLoader>>, - available_space: PartialSize, - base_position: Position, + available_space: PartialScreenSize, + base_position: ScreenPosition, horizontal_accumulator: f32, vertical_offset: f32, total_height: f32, - border: Size, - gaps: Size, + border: ScreenSize, + gaps: ScreenSize, scaling: f32, } impl PlacementResolver { - pub fn new(font_loader: Rc<RefCell<FontLoader>>, mut available_space: PartialSize, border: Size, gaps: Size, scaling: f32) -> Self { - available_space.x -= border.x * scaling * 2.0; - available_space.y = available_space.y.map(|height| height - border.y * scaling * 2.0); + pub fn new( + font_loader: Rc<RefCell<FontLoader>>, + mut available_space: PartialScreenSize, + border: ScreenSize, + gaps: ScreenSize, + scaling: f32, + ) -> Self { + available_space.width -= border.width * scaling * 2.0; + available_space.height = available_space.height.map(|height| height - border.height * scaling * 2.0); - let base_position = border * scaling; + let base_position = ScreenPosition::from_size(border * scaling); let horizontal_accumulator = 0.0; let vertical_offset = 0.0; let total_height = 0.0; @@ -44,9 +50,9 @@ impl PlacementResolver { } } - pub fn derive(&self, mut available_space: PartialSize, offset: Position, border: Size) -> Self { - available_space.x -= offset.x + border.x * self.scaling * 2.0; - available_space.y = available_space.y.map(|height| height - border.y * self.scaling * 2.0); + pub fn derive(&self, mut available_space: PartialScreenSize, offset: ScreenPosition, border: ScreenSize) -> Self { + available_space.width -= offset.left + border.width * self.scaling * 2.0; + available_space.height = available_space.height.map(|height| height - border.height * self.scaling * 2.0); let font_loader = self.font_loader.clone(); let base_position = offset + border * self.scaling; @@ -82,27 +88,27 @@ impl PlacementResolver { .get_text_dimensions(text, font_size * scaling, available_width - text_offset.x * scaling) } - pub fn set_gaps(&mut self, gaps: Size) { + pub fn set_gaps(&mut self, gaps: ScreenSize) { self.gaps = gaps; } - pub fn get_available(&self) -> PartialSize { + pub fn get_available(&self) -> PartialScreenSize { self.available_space } - pub fn get_remaining(&self) -> PartialSize { - let remaining_width = self.available_space.x - self.horizontal_accumulator; + pub fn get_remaining(&self) -> PartialScreenSize { + let remaining_width = self.available_space.width - self.horizontal_accumulator; let remaining_height = self .available_space - .y + .height .map(|height| height - self.total_height - self.vertical_offset); - PartialSize::new(remaining_width, remaining_height) + PartialScreenSize::new(remaining_width, remaining_height) } pub fn newline(&mut self) { - self.total_height += self.vertical_offset + self.gaps.y * self.scaling; - self.base_position.y += self.vertical_offset + self.gaps.y * self.scaling; + self.total_height += self.vertical_offset + self.gaps.height * self.scaling; + self.base_position.top += self.vertical_offset + self.gaps.height * self.scaling; self.horizontal_accumulator = 0.0; self.vertical_offset = 0.0; } @@ -111,10 +117,10 @@ impl PlacementResolver { self.vertical_offset = f32::max(self.vertical_offset, height); } - pub fn allocate(&mut self, size_constraint: &SizeConstraint) -> (PartialSize, Position) { + pub fn allocate(&mut self, size_constraint: &SizeConstraint) -> (PartialScreenSize, ScreenPosition) { let is_width_absolute = size_constraint.width.is_absolute(); let gaps_add = match is_width_absolute { - true => self.gaps.x * 2.0, + true => self.gaps.width * 2.0, false => 0.0, }; @@ -122,7 +128,7 @@ impl PlacementResolver { let mut size = size_constraint.resolve_partial(self.available_space, remaining, self.scaling); let mut gaps_subtract = 0.0; - if remaining.x < size.x - REMAINDER_THRESHHOLD { + if remaining.width < size.width - REMAINDER_THRESHHOLD { self.newline(); remaining = self.get_remaining(); @@ -130,43 +136,43 @@ impl PlacementResolver { size = size_constraint.resolve_partial(self.available_space, remaining, self.scaling); } - size.x = f32::min(size.x, self.available_space.x); + size.width = f32::min(size.width, self.available_space.width); } if self.horizontal_accumulator > ELEMENT_THRESHHOLD { match is_width_absolute { true => {} - false => gaps_subtract += self.gaps.x * self.scaling, + false => gaps_subtract += self.gaps.width * self.scaling, } } - let position = Vector2::new( - self.base_position.x + self.horizontal_accumulator + gaps_subtract, - self.base_position.y, - ); + let position = ScreenPosition { + left: self.base_position.left + self.horizontal_accumulator + gaps_subtract, + top: self.base_position.top, + }; - self.horizontal_accumulator += size.x + gaps_add; + self.horizontal_accumulator += size.width + gaps_add; - if let Some(height) = size.y { + if let Some(height) = size.height { self.register_height(height); } - if remaining.x - size.x > ELEMENT_THRESHHOLD { + if remaining.width - size.width > ELEMENT_THRESHHOLD { match is_width_absolute { true => {} - false => gaps_subtract += self.gaps.x * self.scaling, + false => gaps_subtract += self.gaps.width * self.scaling, } } - size.x -= gaps_subtract; + size.width -= gaps_subtract; (size, position) } - pub fn allocate_right(&mut self, size_constraint: &SizeConstraint) -> (PartialSize, Position) { + pub fn allocate_right(&mut self, size_constraint: &SizeConstraint) -> (PartialScreenSize, ScreenPosition) { let mut remaining = self.get_remaining(); let mut size = size_constraint.resolve_partial(self.available_space, remaining, self.scaling); - if remaining.x < size.x - REMAINDER_THRESHHOLD + self.gaps.x * self.scaling { + if remaining.width < size.width - REMAINDER_THRESHHOLD + self.gaps.width * self.scaling { self.newline(); remaining = self.get_remaining(); @@ -175,14 +181,14 @@ impl PlacementResolver { } } - let position = Vector2::new( - self.base_position.x + (self.available_space.x - size.x - self.gaps.x * self.scaling), - self.base_position.y, - ); + let position = ScreenPosition { + left: self.base_position.left + (self.available_space.width - size.width - self.gaps.width * self.scaling), + top: self.base_position.top, + }; - self.horizontal_accumulator += remaining.x; + self.horizontal_accumulator += remaining.width; - if let Some(height) = size.y { + if let Some(height) = size.height { self.register_height(height); } @@ -190,6 +196,6 @@ impl PlacementResolver { } pub fn final_height(self) -> f32 { - self.total_height + self.vertical_offset + self.border.y * self.scaling + self.total_height + self.vertical_offset + self.border.height * self.scaling } } diff --git a/src/interface/layout/size.rs b/src/interface/layout/size.rs index 7e62846b..e2ebb22b 100644 --- a/src/interface/layout/size.rs +++ b/src/interface/layout/size.rs @@ -1,35 +1,278 @@ -use cgmath::{Vector2, Vector4}; use derive_new::new; +use serde::{Deserialize, Serialize}; -pub type Size = Vector2<f32>; -pub type ClipSize = Vector4<f32>; -pub type Position = Vector2<f32>; +macro_rules! implement_ops { + ($name:ident, $x:ident, $y:ident) => { + impl $name { + pub fn uniform(value: f32) -> Self { + Self { $x: value, $y: value } + } + } + + impl std::ops::AddAssign<$name> for $name { + fn add_assign(&mut self, rhs: Self) { + self.$x += rhs.$x; + self.$y += rhs.$y; + } + } + + impl std::ops::SubAssign<$name> for $name { + fn sub_assign(&mut self, rhs: Self) { + self.$x -= rhs.$x; + self.$y -= rhs.$y; + } + } + + impl std::ops::Add<$name> for $name { + type Output = Self; + + fn add(self, rhs: Self) -> Self { + Self { + $x: self.$x + rhs.$x, + $y: self.$y + rhs.$y, + } + } + } + + impl std::ops::Div<f32> for $name { + type Output = Self; + + fn div(self, rhs: f32) -> Self { + Self { + $x: self.$x / rhs, + $y: self.$y / rhs, + } + } + } + + impl std::ops::Div<ScreenSize> for $name { + type Output = Self; + + fn div(self, rhs: ScreenSize) -> Self { + Self { + $x: self.$x / rhs.width, + $y: self.$y / rhs.height, + } + } + } + + impl std::ops::Mul<f32> for $name { + type Output = Self; + + fn mul(self, rhs: f32) -> Self { + Self { + $x: self.$x * rhs, + $y: self.$y * rhs, + } + } + } + + impl From<$name> for [f32; 2] { + fn from(value: $name) -> Self { + [value.$x, value.$y] + } + } + }; +} + +/// The position as seen on screen. +#[derive(Debug, Clone, Copy, Default, PartialEq, Serialize, Deserialize)] +pub struct ScreenPosition { + pub left: f32, + pub top: f32, +} + +impl ScreenPosition { + pub fn from_size(ScreenSize { width, height }: ScreenSize) -> Self { + Self { left: width, top: height } + } + + pub fn only_top(top: f32) -> Self { + Self { left: 0.0, top } + } +} + +implement_ops!(ScreenPosition, left, top); + +impl std::ops::Sub<ScreenPosition> for ScreenPosition { + type Output = ScreenSize; + + fn sub(self, rhs: ScreenPosition) -> ScreenSize { + ScreenSize { + width: self.left - rhs.left, + height: self.top - rhs.top, + } + } +} + +impl std::ops::AddAssign<ScreenSize> for ScreenPosition { + fn add_assign(&mut self, rhs: ScreenSize) { + self.left += rhs.width; + self.top += rhs.height; + } +} + +/// The size as seen on screen. +#[derive(Debug, Clone, Copy, Default, PartialEq, Serialize, Deserialize)] +pub struct ScreenSize { + pub width: f32, + pub height: f32, +} + +impl ScreenSize { + pub fn only_width(width: f32) -> Self { + Self { width, height: 0.0 } + } +} + +implement_ops!(ScreenSize, width, height); + +impl std::ops::Sub<ScreenSize> for ScreenSize { + type Output = Self; + + fn sub(self, rhs: ScreenSize) -> Self { + Self { + width: self.width - rhs.width, + height: self.height - rhs.height, + } + } +} + +impl std::ops::Add<ScreenPosition> for ScreenSize { + type Output = ScreenPosition; + + fn add(self, rhs: ScreenPosition) -> ScreenPosition { + ScreenPosition { + left: self.width + rhs.left, + top: self.height + rhs.top, + } + } +} + +impl std::ops::Add<ScreenSize> for ScreenPosition { + type Output = ScreenPosition; + + fn add(self, rhs: ScreenSize) -> ScreenPosition { + ScreenPosition { + left: self.left + rhs.width, + top: self.top + rhs.height, + } + } +} + +impl std::ops::Sub<ScreenPosition> for ScreenSize { + type Output = ScreenPosition; + + fn sub(self, rhs: ScreenPosition) -> ScreenPosition { + ScreenPosition { + left: self.width - rhs.left, + top: self.height - rhs.top, + } + } +} + +impl std::ops::Sub<ScreenSize> for ScreenPosition { + type Output = ScreenPosition; + + fn sub(self, rhs: ScreenSize) -> ScreenPosition { + ScreenPosition { + left: self.left - rhs.width, + top: self.top - rhs.height, + } + } +} + +#[derive(Debug, Clone, Copy, Default, PartialEq, Serialize, Deserialize)] +pub struct ScreenClip { + pub left: f32, + pub right: f32, + pub top: f32, + pub bottom: f32, +} + +impl From<ScreenClip> for [f32; 4] { + fn from(val: ScreenClip) -> Self { + [val.left, val.top, val.right, val.bottom] + } +} #[derive(Copy, Clone, new)] -pub struct PartialSize { - pub x: f32, - pub y: Option<f32>, +pub struct PartialScreenSize { + pub width: f32, + pub height: Option<f32>, +} + +impl PartialScreenSize { + pub fn finalize(self) -> ScreenSize { + let width = self.width; + let height = self.height.expect("element cannot have flexible height"); + + ScreenSize { width, height } + } + + pub fn finalize_or(self, height: f32) -> ScreenSize { + let width = self.width; + let height = self.height.unwrap_or(height); + + ScreenSize { width, height } + } +} + +impl From<ScreenSize> for PartialScreenSize { + fn from(size: ScreenSize) -> Self { + Self { + width: size.width, + height: Some(size.height), + } + } +} + +#[derive(Debug, Clone, Copy, Default, PartialEq, Serialize, Deserialize)] +pub struct CornerRadius { + pub top_left: f32, + pub top_right: f32, + pub bottom_left: f32, + pub bottom_right: f32, +} + +impl CornerRadius { + pub fn uniform(value: f32) -> Self { + Self { + top_left: value, + top_right: value, + bottom_left: value, + bottom_right: value, + } + } } -impl PartialSize { - pub fn finalize(self) -> Vector2<f32> { - let x = self.x; - let y = self.y.expect("element cannot have flexible height"); - Vector2::new(x, y) +impl std::ops::Mul<f32> for CornerRadius { + type Output = Self; + + fn mul(self, rhs: f32) -> Self { + Self { + top_left: self.top_left * rhs, + top_right: self.top_right * rhs, + bottom_left: self.bottom_left * rhs, + bottom_right: self.bottom_right * rhs, + } } +} - pub fn finalize_or(self, y: f32) -> Vector2<f32> { - let x = self.x; - let y = self.y.unwrap_or(y); - Vector2::new(x, y) +impl From<CornerRadius> for [f32; 4] { + fn from(val: CornerRadius) -> Self { + [val.top_left, val.top_right, val.bottom_right, val.bottom_left] } } -impl From<Size> for PartialSize { - fn from(size: Size) -> Self { +// TODO: Temorary, remove at some point +impl From<cgmath::Vector4<f32>> for CornerRadius { + fn from(val: cgmath::Vector4<f32>) -> Self { Self { - x: size.x, - y: Some(size.y), + top_left: val.x, + top_right: val.y, + bottom_right: val.z, + bottom_left: val.w, } } } diff --git a/src/interface/mod.rs b/src/interface/mod.rs index b984ef16..77b90da0 100644 --- a/src/interface/mod.rs +++ b/src/interface/mod.rs @@ -13,7 +13,6 @@ use std::cell::RefCell; use std::marker::{ConstParamTy, PhantomData}; use std::rc::Rc; -use cgmath::Vector2; use derive_new::new; use option_ext::OptionExt; use procedural::profile; @@ -139,7 +138,7 @@ pub struct Interface { windows: Vec<(Window, PostUpdate<PerWindow>)>, window_cache: WindowCache, interface_settings: InterfaceSettings, - available_space: Size, + available_space: ScreenSize, themes: Themes, dialog_handle: Option<DialogHandle>, mouse_cursor: MouseCursor, @@ -152,7 +151,7 @@ impl Interface { game_file_loader: &mut GameFileLoader, sprite_loader: &mut SpriteLoader, action_loader: &mut ActionLoader, - available_space: Size, + available_space: ScreenSize, ) -> Self { let window_cache = WindowCache::new(); let interface_settings = InterfaceSettings::new(); @@ -297,7 +296,7 @@ impl Interface { // NOTE: If the window got smaller, we need to re-render the entire interface. // If it got bigger, we can just draw over the previous frame. - match previous_size.x > new_size.x || previous_size.y > new_size.y { + match previous_size.width > new_size.width || previous_size.height > new_size.height { true => self.post_update.render(), false => post_update.render(), } @@ -327,13 +326,13 @@ impl Interface { (render_interface, render_window) } - pub fn update_window_size(&mut self, screen_size: Size) { + pub fn update_window_size(&mut self, screen_size: ScreenSize) { self.available_space = screen_size; self.post_update.resolve(); } #[profile("get hovered element")] - pub fn hovered_element(&self, mouse_position: Position, mouse_mode: &MouseInputMode) -> (Option<ElementCell>, Option<usize>) { + pub fn hovered_element(&self, mouse_position: ScreenPosition, mouse_mode: &MouseInputMode) -> (Option<ElementCell>, Option<usize>) { for (window_index, (window, _)) in self.windows.iter().enumerate().rev() { match window.hovered_element(mouse_position, mouse_mode) { HoverInformation::Element(hovered_element) => return (Some(hovered_element), Some(window_index)), @@ -384,7 +383,7 @@ impl Interface { } #[profile] - pub fn drag_element(&mut self, element: &ElementCell, _window_index: usize, mouse_delta: Position) { + pub fn drag_element(&mut self, element: &ElementCell, _window_index: usize, mouse_delta: ScreenPosition) { //let (_window, post_update) = &mut self.windows[window_index]; if let Some(change_event) = element.borrow_mut().drag(mouse_delta) { @@ -418,7 +417,7 @@ impl Interface { } #[profile] - pub fn move_window(&mut self, window_index: usize, offset: Position) { + pub fn move_window(&mut self, window_index: usize, offset: ScreenPosition) { if let Some((window_class, position)) = self.windows[window_index].0.offset(self.available_space, offset) { self.window_cache.update_position(window_class, position); } @@ -427,7 +426,7 @@ impl Interface { } #[profile] - pub fn resize_window(&mut self, window_index: usize, growth: Size) { + pub fn resize_window(&mut self, window_index: usize, growth: ScreenSize) { let (window, post_update) = &mut self.windows[window_index]; let theme = match window.get_theme_kind() { @@ -446,7 +445,7 @@ impl Interface { post_update.resolve(); - if previous_size.x > new_size.x || previous_size.y > new_size.y { + if previous_size.width > new_size.width || previous_size.height > new_size.height { self.post_update.render(); } } @@ -456,7 +455,7 @@ impl Interface { /// re-render a window with transparency will result in re-rendering the /// entire interface. This serves as a single point of truth and simplifies /// the rest of the code. - fn flag_render_windows(&mut self, start_index: usize, area: Option<(Position, Size)>) { + fn flag_render_windows(&mut self, start_index: usize, area: Option<(ScreenPosition, ScreenSize)>) { for window_index in start_index..self.windows.len() { let needs_render = self.windows[window_index].1.needs_render(); let is_hovering = |(position, scale)| self.windows[window_index].0.hovers_area(position, scale); @@ -525,16 +524,21 @@ impl Interface { render_target: &mut <DeferredRenderer as Renderer>::Target, renderer: &DeferredRenderer, text: &str, - mouse_position: Position, + mouse_position: ScreenPosition, ) { - let offset = Vector2::new(text.len() as f32 * -3.0, 20.0); + let offset = ScreenPosition { + left: text.len() as f32 * -3.0, + top: 20.0, + }; + renderer.render_text( render_target, text, - mouse_position + offset + Vector2::new(1.0, 1.0), + mouse_position + offset + ScreenPosition::uniform(1.0), Color::monochrome(0), 12.0, - ); // move variables into theme + ); // TODO: move variables into theme + renderer.render_text(render_target, text, mouse_position + offset, Color::monochrome(255), 12.0); // move variables into theme } @@ -546,10 +550,15 @@ impl Interface { renderer: &DeferredRenderer, frames_per_second: usize, ) { + let text_position = ScreenPosition { + left: self.themes.game.overlay.text_offset.x * *self.interface_settings.scaling, + top: self.themes.game.overlay.text_offset.y * *self.interface_settings.scaling, + }; + renderer.render_text( render_target, &frames_per_second.to_string(), - *self.themes.game.overlay.text_offset * *self.interface_settings.scaling, + text_position, *self.themes.game.overlay.foreground_color, *self.themes.game.overlay.font_size * *self.interface_settings.scaling, ); @@ -560,7 +569,7 @@ impl Interface { &self, render_target: &mut <DeferredRenderer as Renderer>::Target, renderer: &DeferredRenderer, - mouse_position: Position, + mouse_position: ScreenPosition, grabbed: Option<Grabbed>, ) { if !self.mouse_cursor_hidden { @@ -608,8 +617,8 @@ impl Interface { pub fn open_popup( &mut self, element: ElementCell, - position_tracker: Tracker<Position>, - size_tracker: Tracker<Size>, + position_tracker: Tracker<ScreenPosition>, + size_tracker: Tracker<ScreenSize>, window_index: usize, ) { let entry = &mut self.windows[window_index]; diff --git a/src/interface/theme.rs b/src/interface/theme.rs index 351d060c..6fbff1ba 100644 --- a/src/interface/theme.rs +++ b/src/interface/theme.rs @@ -29,7 +29,7 @@ pub struct ButtonTheme { pub hovered_foreground_color: Mutable<Color, Render>, pub disabled_foreground_color: Mutable<Color, Render>, pub debug_foreground_color: Mutable<Color, Render>, - pub border_radius: MutableRange<Vector4<f32>, Render>, + pub corner_radius: MutableRange<Vector4<f32>, Render>, pub icon_offset: MutableRange<Vector2<f32>, Render>, pub icon_size: MutableRange<Vector2<f32>, Render>, pub icon_text_offset: MutableRange<Vector2<f32>, Render>, @@ -48,7 +48,7 @@ impl ThemeDefault<Menu> for ButtonTheme { hovered_foreground_color: Mutable::new(Color::rgb(220, 170, 215)), disabled_foreground_color: Mutable::new(Color::monochrome(140)), debug_foreground_color: Mutable::new(Color::rgb(230, 140, 230)), - border_radius: MutableRange::new(Vector4::from_value(26.0), Vector4::from_value(0.0), Vector4::from_value(30.0)), + corner_radius: MutableRange::new(Vector4::from_value(26.0), Vector4::from_value(0.0), Vector4::from_value(30.0)), icon_offset: MutableRange::new(Vector2::new(7.0, 2.5), Vector2::zero(), Vector2::new(20.0, 20.0)), icon_size: MutableRange::new(Vector2::new(16.0, 16.0), Vector2::zero(), Vector2::new(20.0, 20.0)), icon_text_offset: MutableRange::new(Vector2::new(40.0, 4.0), Vector2::zero(), Vector2::new(100.0, 20.0)), @@ -69,7 +69,7 @@ impl ThemeDefault<Main> for ButtonTheme { hovered_foreground_color: Mutable::new(Color::rgb(220, 170, 215)), disabled_foreground_color: Mutable::new(Color::monochrome(140)), debug_foreground_color: Mutable::new(Color::rgb(230, 140, 230)), - border_radius: MutableRange::new(Vector4::from_value(6.0), Vector4::from_value(0.0), Vector4::from_value(30.0)), + corner_radius: MutableRange::new(Vector4::from_value(6.0), Vector4::from_value(0.0), Vector4::from_value(30.0)), icon_offset: MutableRange::new(Vector2::new(7.0, 2.5), Vector2::zero(), Vector2::new(20.0, 20.0)), icon_size: MutableRange::new(Vector2::new(10.0, 10.0), Vector2::zero(), Vector2::new(20.0, 20.0)), icon_text_offset: MutableRange::new(Vector2::new(20.0, 1.0), Vector2::zero(), Vector2::new(100.0, 20.0)), @@ -85,8 +85,8 @@ pub struct WindowTheme { pub background_color: Mutable<Color, Render>, pub title_background_color: Mutable<Color, Render>, pub foreground_color: Mutable<Color, Render>, - pub border_radius: MutableRange<Vector4<f32>, Render>, - pub title_border_radius: MutableRange<Vector4<f32>, Render>, + pub corner_radius: MutableRange<Vector4<f32>, Render>, + pub title_corner_radius: MutableRange<Vector4<f32>, Render>, pub border_size: MutableRange<Vector2<f32>, Resolve>, pub text_offset: MutableRange<Vector2<f32>, Render>, pub gaps: MutableRange<Vector2<f32>, Resolve>, @@ -100,8 +100,8 @@ impl ThemeDefault<Menu> for WindowTheme { background_color: Mutable::new(Color::monochrome(30)), title_background_color: Mutable::new(Color::rgba(70, 60, 70, 0)), foreground_color: Mutable::new(Color::rgb(150, 70, 255)), - border_radius: MutableRange::new(Vector4::from_value(30.0), Vector4::from_value(0.0), Vector4::from_value(30.0)), - title_border_radius: MutableRange::new(Vector4::from_value(6.0), Vector4::from_value(0.0), Vector4::from_value(30.0)), + corner_radius: MutableRange::new(Vector4::from_value(30.0), Vector4::from_value(0.0), Vector4::from_value(30.0)), + title_corner_radius: MutableRange::new(Vector4::from_value(6.0), Vector4::from_value(0.0), Vector4::from_value(30.0)), border_size: MutableRange::new(Vector2::new(30.0, 30.0), Vector2::zero(), Vector2::new(30.0, 30.0)), text_offset: MutableRange::new(Vector2::new(5.0, -1.0), Vector2::zero(), Vector2::new(50.0, 30.0)), gaps: MutableRange::new(Vector2::new(9.0, 19.0), Vector2::zero(), Vector2::new(20.0, 20.0)), @@ -117,8 +117,8 @@ impl ThemeDefault<Main> for WindowTheme { background_color: Mutable::new(Color::monochrome(40)), title_background_color: Mutable::new(Color::rgb(170, 60, 70)), foreground_color: Mutable::new(Color::monochrome(160)), - border_radius: MutableRange::new(Vector4::from_value(4.0), Vector4::from_value(0.0), Vector4::from_value(30.0)), - title_border_radius: MutableRange::new(Vector4::from_value(6.0), Vector4::from_value(0.0), Vector4::from_value(30.0)), + corner_radius: MutableRange::new(Vector4::from_value(4.0), Vector4::from_value(0.0), Vector4::from_value(30.0)), + title_corner_radius: MutableRange::new(Vector4::from_value(6.0), Vector4::from_value(0.0), Vector4::from_value(30.0)), border_size: MutableRange::new(Vector2::new(12.0, 6.0), Vector2::zero(), Vector2::new(30.0, 30.0)), text_offset: MutableRange::new(Vector2::new(5.0, -1.0), Vector2::zero(), Vector2::new(50.0, 30.0)), gaps: MutableRange::new(Vector2::new(4.0, 5.0), Vector2::zero(), Vector2::new(20.0, 20.0)), @@ -134,7 +134,7 @@ pub struct ExpandableTheme { pub second_background_color: Mutable<Color, Render>, pub foreground_color: Mutable<Color, Render>, pub hovered_foreground_color: Mutable<Color, Render>, - pub border_radius: MutableRange<Vector4<f32>, Render>, + pub corner_radius: MutableRange<Vector4<f32>, Render>, pub border_size: MutableRange<Vector2<f32>, Resolve>, pub element_offset: MutableRange<Vector2<f32>, Resolve>, pub icon_offset: MutableRange<Vector2<f32>, Render>, @@ -151,7 +151,7 @@ impl ThemeDefault<Menu> for ExpandableTheme { second_background_color: Mutable::new(Color::monochrome(45)), foreground_color: Mutable::new(Color::monochrome(170)), hovered_foreground_color: Mutable::new(Color::rgb(190, 145, 185)), - border_radius: MutableRange::new(Vector4::from_value(6.0), Vector4::from_value(0.0), Vector4::from_value(30.0)), + corner_radius: MutableRange::new(Vector4::from_value(6.0), Vector4::from_value(0.0), Vector4::from_value(30.0)), border_size: MutableRange::new(Vector2::new(5.0, 5.0), Vector2::zero(), Vector2::new(20.0, 20.0)), element_offset: MutableRange::new(Vector2::new(7.0, -2.0), Vector2::new(-10.0, -10.0), Vector2::new(30.0, 30.0)), icon_offset: MutableRange::new(Vector2::new(6.0, 5.0), Vector2::zero(), Vector2::new(30.0, 50.0)), @@ -170,7 +170,7 @@ impl ThemeDefault<Main> for ExpandableTheme { second_background_color: Mutable::new(Color::monochrome(45)), foreground_color: Mutable::new(Color::monochrome(170)), hovered_foreground_color: Mutable::new(Color::rgb(190, 145, 185)), - border_radius: MutableRange::new(Vector4::from_value(6.0), Vector4::from_value(0.0), Vector4::from_value(30.0)), + corner_radius: MutableRange::new(Vector4::from_value(6.0), Vector4::from_value(0.0), Vector4::from_value(30.0)), border_size: MutableRange::new(Vector2::new(5.0, 5.0), Vector2::zero(), Vector2::new(20.0, 20.0)), element_offset: MutableRange::new(Vector2::new(7.0, -2.0), Vector2::new(-10.0, -10.0), Vector2::new(30.0, 30.0)), icon_offset: MutableRange::new(Vector2::new(6.0, 5.0), Vector2::zero(), Vector2::new(30.0, 50.0)), @@ -186,7 +186,7 @@ impl ThemeDefault<Main> for ExpandableTheme { pub struct LabelTheme { pub background_color: Mutable<Color, Render>, pub foreground_color: Mutable<Color, Render>, - pub border_radius: MutableRange<Vector4<f32>, Render>, + pub corner_radius: MutableRange<Vector4<f32>, Render>, pub text_offset: MutableRange<Vector2<f32>, Render>, pub font_size: MutableRange<f32, Render>, pub size_constraint: SizeConstraint, @@ -197,7 +197,7 @@ impl ThemeDefault<Menu> for LabelTheme { Self { background_color: Mutable::new(Color::monochrome(130)), foreground_color: Mutable::new(Color::monochrome(255)), - border_radius: MutableRange::new(Vector4::from_value(6.0), Vector4::from_value(0.0), Vector4::from_value(30.0)), + corner_radius: MutableRange::new(Vector4::from_value(6.0), Vector4::from_value(0.0), Vector4::from_value(30.0)), text_offset: MutableRange::new(Vector2::new(5.0, 0.0), Vector2::from_value(-10.0), Vector2::from_value(20.0)), font_size: MutableRange::new(14.0, 6.0, 30.0), size_constraint: constraint!(120 > 50% < 300, 0), @@ -210,7 +210,7 @@ impl ThemeDefault<Main> for LabelTheme { Self { background_color: Mutable::new(Color::monochrome(130)), foreground_color: Mutable::new(Color::monochrome(255)), - border_radius: MutableRange::new(Vector4::from_value(6.0), Vector4::from_value(0.0), Vector4::from_value(30.0)), + corner_radius: MutableRange::new(Vector4::from_value(6.0), Vector4::from_value(0.0), Vector4::from_value(30.0)), text_offset: MutableRange::new(Vector2::new(5.0, 0.0), Vector2::from_value(-10.0), Vector2::from_value(20.0)), font_size: MutableRange::new(14.0, 6.0, 30.0), size_constraint: constraint!(120 > 50% < 300, 0), @@ -223,7 +223,7 @@ pub struct ValueTheme { pub background_color: Mutable<Color, Render>, pub hovered_background_color: Mutable<Color, Render>, pub foreground_color: Mutable<Color, Render>, - pub border_radius: MutableRange<Vector4<f32>, Render>, + pub corner_radius: MutableRange<Vector4<f32>, Render>, pub text_offset: MutableRange<Vector2<f32>, Render>, pub font_size: MutableRange<f32, Render>, pub size_constraint: SizeConstraint, @@ -235,7 +235,7 @@ impl ThemeDefault<Menu> for ValueTheme { background_color: Mutable::new(Color::rgb(100, 100, 100)), hovered_background_color: Mutable::new(Color::rgb(130, 100, 120)), foreground_color: Mutable::new(Color::rgb(220, 220, 220)), - border_radius: MutableRange::new(Vector4::from_value(6.0), Vector4::from_value(0.0), Vector4::from_value(30.0)), + corner_radius: MutableRange::new(Vector4::from_value(6.0), Vector4::from_value(0.0), Vector4::from_value(30.0)), text_offset: MutableRange::new(Vector2::new(5.0, 0.0), Vector2::from_value(-10.0), Vector2::from_value(20.0)), font_size: MutableRange::new(14.0, 6.0, 30.0), size_constraint: constraint!(60 > !, 14), @@ -249,7 +249,7 @@ impl ThemeDefault<Main> for ValueTheme { background_color: Mutable::new(Color::rgb(100, 100, 100)), hovered_background_color: Mutable::new(Color::rgb(130, 100, 120)), foreground_color: Mutable::new(Color::rgb(220, 220, 220)), - border_radius: MutableRange::new(Vector4::from_value(6.0), Vector4::from_value(0.0), Vector4::from_value(30.0)), + corner_radius: MutableRange::new(Vector4::from_value(6.0), Vector4::from_value(0.0), Vector4::from_value(30.0)), text_offset: MutableRange::new(Vector2::new(5.0, 0.0), Vector2::from_value(-10.0), Vector2::from_value(20.0)), font_size: MutableRange::new(14.0, 6.0, 30.0), size_constraint: constraint!(60 > !, 14), @@ -262,7 +262,7 @@ pub struct CloseButtonTheme { pub background_color: Mutable<Color, Render>, pub hovered_background_color: Mutable<Color, Render>, pub foreground_color: Mutable<Color, Render>, - pub border_radius: MutableRange<Vector4<f32>, Render>, + pub corner_radius: MutableRange<Vector4<f32>, Render>, pub text_offset: MutableRange<Vector2<f32>, Render>, pub font_size: MutableRange<f32, Render>, pub size_constraint: SizeConstraint, @@ -274,7 +274,7 @@ impl ThemeDefault<Menu> for CloseButtonTheme { background_color: Mutable::new(Color::rgb(200, 100, 100)), hovered_background_color: Mutable::new(Color::rgb(200, 140, 100)), foreground_color: Mutable::new(Color::rgb(220, 220, 220)), - border_radius: MutableRange::new(Vector4::from_value(26.0), Vector4::from_value(0.0), Vector4::from_value(30.0)), + corner_radius: MutableRange::new(Vector4::from_value(26.0), Vector4::from_value(0.0), Vector4::from_value(30.0)), text_offset: MutableRange::new(Vector2::new(8.35, 2.55), Vector2::from_value(-10.0), Vector2::from_value(20.0)), font_size: MutableRange::new(20.0, 6.0, 30.0), size_constraint: constraint!(26, 26), @@ -288,7 +288,7 @@ impl ThemeDefault<Main> for CloseButtonTheme { background_color: Mutable::new(Color::rgb(200, 100, 100)), hovered_background_color: Mutable::new(Color::rgb(200, 140, 100)), foreground_color: Mutable::new(Color::rgb(220, 220, 220)), - border_radius: MutableRange::new(Vector4::from_value(1.0), Vector4::from_value(0.0), Vector4::from_value(30.0)), + corner_radius: MutableRange::new(Vector4::from_value(1.0), Vector4::from_value(0.0), Vector4::from_value(30.0)), text_offset: MutableRange::new(Vector2::new(9.0, 0.0), Vector2::from_value(-10.0), Vector2::from_value(20.0)), font_size: MutableRange::new(12.0, 6.0, 30.0), size_constraint: constraint!(25, 12), @@ -351,7 +351,7 @@ pub struct InputTheme { pub text_color: Mutable<Color, Render>, pub ghost_text_color: Mutable<Color, Render>, pub focused_text_color: Mutable<Color, Render>, - pub border_radius: MutableRange<Vector4<f32>, Render>, + pub corner_radius: MutableRange<Vector4<f32>, Render>, pub font_size: MutableRange<f32, Render>, pub text_offset: MutableRange<Vector2<f32>, Render>, pub cursor_offset: MutableRange<f32, Render>, @@ -368,7 +368,7 @@ impl ThemeDefault<Menu> for InputTheme { text_color: Mutable::new(Color::monochrome(200)), ghost_text_color: Mutable::new(Color::monochrome(100)), focused_text_color: Mutable::new(Color::monochrome(200)), - border_radius: MutableRange::new(Vector4::from_value(26.0), Vector4::from_value(0.0), Vector4::from_value(30.0)), + corner_radius: MutableRange::new(Vector4::from_value(26.0), Vector4::from_value(0.0), Vector4::from_value(30.0)), font_size: MutableRange::new(15.0, 6.0, 50.0), text_offset: MutableRange::new(Vector2::new(15.0, 6.0), Vector2::from_value(0.0), Vector2::from_value(50.0)), cursor_offset: MutableRange::new(2.0, 0.0, 10.0), @@ -387,7 +387,7 @@ impl ThemeDefault<Main> for InputTheme { text_color: Mutable::new(Color::monochrome(200)), ghost_text_color: Mutable::new(Color::monochrome(100)), focused_text_color: Mutable::new(Color::monochrome(200)), - border_radius: MutableRange::new(Vector4::from_value(6.0), Vector4::from_value(0.0), Vector4::from_value(30.0)), + corner_radius: MutableRange::new(Vector4::from_value(6.0), Vector4::from_value(0.0), Vector4::from_value(30.0)), font_size: MutableRange::new(14.0, 6.0, 50.0), text_offset: MutableRange::new(Vector2::new(4.0, 0.0), Vector2::from_value(0.0), Vector2::from_value(50.0)), cursor_offset: MutableRange::new(2.0, 0.0, 10.0), @@ -437,12 +437,12 @@ impl Default for CursorTheme { #[derive(Serialize, Deserialize, PrototypeElement)] pub struct ProfilerTheme { pub background_color: Mutable<Color, Render>, - pub border_radius: MutableRange<Vector4<f32>, Render>, + pub corner_radius: MutableRange<Vector4<f32>, Render>, pub line_color: Mutable<Color, Render>, pub line_width: MutableRange<f32, Render>, pub bar_height: MutableRange<f32, Render>, pub bar_gap: MutableRange<Vector2<f32>, Render>, - pub bar_border_radius: MutableRange<Vector4<f32>, Render>, + pub bar_corner_radius: MutableRange<Vector4<f32>, Render>, pub bar_text_color: Mutable<Color, Render>, pub bar_text_size: MutableRange<f32, Render>, pub bar_text_offset: MutableRange<Vector2<f32>, Render>, @@ -454,12 +454,12 @@ impl ThemeDefault<Menu> for ProfilerTheme { fn default() -> Self { Self { background_color: Mutable::new(Color::monochrome(55)), - border_radius: MutableRange::new(Vector4::from_value(2.0), Vector4::from_value(0.0), Vector4::from_value(30.0)), + corner_radius: MutableRange::new(Vector4::from_value(2.0), Vector4::from_value(0.0), Vector4::from_value(30.0)), line_color: Mutable::new(Color::rgb(80, 90, 80)), line_width: MutableRange::new(2.0, 0.5, 4.0), bar_height: MutableRange::new(15.0, 5.0, 30.0), bar_gap: MutableRange::new(Vector2::new(1.0, 5.0), Vector2::from_value(0.0), Vector2::new(10.0, 20.0)), - bar_border_radius: MutableRange::new(Vector4::from_value(0.0), Vector4::from_value(0.0), Vector4::from_value(15.0)), + bar_corner_radius: MutableRange::new(Vector4::from_value(0.0), Vector4::from_value(0.0), Vector4::from_value(15.0)), bar_text_color: Mutable::new(Color::monochrome(0)), bar_text_size: MutableRange::new(14.0, 6.0, 50.0), bar_text_offset: MutableRange::new(Vector2::new(7.0, 0.0), Vector2::new(0.0, -10.0), Vector2::new(40.0, 10.0)), @@ -473,12 +473,12 @@ impl ThemeDefault<Main> for ProfilerTheme { fn default() -> Self { Self { background_color: Mutable::new(Color::monochrome(55)), - border_radius: MutableRange::new(Vector4::from_value(2.0), Vector4::from_value(0.0), Vector4::from_value(30.0)), + corner_radius: MutableRange::new(Vector4::from_value(2.0), Vector4::from_value(0.0), Vector4::from_value(30.0)), line_color: Mutable::new(Color::rgb(80, 90, 80)), line_width: MutableRange::new(2.0, 0.5, 4.0), bar_height: MutableRange::new(15.0, 5.0, 30.0), bar_gap: MutableRange::new(Vector2::new(1.0, 5.0), Vector2::from_value(0.0), Vector2::new(10.0, 20.0)), - bar_border_radius: MutableRange::new(Vector4::from_value(0.0), Vector4::from_value(0.0), Vector4::from_value(15.0)), + bar_corner_radius: MutableRange::new(Vector4::from_value(0.0), Vector4::from_value(0.0), Vector4::from_value(15.0)), bar_text_color: Mutable::new(Color::monochrome(0)), bar_text_size: MutableRange::new(14.0, 6.0, 50.0), bar_text_offset: MutableRange::new(Vector2::new(7.0, 0.0), Vector2::new(0.0, -10.0), Vector2::new(40.0, 10.0)), diff --git a/src/interface/windows/account/login.rs b/src/interface/windows/account/login.rs index 990b3de0..89a0a917 100644 --- a/src/interface/windows/account/login.rs +++ b/src/interface/windows/account/login.rs @@ -24,7 +24,7 @@ impl<'a> PrototypeWindow for LoginWindow<'a> { Self::WINDOW_CLASS.into() } - fn to_window(&self, window_cache: &WindowCache, interface_settings: &InterfaceSettings, available_space: Size) -> Window { + fn to_window(&self, window_cache: &WindowCache, interface_settings: &InterfaceSettings, available_space: ScreenSize) -> Window { let mut login_settings = LoginSettings::new(); let options = self diff --git a/src/interface/windows/account/select_server.rs b/src/interface/windows/account/select_server.rs index 9d43f937..59578db5 100644 --- a/src/interface/windows/account/select_server.rs +++ b/src/interface/windows/account/select_server.rs @@ -19,7 +19,7 @@ impl PrototypeWindow for SelectServerWindow { Self::WINDOW_CLASS.into() } - fn to_window(&self, window_cache: &WindowCache, interface_settings: &InterfaceSettings, available_space: Size) -> Window { + fn to_window(&self, window_cache: &WindowCache, interface_settings: &InterfaceSettings, available_space: ScreenSize) -> Window { let elements = self .servers .iter() diff --git a/src/interface/windows/builder.rs b/src/interface/windows/builder.rs index 01310338..c204872d 100644 --- a/src/interface/windows/builder.rs +++ b/src/interface/windows/builder.rs @@ -52,7 +52,7 @@ impl WindowBuilder { self } - pub fn build(self, window_cache: &WindowCache, interface_settings: &InterfaceSettings, available_space: Size) -> Window { + pub fn build(self, window_cache: &WindowCache, interface_settings: &InterfaceSettings, available_space: ScreenSize) -> Window { let WindowBuilder { window_title, window_class, @@ -103,7 +103,7 @@ impl WindowBuilder { let position = cached_position .map(|position| size_constraint.validated_position(position, size, available_space)) - .unwrap_or((available_space - size) / 2.0); + .unwrap_or(ScreenPosition::from_size((available_space - size) / 2.0)); Window { window_class, diff --git a/src/interface/windows/cache.rs b/src/interface/windows/cache.rs index 33b3e74f..1e724220 100644 --- a/src/interface/windows/cache.rs +++ b/src/interface/windows/cache.rs @@ -1,18 +1,17 @@ use std::collections::HashMap; -use cgmath::Vector2; use derive_new::new; use ron::ser::PrettyConfig; use serde::{Deserialize, Serialize}; #[cfg(feature = "debug")] use crate::debug::*; -use crate::interface::{Position, Size}; +use crate::interface::{ScreenPosition, ScreenSize}; #[derive(Serialize, Deserialize, new)] pub struct WindowState { - pub position: Position, - pub size: Size, + pub position: ScreenPosition, + pub size: ScreenSize, } #[derive(Default, Serialize, Deserialize)] @@ -52,7 +51,7 @@ impl WindowCache { std::fs::write("client/window_cache.ron", data).expect("unable to write file"); } - pub fn register_window(&mut self, identifier: &str, position: Position, size: Size) { + pub fn register_window(&mut self, identifier: &str, position: ScreenPosition, size: ScreenSize) { if let Some(entry) = self.entries.get_mut(identifier) { entry.position = position; entry.size = size; @@ -62,19 +61,19 @@ impl WindowCache { } } - pub fn update_position(&mut self, identifier: &str, position: Vector2<f32>) { + pub fn update_position(&mut self, identifier: &str, position: ScreenPosition) { if let Some(entry) = self.entries.get_mut(identifier) { entry.position = position; } } - pub fn update_size(&mut self, identifier: &str, size: Size) { + pub fn update_size(&mut self, identifier: &str, size: ScreenSize) { if let Some(entry) = self.entries.get_mut(identifier) { entry.size = size; } } - pub fn get_window_state(&self, identifier: &str) -> Option<(Position, Size)> { + pub fn get_window_state(&self, identifier: &str) -> Option<(ScreenPosition, ScreenSize)> { self.entries.get(identifier).map(|entry| (entry.position, entry.size)) } } diff --git a/src/interface/windows/character/creation.rs b/src/interface/windows/character/creation.rs index e43ee0d0..e4c060ee 100644 --- a/src/interface/windows/character/creation.rs +++ b/src/interface/windows/character/creation.rs @@ -24,7 +24,7 @@ impl PrototypeWindow for CharacterCreationWindow { Self::WINDOW_CLASS.into() } - fn to_window(&self, window_cache: &WindowCache, interface_settings: &InterfaceSettings, available_space: Size) -> Window { + fn to_window(&self, window_cache: &WindowCache, interface_settings: &InterfaceSettings, available_space: ScreenSize) -> Window { let name = Rc::new(RefCell::new(String::new())); let selector = { diff --git a/src/interface/windows/character/equipment.rs b/src/interface/windows/character/equipment.rs index 323867ee..d31e61ea 100644 --- a/src/interface/windows/character/equipment.rs +++ b/src/interface/windows/character/equipment.rs @@ -17,7 +17,7 @@ impl PrototypeWindow for EquipmentWindow { Self::WINDOW_CLASS.into() } - fn to_window(&self, window_cache: &WindowCache, interface_settings: &InterfaceSettings, available_space: Size) -> Window { + fn to_window(&self, window_cache: &WindowCache, interface_settings: &InterfaceSettings, available_space: ScreenSize) -> Window { let elements = vec![EquipmentContainer::new(self.items.clone()).wrap()]; WindowBuilder::default() diff --git a/src/interface/windows/character/hotbar.rs b/src/interface/windows/character/hotbar.rs index 35c11dd8..87ffb872 100644 --- a/src/interface/windows/character/hotbar.rs +++ b/src/interface/windows/character/hotbar.rs @@ -17,7 +17,7 @@ impl PrototypeWindow for HotbarWindow { Self::WINDOW_CLASS.into() } - fn to_window(&self, window_cache: &WindowCache, interface_settings: &InterfaceSettings, available_space: Size) -> Window { + fn to_window(&self, window_cache: &WindowCache, interface_settings: &InterfaceSettings, available_space: ScreenSize) -> Window { let elements = vec![HotbarContainer::new(self.skills.clone()).wrap()]; WindowBuilder::default() diff --git a/src/interface/windows/character/inventory.rs b/src/interface/windows/character/inventory.rs index 826950fc..ce4db2ea 100644 --- a/src/interface/windows/character/inventory.rs +++ b/src/interface/windows/character/inventory.rs @@ -17,7 +17,7 @@ impl PrototypeWindow for InventoryWindow { Self::WINDOW_CLASS.into() } - fn to_window(&self, window_cache: &WindowCache, interface_settings: &InterfaceSettings, available_space: Size) -> Window { + fn to_window(&self, window_cache: &WindowCache, interface_settings: &InterfaceSettings, available_space: ScreenSize) -> Window { let elements = vec![InventoryContainer::new(self.items.clone()).wrap()]; WindowBuilder::default() diff --git a/src/interface/windows/character/overview.rs b/src/interface/windows/character/overview.rs index b340caec..5a698e36 100644 --- a/src/interface/windows/character/overview.rs +++ b/src/interface/windows/character/overview.rs @@ -16,7 +16,7 @@ impl PrototypeWindow for CharacterOverviewWindow { Self::WINDOW_CLASS.into() } - fn to_window(&self, window_cache: &WindowCache, interface_settings: &InterfaceSettings, available_space: Size) -> Window { + fn to_window(&self, window_cache: &WindowCache, interface_settings: &InterfaceSettings, available_space: ScreenSize) -> Window { let elements = vec![ /*Text::default() .with_text(|| format!("base level: {}", player.get_base_level())) diff --git a/src/interface/windows/character/selection.rs b/src/interface/windows/character/selection.rs index a29da365..584229b7 100644 --- a/src/interface/windows/character/selection.rs +++ b/src/interface/windows/character/selection.rs @@ -20,7 +20,7 @@ impl PrototypeWindow for CharacterSelectionWindow { Self::WINDOW_CLASS.into() } - fn to_window(&self, window_cache: &WindowCache, interface_settings: &InterfaceSettings, available_space: Size) -> Window { + fn to_window(&self, window_cache: &WindowCache, interface_settings: &InterfaceSettings, available_space: ScreenSize) -> Window { let elements = (0..self.slot_count) .map(|slot| CharacterPreview::new(self.characters.clone(), self.move_request.clone(), slot).wrap()) .collect(); diff --git a/src/interface/windows/character/skill_tree.rs b/src/interface/windows/character/skill_tree.rs index c3c64e82..0f6ab7ad 100644 --- a/src/interface/windows/character/skill_tree.rs +++ b/src/interface/windows/character/skill_tree.rs @@ -17,7 +17,7 @@ impl PrototypeWindow for SkillTreeWindow { Self::WINDOW_CLASS.into() } - fn to_window(&self, window_cache: &WindowCache, interface_settings: &InterfaceSettings, available_space: Size) -> Window { + fn to_window(&self, window_cache: &WindowCache, interface_settings: &InterfaceSettings, available_space: ScreenSize) -> Window { let elements = vec![SkillTreeContainer::new(self.skills.clone()).wrap()]; WindowBuilder::default() diff --git a/src/interface/windows/debug/commands.rs b/src/interface/windows/debug/commands.rs index 4b398b41..aec19cee 100644 --- a/src/interface/windows/debug/commands.rs +++ b/src/interface/windows/debug/commands.rs @@ -17,7 +17,7 @@ impl PrototypeWindow for CommandsWindow { Self::WINDOW_CLASS.into() } - fn to_window(&self, window_cache: &WindowCache, interface_settings: &InterfaceSettings, available_space: Size) -> Window { + fn to_window(&self, window_cache: &WindowCache, interface_settings: &InterfaceSettings, available_space: ScreenSize) -> Window { let input_text = Rc::new(RefCell::new(String::new())); let class_action = { diff --git a/src/interface/windows/debug/inspector.rs b/src/interface/windows/debug/inspector.rs index f3ffbcd4..c5ac99e3 100644 --- a/src/interface/windows/debug/inspector.rs +++ b/src/interface/windows/debug/inspector.rs @@ -14,7 +14,7 @@ impl FrameInspectorWindow { } impl PrototypeWindow for FrameInspectorWindow { - fn to_window(&self, window_cache: &WindowCache, interface_settings: &InterfaceSettings, available_space: Size) -> Window { + fn to_window(&self, window_cache: &WindowCache, interface_settings: &InterfaceSettings, available_space: ScreenSize) -> Window { let elements = vec![FrameInspectorView::new(self.measurement.clone()).wrap()]; WindowBuilder::default() diff --git a/src/interface/windows/debug/maps.rs b/src/interface/windows/debug/maps.rs index d40336c7..e1f2294b 100644 --- a/src/interface/windows/debug/maps.rs +++ b/src/interface/windows/debug/maps.rs @@ -16,7 +16,7 @@ impl PrototypeWindow for MapsWindow { Self::WINDOW_CLASS.into() } - fn to_window(&self, window_cache: &WindowCache, interface_settings: &InterfaceSettings, available_space: Size) -> Window { + fn to_window(&self, window_cache: &WindowCache, interface_settings: &InterfaceSettings, available_space: ScreenSize) -> Window { let map_warps = [ ("geffen", Vector2::new(119, 59)), ("alberta", Vector2::new(28, 234)), diff --git a/src/interface/windows/debug/packet.rs b/src/interface/windows/debug/packet.rs index 94a89c8d..7d7e73d1 100644 --- a/src/interface/windows/debug/packet.rs +++ b/src/interface/windows/debug/packet.rs @@ -29,7 +29,7 @@ impl<const N: usize> PrototypeWindow for PacketWindow<N> { Self::WINDOW_CLASS.into() } - fn to_window(&self, window_cache: &WindowCache, interface_settings: &InterfaceSettings, available_space: Size) -> Window { + fn to_window(&self, window_cache: &WindowCache, interface_settings: &InterfaceSettings, available_space: ScreenSize) -> Window { let elements = vec![PacketView::new(self.packets.clone(), self.show_pings.new_remote()).wrap()]; let clear_selector = { diff --git a/src/interface/windows/debug/profiler.rs b/src/interface/windows/debug/profiler.rs index da5a2637..6d831848 100644 --- a/src/interface/windows/debug/profiler.rs +++ b/src/interface/windows/debug/profiler.rs @@ -23,7 +23,7 @@ impl PrototypeWindow for ProfilerWindow { Self::WINDOW_CLASS.into() } - fn to_window(&self, window_cache: &WindowCache, interface_settings: &InterfaceSettings, available_space: Size) -> Window { + fn to_window(&self, window_cache: &WindowCache, interface_settings: &InterfaceSettings, available_space: ScreenSize) -> Window { let toggle_halting = || { let is_profiler_halted = is_profiler_halted(); set_profiler_halted(!is_profiler_halted); diff --git a/src/interface/windows/debug/time.rs b/src/interface/windows/debug/time.rs index 33df7571..62d4a10d 100644 --- a/src/interface/windows/debug/time.rs +++ b/src/interface/windows/debug/time.rs @@ -15,7 +15,7 @@ impl PrototypeWindow for TimeWindow { Self::WINDOW_CLASS.into() } - fn to_window(&self, window_cache: &WindowCache, interface_settings: &InterfaceSettings, available_space: Size) -> Window { + fn to_window(&self, window_cache: &WindowCache, interface_settings: &InterfaceSettings, available_space: ScreenSize) -> Window { // TODO: Unify Set* events into one that takes a specific time let elements = vec![ Button::default().with_text("Set dawn").with_event(UserEvent::SetDawn).wrap(), diff --git a/src/interface/windows/friends/list.rs b/src/interface/windows/friends/list.rs index 4c1b7516..44b7b361 100644 --- a/src/interface/windows/friends/list.rs +++ b/src/interface/windows/friends/list.rs @@ -20,7 +20,7 @@ impl PrototypeWindow for FriendsWindow { Self::WINDOW_CLASS.into() } - fn to_window(&self, window_cache: &WindowCache, interface_settings: &InterfaceSettings, available_space: Size) -> Window { + fn to_window(&self, window_cache: &WindowCache, interface_settings: &InterfaceSettings, available_space: ScreenSize) -> Window { let friend_name = Rc::new(RefCell::new(String::new())); let add_action = { diff --git a/src/interface/windows/friends/request.rs b/src/interface/windows/friends/request.rs index 7f9b3fd4..abe01c27 100644 --- a/src/interface/windows/friends/request.rs +++ b/src/interface/windows/friends/request.rs @@ -15,7 +15,7 @@ impl FriendRequestWindow { } impl PrototypeWindow for FriendRequestWindow { - fn to_window(&self, window_cache: &WindowCache, interface_settings: &InterfaceSettings, available_space: Size) -> Window { + fn to_window(&self, window_cache: &WindowCache, interface_settings: &InterfaceSettings, available_space: ScreenSize) -> Window { let elements = vec![ Text::default() .with_text(format!("^ffaa00{}^000000 wants to be friends with you", self.friend.name)) diff --git a/src/interface/windows/generic/chat.rs b/src/interface/windows/generic/chat.rs index 3afd4eda..ed3ca1f5 100644 --- a/src/interface/windows/generic/chat.rs +++ b/src/interface/windows/generic/chat.rs @@ -24,7 +24,7 @@ impl PrototypeWindow for ChatWindow { ChatWindow::WINDOW_CLASS.into() } - fn to_window(&self, window_cache: &WindowCache, interface_settings: &InterfaceSettings, available_space: Size) -> Window { + fn to_window(&self, window_cache: &WindowCache, interface_settings: &InterfaceSettings, available_space: ScreenSize) -> Window { let input_text = Rc::new(RefCell::new(String::new())); let button_selector = { diff --git a/src/interface/windows/generic/dialog.rs b/src/interface/windows/generic/dialog.rs index 69a35c40..13486e39 100644 --- a/src/interface/windows/generic/dialog.rs +++ b/src/interface/windows/generic/dialog.rs @@ -27,7 +27,7 @@ impl PrototypeWindow for DialogWindow { Self::WINDOW_CLASS.into() } - fn to_window(&self, window_cache: &WindowCache, interface_settings: &InterfaceSettings, available_space: Size) -> Window { + fn to_window(&self, window_cache: &WindowCache, interface_settings: &InterfaceSettings, available_space: ScreenSize) -> Window { let elements = vec![DialogContainer::new(self.elements.new_remote(), self.npc_id).wrap()]; WindowBuilder::default() diff --git a/src/interface/windows/generic/error.rs b/src/interface/windows/generic/error.rs index 715183ba..59f7720b 100644 --- a/src/interface/windows/generic/error.rs +++ b/src/interface/windows/generic/error.rs @@ -10,7 +10,7 @@ pub struct ErrorWindow { } impl PrototypeWindow for ErrorWindow { - fn to_window(&self, window_cache: &WindowCache, interface_settings: &InterfaceSettings, available_space: Size) -> Window { + fn to_window(&self, window_cache: &WindowCache, interface_settings: &InterfaceSettings, available_space: ScreenSize) -> Window { let elements = vec![ Text::default() .with_text(self.message.clone()) diff --git a/src/interface/windows/generic/menu.rs b/src/interface/windows/generic/menu.rs index c1811c3a..f7c2e194 100644 --- a/src/interface/windows/generic/menu.rs +++ b/src/interface/windows/generic/menu.rs @@ -15,7 +15,7 @@ impl PrototypeWindow for MenuWindow { Self::WINDOW_CLASS.into() } - fn to_window(&self, window_cache: &WindowCache, interface_settings: &InterfaceSettings, available_space: Size) -> Window { + fn to_window(&self, window_cache: &WindowCache, interface_settings: &InterfaceSettings, available_space: ScreenSize) -> Window { let elements = vec![ Button::default() .with_text("Graphics settings") diff --git a/src/interface/windows/mod.rs b/src/interface/windows/mod.rs index 354684bb..fb5372e0 100644 --- a/src/interface/windows/mod.rs +++ b/src/interface/windows/mod.rs @@ -10,8 +10,6 @@ mod mutable; mod prototype; mod settings; -use cgmath::{Vector2, Vector4}; - pub use self::account::*; pub use self::builder::WindowBuilder; pub use self::cache::*; @@ -30,11 +28,11 @@ use crate::loaders::FontLoader; pub struct Window { window_class: Option<String>, - position: Vector2<f32>, + position: ScreenPosition, size_constraint: SizeConstraint, - size: Vector2<f32>, + size: ScreenSize, elements: Vec<ElementCell>, - popup_element: Option<(ElementCell, Tracker<Position>, Tracker<Size>)>, + popup_element: Option<(ElementCell, Tracker<ScreenPosition>, Tracker<ScreenSize>)>, closable: bool, background_color: Option<ColorSelector>, theme_kind: ThemeKind, @@ -69,18 +67,27 @@ impl Window { font_loader: Rc<RefCell<FontLoader>>, interface_settings: &InterfaceSettings, theme: &InterfaceTheme, - available_space: Size, - ) -> (Option<&str>, Vector2<f32>, Size) { + available_space: ScreenSize, + ) -> (Option<&str>, ScreenPosition, ScreenSize) { let height = match self.size_constraint.height.is_flexible() { true => None, - false => Some(self.size.y), + false => Some(self.size.height), + }; + + let border_size = ScreenSize { + width: theme.window.border_size.x, + height: theme.window.border_size.y, + }; + let gaps = ScreenSize { + width: theme.window.gaps.x, + height: theme.window.gaps.y, }; let mut placement_resolver = PlacementResolver::new( font_loader.clone(), - PartialSize::new(self.size.x, height), - *theme.window.border_size, - *theme.window.gaps, + PartialScreenSize::new(self.size.width, height), + border_size, + gaps, *interface_settings.scaling, ); @@ -92,11 +99,11 @@ impl Window { let final_height = theme.window.border_size.y + placement_resolver.final_height(); let final_height = self.size_constraint.validated_height( final_height, - available_space.y.into(), - available_space.y.into(), + available_space.height.into(), + available_space.height.into(), *interface_settings.scaling, ); - self.size.y = final_height; + self.size.height = final_height; self.validate_size(interface_settings, available_space); } @@ -107,9 +114,9 @@ impl Window { let mut placement_resolver = PlacementResolver::new( font_loader, - PartialSize::new(size.x, Some(200.0)), - Vector2::new(0.0, 0.0), //*theme.window.border_size, // TODO: Popup - Vector2::new(0.0, 0.0), //*theme.window.gaps, // TODO: Popup + PartialScreenSize::new(size.width, Some(200.0)), + ScreenSize::default(), //*theme.window.border_size, // TODO: Popup + ScreenSize::default(), //*theme.window.gaps, // TODO: Popup *interface_settings.scaling, ); @@ -137,23 +144,24 @@ impl Window { self.elements[0].borrow().restore_focus(self.elements[0].clone()) } - pub fn hovered_element(&self, mouse_position: Vector2<f32>, mouse_mode: &MouseInputMode) -> HoverInformation { - let absolute_position = mouse_position - self.position; + pub fn hovered_element(&self, mouse_position: ScreenPosition, mouse_mode: &MouseInputMode) -> HoverInformation { + let absolute_position = ScreenPosition::from_size(mouse_position - self.position); if let Some((popup, position_tracker, _)) = &self.popup_element { let position = position_tracker().unwrap(); // FIX: Don't unwrap obviously + let position = ScreenPosition::from_size(mouse_position - position); - match popup.borrow().hovered_element(mouse_position - position, mouse_mode) { + match popup.borrow().hovered_element(position, mouse_mode) { HoverInformation::Hovered => return HoverInformation::Element(popup.clone()), HoverInformation::Missed => {} hover_information => return hover_information, } } - if absolute_position.x >= 0.0 - && absolute_position.y >= 0.0 - && absolute_position.x <= self.size.x - && absolute_position.y <= self.size.y + if absolute_position.left >= 0.0 + && absolute_position.top >= 0.0 + && absolute_position.left <= self.size.width + && absolute_position.top <= self.size.height { for element in &self.elements { match element.borrow().hovered_element(absolute_position, mouse_mode) { @@ -169,21 +177,21 @@ impl Window { HoverInformation::Missed } - pub fn get_area(&self) -> (Position, Size) { + pub fn get_area(&self) -> (ScreenPosition, ScreenSize) { (self.position, self.size) } - pub fn hovers_area(&self, position: Position, size: Size) -> bool { + pub fn hovers_area(&self, position: ScreenPosition, size: ScreenSize) -> bool { let self_combined = self.position + self.size; let area_combined = position + size; - self_combined.x > position.x - && self.position.x < area_combined.x - && self_combined.y > position.y - && self.position.y < area_combined.y + self_combined.left > position.left + && self.position.left < area_combined.left + && self_combined.top > position.top + && self.position.top < area_combined.top } - pub fn offset(&mut self, available_space: Size, offset: Position) -> Option<(&str, Position)> { + pub fn offset(&mut self, available_space: ScreenSize, offset: ScreenPosition) -> Option<(&str, ScreenPosition)> { self.position += offset; self.validate_position(available_space); self.window_class @@ -191,7 +199,7 @@ impl Window { .map(|window_class| (window_class.as_str(), self.position)) } - fn validate_position(&mut self, available_space: Size) { + fn validate_position(&mut self, available_space: ScreenSize) { self.position = self.size_constraint.validated_position(self.position, self.size, available_space); } @@ -199,21 +207,21 @@ impl Window { &mut self, interface_settings: &InterfaceSettings, _theme: &InterfaceTheme, - available_space: Size, - growth: Size, - ) -> (Option<&str>, Size) { + available_space: ScreenSize, + growth: ScreenSize, + ) -> (Option<&str>, ScreenSize) { self.size += growth; self.validate_size(interface_settings, available_space); (self.window_class.as_deref(), self.size) } - fn validate_size(&mut self, interface_settings: &InterfaceSettings, available_space: Size) { + fn validate_size(&mut self, interface_settings: &InterfaceSettings, available_space: ScreenSize) { self.size = self .size_constraint .validated_size(self.size, available_space, *interface_settings.scaling); } - pub fn open_popup(&mut self, element: ElementCell, position_tracker: Tracker<Position>, size_tracker: Tracker<Size>) { + pub fn open_popup(&mut self, element: ElementCell, position_tracker: Tracker<ScreenPosition>, size_tracker: Tracker<ScreenSize>) { // NOTE: Very important to link back let weak_element = Rc::downgrade(&element); element.borrow_mut().link_back(weak_element, None); @@ -236,19 +244,19 @@ impl Window { focused_element: Option<&dyn Element>, mouse_mode: &MouseInputMode, ) { - let clip_size = Vector4::new( - self.position.x, - self.position.y, - self.position.x + self.size.x, - self.position.y + self.size.y, - ); + let screen_clip = ScreenClip { + left: self.position.left, + top: self.position.top, + right: self.position.left + self.size.width, + bottom: self.position.top + self.size.height, + }; renderer.render_rectangle( render_target, self.position, self.size, - clip_size, - *theme.window.border_radius, + screen_clip, + (*theme.window.corner_radius).into(), self.get_background_color(theme), ); @@ -260,7 +268,7 @@ impl Window { interface_settings, theme, self.position, - clip_size, + screen_clip, hovered_element, focused_element, mouse_mode, @@ -278,7 +286,7 @@ impl Window { interface_settings, theme, position, - clip_size, + screen_clip, hovered_element, focused_element, mouse_mode, diff --git a/src/interface/windows/mutable/color.rs b/src/interface/windows/mutable/color.rs index 4cd2ffcc..5a036095 100644 --- a/src/interface/windows/mutable/color.rs +++ b/src/interface/windows/mutable/color.rs @@ -12,7 +12,7 @@ pub struct ColorWindow { } impl PrototypeWindow for ColorWindow { - fn to_window(&self, window_cache: &WindowCache, interface_settings: &InterfaceSettings, available_space: Size) -> Window { + fn to_window(&self, window_cache: &WindowCache, interface_settings: &InterfaceSettings, available_space: ScreenSize) -> Window { let rgb_elements = vec![ Headline::new("red".to_string(), Headline::DEFAULT_SIZE).wrap(), Slider::new(unsafe { &(*self.color_pointer).red as *const u8 }, 0, 255, self.change_event).wrap(), diff --git a/src/interface/windows/mutable/number.rs b/src/interface/windows/mutable/number.rs index 575eddd3..c0562dda 100644 --- a/src/interface/windows/mutable/number.rs +++ b/src/interface/windows/mutable/number.rs @@ -17,7 +17,7 @@ pub struct NumberWindow<T> { } impl<T: Zero + NumOps + NumCast + Copy + PartialOrd + 'static> PrototypeWindow for NumberWindow<T> { - fn to_window(&self, window_cache: &WindowCache, interface_settings: &InterfaceSettings, available_space: Size) -> Window { + fn to_window(&self, window_cache: &WindowCache, interface_settings: &InterfaceSettings, available_space: ScreenSize) -> Window { let elements = vec![ Headline::new("value".to_string(), Headline::DEFAULT_SIZE).wrap(), Slider::new( diff --git a/src/interface/windows/mutable/vector.rs b/src/interface/windows/mutable/vector.rs index efa8e4bc..be9c6e49 100644 --- a/src/interface/windows/mutable/vector.rs +++ b/src/interface/windows/mutable/vector.rs @@ -27,7 +27,7 @@ where T: Array, T::Element: Zero + NumOps + NumCast + Copy + PartialOrd + Display + 'static, { - fn to_window(&self, window_cache: &WindowCache, interface_settings: &InterfaceSettings, available_space: Size) -> Window { + fn to_window(&self, window_cache: &WindowCache, interface_settings: &InterfaceSettings, available_space: ScreenSize) -> Window { const LABELS: [char; 4] = ['x', 'y', 'z', 'w']; let mut elements = Vec::new(); diff --git a/src/interface/windows/prototype.rs b/src/interface/windows/prototype.rs index dca1a4d6..bdee874c 100644 --- a/src/interface/windows/prototype.rs +++ b/src/interface/windows/prototype.rs @@ -1,9 +1,9 @@ -use crate::interface::{InterfaceSettings, Size, Window, WindowCache}; +use crate::interface::{InterfaceSettings, ScreenSize, Window, WindowCache}; pub trait PrototypeWindow { fn window_class(&self) -> Option<&str> { None } - fn to_window(&self, window_cache: &WindowCache, interface_settings: &InterfaceSettings, available_space: Size) -> Window; + fn to_window(&self, window_cache: &WindowCache, interface_settings: &InterfaceSettings, available_space: ScreenSize) -> Window; } diff --git a/src/interface/windows/settings/audio.rs b/src/interface/windows/settings/audio.rs index 1f72b95f..593fc77d 100644 --- a/src/interface/windows/settings/audio.rs +++ b/src/interface/windows/settings/audio.rs @@ -1,6 +1,6 @@ use procedural::*; -use crate::interface::{InterfaceSettings, PrototypeWindow, Size, Window, WindowBuilder, WindowCache}; +use crate::interface::{InterfaceSettings, PrototypeWindow, ScreenSize, Window, WindowBuilder, WindowCache}; #[derive(Default)] pub struct AudioSettingsWindow {} @@ -14,7 +14,7 @@ impl PrototypeWindow for AudioSettingsWindow { Self::WINDOW_CLASS.into() } - fn to_window(&self, window_cache: &WindowCache, interface_settings: &InterfaceSettings, available_space: Size) -> Window { + fn to_window(&self, window_cache: &WindowCache, interface_settings: &InterfaceSettings, available_space: ScreenSize) -> Window { let elements = vec![]; WindowBuilder::default() diff --git a/src/interface/windows/settings/graphics.rs b/src/interface/windows/settings/graphics.rs index 8220d76c..0564bf79 100644 --- a/src/interface/windows/settings/graphics.rs +++ b/src/interface/windows/settings/graphics.rs @@ -19,7 +19,7 @@ impl PrototypeWindow for GraphicsSettingsWindow { Self::WINDOW_CLASS.into() } - fn to_window(&self, window_cache: &WindowCache, interface_settings: &InterfaceSettings, available_space: Size) -> Window { + fn to_window(&self, window_cache: &WindowCache, interface_settings: &InterfaceSettings, available_space: ScreenSize) -> Window { let mut elements = vec![ Text::default().with_text("Shadow detail").with_width(dimension!(50%)).wrap(), PickList::default() diff --git a/src/interface/windows/settings/render.rs b/src/interface/windows/settings/render.rs index f0e4ed7e..07d78f74 100644 --- a/src/interface/windows/settings/render.rs +++ b/src/interface/windows/settings/render.rs @@ -108,7 +108,7 @@ impl PrototypeWindow for RenderSettingsWindow { Self::WINDOW_CLASS.into() } - fn to_window(&self, window_cache: &WindowCache, interface_settings: &InterfaceSettings, available_space: Size) -> Window { + fn to_window(&self, window_cache: &WindowCache, interface_settings: &InterfaceSettings, available_space: ScreenSize) -> Window { let elements = vec![ general_expandable(), map_expandable(), diff --git a/src/loaders/action/mod.rs b/src/loaders/action/mod.rs index 0012f436..c7a70d50 100644 --- a/src/loaders/action/mod.rs +++ b/src/loaders/action/mod.rs @@ -2,7 +2,7 @@ use std::collections::HashMap; use std::ops::Mul; use std::sync::Arc; -use cgmath::{Array, Vector2, Vector4}; +use cgmath::{Array, Vector2}; use derive_new::new; use procedural::*; use vulkano::image::view::ImageView; @@ -11,7 +11,7 @@ use super::Sprite; #[cfg(feature = "debug")] use crate::debug::*; use crate::graphics::{Color, Renderer, SpriteRenderer}; -use crate::interface::InterfaceSettings; +use crate::interface::{InterfaceSettings, ScreenClip, ScreenPosition, ScreenSize}; use crate::loaders::{ByteStream, FromBytes, GameFileLoader, MinorFirst, Version, FALLBACK_ACTIONS_FILE}; use crate::network::ClientTick; @@ -116,7 +116,7 @@ impl Actions { renderer: &T, sprite: &Sprite, animation_state: &AnimationState, - position: Vector2<f32>, + position: ScreenPosition, camera_direction: usize, color: Color, interface_settings: &InterfaceSettings, @@ -160,14 +160,31 @@ impl Actions { let zoom2 = sprite_clip.zoom2.unwrap_or_else(|| Vector2::from_value(1.0)); let final_size = dimesions.zip(zoom2, f32::mul) * zoom; - let final_position = position + offset - final_size / 2.0; + let final_position = Vector2::new(position.left, position.top) + offset - final_size / 2.0; + + let final_size = ScreenSize { + width: final_size.x, + height: final_size.y, + }; + + let final_position = ScreenPosition { + left: final_position.x, + top: final_position.y, + }; + + let screen_clip = ScreenClip { + left: 0.0, + top: 0.0, + right: f32::MAX, + bottom: f32::MAX, + }; renderer.render_sprite( render_target, texture.clone(), final_position, final_size, - Vector4::new(0.0, 0.0, f32::MAX, f32::MAX), + screen_clip, color, false, ); diff --git a/src/main.rs b/src/main.rs index ff1da626..f830096d 100644 --- a/src/main.rs +++ b/src/main.rs @@ -315,7 +315,7 @@ fn main() { &mut game_file_loader, &mut sprite_loader, &mut action_loader, - swapchain_holder.window_size_f32(), + swapchain_holder.window_screen_size(), ); let mut focus_state = FocusState::default(); @@ -384,7 +384,10 @@ fn main() { .downcast_ref::<winit::window::Window>() .unwrap() .inner_size(); - interface.update_window_size(Size::new(window_size.width as f32, window_size.height as f32)); + interface.update_window_size(ScreenSize { + width: window_size.width as f32, + height: window_size.height as f32, + }); swapchain_holder.update_window_size(window_size.into()); } Event::WindowEvent { @@ -1240,7 +1243,7 @@ fn main() { let image_number = swapchain_holder.get_image_number(); let directional_shadow_image = directional_shadow_targets[image_number].image.clone(); let screen_target = &mut screen_targets[image_number]; - let window_size = swapchain_holder.window_size_f32(); + let window_size = swapchain_holder.window_screen_size(); let window_size_u32 = swapchain_holder.window_size_u32(); let entities = &entities[..]; #[cfg(feature = "debug")] diff --git a/src/world/entity/mod.rs b/src/world/entity/mod.rs index 2bfd4ad9..6872d1b2 100644 --- a/src/world/entity/mod.rs +++ b/src/world/entity/mod.rs @@ -8,7 +8,7 @@ use vulkano::buffer::Subbuffer; #[cfg(feature = "debug")] use crate::graphics::MarkerRenderer; use crate::graphics::{Camera, DeferredRenderer, EntityRenderer, ModelVertex, Renderer}; -use crate::interface::{GameTheme, InterfaceSettings, PrototypeWindow, Size, Window, WindowCache}; +use crate::interface::{GameTheme, InterfaceSettings, PrototypeWindow, ScreenPosition, ScreenSize, Window, WindowCache}; use crate::loaders::{ActionLoader, Actions, AnimationState, GameFileLoader, ScriptLoader, Sprite, SpriteLoader}; use crate::network::{AccountId, CharacterInformation, ClientTick, EntityData, EntityId, Sex, StatusType}; use crate::world::Map; @@ -821,7 +821,7 @@ impl Player { renderer: &DeferredRenderer, camera: &dyn Camera, theme: &GameTheme, - window_size: Vector2<f32>, + window_size: ScreenSize, ) { let (view_matrix, projection_matrix) = camera.view_projection_matrices(); let clip_space_position = (projection_matrix * view_matrix) * self.common.position.extend(1.0); @@ -830,7 +830,10 @@ impl Player { clip_space_position.y / clip_space_position.w + 1.0, ); let screen_position = screen_position / 2.0; - let final_position = Vector2::new(screen_position.x * window_size.x, screen_position.y * window_size.y + 5.0); + let final_position = ScreenPosition { + left: screen_position.x * window_size.width, + top: screen_position.y * window_size.height + 5.0, + }; let bar_width = *theme.status_bar.player_bar_width; let gap = *theme.status_bar.gap; @@ -839,17 +842,35 @@ impl Player { let mut offset = 0.0; + let background_position = final_position + - ScreenSize { + width: theme.status_bar.border_size.x, + height: theme.status_bar.border_size.y, + } + - ScreenSize::only_width(bar_width / 2.0); + + let background_size = ScreenSize { + width: bar_width, + height: total_height, + } + ScreenSize { + width: theme.status_bar.border_size.x, + height: theme.status_bar.border_size.y, + } * 2.0; + renderer.render_rectangle( render_target, - final_position - *theme.status_bar.border_size - Vector2::new(bar_width / 2.0, 0.0), - Vector2::new(bar_width, total_height) + *theme.status_bar.border_size * 2.0, + background_position, + background_size, *theme.status_bar.background_color, ); renderer.render_bar( render_target, final_position, - Vector2::new(bar_width, *theme.status_bar.health_height), + ScreenSize { + width: bar_width, + height: *theme.status_bar.health_height, + }, *theme.status_bar.player_health_color, self.common.maximum_health_points as f32, self.common.health_points as f32, @@ -859,8 +880,11 @@ impl Player { renderer.render_bar( render_target, - final_position + Vector2::new(0.0, offset), - Vector2::new(bar_width, *theme.status_bar.spell_point_height), + final_position + ScreenPosition::only_top(offset), + ScreenSize { + width: bar_width, + height: *theme.status_bar.spell_point_height, + }, *theme.status_bar.spell_point_color, self.maximum_spell_points as f32, self.spell_points as f32, @@ -870,8 +894,11 @@ impl Player { renderer.render_bar( render_target, - final_position + Vector2::new(0.0, offset), - Vector2::new(bar_width, *theme.status_bar.activity_point_height), + final_position + ScreenPosition::only_top(offset), + ScreenSize { + width: bar_width, + height: *theme.status_bar.activity_point_height, + }, *theme.status_bar.activity_point_color, self.maximum_activity_points as f32, self.activity_points as f32, @@ -921,7 +948,7 @@ impl Npc { renderer: &DeferredRenderer, camera: &dyn Camera, theme: &GameTheme, - window_size: Vector2<f32>, + window_size: ScreenSize, ) { if self.common.entity_type != EntityType::Monster { return; @@ -929,26 +956,42 @@ impl Npc { let (view_matrix, projection_matrix) = camera.view_projection_matrices(); let clip_space_position = (projection_matrix * view_matrix) * self.common.position.extend(1.0); - let screen_position = Vector2::new( - clip_space_position.x / clip_space_position.w + 1.0, - clip_space_position.y / clip_space_position.w + 1.0, - ); + let screen_position = ScreenPosition { + left: clip_space_position.x / clip_space_position.w + 1.0, + top: clip_space_position.y / clip_space_position.w + 1.0, + }; let screen_position = screen_position / 2.0; - let final_position = Vector2::new(screen_position.x * window_size.x, screen_position.y * window_size.y + 5.0); + let final_position = ScreenPosition { + left: screen_position.left * window_size.width, + top: screen_position.top * window_size.height + 5.0, + }; let bar_width = *theme.status_bar.enemy_bar_width; renderer.render_rectangle( render_target, - final_position - Vector2::new(theme.status_bar.border_size.x + bar_width / 2.0, theme.status_bar.border_size.y), - Vector2::new(bar_width, *theme.status_bar.enemy_health_height) + *theme.status_bar.border_size * 2.0, + final_position + - ScreenSize { + width: theme.status_bar.border_size.x + bar_width / 2.0, + height: theme.status_bar.border_size.y, + }, + ScreenSize { + width: bar_width, + height: *theme.status_bar.enemy_health_height, + } + ScreenSize { + width: theme.status_bar.border_size.x * 2.0, + height: theme.status_bar.border_size.y * 2.0, + }, *theme.status_bar.background_color, ); renderer.render_bar( render_target, final_position, - Vector2::new(bar_width, *theme.status_bar.enemy_health_height), + ScreenSize { + width: bar_width, + height: *theme.status_bar.enemy_health_height, + }, *theme.status_bar.enemy_health_color, self.common.maximum_health_points as f32, self.common.health_points as f32, @@ -1079,7 +1122,7 @@ impl Entity { renderer: &DeferredRenderer, camera: &dyn Camera, theme: &GameTheme, - window_size: Vector2<f32>, + window_size: ScreenSize, ) { match self { Self::Player(player) => player.render_status(render_target, renderer, camera, theme, window_size), @@ -1089,7 +1132,7 @@ impl Entity { } impl PrototypeWindow for Entity { - fn to_window(&self, window_cache: &WindowCache, interface_settings: &InterfaceSettings, available_space: Size) -> Window { + fn to_window(&self, window_cache: &WindowCache, interface_settings: &InterfaceSettings, available_space: ScreenSize) -> Window { match self { Entity::Player(player) => player.to_window(window_cache, interface_settings, available_space), Entity::Npc(npc) => npc.to_window(window_cache, interface_settings, available_space),