aboutsummaryrefslogtreecommitdiff
path: root/src/editor.rs
diff options
context:
space:
mode:
authorArne Dußin2020-12-21 21:12:01 +0100
committerGitHub2020-12-21 21:12:01 +0100
commitc435f278eddcada279fdc424120e4a1448843c20 (patch)
treebe9a5601e99608966d4ccd146c3bfb3a70c7fc02 /src/editor.rs
parent3bc690803fb59493ea8180fd630d65b3e26642d0 (diff)
parent82d11b7d3e15d8175accf7579db1fbe528fc6583 (diff)
downloadgraf_karto-c435f278eddcada279fdc424120e4a1448843c20.tar.gz
graf_karto-c435f278eddcada279fdc424120e4a1448843c20.zip
Merge pull request #24 from LordSentox/refactor
Refactor to make interaction between tools easier
Diffstat (limited to 'src/editor.rs')
-rw-r--r--src/editor.rs163
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
}
}