diff options
| author | Arne Dußin | 2020-11-20 20:00:28 +0100 |
|---|---|---|
| committer | Arne Dußin | 2020-11-20 20:00:28 +0100 |
| commit | cf0cbe3fd28b2099b580edc1714b4d68bf7183cd (patch) | |
| tree | b03561c1ae7860cad247d089cb1ad728efa843ec | |
| parent | f62dabcb390d4808739745c050dfba8e2826b214 (diff) | |
| download | graf_karto-cf0cbe3fd28b2099b580edc1714b4d68bf7183cd.tar.gz graf_karto-cf0cbe3fd28b2099b580edc1714b4d68bf7183cd.zip | |
Add simple tool sidebar gui
| -rw-r--r-- | assets/button/tool_buttons.png | bin | 0 -> 24125 bytes | |||
| -rw-r--r-- | assets/button/tool_buttons.xcf | bin | 0 -> 53024 bytes | |||
| -rw-r--r-- | src/button.rs | 4 | ||||
| -rw-r--r-- | src/editor.rs | 28 | ||||
| -rw-r--r-- | src/gui/mod.rs | 3 | ||||
| -rw-r--r-- | src/gui/tool_sidebar.rs | 58 | ||||
| -rw-r--r-- | src/main.rs | 10 | ||||
| -rw-r--r-- | src/tool/deletion_tool.rs | 19 | ||||
| -rw-r--r-- | src/tool/icon_tool.rs | 18 | ||||
| -rw-r--r-- | src/tool/mod.rs | 10 | ||||
| -rw-r--r-- | src/tool/room_tool.rs | 16 | ||||
| -rw-r--r-- | src/tool/wall_tool.rs | 19 |
12 files changed, 155 insertions, 30 deletions
diff --git a/assets/button/tool_buttons.png b/assets/button/tool_buttons.png Binary files differnew file mode 100644 index 0000000..2a6a214 --- /dev/null +++ b/assets/button/tool_buttons.png diff --git a/assets/button/tool_buttons.xcf b/assets/button/tool_buttons.xcf Binary files differnew file mode 100644 index 0000000..9cd012b --- /dev/null +++ b/assets/button/tool_buttons.xcf diff --git a/src/button.rs b/src/button.rs index ae78dbb..89ce9a5 100644 --- a/src/button.rs +++ b/src/button.rs @@ -134,9 +134,9 @@ pub enum KeyboardKey { } impl Button { - pub fn is_pressed(self, rl: &RaylibHandle) -> bool { + pub fn is_pressed(self, rl: &RaylibHandle, mouse_blocked: bool) -> bool { match self { - Self::Mouse(button) => rl.is_mouse_button_pressed(button.into()), + Self::Mouse(button) => !mouse_blocked && rl.is_mouse_button_pressed(button.into()), Self::Keyboard(key) => rl.is_key_pressed(key.into()), } } diff --git a/src/editor.rs b/src/editor.rs index f8ee4bc..a2eb9c8 100644 --- a/src/editor.rs +++ b/src/editor.rs @@ -5,6 +5,7 @@ use crate::transform::Transform; use raylib::core::drawing::RaylibDrawHandle; use raylib::ffi::KeyboardKey; use raylib::{RaylibHandle, RaylibThread}; +use std::mem; pub struct Editor { map_data: MapData, @@ -33,21 +34,30 @@ impl Editor { } } - pub fn update(&mut self, rl: &RaylibHandle, transform: &Transform) { + /// Get the currently active tool. + pub fn active(&self) -> ToolType { + unsafe { mem::transmute(self.active as u8) } + } + + /// 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) { + self.tools[self.active].deactivate(); + self.active = tool as usize; + self.tools[self.active].activate(); + } + + pub fn update(&mut self, rl: &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) { + if tool.activation_key().is_pressed(rl, false) { // Don't do anything if the tool does not change. if i == self.active { break; } - /* Deactivate the current tool and activate the tool, of which the keybinding has - * been pressed. - */ - self.tools[self.active].deactivate(); - self.active = i; - self.tools[self.active].activate(); + // Activate the tool of which the key binding has been pressed. + self.set_active(unsafe { mem::transmute(i as u8) }); break; } } @@ -67,7 +77,7 @@ impl Editor { tool.update(&self.map_data, rl, transform); } - self.tools[self.active].active_update(&mut self.map_data, rl, transform); + self.tools[self.active].active_update(&mut self.map_data, rl, transform, mouse_blocked); } pub fn draw_tools(&self, rld: &mut RaylibDrawHandle, transform: &Transform) { diff --git a/src/gui/mod.rs b/src/gui/mod.rs new file mode 100644 index 0000000..a4a000b --- /dev/null +++ b/src/gui/mod.rs @@ -0,0 +1,3 @@ +pub mod tool_sidebar; + +pub use self::tool_sidebar::*; diff --git a/src/gui/tool_sidebar.rs b/src/gui/tool_sidebar.rs new file mode 100644 index 0000000..32d0410 --- /dev/null +++ b/src/gui/tool_sidebar.rs @@ -0,0 +1,58 @@ +use crate::math::{Rect, Vec2}; +use crate::tool::ToolType; +use crate::Editor; +use raylib::core::drawing::{RaylibDraw, RaylibDrawHandle}; +use raylib::core::texture::Texture2D; +use raylib::rgui::RaylibDrawGui; +use raylib::{RaylibHandle, RaylibThread}; +use std::mem; + +pub const BUTTON_FILE: &str = "assets/button/tool_buttons.png"; + +pub struct ToolSidebar { + button_texture: Texture2D, +} + +impl ToolSidebar { + pub fn new(rl: &mut RaylibHandle, rlt: &RaylibThread) -> Self { + let button_texture = rl + .load_texture(rlt, BUTTON_FILE) + .expect("Could not read file containing tool icons."); + + Self { button_texture } + } + + fn panel_rect(screen_height: u16) -> Rect<f32> { + Rect::new(0., 0., 104., screen_height as f32) + } + + /// Check if the mouse is currently being captured by this GUI-element. In that case, + /// everything else that might want to access the mouse will be blocked. + pub fn mouse_captured(screen_height: u16, mouse_pos: Vec2<f32>) -> bool { + Self::panel_rect(screen_height).contains(mouse_pos) + } + + pub fn draw(&self, screen_height: u16, rld: &mut impl RaylibDrawGui, editor: &mut Editor) { + rld.gui_panel(Self::panel_rect(screen_height)); + + let mut active = editor.active(); + for i in 0..ToolType::NumTools as usize { + let is_current_active = active as usize == i; + if rld.gui_image_button_ex( + Rect::new(20., i as f32 * 100. + 20., 64., 64.), + None, + &self.button_texture, + Rect::new( + is_current_active as u8 as f32 * 64., + i as f32 * 64., + 64., + 64., + ), + ) { + active = unsafe { mem::transmute(i as u8) }; + } + } + + editor.set_active(active); + } +} diff --git a/src/main.rs b/src/main.rs index 8e3bf51..1ebcbfe 100644 --- a/src/main.rs +++ b/src/main.rs @@ -8,6 +8,7 @@ pub mod config; pub mod dimension_indicator; pub mod editor; pub mod grid; +pub mod gui; pub mod map_data; pub mod math; pub mod svg; @@ -16,6 +17,7 @@ pub mod transform; use config::Config; use editor::Editor; +use gui::ToolSidebar; use raylib::prelude::*; use std::io; use transform::Transform; @@ -52,6 +54,7 @@ fn main() { }; let mut editor = Editor::new(&mut rl, &thread, config); + let tool_sidebar = ToolSidebar::new(&mut rl, &thread); let mut transform = Transform::new(); let mut last_mouse_pos = rl.get_mouse_position(); @@ -74,7 +77,11 @@ fn main() { ); } - editor.update(&rl, &transform); + editor.update( + &rl, + &transform, + ToolSidebar::mouse_captured(screen_height as u16, rl.get_mouse_position().into()), + ); // Update the last mouse position last_mouse_pos = rl.get_mouse_position(); @@ -86,6 +93,7 @@ fn main() { grid::draw_grid(&mut d, screen_width, screen_height, &transform); editor.draw_tools(&mut d, &transform); + tool_sidebar.draw(screen_height as u16, &mut d, &mut editor); } } } diff --git a/src/tool/deletion_tool.rs b/src/tool/deletion_tool.rs index bd80809..c313574 100644 --- a/src/tool/deletion_tool.rs +++ b/src/tool/deletion_tool.rs @@ -40,18 +40,29 @@ impl Tool for DeletionTool { self.deletion_rect = None; } - fn active_update(&mut self, map_data: &mut MapData, rl: &RaylibHandle, transform: &Transform) { + fn active_update( + &mut self, + map_data: &mut MapData, + rl: &RaylibHandle, + transform: &Transform, + mouse_blocked: bool, + ) { let mouse_pos_m = transform.point_px_to_m(rl.get_mouse_position().into()); if let Some((_, ref mut pos2)) = &mut self.deletion_rect { *pos2 = mouse_pos_m; } - if self.keybindings.do_delete.is_pressed(rl) && self.deletion_rect.is_some() { + if self.keybindings.do_delete.is_pressed(rl, mouse_blocked) && self.deletion_rect.is_some() + { let (pos1, pos2) = self.deletion_rect.take().unwrap(); Self::delete_rect(map_data, Rect::bounding_rect(pos1, pos2)); - } else if self.keybindings.start_selection.is_pressed(rl) { + } else if self + .keybindings + .start_selection + .is_pressed(rl, mouse_blocked) + { self.deletion_rect = Some((mouse_pos_m, mouse_pos_m)) - } else if self.keybindings.abort_deletion.is_pressed(rl) { + } else if self.keybindings.abort_deletion.is_pressed(rl, false) { self.deletion_rect = None; } } diff --git a/src/tool/icon_tool.rs b/src/tool/icon_tool.rs index bd16de8..4b3a1eb 100644 --- a/src/tool/icon_tool.rs +++ b/src/tool/icon_tool.rs @@ -123,7 +123,13 @@ impl Tool for IconTool { self.active = false; } - fn active_update(&mut self, map: &mut MapData, rl: &RaylibHandle, transform: &Transform) { + fn active_update( + &mut self, + map: &mut MapData, + rl: &RaylibHandle, + transform: &Transform, + mouse_blocked: bool, + ) { // Update the position of the icon that should be drawn to the current mouse position. let snapped_mouse_pos_m = snap_to_grid( transform.point_px_to_m(rl.get_mouse_position().into()), @@ -132,15 +138,19 @@ impl Tool for IconTool { self.current_icon.position = snapped_mouse_pos_m; // Unwrap the current icon, since it is now definitely set, as we are in the active update. - if self.keybindings.next.is_pressed(rl) { + if self.keybindings.next.is_pressed(rl, mouse_blocked) { self.current_icon.icon_id = (self.current_icon.icon_id + 1) % self.icon_data.len(); } - if self.keybindings.rotate_clockwise.is_pressed(rl) { + if self + .keybindings + .rotate_clockwise + .is_pressed(rl, mouse_blocked) + { self.current_icon.rotation += 45.; } // Handle placing the icon on the map - if self.keybindings.place.is_pressed(rl) { + if self.keybindings.place.is_pressed(rl, mouse_blocked) { map.icons_mut().push(self.current_icon.clone()); } } diff --git a/src/tool/mod.rs b/src/tool/mod.rs index 3b9b845..e528b8f 100644 --- a/src/tool/mod.rs +++ b/src/tool/mod.rs @@ -14,7 +14,7 @@ use crate::transform::Transform; use raylib::core::drawing::RaylibDrawHandle; use raylib::RaylibHandle; -#[derive(Debug)] +#[derive(Copy, Clone, Debug, PartialEq)] #[repr(u8)] pub enum ToolType { RoomTool, @@ -29,7 +29,13 @@ pub trait Tool { fn deactivate(&mut self) {} fn update(&mut self, _map: &MapData, _rl: &RaylibHandle, _transform: &Transform) {} - fn active_update(&mut self, map: &mut MapData, rl: &RaylibHandle, transform: &Transform); + fn active_update( + &mut self, + map: &mut MapData, + rl: &RaylibHandle, + transform: &Transform, + mouse_blocked: bool, + ); fn draw(&self, _map: &MapData, _rld: &mut RaylibDrawHandle, _transform: &Transform) {} diff --git a/src/tool/room_tool.rs b/src/tool/room_tool.rs index 3416596..c4a8b8c 100644 --- a/src/tool/room_tool.rs +++ b/src/tool/room_tool.rs @@ -35,7 +35,13 @@ impl Tool for RoomTool { self.dimension_indicator.clear_dimensions(); } - fn active_update(&mut self, map_data: &mut MapData, rl: &RaylibHandle, transform: &Transform) { + fn active_update( + &mut self, + map_data: &mut MapData, + rl: &RaylibHandle, + transform: &Transform, + mouse_blocked: bool, + ) { let mouse_pos_m = transform.point_px_to_m(rl.get_mouse_position().into()); // Update the currently drawn rectangle, if it exists, and also its dimension indicator. if let Some((ref pos1, ref mut pos2)) = &mut self.unfinished_rect { @@ -45,16 +51,18 @@ impl Tool for RoomTool { } // Start or finish drawing the currently unfinished rectangle - if self.keybindings.finish_draw.is_pressed(rl) && self.unfinished_rect.is_some() { + if self.keybindings.finish_draw.is_pressed(rl, mouse_blocked) + && self.unfinished_rect.is_some() + { let (pos1, pos2) = self.unfinished_rect.take().unwrap(); self.dimension_indicator.clear_dimensions(); map_data.rooms_mut().push(Rect::bounding_rect(pos1, pos2)); - } else if self.keybindings.start_draw.is_pressed(rl) { + } else if self.keybindings.start_draw.is_pressed(rl, mouse_blocked) { let snapped_mouse_pos = snap_to_grid(mouse_pos_m, SNAP_SIZE); self.unfinished_rect = Some((snapped_mouse_pos, snapped_mouse_pos)) } - if self.keybindings.abort_draw.is_pressed(rl) { + if self.keybindings.abort_draw.is_pressed(rl, false) { self.unfinished_rect = None; } } diff --git a/src/tool/wall_tool.rs b/src/tool/wall_tool.rs index 85079b0..2cc5b5d 100644 --- a/src/tool/wall_tool.rs +++ b/src/tool/wall_tool.rs @@ -28,22 +28,33 @@ impl Tool for WallTool { self.unfinished_wall = None; } - fn active_update(&mut self, map_data: &mut MapData, rl: &RaylibHandle, transform: &Transform) { + fn active_update( + &mut self, + map_data: &mut MapData, + rl: &RaylibHandle, + transform: &Transform, + mouse_blocked: bool, + ) { let mouse_pos_m = transform.point_px_to_m(rl.get_mouse_position().into()); if let Some((_, ref mut pos2)) = &mut self.unfinished_wall { *pos2 = snap_to_grid(mouse_pos_m, SNAP_SIZE); } - if self.keybindings.finish_segment.is_pressed(rl) && self.unfinished_wall.is_some() { + if self + .keybindings + .finish_segment + .is_pressed(rl, mouse_blocked) + && self.unfinished_wall.is_some() + { let (pos1, pos2) = self.unfinished_wall.unwrap(); map_data.walls_mut().push((pos1, pos2)); self.unfinished_wall = Some((pos2, pos2)); - } else if self.keybindings.start_wall.is_pressed(rl) { + } else if self.keybindings.start_wall.is_pressed(rl, mouse_blocked) { let snapped_mouse_pos = snap_to_grid(mouse_pos_m, SNAP_SIZE); self.unfinished_wall = Some((snapped_mouse_pos, snapped_mouse_pos)) } - if self.keybindings.abort_segment.is_pressed(rl) { + if self.keybindings.abort_segment.is_pressed(rl, false) { self.unfinished_wall = None; } } |
