aboutsummaryrefslogtreecommitdiff
path: root/src/snapping.rs
diff options
context:
space:
mode:
Diffstat (limited to 'src/snapping.rs')
-rw-r--r--src/snapping.rs79
1 files changed, 79 insertions, 0 deletions
diff --git a/src/snapping.rs b/src/snapping.rs
new file mode 100644
index 0000000..325b62e
--- /dev/null
+++ b/src/snapping.rs
@@ -0,0 +1,79 @@
+//! Responsible for snapping a position with a granularity
+//!
+//! Most of us are not capable of adjusting everything with sub-pixel accuracy. For us filthy casuals,
+//! Snapping was invented. However I hate programs where there is only one option for granularity, so
+//! I thought it should be changeable. This module is responsible for snapping and managing the user
+//! instructions telling the program what granularity should currently be used, if any.
+
+use crate::gui::DecimalNumBox;
+use crate::math::{self, Vec2};
+use raylib::drawing::RaylibDrawHandle;
+use raylib::ffi::KeyboardKey;
+use raylib::RaylibHandle;
+
+/// The struct containing the current snapping information of the program.
+pub struct Snapper {
+ grain: f64,
+ grain_gui: DecimalNumBox<f64>,
+}
+
+impl Snapper {
+ /// Create a new snapper with the default granularity.
+ pub fn new() -> Self {
+ Self::default()
+ }
+
+ /// Update the grain according to the input the program receives.
+ pub fn update(&mut self, rl: &mut RaylibHandle) {
+ if !self.grain_gui.active() && rl.is_key_pressed(KeyboardKey::KEY_G) {
+ self.grain_gui.set_active(true);
+ }
+
+ if !self.grain_gui.active() {
+ return;
+ }
+
+ self.grain_gui.update(rl);
+
+ if rl.is_key_pressed(KeyboardKey::KEY_ENTER) {
+ self.grain_gui.set_active(false);
+ self.grain = self.grain_gui.value();
+ self.grain_gui.set_value(self.grain);
+ } else if rl.is_key_pressed(KeyboardKey::KEY_ESCAPE) {
+ self.grain_gui.set_active(false);
+ self.grain_gui.set_value(self.grain);
+ }
+ }
+
+ /// Draw the snapper gui
+ pub fn draw(&self, rld: &mut RaylibDrawHandle) {
+ self.grain_gui.draw(
+ rld,
+ "m",
+ &Vec2::new(15., (rld.get_screen_height() - 25) as f64),
+ );
+ }
+
+ /// Get the current granularity of the world snapping in meters. Snapping always starts at (0, 0)
+ pub fn grain(&self) -> f64 {
+ self.grain
+ }
+
+ /// Snap a vector to the grid with the factor being the sub-grid accuracy. For instance, 0.5 will
+ /// snap to half a grid cell, while 2.0 would snap to every second grid cell.
+ pub fn snap(&self, pos: Vec2<f64>) -> Vec2<f64> {
+ Vec2::new(
+ math::round(pos.x, self.grain),
+ math::round(pos.y, self.grain),
+ )
+ }
+}
+
+impl Default for Snapper {
+ fn default() -> Self {
+ Self {
+ grain: 0.5,
+ grain_gui: DecimalNumBox::new(0.5),
+ }
+ }
+}