Skip to content

Commit

Permalink
Use optimized scrolling for all three scroll operations of FigureCanvas
Browse files Browse the repository at this point in the history
FigureCanvas' scrollToX and scrollToY uses an optimized scrolling
functionality which leads especially for views with many figures to a
much smoother scrolling experience.

This commit utilizes this optimized scrolling also for scrollTo.

Furthermore the code for all three has been combined in such a way that
all three use the same core functions.
  • Loading branch information
azoitl committed Mar 9, 2024
1 parent 64bd301 commit f1a6cc7
Showing 1 changed file with 36 additions and 61 deletions.
97 changes: 36 additions & 61 deletions org.eclipse.draw2d/src/org/eclipse/draw2d/FigureCanvas.java
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*******************************************************************************
* Copyright (c) 2000, 2023 IBM Corporation and others.
* Copyright (c) 2000, 2024 IBM Corporation and others.
*
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License 2.0 which is available at
Expand Down Expand Up @@ -189,10 +189,8 @@ private static int checkStyle(int style) {
*/
@Override
public org.eclipse.swt.graphics.Point computeSize(int wHint, int hHint, boolean changed) {
// TODO Still doesn't handle scrollbar cases, such as when a constrained
// width
// would require a horizontal scrollbar, and therefore additional
// height.
// TODO Still doesn't handle scrollbar cases, such as when a constrained width
// would require a horizontal scrollbar, and therefore additional height.
int borderSize = computeTrim(0, 0, 0, 0).x * -2;
if (wHint >= 0) {
wHint = Math.max(0, wHint - borderSize);
Expand Down Expand Up @@ -264,6 +262,7 @@ private void hook() {
getLightweightSystem().getUpdateManager().addUpdateListener(new UpdateListener() {
@Override
public void notifyPainting(Rectangle damage, java.util.Map<IFigure, Rectangle> dirtyRegions) {
// nothing to do for now
}

@Override
Expand Down Expand Up @@ -372,15 +371,9 @@ public void scrollSmoothTo(int x, int y) {
* @param y the y coordinate to scroll to
*/
public void scrollTo(int x, int y) {
x = verifyScrollBarOffset(getViewport().getHorizontalRangeModel(), x);
y = verifyScrollBarOffset(getViewport().getVerticalRangeModel(), y);
if (x == getViewport().getViewLocation().x) {
scrollToY(y);
} else if (y == getViewport().getViewLocation().y) {
scrollToX(x);
} else {
getViewport().setViewLocation(x, y);
}
int hOffset = verifyScrollBarOffset(getViewport().getHorizontalRangeModel(), x);
int vOffset = verifyScrollBarOffset(getViewport().getVerticalRangeModel(), y);
performScroll(hOffset, vOffset);
}

/**
Expand All @@ -395,44 +388,7 @@ public void scrollToX(int hOffset) {
if (hOffset == hOffsetOld) {
return;
}
int dx = -hOffset + hOffsetOld;

Rectangle clientArea = getViewport().getBounds().getShrinked(getViewport().getInsets());
Rectangle blit = clientArea.getResized(-Math.abs(dx), 0);
Rectangle expose = clientArea.getCopy();
Point dest = clientArea.getTopLeft();
expose.width = Math.abs(dx);
if (dx < 0) { // Moving left?
blit.translate(-dx, 0); // Move blit area to the right
expose.x = dest.x + blit.width;
} else {
// Moving right
dest.x += dx; // Move expose area to the right
}

// fix for bug 41111
Control[] children = getChildren();
boolean[] manualMove = new boolean[children.length];
for (int i = 0; i < children.length; i++) {
org.eclipse.swt.graphics.Rectangle bounds = children[i].getBounds();
manualMove[i] = blit.width <= 0 || bounds.x > blit.x + blit.width || bounds.y > blit.y + blit.height
|| bounds.x + bounds.width < blit.x || bounds.y + bounds.height < blit.y;
}
scroll(dest.x, dest.y, blit.x, blit.y, blit.width, blit.height, true);
for (int i = 0; i < children.length; i++) {
if (children[i].isDisposed()) {
continue;
}
org.eclipse.swt.graphics.Rectangle bounds = children[i].getBounds();
if (manualMove[i]) {
children[i].setBounds(bounds.x + dx, bounds.y, bounds.width, bounds.height);
}
}

getViewport().setIgnoreScroll(true);
getViewport().setHorizontalLocation(hOffset);
getViewport().setIgnoreScroll(false);
redraw(expose.x, expose.y, expose.width, expose.height, true);
performScroll(hOffset, getViewport().getViewLocation().y);
}

/**
Expand All @@ -447,12 +403,26 @@ public void scrollToY(int vOffset) {
if (vOffset == vOffsetOld) {
return;
}
int dy = -vOffset + vOffsetOld;
performScroll(getViewport().getViewLocation().x, vOffset);
}

private void performScroll(int hOffset, int vOffset) {
int dx = -hOffset + getViewport().getViewLocation().x;
int dy = -vOffset + getViewport().getViewLocation().y;
Rectangle clientArea = getViewport().getBounds().getShrinked(getViewport().getInsets());
Rectangle blit = clientArea.getResized(0, -Math.abs(dy));
Rectangle blit = clientArea.getResized(-Math.abs(dx), -Math.abs(dy));
Rectangle expose = clientArea.getCopy();
Point dest = clientArea.getTopLeft();

expose.width = Math.abs(dx);
if (dx < 0) { // Moving left?
blit.translate(-dx, 0); // Move blit area to the right
expose.x = dest.x + blit.width;
} else {
// Moving right
dest.x += dx; // Move expose area to the right
}

expose.height = Math.abs(dy);
if (dy < 0) { // Moving up?
blit.translate(0, -dy); // Move blit area down
Expand All @@ -462,12 +432,22 @@ public void scrollToY(int vOffset) {
dest.y += dy;
}

scrollChildren(dx, dy, blit, dest);

getViewport().setIgnoreScroll(true);
getViewport().setHorizontalLocation(hOffset);
getViewport().setVerticalLocation(vOffset);
getViewport().setIgnoreScroll(false);
redraw(expose.x, expose.y, expose.width, expose.height, true);
}

private void scrollChildren(int dx, int dy, Rectangle blit, Point dest) {
// fix for bug 41111
Control[] children = getChildren();
boolean[] manualMove = new boolean[children.length];
for (int i = 0; i < children.length; i++) {
org.eclipse.swt.graphics.Rectangle bounds = children[i].getBounds();
manualMove[i] = blit.height <= 0 || bounds.x > blit.x + blit.width || bounds.y > blit.y + blit.height
manualMove[i] = blit.width <= 0 || bounds.x > blit.x + blit.width || bounds.y > blit.y + blit.height
|| bounds.x + bounds.width < blit.x || bounds.y + bounds.height < blit.y;
}
scroll(dest.x, dest.y, blit.x, blit.y, blit.width, blit.height, true);
Expand All @@ -477,14 +457,9 @@ public void scrollToY(int vOffset) {
}
org.eclipse.swt.graphics.Rectangle bounds = children[i].getBounds();
if (manualMove[i]) {
children[i].setBounds(bounds.x, bounds.y + dy, bounds.width, bounds.height);
children[i].setBounds(bounds.x + dx, bounds.y + dy, bounds.width, bounds.height);
}
}

getViewport().setIgnoreScroll(true);
getViewport().setVerticalLocation(vOffset);
getViewport().setIgnoreScroll(false);
redraw(expose.x, expose.y, expose.width, expose.height, true);
}

/**
Expand Down

0 comments on commit f1a6cc7

Please sign in to comment.