aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorArne Dußin2020-11-20 20:00:28 +0100
committerArne Dußin2020-11-20 20:00:28 +0100
commitcf0cbe3fd28b2099b580edc1714b4d68bf7183cd (patch)
treeb03561c1ae7860cad247d089cb1ad728efa843ec
parentf62dabcb390d4808739745c050dfba8e2826b214 (diff)
downloadgraf_karto-cf0cbe3fd28b2099b580edc1714b4d68bf7183cd.tar.gz
graf_karto-cf0cbe3fd28b2099b580edc1714b4d68bf7183cd.zip
Add simple tool sidebar gui
-rw-r--r--assets/button/tool_buttons.pngbin0 -> 24125 bytes
-rw-r--r--assets/button/tool_buttons.xcfbin0 -> 53024 bytes
-rw-r--r--src/button.rs4
-rw-r--r--src/editor.rs28
-rw-r--r--src/gui/mod.rs3
-rw-r--r--src/gui/tool_sidebar.rs58
-rw-r--r--src/main.rs10
-rw-r--r--src/tool/deletion_tool.rs19
-rw-r--r--src/tool/icon_tool.rs18
-rw-r--r--src/tool/mod.rs10
-rw-r--r--src/tool/room_tool.rs16
-rw-r--r--src/tool/wall_tool.rs19
12 files changed, 155 insertions, 30 deletions
diff --git a/assets/button/tool_buttons.png b/assets/button/tool_buttons.png
new file mode 100644
index 0000000..2a6a214
--- /dev/null
+++ b/assets/button/tool_buttons.png
Binary files differ
diff --git a/assets/button/tool_buttons.xcf b/assets/button/tool_buttons.xcf
new file mode 100644
index 0000000..9cd012b
--- /dev/null
+++ b/assets/button/tool_buttons.xcf
Binary files differ
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;
}
}