xref: /JGit/org.eclipse.jgit.ui/src/org/eclipse/jgit/awtui/AWTPlotRenderer.java (revision 5c5f7c6b146b24f2bd4afae1902df85ad6e57ea3)
1 /*
2  * Copyright (C) 2010, Google Inc.
3  * Copyright (C) 2008, Robin Rosenberg <robin.rosenberg@dewire.com>
4  * Copyright (C) 2008, Shawn O. Pearce <spearce@spearce.org> and others
5  *
6  * This program and the accompanying materials are made available under the
7  * terms of the Eclipse Distribution License v. 1.0 which is available at
8  * https://www.eclipse.org/org/documents/edl-v10.php.
9  *
10  * SPDX-License-Identifier: BSD-3-Clause
11  */
12 
13 package org.eclipse.jgit.awtui;
14 
15 import java.awt.Color;
16 import java.awt.Graphics;
17 import java.awt.Graphics2D;
18 import java.awt.Polygon;
19 import java.io.Serializable;
20 
21 import org.eclipse.jgit.awtui.CommitGraphPane.GraphCellRender;
22 import org.eclipse.jgit.awtui.SwingCommitList.SwingLane;
23 import org.eclipse.jgit.lib.Constants;
24 import org.eclipse.jgit.lib.Ref;
25 import org.eclipse.jgit.revplot.AbstractPlotRenderer;
26 import org.eclipse.jgit.revplot.PlotCommit;
27 
28 final class AWTPlotRenderer extends AbstractPlotRenderer<SwingLane, Color>
29 		implements Serializable {
30 	private static final long serialVersionUID = 1L;
31 
32 	final GraphCellRender cell;
33 
34 	transient Graphics2D g;
35 
AWTPlotRenderer(GraphCellRender c)36 	AWTPlotRenderer(GraphCellRender c) {
37 		cell = c;
38 	}
39 
paint(Graphics in, PlotCommit<SwingLane> commit)40 	void paint(Graphics in, PlotCommit<SwingLane> commit) {
41 		g = (Graphics2D) in.create();
42 		try {
43 			final int h = cell.getHeight();
44 			g.setColor(cell.getBackground());
45 			g.fillRect(0, 0, cell.getWidth(), h);
46 			if (commit != null)
47 				paintCommit(commit, h);
48 		} finally {
49 			g.dispose();
50 			g = null;
51 		}
52 	}
53 
54 	/** {@inheritDoc} */
55 	@Override
drawLine(final Color color, int x1, int y1, int x2, int y2, int width)56 	protected void drawLine(final Color color, int x1, int y1, int x2,
57 			int y2, int width) {
58 		if (y1 == y2) {
59 			x1 -= width / 2;
60 			x2 -= width / 2;
61 		} else if (x1 == x2) {
62 			y1 -= width / 2;
63 			y2 -= width / 2;
64 		}
65 
66 		g.setColor(color);
67 		g.setStroke(CommitGraphPane.stroke(width));
68 		g.drawLine(x1, y1, x2, y2);
69 	}
70 
71 	/** {@inheritDoc} */
72 	@Override
drawCommitDot(final int x, final int y, final int w, final int h)73 	protected void drawCommitDot(final int x, final int y, final int w,
74 			final int h) {
75 		g.setColor(Color.blue);
76 		g.setStroke(CommitGraphPane.strokeCache[1]);
77 		g.fillOval(x, y, w, h);
78 		g.setColor(Color.black);
79 		g.drawOval(x, y, w, h);
80 	}
81 
82 	/** {@inheritDoc} */
83 	@Override
drawBoundaryDot(final int x, final int y, final int w, final int h)84 	protected void drawBoundaryDot(final int x, final int y, final int w,
85 			final int h) {
86 		g.setColor(cell.getBackground());
87 		g.setStroke(CommitGraphPane.strokeCache[1]);
88 		g.fillOval(x, y, w, h);
89 		g.setColor(Color.black);
90 		g.drawOval(x, y, w, h);
91 	}
92 
93 	/** {@inheritDoc} */
94 	@Override
drawText(String msg, int x, int y)95 	protected void drawText(String msg, int x, int y) {
96 		final int texth = g.getFontMetrics().getHeight();
97 		final int y0 = (y - texth) / 2 + (cell.getHeight() - texth) / 2;
98 		g.setColor(cell.getForeground());
99 		g.drawString(msg, x, y0 + texth - g.getFontMetrics().getDescent());
100 	}
101 
102 	/** {@inheritDoc} */
103 	@Override
laneColor(SwingLane myLane)104 	protected Color laneColor(SwingLane myLane) {
105 		return myLane != null ? myLane.color : Color.black;
106 	}
107 
paintTriangleDown(int cx, int y, int h)108 	void paintTriangleDown(int cx, int y, int h) {
109 		final int tipX = cx;
110 		final int tipY = y + h;
111 		final int baseX1 = cx - 10 / 2;
112 		final int baseX2 = tipX + 10 / 2;
113 		final int baseY = y;
114 		final Polygon triangle = new Polygon();
115 		triangle.addPoint(tipX, tipY);
116 		triangle.addPoint(baseX1, baseY);
117 		triangle.addPoint(baseX2, baseY);
118 		g.fillPolygon(triangle);
119 		g.drawPolygon(triangle);
120 	}
121 
122 	/** {@inheritDoc} */
123 	@Override
drawLabel(int x, int y, Ref ref)124 	protected int drawLabel(int x, int y, Ref ref) {
125 		String txt;
126 		String name = ref.getName();
127 		if (name.startsWith(Constants.R_HEADS)) {
128 			g.setBackground(Color.GREEN);
129 			txt = name.substring(Constants.R_HEADS.length());
130 		} else if (name.startsWith(Constants.R_REMOTES)){
131 			g.setBackground(Color.LIGHT_GRAY);
132 			txt = name.substring(Constants.R_REMOTES.length());
133 		} else if (name.startsWith(Constants.R_TAGS)){
134 			g.setBackground(Color.YELLOW);
135 			txt = name.substring(Constants.R_TAGS.length());
136 		} else {
137 			// Whatever this would be
138 			g.setBackground(Color.WHITE);
139 			if (name.startsWith(Constants.R_REFS))
140 				txt = name.substring(Constants.R_REFS.length());
141 			else
142 				txt = name; // HEAD and such
143 		}
144 		if (ref.getPeeledObjectId() != null) {
145 			float[] colorComponents = g.getBackground().getRGBColorComponents(null);
146 			colorComponents[0] *= 0.9f;
147 			colorComponents[1] *= 0.9f;
148 			colorComponents[2] *= 0.9f;
149 			g.setBackground(new Color(colorComponents[0],colorComponents[1],colorComponents[2]));
150 		}
151 		if (txt.length() > 12)
152 			txt = txt.substring(0,11) + "\u2026"; // ellipsis "…" (in UTF-8) //$NON-NLS-1$
153 
154 		final int texth = g.getFontMetrics().getHeight();
155 		int textw = g.getFontMetrics().stringWidth(txt);
156 		g.setColor(g.getBackground());
157 		int arcHeight = texth/4;
158 		int y0 = y - texth/2 + (cell.getHeight() - texth)/2;
159 		g.fillRoundRect(x , y0, textw + arcHeight*2, texth -1, arcHeight, arcHeight);
160 		g.setColor(g.getColor().darker());
161 		g.drawRoundRect(x, y0, textw + arcHeight*2, texth -1 , arcHeight, arcHeight);
162 		g.setColor(Color.BLACK);
163 		g.drawString(txt, x + arcHeight, y0 + texth - g.getFontMetrics().getDescent());
164 
165 		return arcHeight * 3 + textw;
166 	}
167 }
168