diff options
Diffstat (limited to 'src/editor.rs')
| -rw-r--r-- | src/editor.rs | 163 |
1 files changed, 127 insertions, 36 deletions
diff --git a/src/editor.rs b/src/editor.rs index b2260f1..e6a2dcb 100644 --- a/src/editor.rs +++ b/src/editor.rs @@ -1,71 +1,115 @@ +use crate::button::{Button, MouseButton}; use crate::config::Config; -use crate::map_data::MapData; +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::ffi::KeyboardKey; use raylib::{RaylibHandle, RaylibThread}; -use std::mem; +use std::collections::HashMap; 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, + ), + ); + tools.insert( + ToolType::SelectionTool, + ( + Box::new(SelectionTool::new()), + config.tool_activation_keys.selection, + ), + ); 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 +120,68 @@ 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); + + // 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); - for tool in &mut self.tools { - tool.update(&self.map_data, rl, transform); + // 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(); } - self.tools[self.active].active_update(&mut self.map_data, rl, transform, mouse_blocked); + // 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() + }; + + 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 } } |
