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/core/internal/storage/KidWalk.java | 3 +- .../egit/ui/internal/history/SWTCommit.java | 5 +- .../egit/ui/internal/history/SWTPlotRenderer.java | 64 +++++++++++++++++++- .../spearce/egit/ui/internal/history/SWTWalk.java | 5 +- .../org/spearce/jgit/awtui/AWTPlotRenderer.java | 46 ++++++++++++++ .../spearce/jgit/revplot/AbstractPlotRenderer.java | 18 +++++- .../src/org/spearce/jgit/revplot/PlotCommit.java | 8 ++- .../src/org/spearce/jgit/revplot/PlotWalk.java | 56 ++++++++++++++++- .../src/org/spearce/jgit/revwalk/RevWalk.java | 19 +++++- 9 files changed, 209 insertions(+), 15 deletions(-) diff --git a/org.spearce.egit.core/src/org/spearce/egit/core/internal/storage/KidWalk.java b/org.spearce.egit.core/src/org/spearce/egit/core/internal/storage/KidWalk.java index 6b8f468..b337efe 100644 --- a/org.spearce.egit.core/src/org/spearce/egit/core/internal/storage/KidWalk.java +++ b/org.spearce.egit.core/src/org/spearce/egit/core/internal/storage/KidWalk.java @@ -11,6 +11,7 @@ import org.spearce.jgit.lib.AnyObjectId; import org.spearce.jgit.lib.Repository; import org.spearce.jgit.revwalk.RevCommit; +import org.spearce.jgit.lib.Ref; import org.spearce.jgit.revwalk.RevWalk; class KidWalk extends RevWalk { @@ -19,7 +20,7 @@ KidWalk(final Repository repo) { } @Override - protected RevCommit createCommit(final AnyObjectId id) { + protected RevCommit createCommit(final AnyObjectId id, final Ref[] tags) { return new KidCommit(id); } } 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 23ec255..56d5842 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,57 @@ protected void drawText(final String msg, final int x, final int y) { g.drawString(msg, cellX + x, cellY + texty); } + @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 + } + Color peeledColor = null; + if (ref.getPeeledObjectId() != null) { + 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 testsz = g.stringExtent(txt); + final int texty = (y * 2 - testsz.y) / 2; + g.setForeground(sys_black); + g.drawString(txt, x + 2, cellY + texty); + g.setLineWidth(2); + Color blend1 = new Color(g.getDevice(), ColorUtil.blend(g.getBackground().getRGB(), sys_gray.getRGB())); + g.setForeground(blend1); + g.drawRoundRectangle(x, cellY + texty -2, testsz.x + 3, testsz.y + 3, testsz.y/4, testsz.y/4); + g.setLineWidth(2); + Color blend2 = new Color(g.getDevice(), ColorUtil.blend(g.getBackground().getRGB(), sys_black.getRGB())); + g.setForeground(blend2); + g.drawRoundRectangle(x + 1, cellY + texty -1, testsz.x + 1, testsz.y + 1, testsz.y/4, testsz.y/4); + + blend1.dispose(); + blend2.dispose(); + if (peeledColor != null) + peeledColor.dispose(); + return 8 + testsz.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..bc347db 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 @@ -11,6 +11,7 @@ import org.spearce.jgit.lib.Repository; import org.spearce.jgit.revplot.PlotWalk; import org.spearce.jgit.revwalk.RevCommit; +import org.spearce.jgit.lib.Ref; class SWTWalk extends PlotWalk { SWTWalk(final Repository repo) { @@ -18,7 +19,7 @@ SWTWalk(final Repository repo) { } @Override - protected RevCommit createCommit(final AnyObjectId id) { - return new SWTCommit(id); + protected RevCommit createCommit(final AnyObjectId id, final Ref[] tags) { + return new SWTCommit(id, tags); } } 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..603547b 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,24 @@ 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); } + /** FIXME: supply text + * @param x + * @param y + * @param ref TODO + * @return TODO + */ + 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..fac89f5 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; + 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..6e253f4 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,26 @@ package org.spearce.jgit.revplot; +import java.io.IOException; +import java.util.Collections; +import java.util.Comparator; +import java.util.List; +import java.util.Map; + 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 { + + Map<AnyObjectId, List<Ref>> reverseRefMap; + /** * Create a new revision walker for a given repository. * @@ -54,6 +66,7 @@ public PlotWalk(final Repository repo) { super(repo); super.sort(RevSort.TOPO, true); + reverseRefMap = repo.getAllRefsByPeeledObjectId(); } @Override @@ -64,7 +77,46 @@ public void sort(final RevSort s, final boolean use) { } @Override - protected RevCommit createCommit(final AnyObjectId id) { - return new PlotCommit(id); + protected RevCommit createCommit(final AnyObjectId id, final Ref[] tags) { + return new PlotCommit(id, tags); + } + + @Override + protected Ref[] getTags(final AnyObjectId commitId) { + List<Ref> list = reverseRefMap.get(commitId); + Ref[] tags; + if (list == null) + tags = null; + else { + if (list != null && list.size() > 1) { + Collections.sort(list, new 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; + } + }); + } + tags = list.toArray(new Ref[list.size()]); + } + return tags; } } diff --git a/org.spearce.jgit/src/org/spearce/jgit/revwalk/RevWalk.java b/org.spearce.jgit/src/org/spearce/jgit/revwalk/RevWalk.java index d7e4c58..41d57c6 100644 --- a/org.spearce.jgit/src/org/spearce/jgit/revwalk/RevWalk.java +++ b/org.spearce.jgit/src/org/spearce/jgit/revwalk/RevWalk.java @@ -53,6 +53,7 @@ import org.spearce.jgit.lib.ObjectId; import org.spearce.jgit.lib.ObjectIdSubclassMap; import org.spearce.jgit.lib.ObjectLoader; +import org.spearce.jgit.lib.Ref; import org.spearce.jgit.lib.Repository; import org.spearce.jgit.lib.WindowCursor; import org.spearce.jgit.revwalk.filter.RevFilter; @@ -541,7 +542,7 @@ public RevTree lookupTree(final AnyObjectId id) { public RevCommit lookupCommit(final AnyObjectId id) { RevCommit c = (RevCommit) objects.get(id); if (c == null) { - c = createCommit(id); + c = createCommit(id, getTags(id)); objects.add(c); } return c; @@ -564,7 +565,7 @@ public RevObject lookupAny(final AnyObjectId id, final int type) { if (r == null) { switch (type) { case Constants.OBJ_COMMIT: - r = createCommit(id); + r = createCommit(id, getTags(id)); break; case Constants.OBJ_TREE: r = new RevTree(id); @@ -687,7 +688,7 @@ public RevObject parseAny(final AnyObjectId id) final int type = ldr.getType(); switch (type) { case Constants.OBJ_COMMIT: { - final RevCommit c = createCommit(ldr.getId()); + final RevCommit c = createCommit(ldr.getId(), getTags(ldr.getId())); c.parseCanonical(this, data); r = c; break; @@ -718,6 +719,14 @@ public RevObject parseAny(final AnyObjectId id) } /** + * @param commitId + * @return the list of refs associated with a commit, possibly filtered + */ + protected Ref[] getTags(final AnyObjectId commitId) { + return null; // Don't get tags in the basic case + } + + /** * Ensure the object's content has been parsed. * <p> * This method only returns successfully if the object exists and was parsed @@ -1008,9 +1017,11 @@ private boolean isNotStarted() { * * @param id * the object this walker requires a commit reference for. + * @param tags + * tags attached to the commit * @return a new unparsed reference for the object. */ - protected RevCommit createCommit(final AnyObjectId id) { + protected RevCommit createCommit(final AnyObjectId id, final Ref[] tags) { return new RevCommit(id); } -- 1.6.0.1.310.gf789d0.dirty -- 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