aboutsummaryrefslogtreecommitdiff
path: root/src/editor.rs
diff options
context:
space:
mode:
Diffstat (limited to 'src/editor.rs')
-rw-r--r--src/editor.rs135
1 files changed, 99 insertions, 36 deletions
diff --git a/src/editor.rs b/src/editor.rs
index b2260f1..bbe4f60 100644
--- a/src/editor.rs
+++ b/src/editor.rs
@@ -1,71 +1,108 @@
+use crate::button::{Button, MouseButton};
use crate::config::Config;
-use crate::map_data::MapData;
+use crate::map::Map;
use crate::tool::*;
use crate::transform::Transform;
use raylib::core::drawing::RaylibDrawHandle;
-use raylib::ffi::KeyboardKey;
use raylib::{RaylibHandle, RaylibThread};
-use std::mem;
+use std::collections::HashMap;
+use crate::grid::{snap_to_grid, SNAP_SIZE};
pub struct Editor {
- map_data: MapData,
- tools: Vec<Box<dyn Tool>>,
- active: usize,
+ map: Map,
+ /// HashMap that matches the ToolType with its proper activation key and of course the tool
+ /// itself.
+ tools: HashMap<ToolType, (Box<dyn Tool>, Button)>,
+ active: ToolType,
+ config: Config
}
impl Editor {
pub fn new(rl: &mut RaylibHandle, rlt: &RaylibThread, config: Config) -> Self {
- let mut tools: Vec<Box<dyn Tool>> = Vec::with_capacity(ToolType::NumTools as usize);
- assert_eq!(ToolType::RoomTool as u8, 0);
- tools.push(Box::new(RoomTool::new(config.room_keybindings)));
- assert_eq!(ToolType::PolygonRoomTool as u8, 1);
- tools.push(Box::new(PolygonRoomTool::new(config.polygon_keybindings)));
- assert_eq!(ToolType::WallTool as u8, 2);
- tools.push(Box::new(WallTool::new(config.wall_keybindings)));
- assert_eq!(ToolType::IconTool as u8, 3);
- tools.push(Box::new(IconTool::new(rl, rlt, config.icon_keybindings)));
- assert_eq!(ToolType::DeletionTool as u8, 4);
- tools.push(Box::new(DeletionTool::new(config.deletion_keybindings)));
+ let map = Map::new(rl, rlt);
+
+ let mut tools: HashMap<ToolType, (Box<dyn Tool>, Button)> =
+ HashMap::with_capacity(ToolType::NumTools as usize);
+
+ tools.insert(
+ ToolType::RectRoomTool,
+ (
+ Box::new(RectRoomTool::new()),
+ config.tool_activation_keys.rect_room,
+ ),
+ );
+ tools.insert(
+ ToolType::PolygonRoomTool,
+ (
+ Box::new(PolygonRoomTool::new()),
+ config.tool_activation_keys.polygon_room,
+ ),
+ );
+ tools.insert(
+ ToolType::WallTool,
+ (Box::new(WallTool::new()), config.tool_activation_keys.wall),
+ );
+ tools.insert(
+ ToolType::IconTool,
+ (
+ Box::new(IconTool::new(config.icon_keys.clone(), map.icon_renderer())),
+ config.tool_activation_keys.icon,
+ ),
+ );
+ tools.insert(
+ ToolType::DeletionTool,
+ (
+ Box::new(DeletionTool::new()),
+ config.tool_activation_keys.deletion,
+ ),
+ );
assert_eq!(ToolType::NumTools as usize, tools.len());
Self {
- map_data: MapData::new(),
+ map,
tools,
- active: 0,
+ active: ToolType::RectRoomTool,
+ config
}
}
/// Get the currently active tool.
pub fn active(&self) -> ToolType {
- unsafe { mem::transmute(self.active as u8) }
+ self.active
}
/// Set the currently active tool. Any process currently going on in a different tool will be
/// aborted.
pub fn set_active(&mut self, tool: ToolType) {
- if tool as usize != self.active {
- self.tools[self.active].deactivate();
- self.active = tool as usize;
- self.tools[self.active].activate();
+ if tool != self.active {
+ self.tools.get_mut(&self.active).unwrap().0.deactivate();
+ self.active = tool;
+ self.tools
+ .get_mut(&self.active)
+ .expect("{:?} is not a Tool in the Editor. Maybe you forgot to register it?")
+ .0
+ .activate();
}
}
- pub fn update(&mut self, rl: &RaylibHandle, transform: &Transform, mouse_blocked: bool) {
+ pub fn update(&mut self, rl: &mut RaylibHandle, transform: &Transform, mouse_blocked: bool) {
// Handle keybindings for tool change
- for (i, tool) in self.tools.iter().enumerate() {
- if tool.activation_key().is_pressed(rl, false) {
+ for (&tool_type, (_, activation_key)) in self.tools.iter() {
+ if activation_key.is_pressed(rl, false) {
// Don't do anything if the tool does not change.
- if i == self.active {
+ if tool_type == self.active {
break;
}
// Activate the tool of which the key binding has been pressed.
- self.set_active(unsafe { mem::transmute(i as u8) });
+ self.set_active(tool_type);
break;
}
}
+ /*
+ TODO: reintroduce saving and loading
// Handle saving and loading the editor contents to the swap file
if rl.is_key_pressed(KeyboardKey::KEY_S) {
self.map_data
@@ -76,21 +113,47 @@ impl Editor {
.load_file("swap.ron")
.expect("Unable to read buffer file");
}
+ */
+
+ let mouse_pos_m = transform.point_px_to_m(&rl.get_mouse_position().into());
+ let snapped_mouse_pos = snap_to_grid(mouse_pos_m, SNAP_SIZE);
- for tool in &mut self.tools {
- tool.update(&self.map_data, rl, transform);
+ // Update the currently active tool
+ let active_tool = &mut self.tools.get_mut(&self.active).unwrap().0;
+ 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) {
+ active_tool.place_single(&mut self.map, &snapped_mouse_pos);
+ }
+ 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) {
+ 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()
+ };
- self.tools[self.active].active_update(&mut self.map_data, rl, transform, mouse_blocked);
+ if let Some(latest_button) = latest_button {
+ active_tool.on_button_pressed(&mut self.map, latest_button);
+ }
}
pub fn draw_tools(&self, rld: &mut RaylibDrawHandle, transform: &Transform) {
- for tool in &self.tools {
- tool.draw(&self.map_data, rld, transform);
+ for (tool, _) in self.tools.values() {
+ tool.draw(rld, transform);
}
}
- pub fn map_data(&self) -> &MapData {
- &self.map_data
+ pub fn map(&self) -> &Map {
+ &self.map
}
}