From 9799d3c6a8f0c242668203a1c70d7b6cfed3e855 Mon Sep 17 00:00:00 2001 From: Arne Dußin Date: Tue, 15 Dec 2020 00:46:54 +0100 Subject: Refactor to make interaction between tools easier --- src/map/rect_room.rs | 68 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 68 insertions(+) create mode 100644 src/map/rect_room.rs (limited to 'src/map/rect_room.rs') diff --git a/src/map/rect_room.rs b/src/map/rect_room.rs new file mode 100644 index 0000000..07f201c --- /dev/null +++ b/src/map/rect_room.rs @@ -0,0 +1,68 @@ +use crate::map::Mappable; +use crate::math::{Rect, Vec2}; +use crate::scaleable::Scaleable; +use crate::transform::Transform; +use raylib::drawing::{RaylibDraw, RaylibDrawHandle}; +use raylib::ffi::Color; +use serde::Serialize; +use std::ops::{Deref, DerefMut}; + +pub type RectRoomData = Rect; + +#[derive(Serialize)] +pub struct RectRoom { + data: RectRoomData, +} + +impl RectRoom { + pub fn from_data(data: RectRoomData) -> Self { + RectRoom { data } + } +} + +impl Mappable for RectRoom { + fn draw(&self, rld: &mut RaylibDrawHandle, transform: &Transform) { + rld.draw_rectangle_rec( + transform.rect_m_to_px(&self.data), + Color { + r: 180, + g: 180, + b: 180, + a: 255, + }, + ); + } + + fn bounding_rect(&self) -> Rect { + 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) { + 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 { + type Target = RectRoomData; + + fn deref(&self) -> &Self::Target { + &self.data + } +} + +impl DerefMut for RectRoom { + fn deref_mut(&mut self) -> &mut Self::Target { + &mut self.data + } +} -- cgit v1.2.3-70-g09d2 From 82d11b7d3e15d8175accf7579db1fbe528fc6583 Mon Sep 17 00:00:00 2001 From: Arne Dußin Date: Wed, 16 Dec 2020 13:34:56 +0100 Subject: Add constant for default colours and selection tool --- src/colours.rs | 86 +++++++++++++++++++++++++++++++++++++++++++ src/config.rs | 2 + src/editor.rs | 48 +++++++++++++++++++----- src/main.rs | 1 + src/map/icon.rs | 28 ++++++++++---- src/map/mappable.rs | 7 ++++ src/map/mod.rs | 6 +-- src/map/polygon_room.rs | 25 +++++++++---- src/map/rect_room.rs | 25 +++++++++---- src/map/wall.rs | 43 ++++++++++++++-------- src/math/rect.rs | 2 +- src/tool/deletion_tool.rs | 16 ++------ src/tool/mod.rs | 3 ++ src/tool/polygon_room_tool.rs | 30 +++------------ src/tool/rect_room_tool.rs | 9 +---- src/tool/selection_tool.rs | 63 +++++++++++++++++++++++++++++++ 16 files changed, 297 insertions(+), 97 deletions(-) create mode 100644 src/colours.rs create mode 100644 src/tool/selection_tool.rs (limited to 'src/map/rect_room.rs') diff --git a/src/colours.rs b/src/colours.rs new file mode 100644 index 0000000..8d69869 --- /dev/null +++ b/src/colours.rs @@ -0,0 +1,86 @@ +use raylib::ffi::Color; + +pub const DEFAULT_COLOURS: Colours = Colours::default(); + +pub struct Colours { + pub deletion_rect: Color, + pub deletion_rect_outline: Color, + pub selection_rect: Color, + pub selection_rect_outline: Color, + pub room_normal: Color, + pub room_selected: Color, + pub wall_normal: Color, + pub wall_selected: Color, + pub icon_normal: Color, + pub icon_selected: Color, +} + +impl Colours { + // NOTE: Unfortunately the default function cannot be made const, since Default is a trait. This + // feature is, as far as I can tell, planned in Rust, but not yet implemented. Once it is, Colours + // should implement Default instead. + const fn default() -> Self { + Self { + deletion_rect: Color { + r: 200, + g: 150, + b: 150, + a: 50, + }, + deletion_rect_outline: Color { + r: 200, + g: 150, + b: 150, + a: 150, + }, + selection_rect: Color { + r: 255, + g: 129, + b: 0, + a: 50, + }, + selection_rect_outline: Color { + r: 255, + g: 129, + b: 0, + a: 150, + }, + room_normal: Color { + r: 180, + g: 180, + b: 180, + a: 255, + }, + room_selected: Color { + r: 150, + g: 200, + b: 150, + a: 255, + }, + wall_normal: Color { + r: 200, + g: 120, + b: 120, + a: 255, + }, + wall_selected: Color { + r: 150, + g: 200, + b: 150, + a: 255, + }, + icon_normal: Color { + r: 255, + g: 255, + b: 255, + a: 255, + }, + icon_selected: Color { + r: 150, + g: 200, + b: 150, + a: 255, + }, + } + } +} diff --git a/src/config.rs b/src/config.rs index 4e63387..2a1e5ed 100644 --- a/src/config.rs +++ b/src/config.rs @@ -19,6 +19,7 @@ pub struct ToolActivationKeys { pub icon: Button, pub polygon_room: Button, pub rect_room: Button, + pub selection: Button, pub wall: Button, } @@ -73,6 +74,7 @@ impl Default for Config { icon: Button::Keyboard(KeyboardKey::I), polygon_room: Button::Keyboard(KeyboardKey::P), rect_room: Button::Keyboard(KeyboardKey::R), + selection: Button::Keyboard(KeyboardKey::S), wall: Button::Keyboard(KeyboardKey::W), }, tool_general_keys: ToolGeneralKeys { diff --git a/src/editor.rs b/src/editor.rs index bbe4f60..e6a2dcb 100644 --- a/src/editor.rs +++ b/src/editor.rs @@ -1,12 +1,12 @@ use crate::button::{Button, MouseButton}; use crate::config::Config; +use crate::grid::{snap_to_grid, SNAP_SIZE}; use crate::map::Map; use crate::tool::*; use crate::transform::Transform; use raylib::core::drawing::RaylibDrawHandle; use raylib::{RaylibHandle, RaylibThread}; use std::collections::HashMap; -use crate::grid::{snap_to_grid, SNAP_SIZE}; pub struct Editor { map: Map, @@ -14,7 +14,7 @@ pub struct Editor { /// itself. tools: HashMap, Button)>, active: ToolType, - config: Config + config: Config, } impl Editor { @@ -56,6 +56,13 @@ impl Editor { config.tool_activation_keys.deletion, ), ); + tools.insert( + ToolType::SelectionTool, + ( + Box::new(SelectionTool::new()), + config.tool_activation_keys.selection, + ), + ); assert_eq!(ToolType::NumTools as usize, tools.len()); @@ -63,7 +70,7 @@ impl Editor { map, tools, active: ToolType::RectRoomTool, - config + config, } } @@ -123,23 +130,44 @@ impl Editor { active_tool.update(&self.map, &snapped_mouse_pos); // Handle common keybindings many of the tools have. - if self.config.tool_general_keys.place_single.is_pressed(rl, mouse_blocked) { + if self + .config + .tool_general_keys + .place_single + .is_pressed(rl, mouse_blocked) + { active_tool.place_single(&mut self.map, &snapped_mouse_pos); } - if self.config.tool_general_keys.finish.is_pressed(rl, mouse_blocked) { + if self + .config + .tool_general_keys + .finish + .is_pressed(rl, mouse_blocked) + { active_tool.finish(&mut self.map); } - if self.config.tool_general_keys.abort.is_pressed(rl, mouse_blocked) { + if self + .config + .tool_general_keys + .abort + .is_pressed(rl, mouse_blocked) + { active_tool.abort(); } // Handle custom keybindings in case the tool has any. let latest_button = if let Some(keyboard_key) = rl.get_key_pressed() { Some(Button::Keyboard(keyboard_key.into())) - } - else { - let mouse_buttons = [Button::Mouse(MouseButton::Left), Button::Mouse(MouseButton::Middle), Button::Mouse(MouseButton::Right)]; - mouse_buttons.iter().find(|button| button.is_pressed(rl, mouse_blocked)).copied() + } else { + let mouse_buttons = [ + Button::Mouse(MouseButton::Left), + Button::Mouse(MouseButton::Middle), + Button::Mouse(MouseButton::Right), + ]; + mouse_buttons + .iter() + .find(|button| button.is_pressed(rl, mouse_blocked)) + .copied() }; if let Some(latest_button) = latest_button { diff --git a/src/main.rs b/src/main.rs index de42ab7..8ddc587 100644 --- a/src/main.rs +++ b/src/main.rs @@ -4,6 +4,7 @@ extern crate log; pub mod button; +pub mod colours; pub mod config; pub mod dimension_indicator; pub mod editor; diff --git a/src/map/icon.rs b/src/map/icon.rs index 50e1906..f623c98 100644 --- a/src/map/icon.rs +++ b/src/map/icon.rs @@ -1,9 +1,9 @@ use super::icon_renderer::IconRenderer; +use crate::colours::DEFAULT_COLOURS; use crate::map::Mappable; -use crate::math::{Vec2, Rect}; +use crate::math::{Rect, Vec2}; use crate::transform::Transform; use raylib::core::drawing::{RaylibDraw, RaylibDrawHandle}; -use raylib::ffi::Color; use serde::{Deserialize, Serialize}; use std::ops::{Deref, DerefMut}; use std::rc::Rc; @@ -21,6 +21,7 @@ pub struct IconData { #[derive(Clone)] pub struct Icon { data: IconData, + selected: bool, renderer: Rc, } @@ -37,7 +38,11 @@ impl Icon { } pub fn from_data(data: IconData, renderer: Rc) -> Self { - Self { data, renderer } + Self { + data, + selected: false, + renderer, + } } } @@ -54,15 +59,22 @@ impl Mappable for Icon { position_px, self.rotation as f32, (transform.pixels_per_m() / info.pixels_per_m) as f32, - Color { - r: 255, - g: 255, - b: 255, - a: 255, + if self.selected() { + DEFAULT_COLOURS.icon_selected + } else { + DEFAULT_COLOURS.icon_normal }, ); } + fn set_selected(&mut self, selected: bool) { + self.selected = selected; + } + + fn selected(&self) -> bool { + self.selected + } + fn bounding_rect(&self) -> Rect { Rect::new(self.data.position.x, self.data.position.y, 0., 0.) } diff --git a/src/map/mappable.rs b/src/map/mappable.rs index f75c990..b348c4b 100644 --- a/src/map/mappable.rs +++ b/src/map/mappable.rs @@ -11,6 +11,13 @@ pub trait Mappable { /// this must always be implemented. fn draw(&self, rld: &mut RaylibDrawHandle, transform: &Transform); + /// Set the selection status of this item. If it is selected, actions that concern all selected + /// items will be applied to this item as well. + fn set_selected(&mut self, selected: bool); + + /// Get if this item is currently selected. + fn selected(&self) -> bool; + /// Get the rectangle that contains the mappable object in its entirety without excess. fn bounding_rect(&self) -> Rect; diff --git a/src/map/mod.rs b/src/map/mod.rs index 93f51a2..ff03474 100644 --- a/src/map/mod.rs +++ b/src/map/mod.rs @@ -75,7 +75,7 @@ impl Map { } pub fn draw(&self, rld: &mut RaylibDrawHandle, transform: &Transform) { - for element in self.iter() { + for element in self.elements() { element.draw(rld, transform); } } @@ -98,7 +98,7 @@ impl Map { /// Iterator over all elements as objects when an operation needs to go over all elements of the /// map. - pub fn iter(&self) -> impl Iterator { + pub fn elements(&self) -> impl Iterator { self.rect_rooms .iter() .map(|r| r as &dyn Mappable) @@ -107,7 +107,7 @@ impl Map { .chain(self.icons.iter().map(|i| i as &dyn Mappable)) } - pub fn iter_mut(&mut self) -> impl Iterator { + pub fn elements_mut(&mut self) -> impl Iterator { self.rect_rooms .iter_mut() .map(|r| r as &mut dyn Mappable) diff --git a/src/map/polygon_room.rs b/src/map/polygon_room.rs index 12c480b..a209a7c 100644 --- a/src/map/polygon_room.rs +++ b/src/map/polygon_room.rs @@ -1,9 +1,9 @@ use super::Mappable; -use crate::math::{self, Rect, Polygon, Triangle, Vec2}; +use crate::colours::DEFAULT_COLOURS; +use crate::math::{self, Polygon, Rect, Triangle, Vec2}; use crate::scaleable::Scaleable; use crate::transform::Transform; use raylib::drawing::{RaylibDraw, RaylibDrawHandle}; -use raylib::ffi::Color; pub type PolygonRoomData = Polygon; @@ -11,13 +11,15 @@ pub struct PolygonRoom { data: PolygonRoomData, // The polygon shape, but in triangles, so the polygon does not have to be triangulated every frame. triangulated: Vec>, + selected: bool, } impl PolygonRoom { pub fn from_data(data: PolygonRoomData) -> Self { Self { data: data.clone(), - triangulated: math::triangulate(data) + triangulated: math::triangulate(data), + selected: false, } } @@ -33,16 +35,23 @@ impl Mappable for PolygonRoom { transform.point_m_to_px(&triangle.corners()[0]), transform.point_m_to_px(&triangle.corners()[1]), transform.point_m_to_px(&triangle.corners()[2]), - Color { - r: 180, - g: 180, - b: 180, - a: 255, + if self.selected() { + DEFAULT_COLOURS.room_selected + } else { + DEFAULT_COLOURS.room_normal }, ) } } + fn set_selected(&mut self, selected: bool) { + self.selected = selected; + } + + fn selected(&self) -> bool { + self.selected + } + fn bounding_rect(&self) -> Rect { Rect::bounding_rect_n(&self.data.corners()) } diff --git a/src/map/rect_room.rs b/src/map/rect_room.rs index 07f201c..5008c63 100644 --- a/src/map/rect_room.rs +++ b/src/map/rect_room.rs @@ -1,9 +1,9 @@ +use crate::colours::DEFAULT_COLOURS; use crate::map::Mappable; use crate::math::{Rect, Vec2}; use crate::scaleable::Scaleable; use crate::transform::Transform; use raylib::drawing::{RaylibDraw, RaylibDrawHandle}; -use raylib::ffi::Color; use serde::Serialize; use std::ops::{Deref, DerefMut}; @@ -12,11 +12,15 @@ pub type RectRoomData = Rect; #[derive(Serialize)] pub struct RectRoom { data: RectRoomData, + selected: bool, } impl RectRoom { pub fn from_data(data: RectRoomData) -> Self { - RectRoom { data } + RectRoom { + data, + selected: false, + } } } @@ -24,15 +28,22 @@ impl Mappable for RectRoom { fn draw(&self, rld: &mut RaylibDrawHandle, transform: &Transform) { rld.draw_rectangle_rec( transform.rect_m_to_px(&self.data), - Color { - r: 180, - g: 180, - b: 180, - a: 255, + if self.selected() { + DEFAULT_COLOURS.room_selected + } else { + DEFAULT_COLOURS.room_normal }, ); } + fn set_selected(&mut self, selected: bool) { + self.selected = selected; + } + + fn selected(&self) -> bool { + self.selected + } + fn bounding_rect(&self) -> Rect { self.data.clone() } diff --git a/src/map/wall.rs b/src/map/wall.rs index 6c90fda..22393bb 100644 --- a/src/map/wall.rs +++ b/src/map/wall.rs @@ -1,15 +1,16 @@ use super::Mappable; -use crate::math::{LineSegment, Vec2, Rect}; +use crate::colours::DEFAULT_COLOURS; +use crate::math::{LineSegment, Rect, Vec2}; use crate::scaleable::Scaleable; use crate::transform::Transform; use raylib::drawing::{RaylibDraw, RaylibDrawHandle}; -use raylib::ffi::Color; use std::ops::{Deref, DerefMut}; pub type WallData = LineSegment; pub struct Wall { data: WallData, + selected: bool, round_start: bool, round_end: bool, } @@ -18,6 +19,7 @@ impl Wall { pub fn from_data(data: WallData, round_start: bool, round_end: bool) -> Self { Self { data, + selected: false, round_start, round_end, } @@ -28,15 +30,19 @@ impl Wall { } } -fn draw_round_corner(rld: &mut RaylibDrawHandle, pos_px: Vec2, transform: &Transform) { +fn draw_round_corner( + rld: &mut RaylibDrawHandle, + pos_px: Vec2, + transform: &Transform, + selected: bool, +) { rld.draw_circle_v( pos_px, transform.length_m_to_px(0.05) as f32, - Color { - r: 200, - g: 120, - b: 120, - a: 255, + if selected { + DEFAULT_COLOURS.wall_selected + } else { + DEFAULT_COLOURS.wall_normal }, ); } @@ -49,22 +55,29 @@ impl Mappable for Wall { start_px, end_px, transform.length_m_to_px(0.1) as f32, - Color { - r: 200, - g: 120, - b: 120, - a: 255, + if self.selected() { + DEFAULT_COLOURS.wall_selected + } else { + DEFAULT_COLOURS.wall_normal }, ); if self.round_start { - draw_round_corner(rld, start_px, transform); + draw_round_corner(rld, start_px, transform, self.selected()); } if self.round_end { - draw_round_corner(rld, end_px, transform); + draw_round_corner(rld, end_px, transform, self.selected()); } } + fn set_selected(&mut self, selected: bool) { + self.selected = selected; + } + + fn selected(&self) -> bool { + self.selected + } + fn bounding_rect(&self) -> Rect { Rect::bounding_rect(self.data.start, self.data.end) } diff --git a/src/math/rect.rs b/src/math/rect.rs index befa4da..50c1cb0 100644 --- a/src/math/rect.rs +++ b/src/math/rect.rs @@ -112,7 +112,7 @@ impl Rect { x: min.x, y: min.y, w: max.x - min.x, - h: max.y - min.y + h: max.y - min.y, } } diff --git a/src/tool/deletion_tool.rs b/src/tool/deletion_tool.rs index ad3af1d..5ff3e6a 100644 --- a/src/tool/deletion_tool.rs +++ b/src/tool/deletion_tool.rs @@ -2,8 +2,8 @@ use super::Tool; 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}; -use raylib::ffi::Color; pub struct DeletionTool { deletion_rect: Option<(Vec2, Vec2)>, @@ -38,22 +38,12 @@ impl Tool for DeletionTool { let rect_px = transform.rect_m_to_px(&Rect::bounding_rect(pos1, pos2)); rld.draw_rectangle_rec( rect_px, - Color { - r: 200, - g: 150, - b: 150, - a: 50, - }, + DEFAULT_COLOURS.deletion_rect ); rld.draw_rectangle_lines_ex( rect_px, 4, - Color { - r: 200, - g: 150, - b: 150, - a: 150, - }, + DEFAULT_COLOURS.deletion_rect_outline ); } } diff --git a/src/tool/mod.rs b/src/tool/mod.rs index 532572a..aeabf19 100644 --- a/src/tool/mod.rs +++ b/src/tool/mod.rs @@ -2,12 +2,14 @@ pub mod deletion_tool; pub mod icon_tool; pub mod polygon_room_tool; pub mod rect_room_tool; +pub mod selection_tool; pub mod wall_tool; pub use deletion_tool::DeletionTool; pub use icon_tool::IconTool; pub use polygon_room_tool::PolygonRoomTool; pub use rect_room_tool::RectRoomTool; +pub use selection_tool::SelectionTool; pub use wall_tool::WallTool; use crate::button::Button; @@ -24,6 +26,7 @@ pub enum ToolType { WallTool, IconTool, DeletionTool, + SelectionTool, NumTools, } diff --git a/src/tool/polygon_room_tool.rs b/src/tool/polygon_room_tool.rs index 4f8edce..1b079d2 100644 --- a/src/tool/polygon_room_tool.rs +++ b/src/tool/polygon_room_tool.rs @@ -2,8 +2,8 @@ use super::Tool; 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}; -use raylib::ffi::Color; struct UnfinishedPolygon { pub corners: Vec>, @@ -103,12 +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, - Color { - r: 150, - g: 200, - b: 150, - a: 255, - }, + DEFAULT_COLOURS.room_selected ); } else if polygon.corners.len() == 2 { // We have three valid corners, so we can draw a triangle. @@ -116,12 +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), - Color { - r: 150, - g: 200, - b: 150, - a: 255, - }, + DEFAULT_COLOURS.room_selected ) } else { // A proper polygon can be drawn. @@ -136,12 +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]), - Color { - r: 150, - g: 200, - b: 150, - a: 255, - }, + DEFAULT_COLOURS.room_selected ) } } else if polygon.check_validity_completed().is_ok() { @@ -153,12 +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]), - Color { - r: 150, - g: 200, - b: 150, - a: 255, - }, + DEFAULT_COLOURS.room_selected ) } } diff --git a/src/tool/rect_room_tool.rs b/src/tool/rect_room_tool.rs index 3eb40aa..dfda495 100644 --- a/src/tool/rect_room_tool.rs +++ b/src/tool/rect_room_tool.rs @@ -2,8 +2,8 @@ use super::Tool; use crate::map::Map; use crate::math::{Rect, Vec2}; use crate::transform::Transform; +use crate::colours::DEFAULT_COLOURS; use raylib::core::drawing::{RaylibDraw, RaylibDrawHandle}; -use raylib::ffi::Color; pub struct RectRoomTool { /// The rectangle that is currently being drawn by the user. Once it is finished, it will be @@ -35,12 +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)), - Color { - r: 150, - g: 200, - b: 150, - a: 255, - }, + DEFAULT_COLOURS.room_selected ); } } diff --git a/src/tool/selection_tool.rs b/src/tool/selection_tool.rs new file mode 100644 index 0000000..49efba9 --- /dev/null +++ b/src/tool/selection_tool.rs @@ -0,0 +1,63 @@ +use super::Tool; +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, Vec2)>, +} + +impl SelectionTool { + pub fn new() -> Self { + Self { + selection_rect: None, + } + } +} + +impl Tool for SelectionTool { + fn deactivate(&mut self) { + self.selection_rect = None; + } + + fn update(&mut self, _map: &Map, mouse_pos_m: &Vec2) { + if let Some((_, ref mut pos2)) = &mut self.selection_rect { + *pos2 = *mouse_pos_m; + } + } + + 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 + ); + } + } + + fn place_single(&mut self, map: &mut Map, mouse_pos_m: &Vec2) { + if let Some((pos1, pos2)) = self.selection_rect { + // Select all items on the map that are inside of the selection rectangle + let bounds = Rect::bounding_rect(pos1, pos2); + for element in map.elements_mut() { + // TODO: Make it possible to do this additively by custom keybinding. + element.set_selected(bounds.contains_rect(&element.bounding_rect())); + } + self.selection_rect = None; + } else { + self.selection_rect = Some((*mouse_pos_m, *mouse_pos_m)); + } + } + + fn abort(&mut self) { + self.selection_rect = None; + } +} -- cgit v1.2.3-70-g09d2