mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
[vcs-log] move references to the right and paint them with tag icons
This commit is contained in:
+21
-73
@@ -4,7 +4,9 @@ import com.intellij.openapi.diagnostic.Logger;
|
||||
import com.intellij.openapi.vcs.changes.issueLinks.IssueLinkRenderer;
|
||||
import com.intellij.openapi.vfs.VirtualFile;
|
||||
import com.intellij.ui.ColoredTableCellRenderer;
|
||||
import com.intellij.util.ObjectUtils;
|
||||
import com.intellij.util.containers.ContainerUtil;
|
||||
import com.intellij.util.ui.JBUI;
|
||||
import com.intellij.util.ui.UIUtil;
|
||||
import com.intellij.vcs.log.VcsRef;
|
||||
import com.intellij.vcs.log.data.VcsLogData;
|
||||
@@ -20,23 +22,20 @@ import javax.swing.*;
|
||||
import java.awt.*;
|
||||
import java.awt.image.BufferedImage;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
public class GraphCommitCellRenderer extends ColoredTableCellRenderer {
|
||||
|
||||
private static final Logger LOG = Logger.getInstance(GraphCommitCellRenderer.class);
|
||||
private static final int MAX_GRAPH_WIDTH = 10;
|
||||
|
||||
private static final int VERTICAL_PADDING = JBUI.scale(7);
|
||||
|
||||
@NotNull private final VcsLogData myLogData;
|
||||
@NotNull private final GraphCellPainter myPainter;
|
||||
@NotNull private final VcsLogGraphTable myGraphTable;
|
||||
@NotNull private final TextLabelPainter myTextLabelPainter;
|
||||
@NotNull private final IssueLinkRenderer myIssueLinkRenderer;
|
||||
@NotNull private final TagLabelPainter myTextLabelPainter = new TagLabelPainter();
|
||||
|
||||
@Nullable private PaintInfo myGraphImage;
|
||||
@Nullable private Collection<VcsRef> myRefs;
|
||||
@NotNull private Font myFont;
|
||||
private int myHeight;
|
||||
|
||||
@@ -46,8 +45,7 @@ public class GraphCommitCellRenderer extends ColoredTableCellRenderer {
|
||||
myLogData = logData;
|
||||
myPainter = painter;
|
||||
myGraphTable = table;
|
||||
myTextLabelPainter = TextLabelPainter.createPainter(false);
|
||||
myIssueLinkRenderer = new IssueLinkRenderer(logData.getProject(), this);
|
||||
myIssueLinkRenderer = new IssueLinkRenderer(myLogData.getProject(), this);
|
||||
myFont = TextLabelPainter.getFont();
|
||||
myHeight = calculateHeight();
|
||||
}
|
||||
@@ -69,23 +67,14 @@ public class GraphCommitCellRenderer extends ColoredTableCellRenderer {
|
||||
}
|
||||
|
||||
private int calculateHeight() {
|
||||
return myTextLabelPainter.calculateSize("", getFontMetrics(myFont)).height + 4;
|
||||
return Math.max(myTextLabelPainter.getSize().height, getFontMetrics(myFont).getHeight() + VERTICAL_PADDING);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void paintComponent(Graphics g) {
|
||||
super.paintComponent(g);
|
||||
|
||||
if (myRefs != null) {
|
||||
int paddingX = (myGraphImage != null ? myGraphImage.getWidth() : 0) + PaintParameters.LABEL_PADDING;
|
||||
Map<String, Color> labelsForReferences = collectLabelsForRefs(myRefs);
|
||||
for (Map.Entry<String, Color> entry : labelsForReferences.entrySet()) {
|
||||
Dimension size = myTextLabelPainter.calculateSize(entry.getKey(), g.getFontMetrics(TextLabelPainter.getFont()));
|
||||
int paddingY = (myGraphTable.getRowHeight() - size.height) / 2;
|
||||
myTextLabelPainter.paint((Graphics2D)g, entry.getKey(), paddingX, paddingY, entry.getValue());
|
||||
paddingX += size.width + PaintParameters.LABEL_PADDING;
|
||||
}
|
||||
}
|
||||
myTextLabelPainter.paint((Graphics2D)g, getWidth() - myTextLabelPainter.getSize().width, 0, getHeight());
|
||||
|
||||
if (myGraphImage != null) {
|
||||
UIUtil.drawImage(g, myGraphImage.getImage(), 0, 0, null);
|
||||
@@ -103,7 +92,6 @@ public class GraphCommitCellRenderer extends ColoredTableCellRenderer {
|
||||
|
||||
GraphCommitCell cell = getAssertCommitCell(value);
|
||||
myGraphImage = getGraphImage(row);
|
||||
myRefs = cell.getRefsToThisCommit();
|
||||
|
||||
int graphPadding;
|
||||
if (myGraphImage != null) {
|
||||
@@ -115,12 +103,22 @@ public class GraphCommitCellRenderer extends ColoredTableCellRenderer {
|
||||
else {
|
||||
graphPadding = 0;
|
||||
}
|
||||
int textPadding = graphPadding + calculateReferencePadding(myRefs);
|
||||
|
||||
setBorder(null);
|
||||
append("");
|
||||
appendTextPadding(textPadding);
|
||||
appendTextPadding(graphPadding);
|
||||
myIssueLinkRenderer.appendTextWithLinks(cell.getText(), myGraphTable.applyHighlighters(this, row, column, "", hasFocus, isSelected));
|
||||
|
||||
Collection<VcsRef> refs = cell.getRefsToThisCommit();
|
||||
if (refs.isEmpty()) {
|
||||
myTextLabelPainter.customizePainter(this, refs);
|
||||
}
|
||||
else {
|
||||
VirtualFile root = ObjectUtils.assertNotNull(ContainerUtil.getFirstItem(refs)).getRoot();
|
||||
myTextLabelPainter
|
||||
.customizePainter(this,
|
||||
ContainerUtil.sorted(refs, myLogData.getLogProvider(root).getReferenceManager().getLabelsOrderComparator()));
|
||||
}
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@@ -139,7 +137,7 @@ public class GraphCommitCellRenderer extends ColoredTableCellRenderer {
|
||||
Graphics2D g2 = image.createGraphics();
|
||||
myPainter.draw(g2, printElements);
|
||||
|
||||
final int width = maxIndex * PaintParameters.getNodeWidth(myGraphTable.getRowHeight());
|
||||
int width = maxIndex * PaintParameters.getNodeWidth(myGraphTable.getRowHeight());
|
||||
return new PaintInfo(image, width);
|
||||
}
|
||||
|
||||
@@ -148,56 +146,6 @@ public class GraphCommitCellRenderer extends ColoredTableCellRenderer {
|
||||
return (GraphCommitCell)value;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private Map<String, Color> collectLabelsForRefs(@NotNull Collection<VcsRef> refs) {
|
||||
if (refs.isEmpty()) {
|
||||
return Collections.emptyMap();
|
||||
}
|
||||
VirtualFile root = refs.iterator().next().getRoot(); // all refs are from the same commit => they have the same root
|
||||
refs = ContainerUtil.sorted(refs, myLogData.getLogProvider(root).getReferenceManager().getLabelsOrderComparator());
|
||||
List<VcsRef> branches = ContainerUtil.newArrayList();
|
||||
List<VcsRef> tags = ContainerUtil.newArrayList();
|
||||
refs.forEach(ref -> {
|
||||
if (ref.getType().isBranch()) {
|
||||
branches.add(ref);
|
||||
}
|
||||
else {
|
||||
tags.add(ref);
|
||||
}
|
||||
});
|
||||
return getLabelsForRefs(branches, tags);
|
||||
}
|
||||
|
||||
private int calculateReferencePadding(@NotNull Collection<VcsRef> references) {
|
||||
if (references.isEmpty()) return 0;
|
||||
|
||||
int paddingX = 2 * PaintParameters.LABEL_PADDING;
|
||||
for (String label : collectLabelsForRefs(references).keySet()) {
|
||||
Dimension size = myTextLabelPainter.calculateSize(label, this.getFontMetrics(TextLabelPainter.getFont()));
|
||||
paddingX += size.width + PaintParameters.LABEL_PADDING;
|
||||
}
|
||||
return paddingX;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private static Map<String, Color> getLabelsForRefs(@NotNull List<VcsRef> branches, @NotNull Collection<VcsRef> tags) {
|
||||
Map<String, Color> labels = ContainerUtil.newLinkedHashMap();
|
||||
for (VcsRef branch : branches) {
|
||||
labels.put(branch.getName(), branch.getType().getBackgroundColor());
|
||||
}
|
||||
if (!tags.isEmpty()) {
|
||||
VcsRef firstTag = tags.iterator().next();
|
||||
Color color = firstTag.getType().getBackgroundColor();
|
||||
if (tags.size() > 1) {
|
||||
labels.put(firstTag.getName() + " +", color);
|
||||
}
|
||||
else {
|
||||
labels.put(firstTag.getName(), color);
|
||||
}
|
||||
}
|
||||
return labels;
|
||||
}
|
||||
|
||||
private static class PaintInfo {
|
||||
private int myWidth;
|
||||
@NotNull private Image myImage;
|
||||
|
||||
@@ -0,0 +1,138 @@
|
||||
/*
|
||||
* Copyright 2000-2016 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package com.intellij.vcs.log.ui.render;
|
||||
/*
|
||||
* Copyright 2000-2015 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import com.intellij.openapi.ui.GraphicsConfig;
|
||||
import com.intellij.openapi.util.Pair;
|
||||
import com.intellij.ui.JBColor;
|
||||
import com.intellij.ui.SimpleColoredComponent;
|
||||
import com.intellij.util.ObjectUtils;
|
||||
import com.intellij.util.containers.ContainerUtil;
|
||||
import com.intellij.util.ui.GraphicsUtil;
|
||||
import com.intellij.util.ui.JBUI;
|
||||
import com.intellij.util.ui.UIUtil;
|
||||
import com.intellij.vcs.log.VcsRef;
|
||||
import com.intellij.vcs.log.VcsRefType;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import javax.swing.*;
|
||||
import java.awt.*;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
public class TagLabelPainter {
|
||||
public static final int TOP_TEXT_PADDING = JBUI.scale(2);
|
||||
public static final int BOTTOM_TEXT_PADDING = JBUI.scale(1);
|
||||
public static final int GRADIENT_WIDTH = JBUI.scale(25);
|
||||
public static final int RIGHT_PADDING = JBUI.scale(5);
|
||||
public static final int MIDDLE_PADDING = JBUI.scale(5);
|
||||
|
||||
@NotNull
|
||||
private List<Pair<String, TagIcon>> myLabels = ContainerUtil.newArrayList();
|
||||
private int myHeight = JBUI.scale(22);
|
||||
private int myWidth = 0;
|
||||
@NotNull
|
||||
private Color myBackground = UIUtil.getTableBackground();
|
||||
@NotNull
|
||||
private Color myForeground = UIUtil.getTableForeground();
|
||||
|
||||
public void customizePainter(@NotNull JComponent component, @NotNull Collection<VcsRef> references) {
|
||||
myBackground = component.getBackground();
|
||||
myForeground = component.getForeground();
|
||||
|
||||
FontMetrics metrics = component.getFontMetrics(getReferenceFont());
|
||||
myHeight = metrics.getHeight() + TOP_TEXT_PADDING + BOTTOM_TEXT_PADDING;
|
||||
myWidth = GRADIENT_WIDTH + RIGHT_PADDING;
|
||||
|
||||
myLabels = ContainerUtil.newArrayList();
|
||||
for (Map.Entry<VcsRefType, Collection<VcsRef>> typeAndRefs : ContainerUtil.groupBy(references, VcsRef::getType).entrySet()) {
|
||||
VcsRef firstRef = ObjectUtils.assertNotNull(ContainerUtil.getFirstItem(typeAndRefs.getValue()));
|
||||
VcsRefType type = typeAndRefs.getKey();
|
||||
boolean multiple = typeAndRefs.getValue().size() > 1;
|
||||
TagIcon tagIcon = new TagIcon(myHeight, myBackground, multiple
|
||||
? new Color[]{type.getBackgroundColor(), type.getBackgroundColor()}
|
||||
: new Color[]{type.getBackgroundColor()});
|
||||
|
||||
String text = firstRef.getName() + (multiple ? " +" : "");
|
||||
myLabels.add(Pair.create(text, tagIcon));
|
||||
|
||||
myWidth += tagIcon.getIconWidth() + metrics.stringWidth(text) + MIDDLE_PADDING;
|
||||
}
|
||||
}
|
||||
|
||||
public void paint(@NotNull Graphics2D g2, int x, int y, int height) {
|
||||
if (myLabels.isEmpty()) return;
|
||||
|
||||
GraphicsConfig config = GraphicsUtil.setupAAPainting(g2);
|
||||
g2.setFont(getReferenceFont());
|
||||
g2.setStroke(new BasicStroke(1.5f));
|
||||
|
||||
FontMetrics fontMetrics = g2.getFontMetrics();
|
||||
|
||||
g2.setPaint(
|
||||
new GradientPaint(x, y, new Color(myBackground.getRed(), myBackground.getGreen(), myBackground.getBlue(), 0), x + GRADIENT_WIDTH, y,
|
||||
myBackground));
|
||||
g2.fill(new Rectangle(x, y, GRADIENT_WIDTH, height));
|
||||
x += GRADIENT_WIDTH;
|
||||
|
||||
g2.setColor(myBackground);
|
||||
g2.fillRect(x, y, myWidth - GRADIENT_WIDTH, height);
|
||||
|
||||
for (Pair<String, TagIcon> label : myLabels) {
|
||||
TagIcon icon = label.second;
|
||||
String text = label.first;
|
||||
|
||||
icon.paintIcon(null, g2, x, y + (height - icon.getIconHeight()) / 2);
|
||||
x += icon.getIconWidth();
|
||||
|
||||
g2.setColor(myForeground);
|
||||
g2.drawString(text, x, y + SimpleColoredComponent.getTextBaseLine(fontMetrics, height));
|
||||
x += fontMetrics.stringWidth(text) + MIDDLE_PADDING;
|
||||
}
|
||||
|
||||
config.restore();
|
||||
}
|
||||
|
||||
public Dimension getSize() {
|
||||
if (myLabels.isEmpty()) return new Dimension();
|
||||
return new Dimension(myWidth, myHeight);
|
||||
}
|
||||
|
||||
protected Font getReferenceFont() {
|
||||
return getFont();
|
||||
}
|
||||
|
||||
public static Font getFont() {
|
||||
return UIUtil.getLabelFont();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -24,8 +24,6 @@ import com.intellij.util.ui.UIUtil;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.awt.*;
|
||||
import java.awt.geom.Area;
|
||||
import java.awt.geom.Ellipse2D;
|
||||
import java.awt.geom.RoundRectangle2D;
|
||||
|
||||
public class TextLabelPainter {
|
||||
|
||||
Reference in New Issue
Block a user