mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
[diff] Highlight the whole line for inline fragment, but with less intensive color.
* Don't highlight the line marker renderer for inline changes - the line fragment wrapping them will be used. * Therefore remove the code for adjusting text range height from the DiffLineMarkerRenderer. * Introduce TextDiffType#myInlineWrapper for diff type of a fragment that is a wrapper for inline changes. - use special background color for such type. - refactor getTextAttributes: for scheme just return the color from scheme, all adjustments (for applied and for inline changes) are made in getTextAttributes(Editor). * Create special inline TextDiffType instance where needed: in the LineBlocks (for DividerPolygons) and in the DiffMarkup (for the gutter and code highlighting).
This commit is contained in:
+3
-35
@@ -20,10 +20,8 @@ import com.intellij.openapi.editor.Editor;
|
||||
import com.intellij.openapi.editor.ex.EditorEx;
|
||||
import com.intellij.openapi.editor.ex.EditorGutterComponentEx;
|
||||
import com.intellij.openapi.editor.markup.LineMarkerRenderer;
|
||||
import com.intellij.openapi.util.TextRange;
|
||||
import com.intellij.util.ui.UIUtil;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.awt.*;
|
||||
|
||||
@@ -34,27 +32,14 @@ import java.awt.*;
|
||||
public class DiffLineMarkerRenderer implements LineMarkerRenderer {
|
||||
|
||||
@NotNull private final TextDiffType myDiffType;
|
||||
@Nullable private final TextRange myTextRange;
|
||||
|
||||
@NotNull
|
||||
public static DiffLineMarkerRenderer createStandardInstance(@NotNull TextDiffType diffType) {
|
||||
return new DiffLineMarkerRenderer(diffType, null);
|
||||
public static DiffLineMarkerRenderer createInstance(@NotNull TextDiffType diffType) {
|
||||
return new DiffLineMarkerRenderer(diffType);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates an instance of the renderer that calculates the visual height of the text range and ensures that the drawn rectangle is at
|
||||
* least as high as needed.
|
||||
* @param diffType the type of the difference.
|
||||
* @param range the highlighted text range.
|
||||
*/
|
||||
@NotNull
|
||||
public static DiffLineMarkerRenderer createHeightAdjustingInstance(@NotNull TextDiffType diffType, @NotNull TextRange range) {
|
||||
return new DiffLineMarkerRenderer(diffType, range);
|
||||
}
|
||||
|
||||
private DiffLineMarkerRenderer(@NotNull TextDiffType diffType, @Nullable TextRange range) {
|
||||
private DiffLineMarkerRenderer(@NotNull TextDiffType diffType) {
|
||||
myDiffType = diffType;
|
||||
myTextRange = range;
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -71,10 +56,6 @@ public class DiffLineMarkerRenderer implements LineMarkerRenderer {
|
||||
int width = gutter.getWidth();
|
||||
int height = range.height;
|
||||
|
||||
if (myTextRange != null) {
|
||||
height = calcHeightInVisualLines(editor, myTextRange) * editor.getLineHeight();
|
||||
}
|
||||
|
||||
if (!myDiffType.isApplied()) {
|
||||
if (height > 2) {
|
||||
g.setColor(color);
|
||||
@@ -91,17 +72,4 @@ public class DiffLineMarkerRenderer implements LineMarkerRenderer {
|
||||
}
|
||||
}
|
||||
|
||||
private static int calcHeightInVisualLines(@NotNull Editor editor, @NotNull TextRange range) {
|
||||
int startY = editor.offsetToVisualPosition(range.getStartOffset()).getLine();
|
||||
int endY = editor.offsetToVisualPosition(range.getEndOffset()).getLine();
|
||||
if (startY > endY) {
|
||||
return 0;
|
||||
}
|
||||
return endY - startY + 1;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public TextDiffType getType() {
|
||||
return myDiffType;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -22,7 +22,9 @@ import com.intellij.openapi.diff.DiffViewer;
|
||||
import com.intellij.openapi.diff.LineTokenizer;
|
||||
import com.intellij.openapi.diff.ex.DiffFragment;
|
||||
import com.intellij.openapi.diff.impl.external.DiffManagerImpl;
|
||||
import com.intellij.openapi.diff.impl.fragments.LineFragment;
|
||||
import com.intellij.openapi.diff.impl.util.FocusDiffSide;
|
||||
import com.intellij.openapi.diff.impl.util.TextDiffType;
|
||||
import com.intellij.openapi.editor.Document;
|
||||
import com.intellij.openapi.editor.EditorFactory;
|
||||
import com.intellij.openapi.editor.ex.EditorEx;
|
||||
@@ -111,4 +113,12 @@ public class DiffUtil {
|
||||
return backgroundColor.darker();
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public static TextDiffType makeTextDiffType(@NotNull LineFragment fragment) {
|
||||
TextDiffType type = TextDiffType.create(fragment.getType());
|
||||
if (fragment.getChildrenIterator() != null) {
|
||||
return TextDiffType.deriveInstanceForInlineWrapperFragment(type);
|
||||
}
|
||||
return type;
|
||||
}
|
||||
}
|
||||
|
||||
+2
@@ -49,6 +49,8 @@ public class FragmentHighlighterImpl implements FragmentHighlighter {
|
||||
}
|
||||
|
||||
public void highlightLine(final LineFragment fragment) {
|
||||
highlightFragmentImpl(fragment);
|
||||
|
||||
addModifyActions(fragment, myAppender1, myAppender2);
|
||||
final Iterator<Fragment> iterator = fragment.getChildrenIterator();
|
||||
if (iterator == null) {
|
||||
|
||||
+14
-15
@@ -21,9 +21,11 @@ import com.intellij.openapi.diff.DiffColors;
|
||||
import com.intellij.openapi.diff.actions.MergeActionGroup;
|
||||
import com.intellij.openapi.diff.actions.MergeOperations;
|
||||
import com.intellij.openapi.diff.impl.DiffLineMarkerRenderer;
|
||||
import com.intellij.openapi.diff.impl.DiffUtil;
|
||||
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.fragments.LineFragment;
|
||||
import com.intellij.openapi.diff.impl.util.GutterActionRenderer;
|
||||
import com.intellij.openapi.diff.impl.util.TextDiffType;
|
||||
import com.intellij.openapi.diff.impl.util.TextDiffTypeEnum;
|
||||
@@ -69,14 +71,16 @@ public abstract class DiffMarkup implements EditorSource, Disposable {
|
||||
|
||||
public void highlightText(@NotNull Fragment fragment, @Nullable GutterIconRenderer gutterIconRenderer) {
|
||||
MarkupModel markupModel = getMarkupModel();
|
||||
Editor editor = getEditor();
|
||||
EditorEx editor = getEditor();
|
||||
TextDiffTypeEnum diffTypeEnum = fragment.getType();
|
||||
if (diffTypeEnum == null || markupModel == null || editor == null) {
|
||||
return;
|
||||
}
|
||||
TextDiffType type = TextDiffType.create(diffTypeEnum);
|
||||
TextDiffType type = fragment instanceof LineFragment
|
||||
? DiffUtil.makeTextDiffType((LineFragment)fragment)
|
||||
: TextDiffType.create(diffTypeEnum);
|
||||
TextRange range = fragment.getRange(getSide());
|
||||
TextAttributes attributes = type.getTextAttributes(getEditor());
|
||||
TextAttributes attributes = type.getTextAttributes(editor);
|
||||
if (attributes == null) {
|
||||
return;
|
||||
}
|
||||
@@ -95,23 +99,18 @@ public abstract class DiffMarkup implements EditorSource, Disposable {
|
||||
rangeMarker.setGutterIconRenderer(gutterIconRenderer);
|
||||
}
|
||||
|
||||
boolean adjustHeight = shouldIncreaseHighlightingHeight(fragment);
|
||||
rangeMarker.setLineMarkerRenderer(adjustHeight
|
||||
? DiffLineMarkerRenderer.createHeightAdjustingInstance(type, range)
|
||||
: DiffLineMarkerRenderer.createStandardInstance(type));
|
||||
if (!(fragment instanceof InlineFragment)) {
|
||||
rangeMarker.setLineMarkerRenderer(DiffLineMarkerRenderer.createInstance(type));
|
||||
|
||||
Color stripeBarColor = attributes.getErrorStripeColor();
|
||||
if (stripeBarColor != null) {
|
||||
rangeMarker.setErrorStripeMarkColor(stripeBarColor);
|
||||
rangeMarker.setThinErrorStripeMark(true);
|
||||
Color stripeBarColor = attributes.getErrorStripeColor();
|
||||
if (stripeBarColor != null) {
|
||||
rangeMarker.setErrorStripeMarkColor(stripeBarColor);
|
||||
rangeMarker.setThinErrorStripeMark(true);
|
||||
}
|
||||
}
|
||||
saveHighlighter(rangeMarker);
|
||||
}
|
||||
|
||||
private static boolean shouldIncreaseHighlightingHeight(@NotNull Fragment fragment) {
|
||||
return fragment instanceof InlineFragment;
|
||||
}
|
||||
|
||||
public void addLineMarker(int line, @Nullable TextAttributesKey type) {
|
||||
RangeHighlighter marker = createLineMarker(type, line);
|
||||
if (marker == null) return;
|
||||
|
||||
+2
-2
@@ -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(DiffLineMarkerRenderer.createStandardInstance(diffType));
|
||||
highlighter.setLineMarkerRenderer(DiffLineMarkerRenderer.createInstance(diffType));
|
||||
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(DiffLineMarkerRenderer.createStandardInstance(type));
|
||||
highlighter.setLineMarkerRenderer(DiffLineMarkerRenderer.createInstance(type));
|
||||
return highlighter;
|
||||
}
|
||||
|
||||
|
||||
@@ -16,6 +16,7 @@
|
||||
package com.intellij.openapi.diff.impl.splitter;
|
||||
|
||||
import com.intellij.openapi.diagnostic.Logger;
|
||||
import com.intellij.openapi.diff.impl.DiffUtil;
|
||||
import com.intellij.openapi.diff.impl.fragments.LineBlock;
|
||||
import com.intellij.openapi.diff.impl.fragments.LineFragment;
|
||||
import com.intellij.openapi.diff.impl.highlighting.FragmentSide;
|
||||
@@ -178,11 +179,19 @@ public class LineBlocks {
|
||||
for (LineBlock block : blocks) {
|
||||
Interval interval1 = new Interval(block.getStartingLine1(), block.getModifiedLines1());
|
||||
Interval interval2 = new Interval(block.getStartingLine2(), block.getModifiedLines2());
|
||||
diffs.add(new Diff(interval1, interval2, TextDiffType.create(block.getType())));
|
||||
diffs.add(new Diff(interval1, interval2, makeTextDiffType(block)));
|
||||
}
|
||||
return new LineBlocks(diffs);
|
||||
}
|
||||
|
||||
private static TextDiffType makeTextDiffType(LineBlock block) {
|
||||
TextDiffType type = TextDiffType.create(block.getType());
|
||||
if (block instanceof LineFragment) {
|
||||
return DiffUtil.makeTextDiffType((LineFragment)block);
|
||||
}
|
||||
return type;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public static LineBlocks fromChanges(@NotNull List<Change> changes) {
|
||||
// changes may come mixed, need to sort them to get correct intervals
|
||||
|
||||
@@ -21,6 +21,7 @@ import com.intellij.openapi.diff.ex.DiffStatusBar;
|
||||
import com.intellij.openapi.editor.Editor;
|
||||
import com.intellij.openapi.editor.colors.EditorColorsScheme;
|
||||
import com.intellij.openapi.editor.colors.TextAttributesKey;
|
||||
import com.intellij.openapi.editor.ex.EditorEx;
|
||||
import com.intellij.openapi.editor.markup.TextAttributes;
|
||||
import com.intellij.util.containers.Convertor;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
@@ -46,16 +47,22 @@ public class TextDiffType implements DiffStatusBar.LegendTypeDescriptor {
|
||||
return textDiffType.getAttributesKey();
|
||||
}
|
||||
};
|
||||
private static final double MIDDLE_COLOR_FACTOR = 0.6;
|
||||
|
||||
private final TextDiffTypeEnum myType;
|
||||
private final TextAttributesKey myAttributesKey;
|
||||
private final String myDisplayName;
|
||||
private final boolean myApplied;
|
||||
private final boolean myInlineWrapper;
|
||||
|
||||
public boolean isApplied() {
|
||||
return myApplied;
|
||||
}
|
||||
|
||||
public boolean isInlineWrapper() {
|
||||
return myInlineWrapper;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public static TextDiffType create(@Nullable final TextDiffTypeEnum type) {
|
||||
if (TextDiffTypeEnum.INSERT.equals(type)) {
|
||||
@@ -78,18 +85,24 @@ public class TextDiffType implements DiffStatusBar.LegendTypeDescriptor {
|
||||
*/
|
||||
@NotNull
|
||||
public static TextDiffType deriveApplied(@NotNull TextDiffType source) {
|
||||
return new TextDiffType(source.myType, source.myDisplayName, source.myAttributesKey, true);
|
||||
return new TextDiffType(source.myType, source.myDisplayName, source.myAttributesKey, true, false);
|
||||
}
|
||||
|
||||
public static TextDiffType deriveInstanceForInlineWrapperFragment(@NotNull TextDiffType source) {
|
||||
return new TextDiffType(source.myType, source.myDisplayName, source.myAttributesKey, source.myApplied, true);
|
||||
}
|
||||
|
||||
private TextDiffType(TextDiffTypeEnum type, String displayName, TextAttributesKey attributesKey) {
|
||||
this(type, displayName, attributesKey, false);
|
||||
this(type, displayName, attributesKey, false, false);
|
||||
}
|
||||
|
||||
private TextDiffType(TextDiffTypeEnum type, String displayName, TextAttributesKey attributesKey, boolean applied) {
|
||||
private TextDiffType(TextDiffTypeEnum type, String displayName, TextAttributesKey attributesKey, boolean applied,
|
||||
boolean inlineWrapper) {
|
||||
myType = type;
|
||||
myAttributesKey = attributesKey;
|
||||
myDisplayName = displayName;
|
||||
myApplied = applied;
|
||||
myInlineWrapper = inlineWrapper;
|
||||
}
|
||||
|
||||
public String getDisplayName() {
|
||||
@@ -108,15 +121,7 @@ public class TextDiffType implements DiffStatusBar.LegendTypeDescriptor {
|
||||
|
||||
@Nullable
|
||||
public TextAttributes getTextAttributes(EditorColorsScheme scheme) {
|
||||
TextAttributes originalAttrs = scheme.getAttributes(myAttributesKey);
|
||||
if (originalAttrs == null) {
|
||||
return null;
|
||||
}
|
||||
TextAttributes overridingAttributes = new TextAttributes();
|
||||
if (myApplied) {
|
||||
overridingAttributes.setBackgroundColor(scheme.getDefaultBackground());
|
||||
}
|
||||
return TextAttributes.merge(originalAttrs, overridingAttributes);
|
||||
return scheme.getAttributes(myAttributesKey);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@@ -124,15 +129,29 @@ public class TextDiffType implements DiffStatusBar.LegendTypeDescriptor {
|
||||
if (isApplied()) {
|
||||
return getLegendColor(editor.getColorsScheme());
|
||||
}
|
||||
else if (isInlineWrapper()) {
|
||||
return getBgColorForFragmentContainingInlines((EditorEx)editor);
|
||||
}
|
||||
else {
|
||||
TextAttributes attributes = getTextAttributes(editor.getColorsScheme());
|
||||
TextAttributes attributes = getTextAttributes(editor);
|
||||
return attributes == null ? null : attributes.getBackgroundColor();
|
||||
}
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public TextAttributes getTextAttributes(Editor editor) {
|
||||
return getTextAttributes(editor.getColorsScheme());
|
||||
public TextAttributes getTextAttributes(@NotNull Editor editor) {
|
||||
TextAttributes originalAttrs = getTextAttributes(editor.getColorsScheme());
|
||||
if (originalAttrs == null) {
|
||||
return null;
|
||||
}
|
||||
TextAttributes overridingAttributes = new TextAttributes();
|
||||
if (myApplied) {
|
||||
overridingAttributes.setBackgroundColor(((EditorEx)editor).getBackgroundColor());
|
||||
}
|
||||
else if (myInlineWrapper) {
|
||||
overridingAttributes.setBackgroundColor(getBgColorForFragmentContainingInlines((EditorEx)editor));
|
||||
}
|
||||
return TextAttributes.merge(originalAttrs, overridingAttributes);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@@ -149,4 +168,30 @@ public class TextDiffType implements DiffStatusBar.LegendTypeDescriptor {
|
||||
return myType;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private Color getBgColorForFragmentContainingInlines(@NotNull EditorEx editor) {
|
||||
TextAttributes originalAttrs = getTextAttributes(editor.getColorsScheme());
|
||||
if (originalAttrs == null) {
|
||||
return null;
|
||||
}
|
||||
Color fg = originalAttrs.getBackgroundColor();
|
||||
if (fg == null) {
|
||||
return null;
|
||||
}
|
||||
Color bg = editor.getBackgroundColor();
|
||||
return getMiddleColor(fg, bg, MIDDLE_COLOR_FACTOR);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private static Color getMiddleColor(Color fg, Color bg, double factor) {
|
||||
int red = avg(fg.getRed(), bg.getRed(), factor);
|
||||
int green = avg(fg.getGreen(), bg.getGreen(), factor);
|
||||
int blue = avg(fg.getBlue(), bg.getBlue(), factor);
|
||||
return new Color(red, green, blue);
|
||||
}
|
||||
|
||||
private static int avg(int fg, int bg, double factor) {
|
||||
return (int)(fg + Math.round(factor * (bg - fg)));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user