Both the SWT (Eclipse) drawing and Swing versions are updated. The coloring and shapes are intentionally not the same as for gitk. Signed-off-by: Robin Rosenberg <robin.rosenberg@xxxxxxxxxx> --- .../egit/ui/internal/history/SWTCommit.java | 5 +- .../egit/ui/internal/history/SWTPlotRenderer.java | 71 +++++++++++++++++++- .../spearce/egit/ui/internal/history/SWTWalk.java | 2 +- .../org/spearce/jgit/awtui/AWTPlotRenderer.java | 46 +++++++++++++ .../spearce/jgit/revplot/AbstractPlotRenderer.java | 23 ++++++- .../src/org/spearce/jgit/revplot/PlotCommit.java | 8 ++- .../src/org/spearce/jgit/revplot/PlotWalk.java | 60 ++++++++++++++++- 7 files changed, 207 insertions(+), 8 deletions(-) diff --git a/org.spearce.egit.ui/src/org/spearce/egit/ui/internal/history/SWTCommit.java b/org.spearce.egit.ui/src/org/spearce/egit/ui/internal/history/SWTCommit.java index fa0d25d..2341fbd 100644 --- a/org.spearce.egit.ui/src/org/spearce/egit/ui/internal/history/SWTCommit.java +++ b/org.spearce.egit.ui/src/org/spearce/egit/ui/internal/history/SWTCommit.java @@ -10,12 +10,13 @@ import org.eclipse.swt.widgets.Widget; import org.spearce.jgit.lib.AnyObjectId; import org.spearce.jgit.revplot.PlotCommit; +import org.spearce.jgit.lib.Ref; class SWTCommit extends PlotCommit<SWTCommitList.SWTLane> { Widget widget; - SWTCommit(final AnyObjectId id) { - super(id); + SWTCommit(final AnyObjectId id, final Ref[] tags) { + super(id, tags); } @Override diff --git a/org.spearce.egit.ui/src/org/spearce/egit/ui/internal/history/SWTPlotRenderer.java b/org.spearce.egit.ui/src/org/spearce/egit/ui/internal/history/SWTPlotRenderer.java index c4ee282..b008df7 100644 --- a/org.spearce.egit.ui/src/org/spearce/egit/ui/internal/history/SWTPlotRenderer.java +++ b/org.spearce.egit.ui/src/org/spearce/egit/ui/internal/history/SWTPlotRenderer.java @@ -15,7 +15,10 @@ import org.eclipse.swt.widgets.Display; import org.eclipse.swt.widgets.Event; import org.eclipse.swt.widgets.TableItem; +import org.eclipse.ui.themes.ColorUtil; import org.spearce.egit.ui.internal.history.SWTCommitList.SWTLane; +import org.spearce.jgit.lib.Constants; +import org.spearce.jgit.lib.Ref; import org.spearce.jgit.revplot.AbstractPlotRenderer; import org.spearce.jgit.revplot.PlotCommit; @@ -26,7 +29,13 @@ private final Color sys_gray; - private Color sys_darkblue; + private final Color sys_darkblue; + + private final Color sys_yellow; + + private final Color sys_green; + + private final Color sys_white; GC g; @@ -43,6 +52,9 @@ SWTPlotRenderer(final Display d) { sys_black = d.getSystemColor(SWT.COLOR_BLACK); sys_gray = d.getSystemColor(SWT.COLOR_GRAY); sys_darkblue = d.getSystemColor(SWT.COLOR_DARK_BLUE); + sys_yellow = d.getSystemColor(SWT.COLOR_YELLOW); + sys_green = d.getSystemColor(SWT.COLOR_GREEN); + sys_white = d.getSystemColor(SWT.COLOR_WHITE); } void paint(final Event event) { @@ -92,7 +104,64 @@ protected void drawText(final String msg, final int x, final int y) { g.drawString(msg, cellX + x, cellY + texty, true); } + @Override + protected int drawLabel(int x, int y, Ref ref) { + String txt; + String name = ref.getOrigName(); + if (name.startsWith(Constants.R_HEADS)) { + g.setBackground(sys_green); + txt = name.substring(Constants.R_HEADS.length()); + } else if (name.startsWith(Constants.R_REMOTES)){ + g.setBackground(sys_gray); + txt = name.substring(Constants.R_REMOTES.length()); + } else if (name.startsWith(Constants.R_TAGS)){ + g.setBackground(sys_yellow); + txt = name.substring(Constants.R_TAGS.length()); + } else { + // Whatever this would be + g.setBackground(sys_white); + if (name.startsWith(Constants.R_REFS)) + txt = name.substring(Constants.R_REFS.length()); + else + txt = name; // HEAD and such + } + + // Make peeled objects, i.e. via annotated tags come out in a paler color + Color peeledColor = null; + if (ref.getPeeledObjectId() == null || !ref.getPeeledObjectId().equals(ref.getObjectId())) { + peeledColor = new Color(g.getDevice(), ColorUtil.blend(g.getBackground().getRGB(), sys_white.getRGB())); + g.setBackground(peeledColor); + } + + if (txt.length() > 12) + txt = txt.substring(0,11) + "\u2026"; // ellipsis "â?¦" (in UTF-8) + + Point textsz = g.stringExtent(txt); + int arc = textsz.y/2; + final int texty = (y * 2 - textsz.y) / 2; + + // Draw backgrounds + g.fillRoundRectangle(x + 1, cellY + texty -1, textsz.x + 3, textsz.y + 1, arc, arc); + g.setForeground(sys_black); + g.drawString(txt, x + 2, cellY + texty, true); + g.setLineWidth(2); + + // And a two color shaded border, blend with whatever background there already is + g.setAlpha(128); + g.setForeground(sys_gray); + g.drawRoundRectangle(x, cellY + texty -2, textsz.x + 5, textsz.y + 3, arc, arc); + g.setLineWidth(2); + g.setForeground(sys_black); + g.drawRoundRectangle(x + 1, cellY + texty -1, textsz.x + 3, textsz.y + 1, arc, arc); + g.setAlpha(255); + + if (peeledColor != null) + peeledColor.dispose(); + return 8 + textsz.x; + } + protected Color laneColor(final SWTLane myLane) { return myLane != null ? myLane.color : sys_black; } + } diff --git a/org.spearce.egit.ui/src/org/spearce/egit/ui/internal/history/SWTWalk.java b/org.spearce.egit.ui/src/org/spearce/egit/ui/internal/history/SWTWalk.java index 527d284..57039b5 100644 --- a/org.spearce.egit.ui/src/org/spearce/egit/ui/internal/history/SWTWalk.java +++ b/org.spearce.egit.ui/src/org/spearce/egit/ui/internal/history/SWTWalk.java @@ -19,6 +19,6 @@ SWTWalk(final Repository repo) { @Override protected RevCommit createCommit(final AnyObjectId id) { - return new SWTCommit(id); + return new SWTCommit(id, getTags(id)); } } diff --git a/org.spearce.jgit/src/org/spearce/jgit/awtui/AWTPlotRenderer.java b/org.spearce.jgit/src/org/spearce/jgit/awtui/AWTPlotRenderer.java index b6b715c..5dcddf5 100644 --- a/org.spearce.jgit/src/org/spearce/jgit/awtui/AWTPlotRenderer.java +++ b/org.spearce.jgit/src/org/spearce/jgit/awtui/AWTPlotRenderer.java @@ -44,6 +44,8 @@ import org.spearce.jgit.awtui.CommitGraphPane.GraphCellRender; import org.spearce.jgit.awtui.SwingCommitList.SwingLane; +import org.spearce.jgit.lib.Constants; +import org.spearce.jgit.lib.Ref; import org.spearce.jgit.revplot.AbstractPlotRenderer; import org.spearce.jgit.revplot.PlotCommit; @@ -134,4 +136,48 @@ void paintTriangleDown(final int cx, final int y, final int h) { g.drawPolygon(triangle); } + @Override + protected int drawLabel(int x, int y, Ref ref) { + String txt; + String name = ref.getOrigName(); + if (name.startsWith(Constants.R_HEADS)) { + g.setBackground(Color.GREEN); + txt = name.substring(Constants.R_HEADS.length()); + } else if (name.startsWith(Constants.R_REMOTES)){ + g.setBackground(Color.LIGHT_GRAY); + txt = name.substring(Constants.R_REMOTES.length()); + } else if (name.startsWith(Constants.R_TAGS)){ + g.setBackground(Color.YELLOW); + txt = name.substring(Constants.R_TAGS.length()); + } else { + // Whatever this would be + g.setBackground(Color.WHITE); + if (name.startsWith(Constants.R_REFS)) + txt = name.substring(Constants.R_REFS.length()); + else + txt = name; // HEAD and such + } + if (ref.getPeeledObjectId() != null) { + float[] colorComponents = g.getBackground().getRGBColorComponents(null); + colorComponents[0] *= 0.9; + colorComponents[1] *= 0.9; + colorComponents[2] *= 0.9; + g.setBackground(new Color(colorComponents[0],colorComponents[1],colorComponents[2])); + } + if (txt.length() > 12) + txt = txt.substring(0,11) + "\u2026"; // ellipsis "â?¦" (in UTF-8) + + final int texth = g.getFontMetrics().getHeight(); + int textw = g.getFontMetrics().stringWidth(txt); + g.setColor(g.getBackground()); + int arcHeight = texth/4; + int y0 = y - texth/2 + (cell.getHeight() - texth)/2; + g.fillRoundRect(x , y0, textw + arcHeight*2, texth -1, arcHeight, arcHeight); + g.setColor(g.getColor().darker()); + g.drawRoundRect(x, y0, textw + arcHeight*2, texth -1 , arcHeight, arcHeight); + g.setColor(Color.BLACK); + g.drawString(txt, x + arcHeight, y0 + texth - g.getFontMetrics().getDescent()); + + return arcHeight * 3 + textw; + } } \ No newline at end of file diff --git a/org.spearce.jgit/src/org/spearce/jgit/revplot/AbstractPlotRenderer.java b/org.spearce.jgit/src/org/spearce/jgit/revplot/AbstractPlotRenderer.java index f175c9d..911dd68 100644 --- a/org.spearce.jgit/src/org/spearce/jgit/revplot/AbstractPlotRenderer.java +++ b/org.spearce.jgit/src/org/spearce/jgit/revplot/AbstractPlotRenderer.java @@ -37,6 +37,7 @@ package org.spearce.jgit.revplot; +import org.spearce.jgit.lib.Ref; import org.spearce.jgit.revwalk.RevFlag; /** @@ -140,11 +141,29 @@ protected void paintCommit(final PlotCommit<TLane> commit, final int h) { else drawCommitDot(dotX, dotY, dotSize, dotSize); + int textx = Math.max(maxCenter + LANE_WIDTH / 2, dotX + dotSize) + 8; + int n = commit.refs == null ? 0 : commit.refs.length; + for (int i = 0; i < n; ++i) { + textx += drawLabel(textx + dotSize, h/2, commit.refs[i]); + } + final String msg = commit.getShortMessage(); - final int textx = Math.max(maxCenter + LANE_WIDTH / 2, dotX + dotSize) + 8; - drawText(msg, textx, h / 2); + drawText(msg, textx + dotSize + n*2, h / 2); } + /** + * Draw a decoration for the Ref ref at x,y + * + * @param x + * left + * @param y + * top + * @param ref + * A peeled ref + * @return width of label in pixels + */ + protected abstract int drawLabel(int x, int y, Ref ref); + private int computeDotSize(final int h) { int d = (int) (Math.min(h, LANE_WIDTH) * 0.50f); d += (d & 1); diff --git a/org.spearce.jgit/src/org/spearce/jgit/revplot/PlotCommit.java b/org.spearce.jgit/src/org/spearce/jgit/revplot/PlotCommit.java index 5a5ef1e..c885a44 100644 --- a/org.spearce.jgit/src/org/spearce/jgit/revplot/PlotCommit.java +++ b/org.spearce.jgit/src/org/spearce/jgit/revplot/PlotCommit.java @@ -39,6 +39,7 @@ import org.spearce.jgit.lib.AnyObjectId; import org.spearce.jgit.revwalk.RevCommit; +import org.spearce.jgit.lib.Ref; /** * A commit reference to a commit in the DAG. @@ -58,14 +59,19 @@ PlotCommit[] children; + final Ref[] refs; + /** * Create a new commit. * * @param id * the identity of this commit. + * @param tags + * the tags associated with this commit, null for no tags */ - protected PlotCommit(final AnyObjectId id) { + protected PlotCommit(final AnyObjectId id, final Ref[] tags) { super(id); + this.refs = tags; passingLanes = NO_LANES; children = NO_CHILDREN; } diff --git a/org.spearce.jgit/src/org/spearce/jgit/revplot/PlotWalk.java b/org.spearce.jgit/src/org/spearce/jgit/revplot/PlotWalk.java index e5e8aba..8801850 100644 --- a/org.spearce.jgit/src/org/spearce/jgit/revplot/PlotWalk.java +++ b/org.spearce.jgit/src/org/spearce/jgit/revplot/PlotWalk.java @@ -37,14 +37,33 @@ package org.spearce.jgit.revplot; +import java.io.IOException; +import java.util.Arrays; +import java.util.Collection; +import java.util.Comparator; +import java.util.Map; +import java.util.Set; + import org.spearce.jgit.lib.AnyObjectId; +import org.spearce.jgit.lib.Commit; +import org.spearce.jgit.lib.Ref; import org.spearce.jgit.lib.Repository; +import org.spearce.jgit.lib.Tag; import org.spearce.jgit.revwalk.RevCommit; import org.spearce.jgit.revwalk.RevSort; import org.spearce.jgit.revwalk.RevWalk; /** Specialized RevWalk for visualization of a commit graph. */ public class PlotWalk extends RevWalk { + + private Map<AnyObjectId, Set<Ref>> reverseRefMap; + + @Override + public void dispose() { + super.dispose(); + reverseRefMap.clear(); + } + /** * Create a new revision walker for a given repository. * @@ -54,6 +73,7 @@ public PlotWalk(final Repository repo) { super(repo); super.sort(RevSort.TOPO, true); + reverseRefMap = repo.getAllRefsByPeeledObjectId(); } @Override @@ -65,6 +85,44 @@ public void sort(final RevSort s, final boolean use) { @Override protected RevCommit createCommit(final AnyObjectId id) { - return new PlotCommit(id); + return new PlotCommit(id, getTags(id)); + } + + protected Ref[] getTags(final AnyObjectId commitId) { + Collection<Ref> list = reverseRefMap.get(commitId); + Ref[] tags; + if (list == null) + tags = null; + else { + tags = list.toArray(new Ref[list.size()]); + Arrays.sort(tags, new PlotRefComparator()); + } + return tags; + } + + class PlotRefComparator implements Comparator<Ref> { + public int compare(Ref o1, Ref o2) { + try { + Object obj1 = getRepository().mapObject(o1.getObjectId(), o1.getName()); + Object obj2 = getRepository().mapObject(o2.getObjectId(), o2.getName()); + long t1 = timeof(obj1); + long t2 = timeof(obj2); + if (t1 > t2) + return -1; + if (t1 < t2) + return 1; + return 0; + } catch (IOException e) { + // ignore + return 0; + } + } + long timeof(Object o) { + if (o instanceof Commit) + return ((Commit)o).getCommitter().getWhen().getTime(); + if (o instanceof Tag) + return ((Tag)o).getTagger().getWhen().getTime(); + return 0; + } } } -- 1.6.0.3.578.g6a50 -- To unsubscribe from this list: send the line "unsubscribe git" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html