Skip to content

Commit

Permalink
implement nudge view while performing certain pen actions (#783)
Browse files Browse the repository at this point in the history
* implement nudging camera in certain pen actions

* split horizontal/vertical nudges needed

* increase nudge amount

* satisfy clippy

* more nudge directions

* nudge when moving content in vertical-space tool

* update nudge needed function

* explicit match for nudge not needed
  • Loading branch information
flxzt authored Aug 28, 2023
1 parent 7ea4541 commit dff923a
Show file tree
Hide file tree
Showing 5 changed files with 105 additions and 17 deletions.
66 changes: 66 additions & 0 deletions crates/rnote-engine/src/camera.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,18 @@ use rnote_compose::ext::AabbExt;
use serde::{Deserialize, Serialize};
use std::time::Duration;

#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord)]
pub enum NudgeDirection {
North,
NorthEast,
East,
SouthEast,
South,
SouthWest,
West,
NorthWest,
}

#[derive(Debug, Clone, Serialize, Deserialize)]
#[serde(default, rename = "camera")]
pub struct Camera {
Expand Down Expand Up @@ -282,6 +294,60 @@ impl Camera {
))
.scale(total_zoom as f32, total_zoom as f32)
}

/// Detects if a nudge is needed, meaning: the position is close to an edge of the current viewport.
pub fn detect_nudge_needed(&self, pos: na::Vector2<f64>) -> Option<NudgeDirection> {
const NUDGE_VIEWPORT_DIST: f64 = 10.0;
let viewport = self.viewport();
let nudge_north = pos[1] <= viewport.mins[1] + NUDGE_VIEWPORT_DIST;
let nudge_east = pos[0] >= viewport.maxs[0] - NUDGE_VIEWPORT_DIST;
let nudge_south = pos[1] >= viewport.maxs[1] - NUDGE_VIEWPORT_DIST;
let nudge_west = pos[0] <= viewport.mins[0] + NUDGE_VIEWPORT_DIST;

match (nudge_north, nudge_east, nudge_south, nudge_west) {
(true, false, _, false) => Some(NudgeDirection::North),
(true, true, _, _) => Some(NudgeDirection::NorthEast),
(false, true, false, _) => Some(NudgeDirection::East),
(_, true, true, _) => Some(NudgeDirection::SouthEast),
(_, false, true, false) => Some(NudgeDirection::South),
(_, _, true, true) => Some(NudgeDirection::SouthWest),
(false, _, false, true) => Some(NudgeDirection::West),
(true, _, _, true) => Some(NudgeDirection::NorthWest),
(false, false, false, false) => None,
}
}

pub fn nudge_by(
&mut self,
amount: f64,
direction: NudgeDirection,
doc: &Document,
) -> WidgetFlags {
let nudge_offset = match direction {
NudgeDirection::North => na::vector![0., -amount],
NudgeDirection::NorthEast => na::vector![amount, -amount],
NudgeDirection::East => na::vector![amount, 0.],
NudgeDirection::SouthEast => na::vector![amount, amount],
NudgeDirection::South => na::vector![0., amount],
NudgeDirection::SouthWest => na::vector![-amount, amount],
NudgeDirection::West => na::vector![-amount, 0.],
NudgeDirection::NorthWest => na::vector![-amount, -amount],
};
self.set_offset(self.offset() + nudge_offset, doc)
}

pub fn nudge(&mut self, direction: NudgeDirection, doc: &Document) -> WidgetFlags {
const NUDGE_AMOUNT: f64 = 20.0;
self.nudge_by(NUDGE_AMOUNT, direction, doc)
}

pub fn nudge_w_pos(&mut self, pos: na::Vector2<f64>, doc: &Document) -> WidgetFlags {
let mut widget_flags = WidgetFlags::default();
if let Some(nudge_direction) = self.detect_nudge_needed(pos) {
widget_flags |= self.nudge(nudge_direction, doc);
}
widget_flags
}
}

#[cfg(test)]
Expand Down
37 changes: 21 additions & 16 deletions crates/rnote-engine/src/pens/penholder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ use super::{
Brush, Eraser, Pen, PenBehaviour, PenMode, PenStyle, Selector, Shaper, Shortcuts, Tools,
Typewriter,
};
use crate::camera::NudgeDirection;
use crate::engine::{EngineView, EngineViewMut};
use crate::pens::shortcuts::ShortcutAction;
use crate::widgetflags::WidgetFlags;
Expand Down Expand Up @@ -297,52 +298,56 @@ impl PenHolder {
modifier_keys,
} => match keyboard_key {
KeyboardKey::NavUp => {
let y_offset = if modifier_keys.contains(&ModifierKey::KeyboardCtrl) {
-engine_view.camera.size()[1]
let nudge_amount = if modifier_keys.contains(&ModifierKey::KeyboardCtrl) {
engine_view.camera.size()[1]
} else {
-engine_view.camera.size()[1] * MOVE_VIEW_FACTOR
engine_view.camera.size()[1] * MOVE_VIEW_FACTOR
};
widget_flags |= engine_view.camera.set_offset(
engine_view.camera.offset() + na::vector![0.0, y_offset],
widget_flags |= engine_view.camera.nudge_by(
nudge_amount,
NudgeDirection::North,
engine_view.doc,
);

EventPropagation::Stop
}
KeyboardKey::NavDown => {
let y_offset = if modifier_keys.contains(&ModifierKey::KeyboardCtrl) {
let nudge_amount = if modifier_keys.contains(&ModifierKey::KeyboardCtrl) {
engine_view.camera.size()[1]
} else {
engine_view.camera.size()[1] * MOVE_VIEW_FACTOR
};
widget_flags |= engine_view.camera.set_offset(
engine_view.camera.offset() + na::vector![0.0, y_offset],
widget_flags |= engine_view.camera.nudge_by(
nudge_amount,
NudgeDirection::East,
engine_view.doc,
);

EventPropagation::Stop
}
KeyboardKey::NavLeft => {
let x_offset = if modifier_keys.contains(&ModifierKey::KeyboardCtrl) {
-engine_view.camera.size()[0]
let nudge_amount = if modifier_keys.contains(&ModifierKey::KeyboardCtrl) {
engine_view.camera.size()[0]
} else {
-engine_view.camera.size()[0] * MOVE_VIEW_FACTOR
engine_view.camera.size()[0] * MOVE_VIEW_FACTOR
};
widget_flags |= engine_view.camera.set_offset(
engine_view.camera.offset() + na::vector![x_offset, 0.0],
widget_flags |= engine_view.camera.nudge_by(
nudge_amount,
NudgeDirection::West,
engine_view.doc,
);

EventPropagation::Stop
}
KeyboardKey::NavRight => {
let x_offset = if modifier_keys.contains(&ModifierKey::KeyboardCtrl) {
let nudge_amount = if modifier_keys.contains(&ModifierKey::KeyboardCtrl) {
engine_view.camera.size()[0]
} else {
engine_view.camera.size()[0] * MOVE_VIEW_FACTOR
};
widget_flags |= engine_view.camera.set_offset(
engine_view.camera.offset() + na::vector![x_offset, 0.0],
widget_flags |= engine_view.camera.nudge_by(
nudge_amount,
NudgeDirection::South,
engine_view.doc,
);

Expand Down
11 changes: 10 additions & 1 deletion crates/rnote-engine/src/pens/selector/penevents.rs
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,8 @@ impl Selector {
path,
element,
);
// possibly nudge camera
widget_flags |= engine_view.camera.nudge_w_pos(element.pos, engine_view.doc);

EventResult {
handled: true,
Expand Down Expand Up @@ -172,11 +174,15 @@ impl Selector {
if offset.magnitude()
> Self::TRANSLATE_MAGNITUDE_THRESHOLD / engine_view.camera.total_zoom()
{
// move selection
engine_view.store.translate_strokes(selection, offset);
engine_view
.store
.translate_strokes_images(selection, offset);
*selection_bounds = selection_bounds.translate(offset);
// possibly nudge camera
widget_flags |=
engine_view.camera.nudge_w_pos(element.pos, engine_view.doc);

// strokes that were not visible previously might come into view
engine_view.store.regenerate_rendering_in_viewport_threaded(
Expand Down Expand Up @@ -269,17 +275,20 @@ impl Selector {
);
let scale = new_extents.component_div(&selection_bounds.extents());

// resize strokes
engine_view
.store
.scale_strokes_with_pivot(selection, scale, pivot);
engine_view
.store
.scale_strokes_images_with_pivot(selection, scale, pivot);

*selection_bounds = selection_bounds
.translate(-pivot)
.scale_non_uniform(scale)
.translate(pivot);
// possibly nudge camera
widget_flags |=
engine_view.camera.nudge_w_pos(element.pos, engine_view.doc);
}
}

Expand Down
4 changes: 4 additions & 0 deletions crates/rnote-engine/src/pens/tools.rs
Original file line number Diff line number Diff line change
Expand Up @@ -350,6 +350,10 @@ impl PenBehaviour for Tools {
&self.verticalspace_tool.strokes_below,
na::vector![0.0, y_offset],
);
// possibly nudge camera
widget_flags |=
engine_view.camera.nudge_w_pos(element.pos, engine_view.doc);
// new strokes might come into view
engine_view.store.regenerate_rendering_in_viewport_threaded(
engine_view.tasks_tx.clone(),
false,
Expand Down
4 changes: 4 additions & 0 deletions crates/rnote-engine/src/pens/typewriter/penevents.rs
Original file line number Diff line number Diff line change
Expand Up @@ -220,10 +220,14 @@ impl Typewriter {
if offset.magnitude()
> Self::TRANSLATE_MAGNITUDE_THRESHOLD / engine_view.camera.total_zoom()
{
// move text
engine_view.store.translate_strokes(&[*stroke_key], offset);
engine_view
.store
.translate_strokes_images(&[*stroke_key], offset);
// possibly nudge camera
widget_flags |=
engine_view.camera.nudge_w_pos(element.pos, engine_view.doc);

*current_pos = element.pos;

Expand Down

0 comments on commit dff923a

Please sign in to comment.