Skip to main content
summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorangelozerr2018-03-14 23:47:03 +0000
committerMickael Istria2018-03-19 12:18:37 +0000
commit13d6b5f4f99bd86e86b52c31f3311f4c10e41efa (patch)
treeb390ec6acddc5d3609810697b0629f36748e6181
parentd8d5eb7180eb317897b89b3d200329830ad5256a (diff)
downloadeclipse.platform.text-13d6b5f4f99bd86e86b52c31f3311f4c10e41efa.tar.gz
eclipse.platform.text-13d6b5f4f99bd86e86b52c31f3311f4c10e41efa.tar.xz
eclipse.platform.text-13d6b5f4f99bd86e86b52c31f3311f4c10e41efa.zip
Bug 529617 - [CodeMining] Line number in vertical ruler can be not
synchronized with line header annotation Change-Id: Idfb97cefe20d3fbdde0f8793f159d6c3cff2937b Signed-off-by: angelozerr <angelo.zerr@gmail.com> Also-By: Mickael Istria <mistria@redhat.com>
-rw-r--r--org.eclipse.jface.text/src/org/eclipse/jface/text/source/AnnotationRulerColumn.java40
-rw-r--r--org.eclipse.jface.text/src/org/eclipse/jface/text/source/LineNumberRulerColumn.java58
-rw-r--r--org.eclipse.jface.text/src/org/eclipse/jface/text/source/VisibleLinesTracker.java149
3 files changed, 175 insertions, 72 deletions
diff --git a/org.eclipse.jface.text/src/org/eclipse/jface/text/source/AnnotationRulerColumn.java b/org.eclipse.jface.text/src/org/eclipse/jface/text/source/AnnotationRulerColumn.java
index 2b4ca76392b..8f8b58c24d8 100644
--- a/org.eclipse.jface.text/src/org/eclipse/jface/text/source/AnnotationRulerColumn.java
+++ b/org.eclipse.jface.text/src/org/eclipse/jface/text/source/AnnotationRulerColumn.java
@@ -20,6 +20,7 @@ import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;
+import java.util.function.Consumer;
import org.eclipse.swt.SWT;
import org.eclipse.swt.custom.StyledText;
@@ -47,13 +48,10 @@ import org.eclipse.swt.widgets.Display;
import org.eclipse.jface.text.BadLocationException;
import org.eclipse.jface.text.IDocument;
import org.eclipse.jface.text.IRegion;
-import org.eclipse.jface.text.ITextListener;
import org.eclipse.jface.text.ITextViewer;
import org.eclipse.jface.text.ITextViewerExtension5;
-import org.eclipse.jface.text.IViewportListener;
import org.eclipse.jface.text.JFaceTextUtil;
import org.eclipse.jface.text.Position;
-import org.eclipse.jface.text.TextEvent;
/**
@@ -70,24 +68,11 @@ public class AnnotationRulerColumn implements IVerticalRulerColumn, IVerticalRul
/**
* Internal listener class.
*/
- class InternalListener implements IViewportListener, IAnnotationModelListener, ITextListener {
-
- @Override
- public void viewportChanged(int verticalPosition) {
- if (verticalPosition != fScrollPos)
- redraw();
- }
-
+ class AnnotationsListener implements IAnnotationModelListener {
@Override
public void modelChanged(IAnnotationModel model) {
postRedraw();
}
-
- @Override
- public void textChanged(TextEvent e) {
- if (e.getViewerRedrawState())
- postRedraw();
- }
}
/**
@@ -139,7 +124,7 @@ public class AnnotationRulerColumn implements IVerticalRulerColumn, IVerticalRul
/** The buffer for double buffering */
private Image fBuffer;
/** The internal listener */
- private InternalListener fInternalListener= new InternalListener();
+ private AnnotationsListener fAnnotationListener= new AnnotationsListener();
/** The width of this vertical ruler */
private int fWidth;
/** Switch for enabling/disabling the setModel method. */
@@ -192,6 +177,8 @@ public class AnnotationRulerColumn implements IVerticalRulerColumn, IVerticalRul
*/
private MouseListener fMouseListener;
+ private Consumer<StyledText> lineHeightChangeHandler= (t) -> postRedraw();
+
/**
* Constructs this column with the given arguments.
*
@@ -204,7 +191,7 @@ public class AnnotationRulerColumn implements IVerticalRulerColumn, IVerticalRul
this(width, annotationAccess);
fAllowSetModel= false;
fModel= model;
- fModel.addAnnotationModelListener(fInternalListener);
+ fModel.addAnnotationModelListener(fAnnotationListener);
}
/**
@@ -230,7 +217,7 @@ public class AnnotationRulerColumn implements IVerticalRulerColumn, IVerticalRul
fWidth= width;
fAllowSetModel= false;
fModel= model;
- fModel.addAnnotationModelListener(fInternalListener);
+ fModel.addAnnotationModelListener(fAnnotationListener);
}
/**
@@ -337,8 +324,7 @@ public class AnnotationRulerColumn implements IVerticalRulerColumn, IVerticalRul
});
if (fCachedTextViewer != null) {
- fCachedTextViewer.addViewportListener(fInternalListener);
- fCachedTextViewer.addTextListener(fInternalListener);
+ VisibleLinesTracker.track(fCachedTextViewer, lineHeightChangeHandler);
// on word wrap toggle a "resized" ControlEvent is fired: suggest a redraw of the ruler
fCachedTextWidget.addControlListener(new ControlAdapter() {
@Override
@@ -506,12 +492,11 @@ public class AnnotationRulerColumn implements IVerticalRulerColumn, IVerticalRul
private void handleDispose() {
if (fCachedTextViewer != null) {
- fCachedTextViewer.removeViewportListener(fInternalListener);
- fCachedTextViewer.removeTextListener(fInternalListener);
+ VisibleLinesTracker.untrack(fCachedTextViewer, lineHeightChangeHandler);
}
if (fModel != null)
- fModel.removeAnnotationModelListener(fInternalListener);
+ fModel.removeAnnotationModelListener(fAnnotationListener);
if (fBuffer != null) {
fBuffer.dispose();
@@ -521,6 +506,7 @@ public class AnnotationRulerColumn implements IVerticalRulerColumn, IVerticalRul
fConfiguredAnnotationTypes.clear();
fAllowedAnnotationTypes.clear();
fAnnotationAccessExtension= null;
+
}
/**
@@ -867,12 +853,12 @@ public class AnnotationRulerColumn implements IVerticalRulerColumn, IVerticalRul
if (fAllowSetModel && model != fModel) {
if (fModel != null)
- fModel.removeAnnotationModelListener(fInternalListener);
+ fModel.removeAnnotationModelListener(fAnnotationListener);
fModel= model;
if (fModel != null)
- fModel.addAnnotationModelListener(fInternalListener);
+ fModel.addAnnotationModelListener(fAnnotationListener);
postRedraw();
}
diff --git a/org.eclipse.jface.text/src/org/eclipse/jface/text/source/LineNumberRulerColumn.java b/org.eclipse.jface.text/src/org/eclipse/jface/text/source/LineNumberRulerColumn.java
index 96c48b2dc1a..b1e24aaa5b9 100644
--- a/org.eclipse.jface.text/src/org/eclipse/jface/text/source/LineNumberRulerColumn.java
+++ b/org.eclipse.jface.text/src/org/eclipse/jface/text/source/LineNumberRulerColumn.java
@@ -17,6 +17,7 @@ package org.eclipse.jface.text.source;
import java.lang.ref.WeakReference;
import java.util.Arrays;
+import java.util.function.Consumer;
import org.eclipse.swt.SWT;
import org.eclipse.swt.custom.StyledText;
@@ -51,13 +52,10 @@ import org.eclipse.jface.util.Util;
import org.eclipse.jface.text.BadLocationException;
import org.eclipse.jface.text.IDocument;
import org.eclipse.jface.text.IRegion;
-import org.eclipse.jface.text.ITextListener;
import org.eclipse.jface.text.ITextViewer;
import org.eclipse.jface.text.ITextViewerExtension;
import org.eclipse.jface.text.ITextViewerExtension5;
-import org.eclipse.jface.text.IViewportListener;
import org.eclipse.jface.text.JFaceTextUtil;
-import org.eclipse.jface.text.TextEvent;
/**
@@ -79,41 +77,6 @@ public class LineNumberRulerColumn implements IVerticalRulerColumn {
&& !"false".equals(System.getProperty("LineNumberRulerColumn.retina.workaround")) //$NON-NLS-1$ //$NON-NLS-2$
&& internalSupportsZoomedPaint();
- /**
- * Internal listener class.
- */
- class InternalListener implements IViewportListener, ITextListener {
-
- /**
- * @since 3.1
- */
- private boolean fCachedRedrawState= true;
-
- @Override
- public void viewportChanged(int verticalPosition) {
- if (fCachedRedrawState && verticalPosition != fScrollPos)
- redraw();
- }
-
- @Override
- public void textChanged(TextEvent event) {
-
- fCachedRedrawState= event.getViewerRedrawState();
- if (!fCachedRedrawState)
- return;
-
- if (updateNumberOfDigits()) {
- computeIndentations();
- layout(event.getViewerRedrawState());
- return;
- }
-
- boolean viewerCompletelyShown= isViewerCompletelyShown();
- if (viewerCompletelyShown || fSensitiveToTextChanges || event.getDocumentEvent() == null)
- postRedraw();
- fSensitiveToTextChanges= viewerCompletelyShown;
- }
- }
/**
* Handles all the mouse interaction in this line number ruler column.
@@ -398,8 +361,6 @@ public class LineNumberRulerColumn implements IVerticalRulerColumn {
private int fScrollPos;
/** The drawable for double buffering */
private Image fBuffer;
- /** The internal listener */
- private InternalListener fInternalListener= new InternalListener();
/** The font of this column */
private Font fFont;
/** The indentation cache */
@@ -447,6 +408,12 @@ public class LineNumberRulerColumn implements IVerticalRulerColumn {
private WeakReference<Font> fLastFont;
private Font fLastZoomedFont;
+ /**
+ * Redraw the ruler handler called when a line height change.
+ *
+ * @since 3.13
+ */
+ private Consumer<StyledText> lineHeightChangeHandler= (t) -> postRedraw();
/**
* Constructs a new vertical ruler column.
@@ -620,6 +587,10 @@ public class LineNumberRulerColumn implements IVerticalRulerColumn {
}
});
+ // track when StyledText is redrawn to check if some line height changed. In this case, the ruler must be redrawn
+ // to draw line number with well height.
+ VisibleLinesTracker.track(fCachedTextViewer, lineHeightChangeHandler);
+
fCanvas= new Canvas(parentControl, SWT.NO_FOCUS ) {
@Override
public void addMouseListener(MouseListener listener) {
@@ -660,9 +631,7 @@ public class LineNumberRulerColumn implements IVerticalRulerColumn {
fCanvas.addMouseWheelListener(fMouseHandler);
if (fCachedTextViewer != null) {
-
- fCachedTextViewer.addViewportListener(fInternalListener);
- fCachedTextViewer.addTextListener(fInternalListener);
+ VisibleLinesTracker.track(fCachedTextViewer, lineHeightChangeHandler);
if (fFont == null) {
if (fCachedTextWidget != null && !fCachedTextWidget.isDisposed())
@@ -684,8 +653,7 @@ public class LineNumberRulerColumn implements IVerticalRulerColumn {
protected void handleDispose() {
if (fCachedTextViewer != null) {
- fCachedTextViewer.removeViewportListener(fInternalListener);
- fCachedTextViewer.removeTextListener(fInternalListener);
+ VisibleLinesTracker.untrack(fCachedTextViewer, lineHeightChangeHandler);
}
if (fBuffer != null) {
diff --git a/org.eclipse.jface.text/src/org/eclipse/jface/text/source/VisibleLinesTracker.java b/org.eclipse.jface.text/src/org/eclipse/jface/text/source/VisibleLinesTracker.java
new file mode 100644
index 00000000000..14d966f8eef
--- /dev/null
+++ b/org.eclipse.jface.text/src/org/eclipse/jface/text/source/VisibleLinesTracker.java
@@ -0,0 +1,149 @@
+/**
+ * Copyright (c) 2018 Angelo ZERR.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Angelo Zerr <angelo.zerr@gmail.com> - Bug 527720 - [CodeMining] Line number in vertical ruler can be not synchronized with line header annotation
+ */
+package org.eclipse.jface.text.source;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.function.Consumer;
+
+import org.eclipse.swt.custom.StyledText;
+import org.eclipse.swt.events.PaintEvent;
+import org.eclipse.swt.events.PaintListener;
+
+import org.eclipse.jface.text.ITextViewer;
+import org.eclipse.jface.text.JFaceTextUtil;
+
+/**
+ * Class to track line height change of visible lines of a given {@link StyledText}.
+ *
+ */
+class VisibleLinesTracker implements PaintListener {
+
+ private static final String DATA_KEY= VisibleLinesTracker.class.getName();
+
+ /**
+ * The viewer to track.
+ */
+ private final ITextViewer viewer;
+
+ /**
+ * The previous bottom line index.
+ */
+ private int oldBottom= -1;
+
+ /**
+ * The previous bottom line pixel.
+ */
+ private int oldBottomPixel;
+
+ /**
+ *
+ * List of handler to call when a visible line height change.
+ */
+ private final Collection<Consumer<StyledText>> handlers;
+
+ /**
+ * Constructor to track line height change of visible lines of the {@link StyledText} of the
+ * given viewer.
+ *
+ * @param viewer the viewer to track
+ */
+ private VisibleLinesTracker(ITextViewer viewer) {
+ this.viewer= viewer;
+ this.handlers= new ArrayList<>();
+ }
+
+ @Override
+ public void paintControl(PaintEvent e) {
+ StyledText textWidget= viewer.getTextWidget();
+ // track if bottom line index or bottom line pixel changed.
+ if (oldBottom == -1) {
+ oldBottom= JFaceTextUtil.getPartialBottomIndex(viewer);
+ oldBottomPixel= JFaceTextUtil.getLinePixel(textWidget, oldBottom);
+ return;
+ }
+ int newBottom= JFaceTextUtil.getPartialBottomIndex(viewer);
+ if (newBottom != oldBottom) {
+ oldBottom= newBottom;
+ oldBottomPixel= JFaceTextUtil.getLinePixel(textWidget, oldBottom);
+ handlers.forEach(handler -> handler.accept(textWidget));
+ return;
+ }
+ int newBottomPixel= JFaceTextUtil.getLinePixel(textWidget, newBottom);
+ if (newBottomPixel != oldBottomPixel) {
+ oldBottomPixel= newBottomPixel;
+ handlers.forEach(handler -> handler.accept(textWidget));
+ return;
+ }
+ }
+
+ /**
+ * Track the line height change of the {@link StyledText} of the given handler an call the given
+ * handler.
+ *
+ * @param viewer the viewer to track
+ * @param handler the handler to call when line height change.
+ */
+ static void track(ITextViewer viewer, Consumer<StyledText> handler) {
+ StyledText textWidget= viewer != null ? viewer.getTextWidget() : null;
+ if (textWidget == null) {
+ return;
+ }
+ VisibleLinesTracker tracker= (VisibleLinesTracker) textWidget.getData(DATA_KEY);
+ if (tracker == null) {
+ tracker= new VisibleLinesTracker(viewer);
+ textWidget.setData(DATA_KEY, tracker);
+ }
+ tracker.addHandler(handler);
+ }
+
+ /**
+ * Untrack the line height change of the {@link StyledText} of the given handler an call the
+ * given handler.
+ *
+ * @param viewer the viewer to track
+ * @param handler the handler to call when line height change.
+ */
+ static void untrack(ITextViewer viewer, Consumer<StyledText> handler) {
+ StyledText textWidget= viewer != null ? viewer.getTextWidget() : null;
+ if (textWidget == null) {
+ return;
+ }
+ VisibleLinesTracker tracker= (VisibleLinesTracker) textWidget.getData(DATA_KEY);
+ if (tracker != null) {
+ tracker.removeHandler(handler);
+ }
+ }
+
+ /**
+ * Add the given handler.
+ *
+ * @param handler the handler to call when a visible line height change.
+ */
+ private void addHandler(Consumer<StyledText> handler) {
+ if (handlers.isEmpty()) {
+ viewer.getTextWidget().addPaintListener(this);
+ }
+ handlers.add(handler);
+ }
+
+ /**
+ * Remove the given handler.
+ *
+ * @param handler the handler to call when a visible line height change.
+ */
+ private void removeHandler(Consumer<StyledText> handler) {
+ handlers.remove(handler);
+ if (handlers.isEmpty()) {
+ viewer.getTextWidget().removePaintListener(this);
+ }
+ }
+}

Back to the top