Skip to content

Commit

Permalink
feat: Reset image zoom scale factor back to 1.0 if user has zoomed ou…
Browse files Browse the repository at this point in the history
…t too far. #12
  • Loading branch information
THEGOLDENPRO committed Oct 30, 2024
1 parent 370794e commit 602c596
Show file tree
Hide file tree
Showing 3 changed files with 96 additions and 17 deletions.
9 changes: 7 additions & 2 deletions src/app.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
use std::time::Duration;

use rdev::display_size;
use cirrus_theming::Theme;
use eframe::egui::{self, Color32, ImageSource, Margin, Rect};
Expand Down Expand Up @@ -41,6 +43,7 @@ impl eframe::App for Roseate {

self.info_box.handle_input(ctx);
self.zoom_pan.handle_zoom_input(ctx);
self.zoom_pan.handle_reset_input(ctx);

egui::CentralPanel::default().frame(central_panel_frame).show(ctx, |ui| {
let window_rect = ctx.input(|i: &egui::InputState| i.screen_rect());
Expand All @@ -62,8 +65,8 @@ impl eframe::App for Roseate {
return;
}

self.zoom_pan.update(ctx);
self.info_box.update(ctx);
self.zoom_pan.update(ctx);

if !self.image_loaded {
let mutable_image = self.image.as_mut().unwrap();
Expand Down Expand Up @@ -91,9 +94,11 @@ impl eframe::App for Roseate {
);

if self.zoom_pan.is_pan_out_of_bounds([scaled_image_width, scaled_image_height].into()) {
self.zoom_pan.schedule_pan_reset();
self.zoom_pan.schedule_pan_reset(Duration::from_millis(300));
};

// NOTE: umm do we move this to window scaling... *probably* if we
// want to stay consistent with zoom_pan but this isn't important right now.
let scaled_image_width_animated = egui_animation::animate_eased(
ctx, "image_scale_width", scaled_image_width, 1.5, simple_easing::cubic_in_out
) as u32;
Expand Down
2 changes: 2 additions & 0 deletions src/window_scaling.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ use std::time::{Duration, Instant};

use eframe::egui::Rect;
use imagesize::ImageSize;
use log::debug;

/// Struct that handles the image auto resizing with window size.
pub struct WindowScaling {
Expand All @@ -20,6 +21,7 @@ impl WindowScaling {
/// Resizes the image to the window size after a short delay
/// or later in the update loop (hence being named 'schedule_').
pub fn schedule_image_scale_to_window_size(&mut self) {
debug!("The image has been scheduled to resize to the window size.");
self.resize_to_window_timer = Some(Instant::now());
}

Expand Down
102 changes: 87 additions & 15 deletions src/zoom_pan.rs
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
use std::time::{Duration, Instant};

use eframe::egui::{Context, Pos2, Response, Vec2};
use log::debug;
use rand::Rng;
use log::debug;
use eframe::egui::{Context, Key, Pos2, Response, Vec2};

/// Struct that controls the zoom and panning of the image.
pub struct ZoomPan {
Expand All @@ -11,7 +11,15 @@ pub struct ZoomPan {
is_panning: bool,
pan_offset: Vec2,
drag_start: Option<Pos2>,
reset_pan_offset: Option<ResetPanOffset>
reset_pan_offset: Option<ResetManager>,
reset_scale_factor: Option<ResetManager>
}

struct ResetManager {
timer: Instant,
delay: Duration,
animation_id: u32,
in_animation: bool
}

impl ZoomPan {
Expand All @@ -22,13 +30,30 @@ impl ZoomPan {
drag_start: None,
is_panning: false,
pan_offset: Vec2::ZERO,
reset_pan_offset: None
reset_pan_offset: None,
reset_scale_factor: None
}
}

pub fn update(&mut self, ctx: &Context) {
// Reset pan offset when scheduled.
// Reset pan offset when scheduled and handle animation.
self.pan_reset_update(ctx);

// Reset zoom factor scale when scheduled and handle animation.
self.scale_reset_update(ctx);

// Schedule scale factor reset if the user zoom out too far.
if self.zoom_factor < 1.0 {
self.schedule_scale_reset(Duration::from_millis(500))
}
}

pub fn handle_reset_input(&mut self, ctx: &Context) {
// TODO: make the key customizable when we get a config.
if ctx.input(|i| i.key_pressed(Key::R)) {
self.schedule_pan_reset(Duration::ZERO);
self.schedule_scale_reset(Duration::ZERO);
}
}

// Method to handle zoom input (scrolling)
Expand All @@ -41,7 +66,7 @@ impl ZoomPan {
let zoom_delta = scroll_delta * self.zoom_factor * 0.004;

// TODO: Make those clamped values customizable when we have configuration.
self.zoom_factor = (self.zoom_factor + zoom_delta).clamp(0.5, 100.0);
self.zoom_factor = (self.zoom_factor + zoom_delta).clamp(0.1, 100.0);
}
}

Expand Down Expand Up @@ -115,19 +140,14 @@ impl ZoomPan {
}
}

struct ResetPanOffset {
timer: Instant,
animation_id: u32,
in_animation: bool
}

impl ZoomPan {
pub fn schedule_pan_reset(&mut self) {
pub fn schedule_pan_reset(&mut self, delay: Duration) {
if self.reset_pan_offset.is_none() {

self.reset_pan_offset = Some(
ResetPanOffset {
ResetManager {
timer: Instant::now(),
delay: delay,
animation_id: rand::thread_rng().gen::<u32>(),
in_animation: false
}
Expand All @@ -145,7 +165,7 @@ impl ZoomPan {

if let Some(reset_pan_offset) = self.reset_pan_offset.as_mut() {

if reset_pan_offset.timer.elapsed() >= Duration::from_millis(300) {
if reset_pan_offset.timer.elapsed() >= reset_pan_offset.delay {
let mut pan_offset_x = 0.0 as f32;
let mut pan_offset_y = 0.0 as f32;

Expand Down Expand Up @@ -183,4 +203,56 @@ impl ZoomPan {
}
}
}

pub fn schedule_scale_reset(&mut self, delay: Duration) {
if self.reset_scale_factor.is_none() {

self.reset_scale_factor = Some(
ResetManager {
timer: Instant::now(),
delay: delay,
animation_id: rand::thread_rng().gen::<u32>(),
in_animation: false
}
);

debug!("Scale factor reset has been scheduled.");
}
}

fn scale_reset_update(&mut self, ctx: &Context) {
// We don't want to reset the pan offset while the user is still panning.
if self.is_panning {
return;
}

if let Some(reset_scale_factor) = self.reset_scale_factor.as_mut() {

if reset_scale_factor.timer.elapsed() >= reset_scale_factor.delay {
let mut scale_factor = 1.0 as f32;

if !reset_scale_factor.in_animation {
scale_factor = self.zoom_factor;

reset_scale_factor.in_animation = true;
}

let scale_factor_animated = egui_animation::animate_eased(
ctx,
format!("scale_factor_{}", reset_scale_factor.animation_id),
scale_factor,
0.5,
simple_easing::cubic_in_out
);

self.zoom_factor = scale_factor_animated;

if self.zoom_factor == 1.0 {
debug!("Scale factor resetting is done.");

self.reset_scale_factor = None;
}
}
}
}
}

0 comments on commit 602c596

Please sign in to comment.