[diff] Draw highlighters above gutters. Step 3: for inline changes

For inline changes the range being highlighted is 0 pixels high (it is calculated in EditorGutterComponentImpl#getLineRendererRectangle)
To avoid the problem, identify if the change is inline (InlineFragment occupying one line), and increase the height of the highlighter area to be 1 editor line high.
This commit is contained in:
Kirill Likhodedov
2012-10-31 15:06:57 +04:00
parent d241dfbd42
commit e98a846648
3 changed files with 32 additions and 9 deletions
@@ -26,13 +26,22 @@ import org.jetbrains.annotations.NotNull;
import java.awt.*;
/**
* Expands the change highlighters to the editor's gutter.
* <p>Draws the diff change highlighters on the editor's gutter.</p>
* <p>Has ability to draw applied changes (used in the merge tool).</p>
*/
public class DiffLineMarkerRenderer implements LineMarkerRenderer {
private final TextDiffType myDiffType;
private final boolean myEnsureAtLeastOneLineHigh;
public DiffLineMarkerRenderer(@NotNull TextDiffType diffType) {
/**
* @param diffType the type of the difference.
* @param ensureAtLeastOneLineHigh if true, the height of the rectangle will be at least one line high,
* if 0 is passed as a height of the Rectangle to {@link #paint(Editor, Graphics, Rectangle)}.
* The height won't be modified if ensureAtLeastOneLineHigh is false, or if height is not 0.
*/
public DiffLineMarkerRenderer(@NotNull TextDiffType diffType, boolean ensureAtLeastOneLineHigh) {
myDiffType = diffType;
myEnsureAtLeastOneLineHigh = ensureAtLeastOneLineHigh;
}
@Override
@@ -49,6 +58,10 @@ public class DiffLineMarkerRenderer implements LineMarkerRenderer {
int width = gutter.getWidth();
int height = range.height;
if (height == 0 && myEnsureAtLeastOneLineHigh) {
height = editor.getLineHeight();
}
if (!myDiffType.isApplied()) {
if (height > 2) {
g.setColor(color);
@@ -23,6 +23,7 @@ import com.intellij.openapi.diff.actions.MergeOperations;
import com.intellij.openapi.diff.impl.DiffLineMarkerRenderer;
import com.intellij.openapi.diff.impl.EditorSource;
import com.intellij.openapi.diff.impl.fragments.Fragment;
import com.intellij.openapi.diff.impl.fragments.InlineFragment;
import com.intellij.openapi.diff.impl.util.GutterActionRenderer;
import com.intellij.openapi.diff.impl.util.TextDiffType;
import com.intellij.openapi.diff.impl.util.TextDiffTypeEnum;
@@ -68,8 +69,9 @@ public abstract class DiffMarkup implements EditorSource, Disposable {
public void highlightText(@NotNull Fragment fragment, @Nullable GutterIconRenderer gutterIconRenderer) {
MarkupModel markupModel = getMarkupModel();
Editor editor = getEditor();
TextDiffTypeEnum diffTypeEnum = fragment.getType();
if (diffTypeEnum == null || markupModel == null) {
if (diffTypeEnum == null || markupModel == null || editor == null) {
return;
}
TextDiffType type = TextDiffType.create(diffTypeEnum);
@@ -82,18 +84,19 @@ public abstract class DiffMarkup implements EditorSource, Disposable {
RangeHighlighter rangeMarker;
if (range.getLength() == 0) {
TextAttributes textAttributes = new TextAttributes(null, null, attributes.getBackgroundColor(), EffectType.BOXED, Font.PLAIN);
rangeMarker = markupModel
.addRangeHighlighter(range.getStartOffset(), range.getStartOffset(), LAYER, textAttributes, HighlighterTargetArea.EXACT_RANGE);
rangeMarker = markupModel.addRangeHighlighter(range.getStartOffset(), range.getStartOffset(), LAYER,
textAttributes, HighlighterTargetArea.EXACT_RANGE);
}
else {
rangeMarker = markupModel.addRangeHighlighter(range.getStartOffset(), range.getEndOffset(), LAYER,
attributes, HighlighterTargetArea.EXACT_RANGE);
attributes, HighlighterTargetArea.EXACT_RANGE);
}
if (gutterIconRenderer != null) {
rangeMarker.setGutterIconRenderer(gutterIconRenderer);
}
rangeMarker.setLineMarkerRenderer(new DiffLineMarkerRenderer(type));
boolean ensureAtLeastOneLineHigh = shouldIncreaseHighlightingHeight(fragment, editor, range);
rangeMarker.setLineMarkerRenderer(new DiffLineMarkerRenderer(type, ensureAtLeastOneLineHigh));
Color stripeBarColor = attributes.getErrorStripeColor();
if (stripeBarColor != null) {
@@ -103,6 +106,13 @@ public abstract class DiffMarkup implements EditorSource, Disposable {
saveHighlighter(rangeMarker);
}
private static boolean shouldIncreaseHighlightingHeight(@NotNull Fragment fragment, @NotNull Editor editor, @NotNull TextRange range) {
int startY = editor.offsetToLogicalPosition(range.getStartOffset()).line;
int endY = editor.offsetToLogicalPosition(range.getEndOffset()).line;
boolean onTheSameLine = (startY == endY);
return onTheSameLine && fragment instanceof InlineFragment;
}
public void addLineMarker(int line, @Nullable TextAttributesKey type) {
RangeHighlighter marker = createLineMarker(type, line);
if (marker == null) return;
@@ -78,7 +78,7 @@ class ChangeHighlighterHolder {
RangeHighlighter highlighter = getMarkupModel().addLineHighlighter(line, layer, null);
highlighter.setLineSeparatorColor(diffType.getTextBackground(myEditor));
highlighterCreated(highlighter, diffType.getTextAttributes(myEditor), applied);
highlighter.setLineMarkerRenderer(new DiffLineMarkerRenderer(diffType));
highlighter.setLineMarkerRenderer(new DiffLineMarkerRenderer(diffType, false));
return highlighter;
}
@@ -89,7 +89,7 @@ class ChangeHighlighterHolder {
TextAttributes attributes = type.getTextAttributes(myEditor);
RangeHighlighter highlighter = getMarkupModel().addRangeHighlighter(start, end, layer, attributes, targetArea);
highlighterCreated(highlighter, attributes, applied);
highlighter.setLineMarkerRenderer(new DiffLineMarkerRenderer(type));
highlighter.setLineMarkerRenderer(new DiffLineMarkerRenderer(type, false));
return highlighter;
}