git.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: Robin Rosenberg <robin.rosenberg@dewire.com>
To: git@vger.kernel.org
Cc: spearce@spearce.org, Robin Rosenberg <robin.rosenberg@dewire.com>
Subject: [EGIT PATCH 4/6] Add tags to the graphical history display.
Date: Mon,  6 Oct 2008 01:36:40 +0200	[thread overview]
Message-ID: <1223249802-9959-5-git-send-email-robin.rosenberg@dewire.com> (raw)
In-Reply-To: <1223249802-9959-4-git-send-email-robin.rosenberg@dewire.com>

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@dewire.com>
---
 .../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

  reply	other threads:[~2008-10-05 23:39 UTC|newest]

Thread overview: 14+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2008-10-05 23:36 (unknown), Robin Rosenberg
2008-10-05 23:36 ` [EGIT PATCH 1/6] Keep original ref name when reading refs Robin Rosenberg
2008-10-05 23:36   ` [EGIT PATCH 2/6] Peel annotated tags when getting all refs Robin Rosenberg
2008-10-05 23:36     ` [EGIT PATCH 3/6] Add a method to get refs by object Id Robin Rosenberg
2008-10-05 23:36       ` Robin Rosenberg [this message]
2008-10-05 23:36         ` [EGIT PATCH 5/6] Add decorate option to log program Robin Rosenberg
2008-10-05 23:36           ` [EGIT PATCH 6/6] Comment the getId method and hint for copy to actually get an ObjectId Robin Rosenberg
2008-10-06  8:08         ` [EGIT PATCH 4/6] Add tags to the graphical history display Shawn O. Pearce
2008-10-06 21:58           ` Robin Rosenberg
2008-10-06 22:14             ` Shawn O. Pearce
2008-10-06  8:15       ` [EGIT PATCH 3/6] Add a method to get refs by object Id Shawn O. Pearce
2008-10-06 22:37         ` Robin Rosenberg
2008-10-06 22:43           ` Shawn O. Pearce
2008-10-06  7:43     ` [EGIT PATCH 2/6] Peel annotated tags when getting all refs Shawn O. Pearce

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=1223249802-9959-5-git-send-email-robin.rosenberg@dewire.com \
    --to=robin.rosenberg@dewire.com \
    --cc=git@vger.kernel.org \
    --cc=spearce@spearce.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).