Skip to content

Commit

Permalink
fix layout manager state
Browse files Browse the repository at this point in the history
  • Loading branch information
flxzt committed May 6, 2022
1 parent d0ebbc6 commit b803598
Show file tree
Hide file tree
Showing 2 changed files with 41 additions and 29 deletions.
63 changes: 34 additions & 29 deletions rnote-ui/src/canvas/canvaslayout.rs
Original file line number Diff line number Diff line change
@@ -1,20 +1,22 @@
mod imp {
use std::cell::Cell;
use std::rc::Rc;
use std::cell::Cell;
use std::rc::Rc;

use gtk4::{
glib, prelude::*, subclass::prelude::*, LayoutManager, Orientation, SizeRequestMode, Widget,
};
use p2d::bounding_volume::{BoundingVolume, AABB};
use rnote_compose::helpers::AABBHelpers;

use gtk4::{
glib, prelude::*, subclass::prelude::*, LayoutManager, Orientation, SizeRequestMode, Widget,
};
use p2d::bounding_volume::{BoundingVolume, AABB};
use rnote_compose::helpers::AABBHelpers;
use crate::canvas::RnoteCanvas;
use rnote_engine::sheet::ExpandMode;
use rnote_engine::{render, Sheet};

use crate::canvas::RnoteCanvas;
use rnote_engine::sheet::ExpandMode;
use rnote_engine::{render, Sheet};
mod imp {
use super::*;

#[derive(Debug, Clone)]
pub struct CanvasLayout {
old_viewport: Rc<Cell<AABB>>,
pub old_viewport: Rc<Cell<AABB>>,
}

impl Default for CanvasLayout {
Expand Down Expand Up @@ -141,29 +143,27 @@ mod imp {
.update_background_rendering_current_viewport();

let viewport = canvas.engine().borrow().camera.viewport();
let viewport_extents = viewport.extents();
let old_viewport = self.old_viewport.get();
let old_viewport_extents = old_viewport.extents();

let old_viewport_render_margins =
old_viewport.extents() * render::VIEWPORT_EXTENTS_MARGIN_FACTOR;

// We only extend the viewport by half of the margin, because we want to trigger rendering before we reach it.
// This has two advantages: Strokes that might take longer to render have a head start while still being out of view,
// And the rendering gets triggered more often, so not that many strokes start to get rendered. This avoids stutters,
// because while the rendering itself is on worker threads, we still have to `integrate` the resulted textures,
// which can also take up quite some time on the main UI thread.
let old_viewport_extended = old_viewport
.extend_by(old_viewport.extents() * render::VIEWPORT_EXTENTS_MARGIN_FACTOR * 0.5);
/*
log::debug!(
"viewport: {:#?}\nold_loosened_viewport: {:#?}",
"viewport: {:#?}\nold_viewport_extended: {:#?}",
viewport,
old_loosened_viewport
old_viewport_extended
);
*/

// Either when we have zoomed out beyond the extended old viewport
if viewport_extents > old_viewport_extents * render::VIEWPORT_EXTENTS_MARGIN_FACTOR
// or if the viewport is moved beyond the extended old viewport
|| !old_viewport
.extend_by(old_viewport_render_margins)
.contains(&viewport)
{
// conditionally update the engine rendering when the thresholds are crossed
// On zoom outs or viewport translations this will evaluate true, so we render the strokes that are coming into view.
// But after zoom ins we need to update old_viewport with layout_manager.update_state()
if !old_viewport_extended.contains(&viewport) {
// Because we don't set the rendering of strokes that are already in the view dirty, we only render those that may come into the view.
canvas
.engine()
.borrow_mut()
Expand All @@ -175,8 +175,6 @@ mod imp {
}
}

use gtk4::{glib, LayoutManager};

glib::wrapper! {
pub struct CanvasLayout(ObjectSubclass<imp::CanvasLayout>)
@extends LayoutManager;
Expand All @@ -192,4 +190,11 @@ impl CanvasLayout {
pub fn new() -> Self {
glib::Object::new(&[]).expect("Failed to create CanvasLayout")
}

// needs to be called after zooming
pub fn update_state(&self, canvas: &RnoteCanvas) {
self.imp()
.old_viewport
.set(canvas.engine().borrow().camera.viewport());
}
}
7 changes: 7 additions & 0 deletions rnote-ui/src/canvas/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -799,6 +799,13 @@ impl RnoteCanvas {

self.regenerate_background_pattern();
self.update_engine_rendering();

// We need to update the layout managers internal state after zooming
self.layout_manager()
.unwrap()
.downcast::<CanvasLayout>()
.unwrap()
.update_state(self);
}

/// Zooms temporarily and then scale the canvas and its contents to a new zoom after a given time.
Expand Down

0 comments on commit b803598

Please sign in to comment.