aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Cargo.toml2
-rw-r--r--src/colours.rs14
-rw-r--r--src/editor.rs3
-rw-r--r--src/gui/dimension_indicator.rs189
-rw-r--r--src/gui/mod.rs4
-rw-r--r--src/main.rs9
-rw-r--r--src/map/mappable.rs8
-rw-r--r--src/map/polygon_room.rs26
-rw-r--r--src/map/rect_room.rs18
-rw-r--r--src/map/wall.rs29
-rw-r--r--src/math/rect.rs2
-rw-r--r--src/math/vec2.rs13
-rw-r--r--src/scaleable.rs11
-rw-r--r--src/tool/deletion_tool.rs13
-rw-r--r--src/tool/polygon_room_tool.rs10
-rw-r--r--src/tool/rect_room_tool.rs4
-rw-r--r--src/tool/selection_tool.rs13
-rw-r--r--src/transformable.rs8
18 files changed, 254 insertions, 122 deletions
diff --git a/Cargo.toml b/Cargo.toml
index b59cc6a..23c17be 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -15,4 +15,4 @@ svgtypes = "*"
xmltree = "*"
pretty_env_logger = "*"
log = "*"
-thiserror = "*"
+thiserror = "*" \ No newline at end of file
diff --git a/src/colours.rs b/src/colours.rs
index 8d69869..bafb53c 100644
--- a/src/colours.rs
+++ b/src/colours.rs
@@ -13,6 +13,8 @@ pub struct Colours {
pub wall_selected: Color,
pub icon_normal: Color,
pub icon_selected: Color,
+ pub dimension_indicators: Color,
+ pub dimension_text: Color,
}
impl Colours {
@@ -81,6 +83,18 @@ impl Colours {
b: 150,
a: 255,
},
+ dimension_indicators: Color {
+ r: 200,
+ g: 200,
+ b: 200,
+ a: 255,
+ },
+ dimension_text: Color {
+ r: 200,
+ g: 200,
+ b: 200,
+ a: 255,
+ },
}
}
}
diff --git a/src/editor.rs b/src/editor.rs
index e6a2dcb..87a8db4 100644
--- a/src/editor.rs
+++ b/src/editor.rs
@@ -184,4 +184,7 @@ impl Editor {
pub fn map(&self) -> &Map {
&self.map
}
+ pub fn map_mut(&mut self) -> &mut Map {
+ &mut self.map
+ }
}
diff --git a/src/gui/dimension_indicator.rs b/src/gui/dimension_indicator.rs
index 3d8313d..aa00f67 100644
--- a/src/gui/dimension_indicator.rs
+++ b/src/gui/dimension_indicator.rs
@@ -1,10 +1,11 @@
-use crate::math::{self, Vec2, Rect};
+use crate::colours::DEFAULT_COLOURS;
+use crate::map::Map;
+use crate::math::{self, Rect, Vec2};
use crate::transform::Transform;
+use nalgebra::{Matrix3, Vector2};
use raylib::drawing::RaylibDraw;
+use raylib::ffi::{Color, KeyboardKey};
use raylib::RaylibHandle;
-use raylib::ffi::{KeyboardKey, Color};
-use crate::map::Map;
-use std::mem;
/// A state the [DimensionIndicator] is currently in. This determines the behaviour of it and what
/// inputs it might be waiting for.
@@ -18,8 +19,8 @@ enum State {
Ruling {
dim_x: String,
dim_y: String,
- editing_x: bool
- }
+ editing_x: bool,
+ },
}
/// Used to render the horizontal and vertical dimensions of whatever is selected on the map and, if
@@ -28,7 +29,7 @@ pub struct DimensionIndicator {
/// The [State] the dimension indicator is currently in.
state: State,
/// The last dimensions that were valid.
- dimensions: Rect<f64>
+ bounds: Rect<f64>,
}
impl Default for State {
@@ -44,7 +45,7 @@ impl DimensionIndicator {
pub fn new() -> Self {
Self {
state: State::default(),
- dimensions: Rect::new(0., 0., 0., 0.);
+ bounds: Rect::new(0., 0., 0., 0.),
}
}
@@ -52,7 +53,7 @@ impl DimensionIndicator {
pub fn update(&mut self, map: &mut Map, rl: &mut RaylibHandle) {
match &self.state {
&State::Watching => self.update_watching(map, rl),
- &State::Ruling{ .. } => self.update_ruling(map, rl),
+ &State::Ruling { .. } => self.update_ruling(map, rl),
};
}
@@ -73,22 +74,21 @@ impl DimensionIndicator {
min.y = math::partial_min(min.y, element_bounds.y);
max.x = math::partial_max(max.x, element_bounds.x + element_bounds.w);
max.y = math::partial_max(max.y, element_bounds.y + element_bounds.h);
- }
- else {
+ } else {
// No selection size detected yet. Set now.
min.x = element_bounds.x;
min.y = element_bounds.y;
max.x = element_bounds.x + element_bounds.w;
max.y = element_bounds.y + element_bounds.h;
}
+ selection_exists = true;
}
}
// Set the current selection limits, if any.
- self.dimensions = if selection_exists {
+ self.bounds = if selection_exists {
Rect::bounding_rect(min, max)
- }
- else {
+ } else {
Rect::new(0., 0., 0., 0.)
};
@@ -96,28 +96,151 @@ impl DimensionIndicator {
// is a selection to begin with.
if selection_exists && rl.is_key_pressed(KeyboardKey::KEY_TAB) {
self.state = State::Ruling {
- dim_x: self.dimensions.w.to_string(),
- dim_y: self.dimensions.h.to_string(),
- editing_x: true
+ dim_x: self.bounds.w.to_string(),
+ dim_y: self.bounds.h.to_string(),
+ editing_x: true,
};
}
}
fn update_ruling(&mut self, map: &mut Map, rl: &mut RaylibHandle) {
- /* Capture the current key press and interpret it, if it exists. Otherwise, there is nothing
- * to update.
- */
- let key = match rl.get_key_pressed() {
- Some(key) => key,
- None => return,
+ // Get the currently edited dimension for processing.
+ let (edited_dim, editing_x) = match &mut self.state {
+ State::Watching => panic!("Called ruler update when in watching state"),
+ State::Ruling {
+ dim_x,
+ dim_y,
+ editing_x,
+ } => {
+ if *editing_x {
+ (dim_x, editing_x)
+ } else {
+ (dim_y, editing_x)
+ }
+ }
};
+ // Switch the currently edited dimension when pressing tab.
+ if rl.is_key_pressed(KeyboardKey::KEY_TAB) {
+ *editing_x = !*editing_x;
+ return;
+ }
+ // Finish editing mode on enter.
+ if rl.is_key_pressed(KeyboardKey::KEY_ENTER) {
+ self.state = State::Watching;
+ return;
+ }
+
+ // Marker to see if the dimensions will have to be checked for an update.
+ let mut dimension_changed = false;
+ // Delete the last character of the dimension on backspace.
+ if rl.is_key_pressed(KeyboardKey::KEY_BACKSPACE) {
+ edited_dim.pop();
+ dimension_changed = true;
+ }
+ /* Capture the current key and try to add it to the string of the current dimension,
+ * if possible.
+ */
+ else if let Some(key) = rl.get_key_pressed() {
+ match key {
+ // Add a decimal point to the dimension if possible.
+ KeyboardKey::KEY_PERIOD => {
+ if !edited_dim.contains('.') {
+ edited_dim.push('.');
+ }
+ // Nothing changed here, since there is an implicit .0 at the end.
+ }
+ // Handle the entered key if it is a number to append it to the currently edited dimension.
+ _ => {
+ if key as u16 >= KeyboardKey::KEY_ZERO as u16
+ && key as u16 <= KeyboardKey::KEY_NINE as u16
+ {
+ edited_dim.push(key as u8 as char);
+ dimension_changed = true;
+ }
+ }
+ };
+ }
+
+ if dimension_changed {
+ /* Try to parse the dimension from the currently edited string. If it
+ * is valid, change the dimensions of the currently selected items. If
+ * not, ignore the change and wait for a valid dimension.
+ */
+ if let Ok(dim) = edited_dim.parse::<f64>() {
+ let new_bounds = if *editing_x {
+ Rect::new(self.bounds.x, self.bounds.y, dim, self.bounds.h)
+ } else {
+ Rect::new(self.bounds.x, self.bounds.y, self.bounds.h, dim)
+ };
+ self.set_bounds(map, new_bounds);
+ }
+ }
+ }
+
+ /// Set the selection boundaries to the given bounds. Tries to transform the
+ /// currently selected items in the map so they fit inside of the new bounding box.
+ ///
+ /// # Panics
+ /// If the `bounds` have a negative value for width or height, the dimensions
+ /// cannot be set and the function will panic.
+ pub fn set_bounds(&mut self, map: &mut Map, bounds: Rect<f64>) {
+ if bounds.w <= 0. || bounds.h <= 0. {
+ panic!("Cannot set dimensions of elements to zero.");
+ }
+
+ // If the bounds are the same as before, there is nothing to do.
+ if self.bounds == bounds {
+ return;
+ }
+
+ /* Create a matrix to transform from the current rectangle bounds into the
+ * new bounds. Internally, this is a three-step process. First, we
+ * translate the points currently in the bounding box to the origin
+ * (0, 0) origin vector of the map, then scale and finally move it to the
+ * origin of the new rectangle. This needs to be applied to all vertices
+ * of all elements that can be scaled.
+ */
+ let scale = Vector2::new(bounds.w / self.bounds.w, bounds.h / self.bounds.h);
+ let transform = Matrix3::new_translation(&Vector2::new(-self.bounds.x, -self.bounds.y))
+ .append_nonuniform_scaling(&scale)
+ .append_translation(&Vector2::new(bounds.x, bounds.y));
+
+ for element in map.elements_mut() {
+ if element.selected() {
+ if let Some(transformable) = element.as_non_rigid_mut() {
+ transformable.apply_matrix(&transform);
+ }
+ }
+ }
+
+ self.bounds = bounds;
}
pub fn draw(&self, rld: &mut impl RaylibDraw, transform: &Transform) {
- // Draw all the dimension lines.
- for (start, end) in &self.length_lines {
+ /* Ignore a selection that has no non-null dimensions, since this usually
+ * indicates that there is nothing to be scaled.
+ */
+ if self.bounds.w == 0. && self.bounds.h == 0. {
+ return;
+ }
+
+ let (dim_str_width, dim_str_height) = match &self.state {
+ State::Watching => (self.bounds.w.to_string(), self.bounds.h.to_string()),
+ State::Ruling { dim_x, dim_y, .. } => (dim_x.clone(), dim_y.clone()),
+ };
+
+ // Draw the horizontal dimension at the bottom and the vertical dimension to the right.
+ // Use the valid dimensions, but show the edited dimensions in the String (should they differ)
+ let top_right = Vec2::new(self.bounds.x + self.bounds.w, self.bounds.y);
+ let bot_left = Vec2::new(self.bounds.x, self.bounds.y + self.bounds.h);
+ let bot_right = Vec2::new(self.bounds.x + self.bounds.w, self.bounds.y + self.bounds.h);
+ let dimensions = [
+ (bot_left, bot_right, dim_str_width),
+ (bot_right, top_right, dim_str_height),
+ ];
+ for (start, end, dim_str) in &dimensions {
// Don't draw anything if the length is zero.
if start == end {
continue;
@@ -138,27 +261,21 @@ impl DimensionIndicator {
let end_px = transform.point_m_to_px(end) + line_normal * 10.;
/* Draw the indicator line, with stubs at both ends. */
- let line_colour = Color {
- r: 200,
- g: 200,
- b: 200,
- a: 255,
- };
// First the two stubs.
rld.draw_line_ex(
start_px - line_normal * 5.,
start_px + line_normal * 5.,
2.,
- line_colour,
+ DEFAULT_COLOURS.dimension_indicators,
);
rld.draw_line_ex(
end_px - line_normal * 5.,
end_px + line_normal * 5.,
2.,
- line_colour,
+ DEFAULT_COLOURS.dimension_indicators,
);
// Then the actual indicator line.
- rld.draw_line_ex(start_px, end_px, 2., line_colour);
+ rld.draw_line_ex(start_px, end_px, 2., DEFAULT_COLOURS.dimension_indicators);
/* Draw the indicator text showing how long this line is in meters.
* It should be placed in the middle of the line, but not into the line directly, so it
@@ -166,11 +283,11 @@ impl DimensionIndicator {
*/
let text_pos = transform.point_m_to_px(&((*end + *start) / 2.)) + line_normal * 20.;
rld.draw_text(
- &format!("{}m", &(*end - *start).length()),
+ &format!("{}m", dim_str),
text_pos.x as i32,
text_pos.y as i32,
20,
- line_colour,
+ DEFAULT_COLOURS.dimension_text,
);
}
}
diff --git a/src/gui/mod.rs b/src/gui/mod.rs
index 0351ab3..032d430 100644
--- a/src/gui/mod.rs
+++ b/src/gui/mod.rs
@@ -1,5 +1,5 @@
-pub mod tool_sidebar;
pub mod dimension_indicator;
+pub mod tool_sidebar;
+pub use self::dimension_indicator::*;
pub use self::tool_sidebar::*;
-pub use self::dimension_indicator::*; \ No newline at end of file
diff --git a/src/main.rs b/src/main.rs
index 7957f14..6e54c59 100644
--- a/src/main.rs
+++ b/src/main.rs
@@ -12,14 +12,14 @@ pub mod grid;
pub mod gui;
pub mod map;
pub mod math;
-pub mod scaleable;
pub mod svg;
pub mod tool;
pub mod transform;
+pub mod transformable;
use config::Config;
use editor::Editor;
-use gui::ToolSidebar;
+use gui::{DimensionIndicator, ToolSidebar};
use raylib::prelude::*;
use std::ffi::CString;
use std::io;
@@ -65,6 +65,7 @@ fn main() {
));
let mut editor = Editor::new(&mut rl, &thread, config);
+ let mut dimension_indicator = DimensionIndicator::new();
let tool_sidebar = ToolSidebar::new(&mut rl, &thread);
let mut transform = Transform::new();
@@ -90,6 +91,8 @@ fn main() {
);
}
+ dimension_indicator.update(editor.map_mut(), &mut rl);
+
editor.update(
&mut rl,
&transform,
@@ -105,6 +108,8 @@ fn main() {
editor.draw_tools(&mut d, &transform);
tool_sidebar.draw(screen_height as u16, &mut d, &mut editor);
+
+ dimension_indicator.draw(&mut d, &transform);
}
}
}
diff --git a/src/map/mappable.rs b/src/map/mappable.rs
index b348c4b..323361a 100644
--- a/src/map/mappable.rs
+++ b/src/map/mappable.rs
@@ -2,8 +2,8 @@
//! dimension on the map and may be scaleable
use crate::math::Rect;
-use crate::scaleable::Scaleable;
use crate::transform::Transform;
+use crate::transformable::NonRigidTransformable;
use raylib::drawing::RaylibDrawHandle;
pub trait Mappable {
@@ -21,7 +21,11 @@ pub trait Mappable {
/// Get the rectangle that contains the mappable object in its entirety without excess.
fn bounding_rect(&self) -> Rect<f64>;
- fn as_scaleable(&self) -> Option<&dyn Scaleable> {
+ fn as_non_rigid(&self) -> Option<&dyn NonRigidTransformable> {
+ None
+ }
+
+ fn as_non_rigid_mut(&mut self) -> Option<&mut dyn NonRigidTransformable> {
None
}
}
diff --git a/src/map/polygon_room.rs b/src/map/polygon_room.rs
index a209a7c..65eeaab 100644
--- a/src/map/polygon_room.rs
+++ b/src/map/polygon_room.rs
@@ -1,9 +1,10 @@
use super::Mappable;
use crate::colours::DEFAULT_COLOURS;
-use crate::math::{self, Polygon, Rect, Triangle, Vec2};
-use crate::scaleable::Scaleable;
+use crate::math::{self, Polygon, Rect, Triangle};
use crate::transform::Transform;
+use crate::transformable::NonRigidTransformable;
use raylib::drawing::{RaylibDraw, RaylibDrawHandle};
+use nalgebra::{Matrix3, Point2};
pub type PolygonRoomData = Polygon<f64>;
@@ -56,20 +57,21 @@ impl Mappable for PolygonRoom {
Rect::bounding_rect_n(&self.data.corners())
}
- fn as_scaleable(&self) -> Option<&dyn Scaleable> {
- Some(self as &dyn Scaleable)
+ fn as_non_rigid(&self) -> Option<&dyn NonRigidTransformable> {
+ Some(self as &dyn NonRigidTransformable)
}
-}
-impl Scaleable for PolygonRoom {
- fn scale(&mut self, by: &Vec2<f64>) {
- if by.x < 0. || by.y < 0. {
- panic!("Cannot set dimensions with negative size");
- }
+ fn as_non_rigid_mut(&mut self) -> Option<&mut dyn NonRigidTransformable> {
+ Some(self as &mut dyn NonRigidTransformable)
+ }
+}
+impl NonRigidTransformable for PolygonRoom {
+ fn apply_matrix(&mut self, matrix: &Matrix3<f64>) {
for corner in self.data.corners_mut() {
- corner.x *= by.x;
- corner.y *= by.y;
+ *corner = matrix
+ .transform_point(&Point2::new(corner.x, corner.y))
+ .into();
}
self.retriangulate();
diff --git a/src/map/rect_room.rs b/src/map/rect_room.rs
index 5008c63..ee184fb 100644
--- a/src/map/rect_room.rs
+++ b/src/map/rect_room.rs
@@ -1,7 +1,6 @@
use crate::colours::DEFAULT_COLOURS;
use crate::map::Mappable;
-use crate::math::{Rect, Vec2};
-use crate::scaleable::Scaleable;
+use crate::math::Rect;
use crate::transform::Transform;
use raylib::drawing::{RaylibDraw, RaylibDrawHandle};
use serde::Serialize;
@@ -47,21 +46,6 @@ impl Mappable for RectRoom {
fn bounding_rect(&self) -> Rect<f64> {
self.data.clone()
}
-
- fn as_scaleable(&self) -> Option<&dyn Scaleable> {
- Some(self as &dyn Scaleable)
- }
-}
-
-impl Scaleable for RectRoom {
- fn scale(&mut self, by: &Vec2<f64>) {
- if by.x < 0. || by.y < 0. {
- panic!("Cannot set dimensions with negative size");
- }
-
- self.data.x *= by.x;
- self.data.y *= by.y;
- }
}
impl Deref for RectRoom {
diff --git a/src/map/wall.rs b/src/map/wall.rs
index 22393bb..d18096b 100644
--- a/src/map/wall.rs
+++ b/src/map/wall.rs
@@ -1,10 +1,11 @@
use super::Mappable;
use crate::colours::DEFAULT_COLOURS;
use crate::math::{LineSegment, Rect, Vec2};
-use crate::scaleable::Scaleable;
use crate::transform::Transform;
+use crate::transformable::NonRigidTransformable;
use raylib::drawing::{RaylibDraw, RaylibDrawHandle};
use std::ops::{Deref, DerefMut};
+use nalgebra::{Matrix3, Point2};
pub type WallData = LineSegment<f64>;
@@ -81,18 +82,24 @@ impl Mappable for Wall {
fn bounding_rect(&self) -> Rect<f64> {
Rect::bounding_rect(self.data.start, self.data.end)
}
-}
-impl Scaleable for Wall {
- fn scale(&mut self, by: &Vec2<f64>) {
- if by.x <= 0. || by.y <= 0. {
- panic!("Cannot set dimensions with negative size");
- }
+ fn as_non_rigid(&self) -> Option<&dyn NonRigidTransformable> {
+ Some(self as &dyn NonRigidTransformable)
+ }
+
+ fn as_non_rigid_mut(&mut self) -> Option<&mut dyn NonRigidTransformable> {
+ Some(self as &mut dyn NonRigidTransformable)
+ }
+}
- self.data.start.x *= by.x;
- self.data.start.y *= by.y;
- self.data.end.x *= by.x;
- self.data.end.y *= by.y;
+impl NonRigidTransformable for Wall {
+ fn apply_matrix(&mut self, matrix: &Matrix3<f64>) {
+ self.data.start = matrix
+ .transform_point(&self.data.start.into())
+ .into();
+ self.data.end = matrix
+ .transform_point(&self.data.end.into())
+ .into();
}
}
diff --git a/src/math/rect.rs b/src/math/rect.rs
index 50c1cb0..b571644 100644
--- a/src/math/rect.rs
+++ b/src/math/rect.rs
@@ -7,7 +7,7 @@ use serde::{Deserialize, Serialize};
use std::ops::{Add, AddAssign};
/// Represents a Rectangle with the value type T.
-#[derive(Copy, Clone, Debug, Default, Serialize, Deserialize)]
+#[derive(Copy, Clone, Debug, Default, PartialEq, Eq, Serialize, Deserialize)]
pub struct Rect<T: Scalar + Copy> {
/// The x coordinate, or leftmost coordinate of the Rect.
pub x: T,
diff --git a/src/math/vec2.rs b/src/math/vec2.rs
index d591f1d..b9e3215 100644
--- a/src/math/vec2.rs
+++ b/src/math/vec2.rs
@@ -7,6 +7,7 @@ use std::cmp::Ordering;
use std::convert::{From, Into};
use std::ops::{Add, AddAssign, Div, Mul, MulAssign, Neg, Sub, SubAssign};
use std::{fmt, mem};
+use nalgebra::Point2;
#[derive(Clone, Copy, Debug, Default, PartialEq, Serialize, Deserialize, Eq, Hash)]
pub struct Vec2<T: Scalar + Copy> {
@@ -45,6 +46,18 @@ impl<T: Scalar + Copy> Vec2<T> {
}
}
+impl<T: Scalar + Copy> Into<Point2<T>> for Vec2<T> {
+ fn into(self) -> Point2<T> {
+ Point2::new(self.x, self.y)
+ }
+}
+
+impl<T: Scalar + Copy> From<Point2<T>> for Vec2<T> {
+ fn from(v: Point2<T>) -> Self {
+ Self::new(v.x, v.y)
+ }
+}
+
// This is sad, but also sadly necessary :/
impl<T> From<raylib::ffi::Vector2> for Vec2<T>
where
diff --git a/src/scaleable.rs b/src/scaleable.rs
deleted file mode 100644
index 450e61e..0000000
--- a/src/scaleable.rs
+++ /dev/null
@@ -1,11 +0,0 @@
-use crate::math::Vec2;
-
-/// Trait representing something that covers an area and that can be resized accordingly.
-pub trait Scaleable {
- /// Scale the object by the specified amount in horizontal and vertical direction (right and
- /// downwards).
- ///
- /// # Panics
- /// If at least one of the dimensions is zero or less, the object cannot be scaled and panics.
- fn scale(&mut self, by: &Vec2<f64>);
-}
diff --git a/src/tool/deletion_tool.rs b/src/tool/deletion_tool.rs
index 5ff3e6a..cd38f6c 100644
--- a/src/tool/deletion_tool.rs
+++ b/src/tool/deletion_tool.rs
@@ -1,8 +1,8 @@
use super::Tool;
+use crate::colours::DEFAULT_COLOURS;
use crate::map::Map;
use crate::math::{Rect, Surface, Vec2};
use crate::transform::Transform;
-use crate::colours::DEFAULT_COLOURS;
use raylib::core::drawing::{RaylibDraw, RaylibDrawHandle};
pub struct DeletionTool {
@@ -36,15 +36,8 @@ impl Tool for DeletionTool {
fn draw(&self, rld: &mut RaylibDrawHandle, transform: &Transform) {
if let Some((pos1, pos2)) = self.deletion_rect {
let rect_px = transform.rect_m_to_px(&Rect::bounding_rect(pos1, pos2));
- rld.draw_rectangle_rec(
- rect_px,
- DEFAULT_COLOURS.deletion_rect
- );
- rld.draw_rectangle_lines_ex(
- rect_px,
- 4,
- DEFAULT_COLOURS.deletion_rect_outline
- );
+ rld.draw_rectangle_rec(rect_px, DEFAULT_COLOURS.deletion_rect);
+ rld.draw_rectangle_lines_ex(rect_px, 4, DEFAULT_COLOURS.deletion_rect_outline);
}
}
diff --git a/src/tool/polygon_room_tool.rs b/src/tool/polygon_room_tool.rs
index 1b079d2..de6714d 100644
--- a/src/tool/polygon_room_tool.rs
+++ b/src/tool/polygon_room_tool.rs
@@ -1,8 +1,8 @@
use super::Tool;
+use crate::colours::DEFAULT_COLOURS;
use crate::map::Map;
use crate::math::{self, Polygon, PolygonError, Vec2};
use crate::transform::Transform;
-use crate::colours::DEFAULT_COLOURS;
use raylib::core::drawing::{RaylibDraw, RaylibDrawHandle};
struct UnfinishedPolygon {
@@ -103,7 +103,7 @@ impl Tool for PolygonRoomTool {
transform.point_m_to_px(&polygon.corners[0]),
transform.point_m_to_px(&polygon.working_corner),
transform.length_m_to_px(0.1) as f32,
- DEFAULT_COLOURS.room_selected
+ DEFAULT_COLOURS.room_selected,
);
} else if polygon.corners.len() == 2 {
// We have three valid corners, so we can draw a triangle.
@@ -111,7 +111,7 @@ impl Tool for PolygonRoomTool {
transform.point_m_to_px(&polygon.corners[0]),
transform.point_m_to_px(&polygon.corners[1]),
transform.point_m_to_px(&polygon.working_corner),
- DEFAULT_COLOURS.room_selected
+ DEFAULT_COLOURS.room_selected,
)
} else {
// A proper polygon can be drawn.
@@ -126,7 +126,7 @@ impl Tool for PolygonRoomTool {
transform.point_m_to_px(&triangle[0]),
transform.point_m_to_px(&triangle[1]),
transform.point_m_to_px(&triangle[2]),
- DEFAULT_COLOURS.room_selected
+ DEFAULT_COLOURS.room_selected,
)
}
} else if polygon.check_validity_completed().is_ok() {
@@ -138,7 +138,7 @@ impl Tool for PolygonRoomTool {
transform.point_m_to_px(&triangle[0]),
transform.point_m_to_px(&triangle[1]),
transform.point_m_to_px(&triangle[2]),
- DEFAULT_COLOURS.room_selected
+ DEFAULT_COLOURS.room_selected,
)
}
}
diff --git a/src/tool/rect_room_tool.rs b/src/tool/rect_room_tool.rs
index dfda495..29173cd 100644
--- a/src/tool/rect_room_tool.rs
+++ b/src/tool/rect_room_tool.rs
@@ -1,8 +1,8 @@
use super::Tool;
+use crate::colours::DEFAULT_COLOURS;
use crate::map::Map;
use crate::math::{Rect, Vec2};
use crate::transform::Transform;
-use crate::colours::DEFAULT_COLOURS;
use raylib::core::drawing::{RaylibDraw, RaylibDrawHandle};
pub struct RectRoomTool {
@@ -35,7 +35,7 @@ impl Tool for RectRoomTool {
if let Some((pos1, pos2)) = self.unfinished_rect {
rld.draw_rectangle_rec(
transform.rect_m_to_px(&Rect::bounding_rect(pos1, pos2)),
- DEFAULT_COLOURS.room_selected
+ DEFAULT_COLOURS.room_selected,
);
}
}
diff --git a/src/tool/selection_tool.rs b/src/tool/selection_tool.rs
index 49efba9..30f91bf 100644
--- a/src/tool/selection_tool.rs
+++ b/src/tool/selection_tool.rs
@@ -1,9 +1,9 @@
use super::Tool;
+use crate::colours::DEFAULT_COLOURS;
use crate::map::Map;
use crate::math::{Rect, Surface, Vec2};
use crate::transform::Transform;
use raylib::core::drawing::{RaylibDraw, RaylibDrawHandle};
-use crate::colours::DEFAULT_COLOURS;
pub struct SelectionTool {
selection_rect: Option<(Vec2<f64>, Vec2<f64>)>,
@@ -31,15 +31,8 @@ impl Tool for SelectionTool {
fn draw(&self, rld: &mut RaylibDrawHandle, transform: &Transform) {
if let Some((pos1, pos2)) = self.selection_rect {
let rect_px = transform.rect_m_to_px(&Rect::bounding_rect(pos1, pos2));
- rld.draw_rectangle_rec(
- rect_px,
- DEFAULT_COLOURS.selection_rect
- );
- rld.draw_rectangle_lines_ex(
- rect_px,
- 4,
- DEFAULT_COLOURS.selection_rect_outline
- );
+ rld.draw_rectangle_rec(rect_px, DEFAULT_COLOURS.selection_rect);
+ rld.draw_rectangle_lines_ex(rect_px, 4, DEFAULT_COLOURS.selection_rect_outline);
}
}
diff --git a/src/transformable.rs b/src/transformable.rs
new file mode 100644
index 0000000..c181bd6
--- /dev/null
+++ b/src/transformable.rs
@@ -0,0 +1,8 @@
+use nalgebra::Matrix3;
+
+/// Trait for things that can be stretched and rotated etc. as one pleases without
+/// becoming invalid. A room for instance would fall into this category, while an icon might not.
+pub trait NonRigidTransformable {
+ /// Applies the provided matrix to all vertices of this transformable element.
+ fn apply_matrix(&mut self, matrix: &Matrix3<f64>);
+}