mirror of
https://github.com/GraphiteEditor/Graphite.git
synced 2026-09-27 16:18:11 +08:00
Minimum viewport scale cover when zooming (#1282)
* Minimum viewport scale cover * Update const name
This commit is contained in:
@@ -181,8 +181,12 @@ impl MessageHandler<DocumentMessage, (u64, &InputPreprocessorMessageHandler, &Pe
|
||||
}
|
||||
#[remain::unsorted]
|
||||
Navigation(message) => {
|
||||
self.navigation_handler
|
||||
.process_message(message, responses, (&self.document_legacy, ipp, self.selected_visible_layers_bounding_box(&render_data)));
|
||||
let document_bounds = self.document_bounds(&render_data);
|
||||
self.navigation_handler.process_message(
|
||||
message,
|
||||
responses,
|
||||
(&self.document_legacy, document_bounds, ipp, self.selected_visible_layers_bounding_box(&render_data)),
|
||||
);
|
||||
}
|
||||
#[remain::unsorted]
|
||||
Overlays(message) => {
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
use crate::consts::{
|
||||
VIEWPORT_ROTATE_SNAP_INTERVAL, VIEWPORT_SCROLL_RATE, VIEWPORT_ZOOM_LEVELS, VIEWPORT_ZOOM_MOUSE_RATE, VIEWPORT_ZOOM_SCALE_MAX, VIEWPORT_ZOOM_SCALE_MIN, VIEWPORT_ZOOM_TO_FIT_PADDING_SCALE_FACTOR,
|
||||
VIEWPORT_ZOOM_WHEEL_RATE,
|
||||
VIEWPORT_ROTATE_SNAP_INTERVAL, VIEWPORT_SCROLL_RATE, VIEWPORT_ZOOM_LEVELS, VIEWPORT_ZOOM_MIN_FRACTION_COVER, VIEWPORT_ZOOM_MOUSE_RATE, VIEWPORT_ZOOM_SCALE_MAX, VIEWPORT_ZOOM_SCALE_MIN,
|
||||
VIEWPORT_ZOOM_TO_FIT_PADDING_SCALE_FACTOR, VIEWPORT_ZOOM_WHEEL_RATE,
|
||||
};
|
||||
use crate::messages::frontend::utility_types::MouseCursorIcon;
|
||||
use crate::messages::input_mapper::utility_types::input_keyboard::{Key, KeysGroup};
|
||||
@@ -51,11 +51,18 @@ impl Default for NavigationMessageHandler {
|
||||
}
|
||||
}
|
||||
|
||||
impl MessageHandler<NavigationMessage, (&Document, &InputPreprocessorMessageHandler, Option<[DVec2; 2]>)> for NavigationMessageHandler {
|
||||
impl MessageHandler<NavigationMessage, (&Document, Option<[DVec2; 2]>, &InputPreprocessorMessageHandler, Option<[DVec2; 2]>)> for NavigationMessageHandler {
|
||||
#[remain::check]
|
||||
fn process_message(&mut self, message: NavigationMessage, responses: &mut VecDeque<Message>, (document, ipp, selection_bounds): (&Document, &InputPreprocessorMessageHandler, Option<[DVec2; 2]>)) {
|
||||
fn process_message(
|
||||
&mut self,
|
||||
message: NavigationMessage,
|
||||
responses: &mut VecDeque<Message>,
|
||||
(document, document_bounds, ipp, selection_bounds): (&Document, Option<[DVec2; 2]>, &InputPreprocessorMessageHandler, Option<[DVec2; 2]>),
|
||||
) {
|
||||
use NavigationMessage::*;
|
||||
|
||||
let old_zoom = self.zoom;
|
||||
|
||||
#[remain::sorted]
|
||||
match message {
|
||||
DecreaseCanvasZoom { center_on_mouse } => {
|
||||
@@ -157,6 +164,8 @@ impl MessageHandler<NavigationMessage, (&Document, &InputPreprocessorMessageHand
|
||||
let amount = 1. + difference * VIEWPORT_ZOOM_MOUSE_RATE;
|
||||
|
||||
self.zoom *= amount;
|
||||
self.zoom *= Self::clamp_zoom(self.zoom, document_bounds, old_zoom, ipp);
|
||||
|
||||
if let Some(mouse) = zoom_from_viewport {
|
||||
let zoom_factor = self.snapped_scale() / zoom_start;
|
||||
|
||||
@@ -192,6 +201,7 @@ impl MessageHandler<NavigationMessage, (&Document, &InputPreprocessorMessageHand
|
||||
}
|
||||
SetCanvasZoom { zoom_factor } => {
|
||||
self.zoom = zoom_factor.clamp(VIEWPORT_ZOOM_SCALE_MIN, VIEWPORT_ZOOM_SCALE_MAX);
|
||||
self.zoom *= Self::clamp_zoom(self.zoom, document_bounds, old_zoom, ipp);
|
||||
responses.add(BroadcastEvent::DocumentIsDirty);
|
||||
responses.add(DocumentMessage::DirtyRenderDocumentInOutlineView);
|
||||
responses.add(PortfolioMessage::UpdateDocumentWidgets);
|
||||
@@ -243,7 +253,8 @@ impl MessageHandler<NavigationMessage, (&Document, &InputPreprocessorMessageHand
|
||||
let mut zoom_factor = 1. + scroll.abs() * VIEWPORT_ZOOM_WHEEL_RATE;
|
||||
if ipp.mouse.scroll_delta.y > 0 {
|
||||
zoom_factor = 1. / zoom_factor
|
||||
};
|
||||
}
|
||||
zoom_factor *= Self::clamp_zoom(self.zoom * zoom_factor, document_bounds, old_zoom, ipp);
|
||||
|
||||
responses.add(self.center_zoom(ipp.viewport_bounds.size(), zoom_factor, ipp.mouse.position));
|
||||
responses.add(SetCanvasZoom { zoom_factor: self.zoom * zoom_factor });
|
||||
@@ -351,4 +362,15 @@ impl NavigationMessageHandler {
|
||||
|
||||
NavigationMessage::TranslateCanvas { delta }.into()
|
||||
}
|
||||
|
||||
pub fn clamp_zoom(zoom: f64, document_bounds: Option<[DVec2; 2]>, old_zoom: f64, ipp: &InputPreprocessorMessageHandler) -> f64 {
|
||||
let document_size = (document_bounds.map(|[min, max]| max - min).unwrap_or_default() / old_zoom) * zoom;
|
||||
let scale_factor = (document_size / ipp.viewport_bounds.size()).max_element();
|
||||
|
||||
if scale_factor > f64::EPSILON * 100. && scale_factor.is_finite() && scale_factor < VIEWPORT_ZOOM_MIN_FRACTION_COVER {
|
||||
VIEWPORT_ZOOM_MIN_FRACTION_COVER / scale_factor
|
||||
} else {
|
||||
1.
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user