From e98a8466484fcd2e91c41473a520f17fa97079ec Mon Sep 17 00:00:00 2001 From: Kirill Likhodedov Date: Sun, 26 Aug 2012 13:48:40 +0400 Subject: [PATCH] [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. --- .../diff/impl/DiffLineMarkerRenderer.java | 17 ++++++++++++++-- .../diff/impl/highlighting/DiffMarkup.java | 20 ++++++++++++++----- .../ChangeHighlighterHolder.java | 4 ++-- 3 files changed, 32 insertions(+), 9 deletions(-) diff --git a/platform/platform-impl/src/com/intellij/openapi/diff/impl/DiffLineMarkerRenderer.java b/platform/platform-impl/src/com/intellij/openapi/diff/impl/DiffLineMarkerRenderer.java index a68fa5d55dde..86cf702f5559 100644 --- a/platform/platform-impl/src/com/intellij/openapi/diff/impl/DiffLineMarkerRenderer.java +++ b/platform/platform-impl/src/com/intellij/openapi/diff/impl/DiffLineMarkerRenderer.java @@ -26,13 +26,22 @@ import org.jetbrains.annotations.NotNull; import java.awt.*; /** - * Expands the change highlighters to the editor's gutter. + *

Draws the diff change highlighters on the editor's gutter.

+ *

Has ability to draw applied changes (used in the merge tool).

*/ 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); diff --git a/platform/platform-impl/src/com/intellij/openapi/diff/impl/highlighting/DiffMarkup.java b/platform/platform-impl/src/com/intellij/openapi/diff/impl/highlighting/DiffMarkup.java index 9558e9088189..7347f82e4c04 100644 --- a/platform/platform-impl/src/com/intellij/openapi/diff/impl/highlighting/DiffMarkup.java +++ b/platform/platform-impl/src/com/intellij/openapi/diff/impl/highlighting/DiffMarkup.java @@ -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; diff --git a/platform/platform-impl/src/com/intellij/openapi/diff/impl/incrementalMerge/ChangeHighlighterHolder.java b/platform/platform-impl/src/com/intellij/openapi/diff/impl/incrementalMerge/ChangeHighlighterHolder.java index 83f21252bed9..ac81a93025e1 100644 --- a/platform/platform-impl/src/com/intellij/openapi/diff/impl/incrementalMerge/ChangeHighlighterHolder.java +++ b/platform/platform-impl/src/com/intellij/openapi/diff/impl/incrementalMerge/ChangeHighlighterHolder.java @@ -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; }