[log] Shift mouse-over-node/branch area in multi-root projects

Use the root column width, since the column might be made resizeable
in future.

The column model is not ready at the beginning => listen to column
model changes and pass the root column to the GraphCellPainter.
This commit is contained in:
Kirill Likhodedov
2013-11-04 21:38:22 +04:00
parent 75a447a835
commit ed93e59160
5 changed files with 65 additions and 19 deletions
@@ -6,6 +6,7 @@ import com.intellij.vcs.log.printmodel.SpecialPrintElement;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import javax.swing.table.TableColumn;
import java.awt.*;
/**
@@ -20,5 +21,7 @@ public interface GraphCellPainter {
@Nullable
SpecialPrintElement mouseOverArrow(@NotNull GraphPrintCell row, int x, int y);
void setRootColumn(TableColumn column);
}
@@ -15,27 +15,27 @@ public class PositionUtil {
return (float)Math.sqrt((x1 - x2) * (x1 - x2) + (y1 - y2) * (y1 - y2));
}
public static boolean overUpEdge(ShortEdge edge, int x, int y) {
public static boolean overUpEdge(ShortEdge edge, int x, int y, int offset) {
float thick = THICK_LINE;
int x1 = WIDTH_NODE * edge.getDownPosition() + WIDTH_NODE / 2;
int x1 = WIDTH_NODE * edge.getDownPosition() + WIDTH_NODE / 2 + offset;
int y1 = HEIGHT_CELL / 2;
int x2 = WIDTH_NODE * edge.getUpPosition() + WIDTH_NODE / 2;
int x2 = WIDTH_NODE * edge.getUpPosition() + WIDTH_NODE / 2 + offset;
int y2 = -HEIGHT_CELL / 2;
//return true;
return (distance(x1, y1, x, y) + distance(x2, y2, x, y) < distance(x1, y1, x2, y2) + thick);
}
public static boolean overDownEdge(ShortEdge edge, int x, int y) {
public static boolean overDownEdge(ShortEdge edge, int x, int y, int offset) {
float thick = THICK_LINE;
int x1 = WIDTH_NODE * edge.getUpPosition() + WIDTH_NODE / 2;
int x1 = WIDTH_NODE * edge.getUpPosition() + WIDTH_NODE / 2 + offset;
int y1 = HEIGHT_CELL / 2;
int x2 = WIDTH_NODE * edge.getDownPosition() + WIDTH_NODE / 2;
int x2 = WIDTH_NODE * edge.getDownPosition() + WIDTH_NODE / 2 + offset;
int y2 = HEIGHT_CELL + HEIGHT_CELL / 2;
return distance(x1, y1, x, y) + distance(x2, y2, x, y) < distance(x1, y1, x2, y2) + thick;
}
public static boolean overNode(int position, int x, int y) {
int x0 = WIDTH_NODE * position + WIDTH_NODE / 2;
public static boolean overNode(int position, int x, int y, int xOffset) {
int x0 = WIDTH_NODE * position + WIDTH_NODE / 2 + xOffset;
int y0 = HEIGHT_CELL / 2;
int r = CIRCLE_RADIUS;
return distance(x0, y0, x, y) <= r;
@@ -10,6 +10,7 @@ import com.intellij.vcs.log.printmodel.SpecialPrintElement;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import javax.swing.table.TableColumn;
import java.awt.*;
import java.awt.geom.Ellipse2D;
@@ -19,6 +20,8 @@ import java.awt.geom.Ellipse2D;
public class SimpleGraphCellPainter implements GraphCellPainter {
private static final Color MARK_COLOR = JBColor.BLACK;
private final boolean myMultiRoot;
private TableColumn myRootColumn;
private Graphics2D g2;
@@ -27,6 +30,10 @@ public class SimpleGraphCellPainter implements GraphCellPainter {
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);
public SimpleGraphCellPainter(boolean multiRoot) {
myMultiRoot = multiRoot;
}
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;
@@ -210,18 +217,18 @@ public class SimpleGraphCellPainter implements GraphCellPainter {
public GraphElement mouseOver(@NotNull GraphPrintCell row, int x, int y) {
for (SpecialPrintElement printElement : row.getSpecialPrintElements()) {
if (printElement.getType() == SpecialPrintElement.Type.COMMIT_NODE) {
if (PositionUtil.overNode(printElement.getPosition(), x, y)) {
if (PositionUtil.overNode(printElement.getPosition(), x, y, getXOffset())) {
return printElement.getGraphElement();
}
}
}
for (ShortEdge edge : row.getUpEdges()) {
if (PositionUtil.overUpEdge(edge, x, y)) {
if (PositionUtil.overUpEdge(edge, x, y, getXOffset())) {
return edge.getEdge();
}
}
for (ShortEdge edge : row.getDownEdges()) {
if (PositionUtil.overDownEdge(edge, x, y)) {
if (PositionUtil.overDownEdge(edge, x, y, getXOffset())) {
return edge.getEdge();
}
}
@@ -229,16 +236,25 @@ public class SimpleGraphCellPainter implements GraphCellPainter {
return null;
}
private int getXOffset() {
return myMultiRoot && myRootColumn != null ? myRootColumn.getWidth() : 0;
}
@Nullable
@Override
public SpecialPrintElement mouseOverArrow(@NotNull GraphPrintCell row, int x, int y) {
for (SpecialPrintElement printElement : row.getSpecialPrintElements()) {
if (printElement.getType() != SpecialPrintElement.Type.COMMIT_NODE) {
if (PositionUtil.overNode(printElement.getPosition(), x, y)) {
if (PositionUtil.overNode(printElement.getPosition(), x, y, getXOffset())) {
return printElement;
}
}
}
return null;
}
@Override
public void setRootColumn(TableColumn column) {
myRootColumn = column;
}
}
@@ -465,6 +465,10 @@ public class VcsLogDataHolder implements Disposable {
return myCurrentUser;
}
public boolean isMultiRoot() {
return myLogProviders.size() > 1;
}
private static class RecentCommitsInfo {
List<TimedVcsCommit> firstBlockCommits;
Collection<VcsRef> newRefs;
@@ -28,12 +28,8 @@ import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import javax.swing.*;
import javax.swing.event.ListSelectionEvent;
import javax.swing.event.ListSelectionListener;
import javax.swing.table.DefaultTableCellRenderer;
import javax.swing.table.TableCellRenderer;
import javax.swing.table.TableColumn;
import javax.swing.table.TableModel;
import javax.swing.event.*;
import javax.swing.table.*;
import java.awt.*;
import java.awt.datatransfer.StringSelection;
import java.awt.event.MouseAdapter;
@@ -51,7 +47,7 @@ public class VcsLogGraphTable extends JBTable implements TypeSafeDataProvider, C
private static final int ROOT_INDICATOR_WIDTH = 5;
@NotNull private final VcsLogUI myUI;
@NotNull private final GraphCellPainter myGraphPainter = new SimpleGraphCellPainter();
@NotNull private final GraphCellPainter myGraphPainter;
private volatile boolean myRepaintFreezed;
@@ -59,6 +55,8 @@ public class VcsLogGraphTable extends JBTable implements TypeSafeDataProvider, C
super();
myUI = UI;
myGraphPainter = new SimpleGraphCellPainter(logDataHolder.isMultiRoot());
setDefaultRenderer(VirtualFile.class, new RootCellRenderer(myUI));
setDefaultRenderer(GraphCommitCell.class, new GraphCommitCellRender(myGraphPainter, logDataHolder, myUI.getColorManager()));
setDefaultRenderer(CommitCell.class, new CommitCellRender(myUI.getColorManager()));
@@ -83,6 +81,31 @@ public class VcsLogGraphTable extends JBTable implements TypeSafeDataProvider, C
addMouseListener(mouseAdapter);
PopupHandler.installPopupHandler(this, VcsLogUI.POPUP_ACTION_GROUP, VcsLogUI.VCS_LOG_TABLE_PLACE);
getColumnModel().addColumnModelListener(new TableColumnModelListener() {
@Override
public void columnAdded(TableColumnModelEvent e) {
if (e.getToIndex() == AbstractVcsLogTableModel.ROOT_COLUMN) {
myGraphPainter.setRootColumn(getColumnModel().getColumn(AbstractVcsLogTableModel.ROOT_COLUMN));
}
}
@Override
public void columnRemoved(TableColumnModelEvent e) {
}
@Override
public void columnMoved(TableColumnModelEvent e) {
}
@Override
public void columnMarginChanged(ChangeEvent e) {
}
@Override
public void columnSelectionChanged(ListSelectionEvent e) {
}
});
}
@Override