From f92e9f6f07b1e3834c2ca58ce3510734819d08e4 Mon Sep 17 00:00:00 2001 From: Arne Dußin Date: Wed, 27 Jan 2021 14:01:50 +0100 Subject: Rework graf karto to fit the client/server structure --- src/client/gui/tool_sidebar.rs | 91 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 91 insertions(+) create mode 100644 src/client/gui/tool_sidebar.rs (limited to 'src/client/gui/tool_sidebar.rs') diff --git a/src/client/gui/tool_sidebar.rs b/src/client/gui/tool_sidebar.rs new file mode 100644 index 0000000..3147bf8 --- /dev/null +++ b/src/client/gui/tool_sidebar.rs @@ -0,0 +1,91 @@ +//! The sidebar showing all tools available to the user. This toolbar handles changing the active tool +//! based on the mouse input and (TODO!) keyboard inputs. +// TODO: Currently, the keyboard shortcuts for tools are handled by the editor, but a lot speaks for +// them being handled by the ToolSidebar instead. + +use crate::client::input::Input; +use crate::client::tool::ToolType; +use crate::client::Editor; +use crate::math::Rect; +use raylib::core::texture::Texture2D; +use raylib::rgui::RaylibDrawGui; +use raylib::{RaylibHandle, RaylibThread}; +use std::mem; + +/// The file containing textures for all buttons describing the tools. +pub const BUTTON_FILE: &str = "assets/button/tool_buttons.png"; + +/// Sidebar that renders and handles input for the tool activation buttons. +pub struct ToolSidebar { + button_texture: Texture2D, + bindings_id: usize, + panel_rect: Rect, +} + +impl ToolSidebar { + /// Create a new tool sidebar. There should be only one sidebar per program instance. + pub fn new(rl: &mut RaylibHandle, rlt: &RaylibThread, input: &mut Input) -> Self { + let button_texture = rl + .load_texture(rlt, BUTTON_FILE) + .expect("Could not read file containing tool icons."); + + let panel_rect = Self::panel_rect(rl.get_screen_height() as u16); + let bindings_id = input.add_local_handler(panel_rect.clone()); + + Self { + button_texture, + bindings_id, + panel_rect, + } + } + + fn panel_rect(screen_height: u16) -> Rect { + /* The width is currently hardcoded as 104, which is + * 64 (button-size) + 20 left gap + 20 right gap + */ + Rect::new(0, 0, 104, screen_height) + } + + /// Update the state of the tool sidebar. Due to raylib limitations, this is not where the tools + /// are selected for the editor, which happens in draw. + pub fn update(&mut self, screen_height: u16, input: &mut Input) { + let new_panel_rect = Self::panel_rect(screen_height); + if new_panel_rect != self.panel_rect { + self.panel_rect = new_panel_rect; + input.set_binding_rect(self.bindings_id, self.panel_rect); + } + } + + /// Draw the tool buttons and encasing panel. Because of the way raylib works, this also handles + /// clicking on tool buttons, which may be changed in the future, should a different gui be + /// chosen. + pub fn draw(&self, rld: &mut impl RaylibDrawGui, editor: &mut Editor) { + rld.gui_panel(Rect::new( + self.panel_rect.x as f32, + self.panel_rect.y as f32, + self.panel_rect.w as f32, + self.panel_rect.h as f32, + )); + + // TODO: Update to new input system. Create buttons that integrate. + 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); + } +} -- cgit v1.2.3-70-g09d2