Skip to content

Commit c1f4567

Browse files
Christopher-HermannBeckerWdf
authored andcommitted
[Sticky Scrolling] Dispatch scrolling to source viewer
Scrolling on the sticky lines control is dispatched to the linked source viewer. With this change the source viewer's scrolling behavior remains consistent, regardless of whether sticky scrolling is enalbed or not. Follow up for eclipse-platform#1894
1 parent c06713f commit c1f4567

File tree

3 files changed

+99
-8
lines changed

3 files changed

+99
-8
lines changed

bundles/org.eclipse.ui.editors/src/org/eclipse/ui/internal/texteditor/stickyscroll/StickyScrollingControl.java

Lines changed: 49 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,10 @@
3939
import org.eclipse.swt.widgets.Canvas;
4040
import org.eclipse.swt.widgets.Composite;
4141
import org.eclipse.swt.widgets.Display;
42+
import org.eclipse.swt.widgets.Event;
4243
import org.eclipse.swt.widgets.Label;
44+
import org.eclipse.swt.widgets.Listener;
45+
import org.eclipse.swt.widgets.ScrollBar;
4346

4447
import org.eclipse.core.runtime.ICoreRunnable;
4548
import org.eclipse.core.runtime.jobs.Job;
@@ -98,11 +101,15 @@ public class StickyScrollingControl {
98101

99102
private final static int BOTTOM_SEPARATOR_SPACING= 2;
100103

104+
private StickyScrollingHandler stickyScrollingHandler;
105+
101106
public StickyScrollingControl(ISourceViewer sourceViewer, StickyScrollingControlSettings settings) {
102-
this(sourceViewer, null, settings);
107+
this(sourceViewer, null, settings, null);
103108
}
104109

105-
public StickyScrollingControl(ISourceViewer sourceViewer, IVerticalRuler verticalRuler, StickyScrollingControlSettings settings) {
110+
public StickyScrollingControl(ISourceViewer sourceViewer, IVerticalRuler verticalRuler,
111+
StickyScrollingControlSettings settings, StickyScrollingHandler stickyScrollingHandler) {
112+
this.stickyScrollingHandler= stickyScrollingHandler;
106113
this.stickyLines= new ArrayList<>();
107114
this.sourceViewer= sourceViewer;
108115
this.verticalRuler= verticalRuler;
@@ -441,6 +448,10 @@ public void mouseExit(MouseEvent e) {
441448
stickyLineText.setLineBackground(0, getNumberStickyLines(), null);
442449
}
443450
});
451+
452+
ScrollingDispatchingListener scrollingDispatchingListener= new ScrollingDispatchingListener();
453+
canvas.addListener(SWT.MouseHorizontalWheel, scrollingDispatchingListener);
454+
canvas.addListener(SWT.MouseVerticalWheel, scrollingDispatchingListener);
444455
}
445456

446457
/**
@@ -479,6 +490,42 @@ public void caretMoved(CaretEvent event) {
479490
ensureSourceViewerLineVisible(line);
480491
});
481492
}
493+
}
494+
495+
/**
496+
* A mouse wheel listener that is dispatching the scrolling on the sticky lines canvas to the
497+
* source viewer. The calculation of the scrolling steps is copied from
498+
* {@link Composite}#scrollWheel.
499+
*/
500+
class ScrollingDispatchingListener implements Listener {
482501

502+
@Override
503+
public void handleEvent(Event event) {
504+
StyledText textWidget= sourceViewer.getTextWidget();
505+
506+
ScrollBar bar= event.type == SWT.MouseHorizontalWheel ? textWidget.getHorizontalBar() : textWidget.getVerticalBar();
507+
if (bar == null) {
508+
return;
509+
}
510+
511+
int deltaY= event.count;
512+
if (-1 < deltaY && deltaY < 0) {
513+
deltaY= -1;
514+
}
515+
if (0 < deltaY && deltaY < 1) {
516+
deltaY= 1;
517+
}
518+
519+
int pixel= Math.max(0, (int) (0.5f + bar.getSelection() - bar.getIncrement() * deltaY));
520+
521+
if (event.type == SWT.MouseHorizontalWheel) {
522+
sourceViewer.getTextWidget().setHorizontalPixel(pixel);
523+
} else {
524+
sourceViewer.getTextWidget().setTopPixel(pixel);
525+
if (stickyScrollingHandler != null) {
526+
stickyScrollingHandler.viewportChanged(pixel);
527+
}
528+
}
529+
}
483530
}
484531
}

bundles/org.eclipse.ui.editors/src/org/eclipse/ui/internal/texteditor/stickyscroll/StickyScrollingHandler.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -85,7 +85,7 @@ public StickyScrollingHandler(ISourceViewer sourceViewer, IVerticalRuler vertica
8585
this.stickyLinesProvider= stickyLinesProvider;
8686

8787
StickyScrollingControlSettings settings= loadAndListenForProperties(preferenceStore);
88-
stickyScrollingControl= new StickyScrollingControl(sourceViewer, verticalRuler, settings);
88+
stickyScrollingControl= new StickyScrollingControl(sourceViewer, verticalRuler, settings, this);
8989

9090
sourceViewer.addViewportListener(this);
9191
}

tests/org.eclipse.ui.editors.tests/src/org/eclipse/ui/internal/texteditor/stickyscroll/StickyScrollingControlTest.java

Lines changed: 49 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@
3737
import org.eclipse.swt.widgets.Control;
3838
import org.eclipse.swt.widgets.Display;
3939
import org.eclipse.swt.widgets.Event;
40+
import org.eclipse.swt.widgets.ScrollBar;
4041
import org.eclipse.swt.widgets.Shell;
4142

4243
import org.eclipse.jface.text.Document;
@@ -59,14 +60,14 @@ public void setup() {
5960
shell.setSize(200, 200);
6061
shell.setLayout(new FillLayout());
6162
ruler = new CompositeRuler();
62-
sourceViewer = new SourceViewer(shell, ruler, SWT.None);
63+
sourceViewer = new SourceViewer(shell, ruler, SWT.V_SCROLL | SWT.H_SCROLL);
6364

6465
lineNumberColor = new Color(0, 0, 0);
6566
hoverColor = new Color(1, 1, 1);
6667
backgroundColor = new Color(2, 2, 2);
6768
StickyScrollingControlSettings settings = new StickyScrollingControlSettings(5, lineNumberColor, hoverColor,
6869
backgroundColor, true);
69-
stickyScrollingControl = new StickyScrollingControl(sourceViewer, ruler, settings);
70+
stickyScrollingControl = new StickyScrollingControl(sourceViewer, ruler, settings, null);
7071
}
7172

7273
@After
@@ -177,20 +178,20 @@ public void testLayoutStickyLinesCanvasOnResize() {
177178
Canvas stickyControlCanvas = getStickyControlCanvas(shell);
178179
assertEquals(0, stickyControlCanvas.getBounds().x);
179180
assertEquals(0, stickyControlCanvas.getBounds().y);
180-
assertEquals(201, stickyControlCanvas.getBounds().width);
181+
assertEquals(getExpectedWitdh(200), stickyControlCanvas.getBounds().width);
181182
assertThat(stickyControlCanvas.getBounds().height, greaterThan(0));
182183

183184
sourceViewer.getTextWidget().setBounds(0, 0, 150, 200);
184185

185186
stickyControlCanvas = getStickyControlCanvas(shell);
186187
assertEquals(0, stickyControlCanvas.getBounds().x);
187188
assertEquals(0, stickyControlCanvas.getBounds().y);
188-
assertEquals(151, stickyControlCanvas.getBounds().width);
189+
assertEquals(getExpectedWitdh(150), stickyControlCanvas.getBounds().width);
189190
assertThat(stickyControlCanvas.getBounds().height, greaterThan(0));
190191
}
191192

192193
@Test
193-
public void navigateToStickyLine() {
194+
public void testNavigateToStickyLine() {
194195
String text = """
195196
line 1
196197
line 2""";
@@ -209,6 +210,40 @@ public void navigateToStickyLine() {
209210
assertEquals(0, selectedRange.y);
210211
}
211212

213+
@Test
214+
public void testVerticalScrollingIsDispatched() {
215+
Canvas stickyControlCanvas = getStickyControlCanvas(shell);
216+
String text = """
217+
line 1
218+
line 2""";
219+
sourceViewer.getTextWidget().setText(text);
220+
sourceViewer.getTextWidget().getVerticalBar().setIncrement(10);
221+
assertEquals(0, sourceViewer.getTextWidget().getTopPixel());
222+
223+
Event event = new Event();
224+
event.count = -1;
225+
stickyControlCanvas.notifyListeners(SWT.MouseVerticalWheel, event);
226+
227+
assertEquals(10, sourceViewer.getTextWidget().getTopPixel());
228+
}
229+
230+
@Test
231+
public void testHorizontalScrollingIsDispatched() {
232+
Canvas stickyControlCanvas = getStickyControlCanvas(shell);
233+
String text = """
234+
line 1
235+
line 2""";
236+
sourceViewer.getTextWidget().setText(text);
237+
sourceViewer.getTextWidget().getHorizontalBar().setIncrement(10);
238+
assertEquals(0, sourceViewer.getTextWidget().getHorizontalPixel());
239+
240+
Event event = new Event();
241+
event.count = -1;
242+
stickyControlCanvas.notifyListeners(SWT.MouseHorizontalWheel, event);
243+
244+
assertEquals(10, sourceViewer.getTextWidget().getHorizontalPixel());
245+
}
246+
212247
private Canvas getStickyControlCanvas(Composite composite) {
213248
for (Control control : composite.getChildren()) {
214249
if (control instanceof Canvas canvas) {
@@ -233,4 +268,13 @@ private StyledText getStickyLineText() {
233268
return (StyledText) canvas.getChildren()[1];
234269
}
235270

271+
private int getExpectedWitdh(int textWidgetWitdth) {
272+
ScrollBar verticalBar = sourceViewer.getTextWidget().getVerticalBar();
273+
if (verticalBar.isVisible()) {
274+
return textWidgetWitdth - verticalBar.getSize().x + 1;
275+
} else {
276+
return textWidgetWitdth + 1;
277+
}
278+
}
279+
236280
}

0 commit comments

Comments
 (0)