From a506a9e8c3462cfd8e6384386285c07f8f9a96a0 Mon Sep 17 00:00:00 2001
From: Nao Pross <naopross@thearcway.org>
Date: Thu, 10 Jan 2019 11:06:50 +0100
Subject: Add pan and partial zoom implementation

The zoom currently works only by zooming towards the center of the
window, when instead it should zoom under the cursor.
---
 src/graphics.rs | 61 +++++++++++++++++++++++++++++++++++++++++++++++++--------
 1 file changed, 53 insertions(+), 8 deletions(-)

diff --git a/src/graphics.rs b/src/graphics.rs
index 18ccfec..d50562d 100644
--- a/src/graphics.rs
+++ b/src/graphics.rs
@@ -1,8 +1,11 @@
 use std::collections::HashMap;
 
-use sfml::system::Vector2f;
 use sfml::window::mouse::Button;
 
+use sfml::system::{
+	Vector2f,
+};
+
 use sfml::window::{
 	ContextSettings,
 	Event,
@@ -19,12 +22,12 @@ use sfml::graphics::{
 	Texture,
 	Image,
 	Color,
-	Rect,
 };
 
 use sfml::graphics::{
 	RectangleShape,
 	Transformable,
+	Rect,
 };
 
 
@@ -39,11 +42,18 @@ pub struct Graphics {
 	view: View,
 	// status
 	running: bool,
+	panning: bool,
+	// pan
+	pan_start: Vector2f,
+	pan_start_center: Vector2f,
+	// absolute zoom
+	zoom: f32,
 	// loaded resources
 	tilesets: HashMap<u32, Image>,
 	textures: HashMap<u32, Texture>,
 }
 
+
 impl Graphics {
 	pub fn new() -> Graphics {
 		let default_window_size = (1280, 720);
@@ -80,6 +90,14 @@ impl Graphics {
 			),
 			// status
 			running: true,
+			panning: false,
+			// zoom and pan
+			pan_start: Vector2f::new(0.0, 0.0),
+			pan_start_center: Vector2f::new(
+				default_window_size.0 as f32 / 2.0,
+				default_window_size.1 as f32 / 2.0
+			),
+			zoom: 1.0,
 			// resources
 			tilesets: HashMap::new(),
 			textures: HashMap::new(),
@@ -141,6 +159,7 @@ impl Graphics {
 							}
 						};
 
+
 						let image = match Image::from_memory(asset.as_ref()) {
 							Some(image) => image,
 							None => {
@@ -205,23 +224,49 @@ impl Graphics {
 					self.window.close();
 					self.running = false;
 				},
-				Event::MouseWheelScrolled { wheel: _, delta, x, y } => {
+				Event::MouseWheelScrolled { wheel: _, delta, x: _, y: _ } => {
+					// TODO: zoom towards (x, y)
+
+					// delta is probalby a value between -1 and 1
+					let local_zoom = 1.0 + delta * 0.1;
+					// update absolute zoom
+					self.zoom *= local_zoom;
 
+					self.view.zoom(local_zoom);
+					self.window.set_view(&self.view);
 				},
-				Event::MouseButtonPressed { button, x: _, y: _ } => {
+				Event::MouseButtonPressed { button, x, y} => {
 					match button {
-						Button::Left => {},
-						Button::Right => {}
+						Button::Right => {},
+						Button::Left => {
+							// set pan start position
+							self.panning = true;
+							self.pan_start = Vector2f::new(x as f32, y as f32);
+						}
 						_ => {},
 					}
 				},
 				Event::MouseButtonReleased { button, x: _, y: _ } => {
 					match button {
-						Button::Left => {}
-						Button::Right => {},
+						Button::Right => {}
+						Button::Left => {
+							self.panning = false;
+							self.pan_start_center = self.view.center();
+						},
 						_ => {},
 					}
 				},
+				Event::MouseMoved { x, y } => {
+					if self.panning {
+						// get delta of vectors
+						// (pan_start_pos - current_mouse_pos) * zoom
+						let delta = (self.pan_start - Vector2f::new(x as f32, y as f32)) * self.zoom;
+
+						// move view by moving the center by delta
+						self.view.set_center(self.pan_start_center + delta);
+						self.window.set_view(&self.view);
+					}
+				}
 				_ => {},
 			}
 		}
-- 
cgit v1.2.1