[history] Less flashy tags and branches in dark mode

Many of the tag and branch labels in the Git History view used very
bright colors, which doesn't look that well in dark mode.

Newly the rendering adapts to the table background, which changes
when the theme changes. If the table has a dark background use
darker colors, and if needed, use white for the text.

Bug: 536171
Change-Id: I0fdb9b5d6ecf0e16b221f559c33c7d6a649b401a
Signed-off-by: Thomas Wolf <thomas.wolf@paranor.ch>
diff --git a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/history/CommitGraphTable.java b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/history/CommitGraphTable.java
index 795b3e0..de56733 100644
--- a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/history/CommitGraphTable.java
+++ b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/history/CommitGraphTable.java
@@ -293,7 +293,7 @@
 		});
 		table.setLabelProvider(graphLabelProvider);
 		table.setContentProvider(new GraphContentProvider());
-		renderer = new SWTPlotRenderer(rawTable.getDisplay(), resources);
+		renderer = new SWTPlotRenderer(rawTable, resources);
 
 		clipboard = new Clipboard(rawTable.getDisplay());
 		rawTable.addDisposeListener(new DisposeListener() {
diff --git a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/history/SWTPlotRenderer.java b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/history/SWTPlotRenderer.java
index 8993e91..6b27b36 100644
--- a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/history/SWTPlotRenderer.java
+++ b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/history/SWTPlotRenderer.java
@@ -33,6 +33,7 @@
 import org.eclipse.swt.graphics.RGB;
 import org.eclipse.swt.widgets.Display;
 import org.eclipse.swt.widgets.Event;
+import org.eclipse.swt.widgets.Table;
 import org.eclipse.swt.widgets.TableItem;
 
 class SWTPlotRenderer extends AbstractPlotRenderer<SWTLane, Color> {
@@ -85,26 +86,32 @@
 
 	private final ResourceManager resources;
 
-	GC g;
+	private GC g;
 
-	int cellX;
+	private int cellX;
 
-	int cellY;
+	private int cellY;
 
-	Color cellFG;
+	private Color cellFG;
 
-	Color cellBG;
+	private Color cellBG;
+
+	private Color tableBG;
 
 	private Ref headRef;
 
+	private Table table;
+
 	/**
 	 * Number of tags of the current commit being rendered. Reset after each
 	 * commit.
 	 */
 	private int tagCount = 0;
 
-	SWTPlotRenderer(final Display d, final ResourceManager resources) {
+	SWTPlotRenderer(final Table table, final ResourceManager resources) {
 		this.resources = resources;
+		this.table = table;
+		Display d = table.getDisplay();
 		sys_black = d.getSystemColor(SWT.COLOR_BLACK);
 		sys_gray = d.getSystemColor(SWT.COLOR_GRAY);
 		sys_white = d.getSystemColor(SWT.COLOR_WHITE);
@@ -120,6 +127,11 @@
 		cellY = event.y;
 		cellFG = g.getForeground();
 		cellBG = g.getBackground();
+		// Can't use cellBG for determining dark mode; it changes for
+		// selected/inactive selected cells. The table background updates fine
+		// on theme changes.
+		tableBG = table.getBackground();
+
 		if (textHeight == 0)
 			textHeight = g.stringExtent("/").y; //$NON-NLS-1$
 
@@ -188,6 +200,9 @@
 		boolean branch = false;
 		RGB labelOuter;
 		RGB labelInner;
+		Color labelTextColor = sys_black;
+		boolean adjustColors = true;
+
 		if (name.startsWith(Constants.R_HEADS)) {
 			branch = true;
 			labelOuter = OUTER_HEAD;
@@ -223,7 +238,22 @@
 			}
 		} else {
 			labelOuter = OUTER_OTHER;
-			labelInner = INNER_OTHER;
+			float hsb[] = tableBG.getRGB().getHSB();
+			if (hsb[2] < 0.5) {
+				// Dark table: use table background a little lightened
+				if (hsb[2] < 0.1) {
+					hsb[2] = 0.3f;
+				} else {
+					hsb[2] *= 1.7;
+				}
+				labelInner = new RGB(hsb[0], hsb[1], hsb[2]);
+				labelTextColor = hsb[2] < 0.5 ? sys_white : sys_black;
+				adjustColors = false;
+			} else {
+				// Light table
+				labelInner = INNER_OTHER;
+				labelTextColor = sys_black;
+			}
 
 			if (name.startsWith(Constants.R_REFS))
 				txt = name.substring(Constants.R_REFS.length());
@@ -231,6 +261,26 @@
 				txt = name; // HEAD and such
 		}
 
+		if (adjustColors) {
+			float hsb[] = tableBG.getRGB().getHSB();
+			if (hsb[2] < 0.5) {
+				// Dark table: darken the fill color
+				hsb = labelInner.getHSB();
+				if (hsb[2] >= 0.5) {
+					// With the very bright, weakly saturated colors we have,
+					// the following works reasonably well: Bump the saturation
+					// up, and darken a little. Unless it's a gray: then darken
+					// only.
+					if (!(labelInner.red == labelInner.blue
+							&& labelInner.blue == labelInner.green)) {
+						hsb[1] = (float) Math.min(1.0, hsb[1] * 1.5);
+					}
+					hsb[2] *= 0.7;
+					labelInner = new RGB(hsb[0], hsb[1], hsb[2]);
+				}
+				labelTextColor = hsb[2] < 0.5 ? sys_white : sys_black;
+			}
+		}
 		int maxLength;
 		if (tag)
 			maxLength = Activator.getDefault().getPreferenceStore()
@@ -276,11 +326,14 @@
 		g.drawRoundRectangle(cellX + x, cellY + texty - 1, outerWidth,
 				textsz.y + 1, arc, arc);
 
-		g.setForeground(sys_black);
+		g.setForeground(labelTextColor);
 
 		// Draw text
 		g.drawString(txt, cellX + x + 4, cellY + texty, true);
 
+		g.setBackground(cellBG);
+		g.setBackground(cellFG);
+
 		if (isHead)
 			g.setFont(oldFont);