blob: 34d2ea5bb13e62059aa15c09e341971e7d63ae47 [file] [log] [blame]
/*
* Copyright 2000-2014 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.printer.idea;
import com.intellij.ui.JBColor;
import com.intellij.vcs.log.graph.EdgePrintElement;
import com.intellij.vcs.log.graph.PrintElement;
import com.intellij.vcs.log.graph.SimplePrintElement;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.awt.*;
import java.awt.geom.Ellipse2D;
import java.util.Collection;
/**
* @author erokhins
*/
public class SimpleGraphCellPainter implements GraphCellPainter {
private static final Color MARK_COLOR = JBColor.BLACK;
private final Stroke usual = new BasicStroke(PrintParameters.THICK_LINE, BasicStroke.CAP_ROUND, BasicStroke.JOIN_BEVEL);
private final Stroke hide = new BasicStroke(PrintParameters.THICK_LINE, BasicStroke.CAP_ROUND, BasicStroke.JOIN_BEVEL, 0, new float[]{7}, 0);
private final Stroke selectUsual = new BasicStroke(PrintParameters.SELECT_THICK_LINE, BasicStroke.CAP_ROUND, BasicStroke.JOIN_BEVEL);
private final Stroke selectHide = new BasicStroke(PrintParameters.SELECT_THICK_LINE, BasicStroke.CAP_ROUND, BasicStroke.JOIN_BEVEL, 0, new float[]{7}, 0);
private Graphics2D g2;
@NotNull
private final ColorGenerator myColorGenerator;
public SimpleGraphCellPainter(@NotNull ColorGenerator colorGenerator) {
myColorGenerator = colorGenerator;
}
private void paintUpLine(int from, int to, Color color) {
int x1 = PrintParameters.WIDTH_NODE * from + PrintParameters.WIDTH_NODE / 2;
int y1 = PrintParameters.HEIGHT_CELL / 2;
int x2 = PrintParameters.WIDTH_NODE * to + PrintParameters.WIDTH_NODE / 2;
int y2 = -PrintParameters.HEIGHT_CELL / 2;
g2.setColor(color);
g2.drawLine(x2, y2, x1, y1);
}
private void paintDownLine(int from, int to, Color color) {
int x1 = PrintParameters.WIDTH_NODE * from + PrintParameters.WIDTH_NODE / 2;
int y1 = PrintParameters.HEIGHT_CELL / 2;
int x2 = PrintParameters.WIDTH_NODE * to + PrintParameters.WIDTH_NODE / 2;
int y2 = PrintParameters.HEIGHT_CELL + PrintParameters.HEIGHT_CELL / 2;
g2.setColor(color);
g2.drawLine(x1, y1, x2, y2);
}
private void paintCircle(int position, Color color, boolean select) {
int x0 = PrintParameters.WIDTH_NODE * position + PrintParameters.WIDTH_NODE / 2;
int y0 = PrintParameters.HEIGHT_CELL / 2;
int r = PrintParameters.CIRCLE_RADIUS;
if (select) {
r = PrintParameters.SELECT_CIRCLE_RADIUS;
}
Ellipse2D.Double circle = new Ellipse2D.Double(x0 - r + 0.5, y0 - r + 0.5, 2 * r, 2 * r);
g2.setColor(color);
g2.fill(circle);
}
private void paintDownArrow(int position, Color color) {
int x0 = PrintParameters.WIDTH_NODE * position + PrintParameters.WIDTH_NODE / 2;
int r = PrintParameters.CIRCLE_RADIUS;
int y0 = PrintParameters.HEIGHT_CELL - r - 2;
g2.setColor(color);
g2.drawLine(x0, PrintParameters.HEIGHT_CELL / 2, x0, y0 + r);
g2.drawLine(x0, y0 + r, x0 + r, y0);
g2.drawLine(x0, y0 + r, x0 - r, y0);
}
private void paintUpArrow(int position, Color color) {
int x0 = PrintParameters.WIDTH_NODE * position + PrintParameters.WIDTH_NODE / 2;
int r = PrintParameters.CIRCLE_RADIUS;
int y0 = r + 2;
g2.setColor(color);
g2.drawLine(x0, PrintParameters.HEIGHT_CELL / 2, x0, y0 - r);
g2.drawLine(x0, y0 - r, x0 + r, y0);
g2.drawLine(x0, y0 - r, x0 - r, y0);
}
private void setStroke(boolean usual, boolean select) {
if (usual) {
if (select) {
g2.setStroke(selectUsual);
}
else {
g2.setStroke(this.usual);
}
}
else {
if (select) {
g2.setStroke(selectHide);
}
else {
g2.setStroke(hide);
}
}
}
private interface LitePrinter {
void print(Color color);
}
private void drawLogic(boolean isSelected, boolean isUsual, Color usualColor, LitePrinter printer) {
if (isSelected) {
setStroke(isUsual, true);
printer.print(MARK_COLOR);
setStroke(isUsual, false);
printer.print(usualColor);
} else {
setStroke(isUsual, false);
printer.print(usualColor);
}
}
@NotNull
private Color getColor(@NotNull PrintElement printElement) {
return myColorGenerator.getColor(printElement.getColorId());
}
private static boolean isUsual(PrintElement printElement) {
if (!(printElement instanceof EdgePrintElement))
return true;
EdgePrintElement.LineStyle lineStyle = ((EdgePrintElement)printElement).getLineStyle();
return lineStyle == EdgePrintElement.LineStyle.SOLID;
}
@Override
public void draw(@NotNull Graphics2D g2, @NotNull Collection<PrintElement> printElements) {
this.g2 = g2;
g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
for (final PrintElement printElement : printElements) {
LitePrinter printer = null;
if (printElement instanceof EdgePrintElement) {
printer = new LitePrinter() {
@Override
public void print(Color color) {
EdgePrintElement edgePrintElement = (EdgePrintElement)printElement;
int from = edgePrintElement.getPositionInCurrentRow();
int to = edgePrintElement.getPositionInOtherRow();
if (edgePrintElement.getType() == EdgePrintElement.Type.DOWN) {
paintDownLine(from, to, color);
} else {
paintUpLine(from, to, color);
}
}
};
}
if (printElement instanceof SimplePrintElement) {
final int position = printElement.getPositionInCurrentRow();
switch (((SimplePrintElement)printElement).getType()) {
case NODE:
if (printElement.isSelected()) {
paintCircle(position, MARK_COLOR, true);
paintCircle(position, getColor(printElement), false);
} else {
paintCircle(position, getColor(printElement), false);
}
break;
case UP_ARROW:
printer = new LitePrinter() {
@Override
public void print(Color color) {
paintUpArrow(position, color);
}
};
break;
case DOWN_ARROW:
printer = new LitePrinter() {
@Override
public void print(Color color) {
paintDownArrow(position, color);
}
};
break;
}
}
if (printer != null)
drawLogic(printElement.isSelected(), isUsual(printElement), getColor(printElement), printer);
}
}
@Nullable
@Override
public PrintElement mouseOver(@NotNull Collection<PrintElement> printElements, int x, int y) {
for (PrintElement printElement : printElements) {
if (printElement instanceof SimplePrintElement) {
if (PositionUtil.overNode(printElement.getPositionInCurrentRow(), x, y, ((SimplePrintElement)printElement).getType())) {
return printElement;
}
}
}
for (PrintElement printElement : printElements) {
if (printElement instanceof EdgePrintElement) {
EdgePrintElement edgePrintElement = (EdgePrintElement)printElement;
if (edgePrintElement.getType() == EdgePrintElement.Type.DOWN) {
if (PositionUtil.overDownEdge(edgePrintElement.getPositionInCurrentRow(), edgePrintElement.getPositionInOtherRow(), x, y)) {
return printElement;
}
} else {
if (PositionUtil.overUpEdge(edgePrintElement.getPositionInOtherRow(), edgePrintElement.getPositionInCurrentRow(), x, y)) {
return printElement;
}
}
}
}
return null;
}
}