aboutsummaryrefslogtreecommitdiff
path: root/src/tool/icon_tool.rs
diff options
context:
space:
mode:
authorArne Dußin2020-12-15 00:46:54 +0100
committerArne Dußin2020-12-15 22:51:46 +0100
commit9799d3c6a8f0c242668203a1c70d7b6cfed3e855 (patch)
tree9116acbc886f680f82309a42b4e6147e65c1433b /src/tool/icon_tool.rs
parent3bc690803fb59493ea8180fd630d65b3e26642d0 (diff)
downloadgraf_karto-9799d3c6a8f0c242668203a1c70d7b6cfed3e855.tar.gz
graf_karto-9799d3c6a8f0c242668203a1c70d7b6cfed3e855.zip
Refactor to make interaction between tools easier
Diffstat (limited to 'src/tool/icon_tool.rs')
-rw-r--r--src/tool/icon_tool.rs197
1 files changed, 30 insertions, 167 deletions
diff --git a/src/tool/icon_tool.rs b/src/tool/icon_tool.rs
index e972c1c..09b0ac1 100644
--- a/src/tool/icon_tool.rs
+++ b/src/tool/icon_tool.rs
@@ -1,115 +1,33 @@
use crate::button::Button;
-use crate::config::{IconToolKeybindings, ToolKeybindings};
-use crate::grid::{snap_to_grid, SNAP_SIZE};
-use crate::map_data::MapData;
+use crate::config::IconToolKeys;
+use crate::map::icon_renderer::IconRenderer;
+use crate::map::{Icon, Map, Mappable};
use crate::math::Vec2;
use crate::tool::Tool;
use crate::transform::Transform;
-use raylib::core::drawing::{RaylibDraw, RaylibDrawHandle};
-use raylib::core::texture::Texture2D;
-use raylib::ffi::Color;
-use raylib::{RaylibHandle, RaylibThread};
-use ron::de::from_reader;
-use serde::{Deserialize, Serialize};
-use std::fs::{self, File};
+use raylib::core::drawing::RaylibDrawHandle;
+use std::rc::Rc;
pub const ICON_DIR: &str = "assets/icons";
-#[derive(Deserialize)]
-struct IconFileInfo {
- /// The position the icon should be anchored in pixels. This is the Vector it will be moved by
- /// relative to the mouse pointer (to the left and up).
- anchor: Vec2<f64>,
- /// The scale of the icon as expressed in image pixels per real meter.
- pixels_per_m: f64,
-}
-
-#[derive(Clone, Serialize, Deserialize)]
-pub struct IconInfo {
- /// The id of the icon is the icons position in the currently loaded icon_data vector.
- pub icon_id: usize,
- /// The position of the icon on the map, given by the vector in meters.
- pub position: Vec2<f64>,
- /// Rotation of the icon texture in degrees.
- pub rotation: f64,
-}
-
pub struct IconTool {
// TODO: support svg
- keybindings: IconToolKeybindings,
- /// The icon data, containing the image texture and the info for that image texture like the
- /// scale the image actually has.
- icon_data: Vec<(Texture2D, IconFileInfo)>,
+ keybindings: IconToolKeys,
/// Saves whether the IconTool is the currently active tool or not.
active: bool,
/// The information of the icon that should be placed / is currently being placed, if it
/// exists.
- current_icon: IconInfo,
-}
-
-impl Default for IconInfo {
- fn default() -> Self {
- Self {
- icon_id: 0,
- position: Vec2::new(0., 0.),
- rotation: 0.,
- }
- }
+ current_icon: Icon,
+ renderer: Rc<IconRenderer>,
}
impl IconTool {
- pub fn new(
- rl: &mut RaylibHandle,
- rlt: &RaylibThread,
- keybindings: IconToolKeybindings,
- ) -> Self {
- /* Read all available icons from the icon directory. SVGs do not need any special scale
- * file, but pixel-based file formats require a RON-file declaring what the scale of the
- * picture is right beside them.
- */
- let mut image_files = Vec::new();
- for entry in fs::read_dir(ICON_DIR).expect("Could not open icon directory") {
- let entry = entry.expect("Failed to read file from icon directory");
-
- // Ignore the RON-files for now and put the image files into the vec
- if entry
- .path()
- .extension()
- .expect("Entry does not have a file extension")
- != "ron"
- {
- image_files.push(entry);
- }
- }
-
- // Read the RON-files where it is necessary.
- let mut icon_data = Vec::with_capacity(image_files.len());
- for file in image_files {
- // TODO: Handle svg
-
- let texture = rl
- .load_texture(
- rlt,
- file.path()
- .to_str()
- .expect("Unable to convert path to string."),
- )
- .expect("Could not read image file");
-
- let mut file = file.path();
- file.set_extension("ron");
- let ron = File::open(file).expect("Could not read ron file for icon information.");
- let icon_info: IconFileInfo =
- from_reader(ron).expect("Could not parse icon info from reader.");
-
- icon_data.push((texture, icon_info));
- }
-
+ pub fn new(keybindings: IconToolKeys, renderer: Rc<IconRenderer>) -> Self {
Self {
keybindings,
- icon_data,
active: false,
- current_icon: IconInfo::default(),
+ current_icon: Icon::new(0, Vec2::default(), 0., renderer.clone()),
+ renderer,
}
}
}
@@ -123,85 +41,30 @@ impl Tool for IconTool {
self.active = false;
}
- 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()),
- SNAP_SIZE,
- );
- 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, 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, mouse_blocked)
- {
- self.current_icon.rotation += 45.;
- }
-
- // Handle placing the icon on the map
- if self.keybindings.place.is_pressed(rl, mouse_blocked) {
- map.icons_mut().push(self.current_icon.clone());
- }
+ fn update(&mut self, _map: &Map, mouse_pos_m: &Vec2<f64>) {
+ self.current_icon.position = *mouse_pos_m;
}
- fn draw(&self, map: &MapData, rld: &mut RaylibDrawHandle, transform: &Transform) {
- // Draw all icons that have been placed on the map.
- for icon in map.icons() {
- let (texture, info) = &self.icon_data[icon.icon_id];
- // Round the position to whole pixels to fix rotation problems.
- let mut position_px =
- transform.point_m_to_px(&(icon.position - (info.anchor / info.pixels_per_m)));
- position_px.x = position_px.x.floor();
- position_px.y = position_px.y.floor();
- rld.draw_texture_ex(
- texture,
- position_px,
- icon.rotation as f32,
- (transform.pixels_per_m() / info.pixels_per_m) as f32,
- Color {
- r: 255,
- g: 255,
- b: 255,
- a: 255,
- },
- );
- }
-
- // Draw the icon that would be placed
+ fn draw(&self, rld: &mut RaylibDrawHandle, transform: &Transform) {
if self.active {
- let (texture, info) = &self.icon_data[self.current_icon.icon_id];
- // Round the position to whole pixels to fix rotation problems.
- let mut position_px = transform
- .point_m_to_px(&(self.current_icon.position - (info.anchor / info.pixels_per_m)));
- position_px.x = position_px.x.floor();
- position_px.y = position_px.y.floor();
- rld.draw_texture_ex(
- texture,
- position_px,
- self.current_icon.rotation as f32,
- (transform.pixels_per_m() / info.pixels_per_m) as f32,
- Color {
- r: 120,
- g: 200,
- b: 120,
- a: 255,
- },
- );
+ self.current_icon.draw(rld, transform);
}
}
- fn activation_key(&self) -> Button {
- self.keybindings.activation_key()
+ fn place_single(&mut self, map: &mut Map, _mouse_pos_m: &Vec2<f64>) {
+ map.push_icon(self.current_icon.clone());
+ }
+
+ fn on_button_pressed(&mut self, _map: &mut Map, button: Button) {
+ if button == self.keybindings.next {
+ self.current_icon.id = (self.current_icon.id + 1) % self.renderer.num_icons();
+ } else if button == self.keybindings.previous {
+ self.current_icon.id =
+ (self.current_icon.id + self.renderer.num_icons() - 1) % self.renderer.num_icons();
+ } else if button == self.keybindings.rotate_clockwise {
+ self.current_icon.rotation += 45.;
+ } else if button == self.keybindings.rotate_counterclockwise {
+ self.current_icon.rotation -= 45.;
+ }
}
}