Skip to content

Commit

Permalink
Smoother edge panning on large selections (#5578)
Browse files Browse the repository at this point in the history
  • Loading branch information
c-ola committed Mar 22, 2024
1 parent 0543aa4 commit 33fee4c
Showing 1 changed file with 28 additions and 12 deletions.
40 changes: 28 additions & 12 deletions src/core/control/tools/EditSelection.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -796,25 +796,40 @@ bool EditSelection::handleEdgePan(EditSelection* self) {
const double zoom = self->view->getXournal()->getZoom();

// Helper function to compute scroll amount for a single dimension, based on visible region and selection bbox
const auto computeScrollAmt = [&](double visMin, double visLen, double bboxMin, double bboxLen,
double layoutSize) -> double {
const auto computeScrollAmt = [&](double visMin, double visLen, double bboxMin, double bboxLen, double layoutSize,
double relMousePos) -> double {
const bool belowMin = bboxMin < visMin;
const bool aboveMax = bboxMin + bboxLen > visMin + visLen;
const double visMax = visMin + visLen;
const double bboxMax = bboxMin + bboxLen;

const bool isLargeSelection = bboxLen > visLen;
const auto centerVis = (visMin + visLen / 2);
const auto mouseDiff = (bboxMin + relMousePos * zoom - centerVis);

// Scroll amount multiplier
double mult = 0.0;

// Calculate bonus scroll amount due to proportion of selection out of view.
const double maxMult = settings->getEdgePanMaxMult();
int panDir = 0;
if (aboveMax) {
panDir = 1;
mult = maxMult * std::min(bboxLen, bboxMax - visMax) / bboxLen;
} else if (belowMin) {
panDir = -1;
mult = maxMult * std::min(bboxLen, visMin - bboxMin) / bboxLen;

// If the selection is larger than the view, scroll based on mouse position relative to the center of the
// visible view Otherwise calculate bonus scroll amount due to proportion of selection out of view.
if (isLargeSelection) {
mult = maxMult * std::abs(mouseDiff) / (visLen);
if (mouseDiff > 0.1 * visLen / 2.0) {
panDir = 1;
} else if (mouseDiff < -0.1 * visLen / 2.0) {
panDir = -1;
}
} else {
if (aboveMax) {
panDir = 1;
mult = maxMult * std::min(bboxLen, bboxMax - visMax) / bboxLen;
} else if (belowMin) {
panDir = -1;
mult = maxMult * std::min(bboxLen, visMin - bboxMin) / bboxLen;
}
}

// Base amount to translate selection (in document coordinates) per timer tick
Expand All @@ -833,14 +848,15 @@ bool EditSelection::handleEdgePan(EditSelection* self) {

return layoutScroll;
};

// Compute scroll (for layout) and translation (for selection) for x and y
const int layoutWidth = layout->getMinimalWidth();
const int layoutHeight = layout->getMinimalHeight();
const auto visRect = layout->getVisibleRect();
const auto bbox = self->getBoundingBoxInView();
const auto layoutScrollX = computeScrollAmt(visRect.x, visRect.width, bbox.x, bbox.width, layoutWidth);
const auto layoutScrollY = computeScrollAmt(visRect.y, visRect.height, bbox.y, bbox.height, layoutHeight);
const auto layoutScrollX =
computeScrollAmt(visRect.x, visRect.width, bbox.x, bbox.width, layoutWidth, self->relMousePosX);
const auto layoutScrollY =
computeScrollAmt(visRect.y, visRect.height, bbox.y, bbox.height, layoutHeight, self->relMousePosY);
const auto translateX = layoutScrollX / zoom;
const auto translateY = layoutScrollY / zoom;

Expand Down

0 comments on commit 33fee4c

Please sign in to comment.