diff options
| author | angelozerr | 2017-12-21 14:31:28 +0000 |
|---|---|---|
| committer | Mickael Istria | 2018-01-08 11:11:52 +0000 |
| commit | ae1808bedf9b19c2eeb02600f58c48787041a1d3 (patch) | |
| tree | 8d2af13daa207671fee4e5d00a002c901bbc09e8 | |
| parent | 71eeeb63bd19b1263f0378d09b7d92a5108e3b44 (diff) | |
| download | eclipse.platform.text-ae1808bedf9b19c2eeb02600f58c48787041a1d3.tar.gz eclipse.platform.text-ae1808bedf9b19c2eeb02600f58c48787041a1d3.tar.xz eclipse.platform.text-ae1808bedf9b19c2eeb02600f58c48787041a1d3.zip | |
Bug 529087 - [CodeMining] Improve draw of line content annotation.I20180110-0100I20180109-2000I20180108-2000
Change-Id: I4aabd08ea87b650722d3e50a77832689feb61521
Signed-off-by: angelozerr <angelo.zerr@gmail.com>
5 files changed, 160 insertions, 84 deletions
diff --git a/org.eclipse.jface.text.examples/src/org/eclipse/jface/text/examples/sources/inlined/ColorAnnotation.java b/org.eclipse.jface.text.examples/src/org/eclipse/jface/text/examples/sources/inlined/ColorAnnotation.java index a6e7a318768..3a169613ffd 100644 --- a/org.eclipse.jface.text.examples/src/org/eclipse/jface/text/examples/sources/inlined/ColorAnnotation.java +++ b/org.eclipse.jface.text.examples/src/org/eclipse/jface/text/examples/sources/inlined/ColorAnnotation.java @@ -30,19 +30,17 @@ public class ColorAnnotation extends LineContentAnnotation { super(pos, viewer);
}
- @Override
- public int getWidth() {
- StyledText styledText = super.getTextWidget();
- return getSquareWidth(styledText);
- }
-
public void setColor(Color color) {
this.color = color;
}
@Override
- public void draw(GC gc, StyledText textWidget, int offset, int length, Color color, int x, int y) {
- int size = getSquareSize(gc.getFontMetrics());
+ protected int drawAndComputeWidth(GC gc, StyledText textWidget, int offset, int length, Color color, int x, int y) {
+ FontMetrics fontMetrics = gc.getFontMetrics();
+ int size = getSquareSize(fontMetrics);
+ x += fontMetrics.getLeading();
+ y += fontMetrics.getDescent();
+
Rectangle rect = new Rectangle(x, y, size, size);
// Fill square
@@ -52,6 +50,7 @@ public class ColorAnnotation extends LineContentAnnotation { // Draw square box
gc.setForeground(textWidget.getForeground());
gc.drawRectangle(rect);
+ return getSquareWidth(gc.getFontMetrics());
}
/**
@@ -70,12 +69,9 @@ public class ColorAnnotation extends LineContentAnnotation { * @param styledText
* @return the width of square
*/
- private static int getSquareWidth(StyledText styledText) {
- GC gc = new GC(styledText);
- FontMetrics fontMetrics = gc.getFontMetrics();
+ private static int getSquareWidth(FontMetrics fontMetrics) {
// width = 2 spaces + size width of square
int width = 2 * fontMetrics.getAverageCharWidth() + getSquareSize(fontMetrics);
- gc.dispose();
return width;
}
}
diff --git a/org.eclipse.jface.text.examples/src/org/eclipse/jface/text/examples/sources/inlined/InlinedAnnotationDemo.java b/org.eclipse.jface.text.examples/src/org/eclipse/jface/text/examples/sources/inlined/InlinedAnnotationDemo.java index 3f3d81575a2..5043c0c0a8b 100644 --- a/org.eclipse.jface.text.examples/src/org/eclipse/jface/text/examples/sources/inlined/InlinedAnnotationDemo.java +++ b/org.eclipse.jface.text.examples/src/org/eclipse/jface/text/examples/sources/inlined/InlinedAnnotationDemo.java @@ -170,7 +170,7 @@ public class InlinedAnnotationDemo { // Color annotation
if (color != null) {
- Position colorPos = new Position(pos.offset + index + "color:".length(), rgb.length());
+ Position colorPos = new Position(pos.offset + index + "color:".length(), 1);
ColorAnnotation colorAnnotation = support.findExistingAnnotation(colorPos);
if (colorAnnotation == null) {
colorAnnotation = new ColorAnnotation(colorPos, viewer);
@@ -179,6 +179,24 @@ public class InlinedAnnotationDemo { annotations.add(colorAnnotation);
}
+ // rgb parameter names annotations
+ int rgbIndex = line.indexOf("rgb");
+ if (rgbIndex != -1) {
+ rgbIndex = rgbIndex + "rgb".length();
+ int startOffset = pos.offset + rgbIndex;
+ String rgbContent = line.substring(rgbIndex, line.length());
+ int startIndex = addRGBParamNameAnnotation("red:", rgbContent, 0, startOffset, viewer, support,
+ annotations);
+ if (startIndex != -1) {
+ startIndex = addRGBParamNameAnnotation("green:", rgbContent, startIndex, startOffset, viewer,
+ support, annotations);
+ if (startIndex != -1) {
+ startIndex = addRGBParamNameAnnotation("blue:", rgbContent, startIndex, startOffset,
+ viewer, support, annotations);
+ }
+ }
+ }
+
} catch (BadLocationException e) {
e.printStackTrace();
}
@@ -188,6 +206,41 @@ public class InlinedAnnotationDemo { }
/**
+ * Add RGB parameter name annotation
+ *
+ * @param paramName
+ * @param rgbContent
+ * @param startIndex
+ * @param startOffset
+ * @param viewer
+ * @param support
+ * @param annotations
+ * @return the current parsed index
+ */
+ private static int addRGBParamNameAnnotation(String paramName, String rgbContent, int startIndex, int startOffset,
+ ISourceViewer viewer, InlinedAnnotationSupport support, Set<AbstractInlinedAnnotation> annotations) {
+ char startChar = startIndex == 0 ? '(' : ',';
+ char[] chars = rgbContent.toCharArray();
+ for (int i = startIndex; i < chars.length; i++) {
+ char c = chars[i];
+ if (c == startChar) {
+ if (i == chars.length - 1) {
+ return -1;
+ }
+ Position paramPos = new Position(startOffset + i + 1, 1);
+ LineContentAnnotation colorParamAnnotation = support.findExistingAnnotation(paramPos);
+ if (colorParamAnnotation == null) {
+ colorParamAnnotation = new LineContentAnnotation(paramPos, viewer);
+ }
+ colorParamAnnotation.setText(paramName);
+ annotations.add(colorParamAnnotation);
+ return i + 1;
+ }
+ }
+ return -1;
+ }
+
+ /**
* Parse the given input rgb color and returns an instance of SWT Color and null
* otherwise.
*
diff --git a/org.eclipse.jface.text/src/org/eclipse/jface/text/source/inlined/InlinedAnnotationDrawingStrategy.java b/org.eclipse.jface.text/src/org/eclipse/jface/text/source/inlined/InlinedAnnotationDrawingStrategy.java index 8a9647f356b..cb9dd368749 100644 --- a/org.eclipse.jface.text/src/org/eclipse/jface/text/source/inlined/InlinedAnnotationDrawingStrategy.java +++ b/org.eclipse.jface.text/src/org/eclipse/jface/text/source/inlined/InlinedAnnotationDrawingStrategy.java @@ -13,7 +13,6 @@ package org.eclipse.jface.text.source.inlined; import org.eclipse.swt.custom.StyleRange; import org.eclipse.swt.custom.StyledText; import org.eclipse.swt.graphics.Color; -import org.eclipse.swt.graphics.FontMetrics; import org.eclipse.swt.graphics.GC; import org.eclipse.swt.graphics.GlyphMetrics; import org.eclipse.swt.graphics.Rectangle; @@ -52,14 +51,6 @@ class InlinedAnnotationDrawingStrategy implements IDrawingStrategy { */ public static void draw(AbstractInlinedAnnotation annotation, GC gc, StyledText textWidget, int offset, int length, Color color) { - if (annotation.isMarkedDeleted()) { - // When annotation is deleted, redraw the styled text to hide old draw of - // annotations - textWidget.redraw(); - // update caret offset since line spacing has changed. - textWidget.setCaretOffset(textWidget.getCaretOffset()); - return; - } if (annotation instanceof LineHeaderAnnotation) { draw((LineHeaderAnnotation) annotation, gc, textWidget, offset, length, color); } else { @@ -79,6 +70,14 @@ class InlinedAnnotationDrawingStrategy implements IDrawingStrategy { */ private static void draw(LineHeaderAnnotation annotation, GC gc, StyledText textWidget, int offset, int length, Color color) { + if (annotation.isMarkedDeleted()) { + // When annotation is deleted, redraw the styled text to hide old draw of + // annotations + textWidget.redraw(); + // update caret offset since line spacing has changed. + textWidget.setCaretOffset(textWidget.getCaretOffset()); + return; + } // compute current, previous line index. int lineIndex= -1; try { @@ -93,6 +92,10 @@ class InlinedAnnotationDrawingStrategy implements IDrawingStrategy { if (viewer instanceof ITextViewerExtension5) { firstLineIndex= ((ITextViewerExtension5) viewer).modelLine2WidgetLine(firstLineIndex); } + if (previousLineIndex < firstLineIndex) { + // the previous line index where annotation must be drawn in line spacing is hidden, don't draw it. + return; + } if (gc != null) { // Compute the location of the annotation int x= textWidget.getLocationAtOffset(offset).x; @@ -146,31 +149,65 @@ class InlinedAnnotationDrawingStrategy implements IDrawingStrategy { */ private static void draw(LineContentAnnotation annotation, GC gc, StyledText textWidget, int offset, int length, Color color) { + StyleRange style= null; + try { + style= textWidget.getStyleRangeAtOffset(offset); + } catch (Exception e) { + return; + } + if (annotation.isMarkedDeleted()) { + // When annotation is deleted, update metrics to null to remove extra spaces of the line content annotation. + if (style != null) { + style.metrics= null; + textWidget.setStyleRange(style); + } + return; + } if (gc != null) { // Compute the location of the annotation - FontMetrics fontMetrics= gc.getFontMetrics(); Rectangle bounds= textWidget.getTextBounds(offset, offset); - int x= bounds.x + fontMetrics.getLeading(); - int y= bounds.y + fontMetrics.getDescent(); + int x= bounds.x; + int y= bounds.y; // Draw the line content annotation annotation.draw(gc, textWidget, offset, length, color, x, y); - - // The inline annotation replaces one character by taking a place width - // GlyphMetrics - // Here we need to redraw this first character because GlyphMetrics clip this - // character. - String s= textWidget.getText(offset, offset); - StyleRange style= textWidget.getStyleRangeAtOffset(offset); - if (style != null) { - if (style.background != null) { - gc.setBackground(style.background); + // check the width annotation + int width= annotation.getWidth(); + GlyphMetrics metrics= style != null ? style.metrics : null; + if (metrics == null || metrics.width != width) { + // The annotation drawn width is not the same than metrics width, update it. + if (metrics == null) { + metrics= new GlyphMetrics(0, 0, width); + } else { + metrics.width= width; + } + if (style == null) { + style= new StyleRange(); + style.start= offset; + style.length= 1; + style.background= textWidget.getBackground(); + style.foreground= textWidget.getForeground(); } - if (style.foreground != null) { - gc.setForeground(style.foreground); + style.metrics= metrics; + textWidget.setStyleRange(style); + return; + } + if (width != 0) { + // The inline annotation replaces one character by taking a place width + // GlyphMetrics + // Here we need to redraw this first character because GlyphMetrics clip this + // character. + String s= textWidget.getText(offset, offset); + if (style != null) { + if (style.background != null) { + gc.setBackground(style.background); + } + if (style.foreground != null) { + gc.setForeground(style.foreground); + } } + gc.drawString(s, bounds.x + bounds.width - gc.stringExtent(s).x, bounds.y, true); } - gc.drawString(s, bounds.x + bounds.width - gc.stringExtent(s).x, bounds.y, true); } else { textWidget.redrawRange(offset, length, true); } diff --git a/org.eclipse.jface.text/src/org/eclipse/jface/text/source/inlined/InlinedAnnotationSupport.java b/org.eclipse.jface.text/src/org/eclipse/jface/text/source/inlined/InlinedAnnotationSupport.java index 33df72ff102..0d20e101130 100644 --- a/org.eclipse.jface.text/src/org/eclipse/jface/text/source/inlined/InlinedAnnotationSupport.java +++ b/org.eclipse.jface.text/src/org/eclipse/jface/text/source/inlined/InlinedAnnotationSupport.java @@ -21,7 +21,6 @@ import java.util.Set; import java.util.function.Consumer; import org.eclipse.swt.SWT; -import org.eclipse.swt.custom.StyleRange; import org.eclipse.swt.custom.StyledText; import org.eclipse.swt.custom.StyledTextLineSpacingProvider; import org.eclipse.swt.graphics.Color; @@ -140,7 +139,6 @@ public class InlinedAnnotationSupport implements StyledTextLineSpacingProvider { if (annotationModel == null) { return; } - StyledText styledText= fViewer.getTextWidget(); Map<AbstractInlinedAnnotation, Position> annotationsToAdd= new HashMap<>(); List<AbstractInlinedAnnotation> annotationsToRemove= fInlinedAnnotations != null ? new ArrayList<>(fInlinedAnnotations) @@ -151,32 +149,11 @@ public class InlinedAnnotationSupport implements StyledTextLineSpacingProvider { // The annotation was not created, add it annotationsToAdd.put(ann, ann.getPosition()); } - if (ann instanceof LineContentAnnotation) { - // Create metrics with well width to add space where the inline annotation must - // be drawn. - runInUIThread(styledText, (text) -> { - StyleRange s= new StyleRange(); - s.start= ann.getPosition().getOffset(); - s.length= 1; - s.metrics= ((LineContentAnnotation) ann).createMetrics(); - text.setStyleRange(s); - }); - } } // Process annotations to remove for (AbstractInlinedAnnotation ann : annotationsToRemove) { // Mark annotation as deleted to ignore the draw ann.markDeleted(true); - if (ann instanceof LineContentAnnotation) { - // Set metrics to null to remove space of the inline annotation - runInUIThread(styledText, (text) -> { - StyleRange s= new StyleRange(); - s.start= ann.getPosition().getOffset(); - s.length= 1; - s.metrics= null; - text.setStyleRange(s); - }); - } } // Update annotation model synchronized (getLockObject(annotationModel)) { @@ -217,7 +194,7 @@ public class InlinedAnnotationSupport implements StyledTextLineSpacingProvider { return null; } for (AbstractInlinedAnnotation ann : fInlinedAnnotations) { - if (ann.getPosition().offset == pos.offset) { + if (pos.equals(ann.getPosition()) && !ann.getPosition().isDeleted()) { try { return (T) ann; } catch (ClassCastException e) { diff --git a/org.eclipse.jface.text/src/org/eclipse/jface/text/source/inlined/LineContentAnnotation.java b/org.eclipse.jface.text/src/org/eclipse/jface/text/source/inlined/LineContentAnnotation.java index e2aae83f90b..7b136c74f46 100644 --- a/org.eclipse.jface.text/src/org/eclipse/jface/text/source/inlined/LineContentAnnotation.java +++ b/org.eclipse.jface.text/src/org/eclipse/jface/text/source/inlined/LineContentAnnotation.java @@ -11,9 +11,8 @@ package org.eclipse.jface.text.source.inlined;
import org.eclipse.swt.custom.StyledText;
-import org.eclipse.swt.graphics.FontMetrics;
+import org.eclipse.swt.graphics.Color;
import org.eclipse.swt.graphics.GC;
-import org.eclipse.swt.graphics.GlyphMetrics;
import org.eclipse.jface.text.Position;
import org.eclipse.jface.text.source.ISourceViewer;
@@ -27,6 +26,11 @@ import org.eclipse.jface.text.source.ISourceViewer; public class LineContentAnnotation extends AbstractInlinedAnnotation {
/**
+ * The annotation width
+ */
+ private int width;
+
+ /**
* Line content annotation constructor.
*
* @param position the position where the annotation must be drawn.
@@ -37,32 +41,41 @@ public class LineContentAnnotation extends AbstractInlinedAnnotation { }
/**
- * Returns an instance of GlyphMetrics used to takes 'width' place when the annotation is drawn
- * inside the line.
+ * Returns the annotation width. By default it computes the well width for the text annotation.
*
- * @return an instance of GlyphMetrics used to takes 'width' place when the annotation is drawn
- * inside the line.
+ * @return the annotation width.
*/
- public GlyphMetrics createMetrics() {
- return new GlyphMetrics(0, 0, getWidth());
+ public final int getWidth() {
+ return width;
}
/**
- * Returns the annotation width. By default it computes the well width for the text annotation.
+ * {@inheritDoc}
+ * <p>
+ * After drawn, compute the text width and update it.
+ * </p>
+ */
+ @Override
+ public final void draw(GC gc, StyledText textWidget, int offset, int length, Color color, int x, int y) {
+ width= drawAndComputeWidth(gc, textWidget, offset, length, color, x, y);
+ }
+
+ /**
+ * Draw the inlined annotation. By default it draws the text of the annotation with gray color.
+ * User can override this method to draw anything.
*
- * @return the annotation width.
+ * @param gc the graphics context
+ * @param textWidget the text widget to draw on
+ * @param offset the offset of the line
+ * @param length the length of the line
+ * @param color the color of the line
+ * @param x the x position of the annotation
+ * @param y the y position of the annotation
+ * @return the text width.
*/
- public int getWidth() {
- String text= super.getText();
- if (text == null) {
- return 0;
- }
- int nbChars= text.length() + 1;
- StyledText styledText= super.getTextWidget();
- GC gc= new GC(styledText);
- FontMetrics fontMetrics= gc.getFontMetrics();
- int width= nbChars * fontMetrics.getAverageCharWidth();
- gc.dispose();
- return width;
+ protected int drawAndComputeWidth(GC gc, StyledText textWidget, int offset, int length, Color color, int x, int y) {
+ // Draw the text annotation and returns the width
+ super.draw(gc, textWidget, offset, length, color, x, y);
+ return gc.stringExtent(getText()).x + 2 * gc.getFontMetrics().getAverageCharWidth();
}
}
|
