2 * Copyright (C) 2008 Shawn Pearce <spearce@spearce.org>
4 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU General Public
6 * License, version 2, as published by the Free Software Foundation.
8 * This library is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
11 * General Public License for more details.
13 * You should have received a copy of the GNU General Public
14 * License along with this library; if not, write to the Free Software
15 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301
17 package org
.spearce
.jgit
.revplot
;
19 import org
.spearce
.jgit
.revwalk
.RevFlag
;
22 * Basic commit graph renderer for graphical user interfaces.
24 * Lanes are drawn as columns left-to-right in the graph, and the commit short
25 * message is drawn to the right of the lane lines for this cell. It is assumed
26 * that the commits are being drawn as rows of some sort of table.
28 * Client applications can subclass this implementation to provide the necessary
29 * drawing primitives required to display a commit graph. Most of the graph
30 * layout is handled by this class, allowing applications to implement only a
31 * handful of primitive stubs.
33 * This class is suitable for us within an AWT TableCellRenderer or within a SWT
34 * PaintListener registered on a Table instance. It is meant to rubber stamp the
35 * graphics necessary for one row of a plotted commit list.
37 * Subclasses should call {@link #paintCommit(PlotCommit, int)} after they have
38 * otherwise configured their instance to draw one commit into the current
41 * All drawing methods assume the coordinate space for the current commit's cell
42 * starts at (upper left corner is) 0,0. If this is not true (like say in SWT)
43 * the implementation must perform the cell offset computations within the
44 * various draw methods.
47 * type of lane being used by the application.
49 * type of color object used by the graphics library.
51 public abstract class AbstractPlotRenderer
<TLane
extends PlotLane
, TColor
> {
52 private static final int LANE_WIDTH
= 14;
54 private static final int LINE_WIDTH
= 2;
56 private static final int LEFT_PAD
= 2;
59 * Paint one commit using the underlying graphics library.
62 * the commit to render in this cell. Must not be null.
64 * total height (in pixels) of this cell.
66 protected void paintCommit(final PlotCommit
<TLane
> commit
, final int h
) {
67 final int dotSize
= Math
.max(0, Math
.min(LANE_WIDTH
- 2, h
- 8)) + 1;
68 final TLane myLane
= commit
.getLane();
69 final int myLaneX
= laneC(myLane
);
70 final TColor myColor
= laneColor(myLane
);
73 for (final TLane passingLane
: (TLane
[]) commit
.passingLanes
) {
74 final int cx
= laneC(passingLane
);
75 final TColor c
= laneColor(passingLane
);
76 drawLine(c
, cx
, 0, cx
, h
, LINE_WIDTH
);
77 maxCenter
= Math
.max(maxCenter
, cx
);
80 final int nParent
= commit
.getParentCount();
81 for (int i
= 0; i
< nParent
; i
++) {
82 final PlotCommit
<TLane
> p
;
87 p
= (PlotCommit
<TLane
>) commit
.getParent(i
);
92 pColor
= laneColor(pLane
);
95 if (Math
.abs(myLaneX
- cx
) > LANE_WIDTH
) {
97 final int ix
= cx
- LANE_WIDTH
/ 2;
98 drawLine(pColor
, myLaneX
, h
/ 2, ix
, h
/ 2, LINE_WIDTH
);
99 drawLine(pColor
, ix
, h
/ 2, cx
, h
, LINE_WIDTH
);
101 final int ix
= cx
+ LANE_WIDTH
/ 2;
102 drawLine(pColor
, myLaneX
, h
/ 2, ix
, h
/ 2, LINE_WIDTH
);
103 drawLine(pColor
, ix
, h
/ 2, cx
, h
, LINE_WIDTH
);
106 drawLine(pColor
, myLaneX
, h
/ 2, cx
, h
, LINE_WIDTH
);
108 maxCenter
= Math
.max(maxCenter
, cx
);
111 final int dotX
= myLaneX
- dotSize
/ 2 - 1;
112 final int dotY
= (h
- dotSize
) / 2;
114 if (commit
.getChildCount() > 0)
115 drawLine(myColor
, myLaneX
, 0, myLaneX
, dotY
, LINE_WIDTH
);
117 if (commit
.has(RevFlag
.UNINTERESTING
))
118 drawBoundaryDot(dotX
, dotY
, dotSize
, dotSize
);
120 drawCommitDot(dotX
, dotY
, dotSize
, dotSize
);
122 final String msg
= commit
.getShortMessage();
123 final int textx
= Math
.max(maxCenter
+ LANE_WIDTH
/ 2, dotX
+ dotSize
) + 8;
124 drawText(msg
, textx
, h
/ 2);
128 * Obtain the color reference used to paint this lane.
130 * Colors returned by this method will be passed to the other drawing
131 * primitives, so the color returned should be application specific.
133 * If a null lane is supplied the return value must still be acceptable to a
134 * drawing method. Usually this means the implementation should return a
138 * the current lane. May be null.
139 * @return graphics specific color reference. Must be a valid color.
141 protected abstract TColor
laneColor(TLane myLane
);
144 * Draw a single line within this cell.
147 * the color to use while drawing the line.
149 * starting X coordinate, 0 based.
151 * starting Y coordinate, 0 based.
153 * ending X coordinate, 0 based.
155 * ending Y coordinate, 0 based.
157 * number of pixels wide for the line. Always at least 1.
159 protected abstract void drawLine(TColor color
, int x1
, int y1
, int x2
,
163 * Draw a single commit dot.
165 * Usually the commit dot is a filled oval in blue, then a drawn oval in
166 * black, using the same coordinates for both operations.
169 * upper left of the oval's bounding box.
171 * upper left of the oval's bounding box.
173 * width of the oval's bounding box.
175 * height of the oval's bounding box.
177 protected abstract void drawCommitDot(int x
, int y
, int w
, int h
);
180 * Draw a single boundary commit (aka uninteresting commit) dot.
182 * Usually a boundary commit dot is a light gray oval with a white center.
185 * upper left of the oval's bounding box.
187 * upper left of the oval's bounding box.
189 * width of the oval's bounding box.
191 * height of the oval's bounding box.
193 protected abstract void drawBoundaryDot(int x
, int y
, int w
, int h
);
196 * Draw a single line of text.
198 * The font and colors used to render the text are left up to the
202 * the text to draw. Does not contain LFs.
204 * first pixel from the left that the text can be drawn at.
205 * Character data must not appear before this position.
207 * pixel coordinate of the centerline of the text.
208 * Implementations must adjust this coordinate to account for the
209 * way their implementation handles font rendering.
211 protected abstract void drawText(String msg
, int x
, int y
);
213 private int laneX(final PlotLane myLane
) {
214 final int p
= myLane
!= null ? myLane
.getPosition() : 0;
215 return LEFT_PAD
+ LANE_WIDTH
* p
;
218 private int laneC(final PlotLane myLane
) {
219 return laneX(myLane
) + LANE_WIDTH
/ 2;