Bug 536008 - [Dark Theme] Disabled label looks bad in dark theme

Added a theme tweak to set foreground color for disable Label.

Image labels are not supported due to complexity and lack of demand.

Change-Id: Ib81641b3cbeeb3ddd84435f71fef583a81a52d93
Signed-off-by: Alexandr Miloslavskiy <alexandr.miloslavskiy@syntevo.com>
diff --git a/bundles/org.eclipse.swt/Eclipse SWT PI/win32/org/eclipse/swt/internal/win32/OS.java b/bundles/org.eclipse.swt/Eclipse SWT PI/win32/org/eclipse/swt/internal/win32/OS.java
index 53c4e2d..722da0f 100644
--- a/bundles/org.eclipse.swt/Eclipse SWT PI/win32/org/eclipse/swt/internal/win32/OS.java
+++ b/bundles/org.eclipse.swt/Eclipse SWT PI/win32/org/eclipse/swt/internal/win32/OS.java
@@ -2361,6 +2361,7 @@
 	display.setData("org.eclipse.swt.internal.win32.Text.use_WS_BORDER",       isDarkTheme);
 	display.setData("org.eclipse.swt.internal.win32.Tree.use_WS_BORDER",       isDarkTheme);
 	display.setData("org.eclipse.swt.internal.win32.Table.headerLineColor",    isDarkTheme ? new Color(display, 0x50, 0x50, 0x50) : null);
+	display.setData("org.eclipse.swt.internal.win32.Label.disabledForegroundColor", isDarkTheme ? new Color(display, 0x80, 0x80, 0x80) : null);
 }
 
 public static final boolean SetDllDirectory (TCHAR lpPathName) {
diff --git a/bundles/org.eclipse.swt/Eclipse SWT/win32/org/eclipse/swt/widgets/Display.java b/bundles/org.eclipse.swt/Eclipse SWT/win32/org/eclipse/swt/widgets/Display.java
index 8418bab..9e9fd84 100644
--- a/bundles/org.eclipse.swt/Eclipse SWT/win32/org/eclipse/swt/widgets/Display.java
+++ b/bundles/org.eclipse.swt/Eclipse SWT/win32/org/eclipse/swt/widgets/Display.java
@@ -230,6 +230,12 @@
 	 */
 	static final String TABLE_HEADER_LINE_COLOR_KEY  = "org.eclipse.swt.internal.win32.Table.headerLineColor"; //$NON-NLS-1$
 	int tableHeaderLinePixel = -1;
+	/**
+	 * Disabled Label is drawn with specified foreground color.
+	 * Expects a <code>Color</code> value.
+	 */
+	static final String LABEL_DISABLED_FOREGROUND_COLOR_KEY = "org.eclipse.swt.internal.win32.Label.disabledForegroundColor"; //$NON-NLS-1$
+	int disabledLabelForegroundPixel = -1;
 
 	/* Custom icons */
 	long hIconSearch;
@@ -4412,6 +4418,9 @@
 		case TABLE_HEADER_LINE_COLOR_KEY:
 			tableHeaderLinePixel = disableCustomThemeTweaks ? -1 : _toColorPixel(value);
 			return;
+		case LABEL_DISABLED_FOREGROUND_COLOR_KEY:
+			disabledLabelForegroundPixel = disableCustomThemeTweaks ? -1 : _toColorPixel(value);
+			break;
 	}
 
 	/* Remove the key/value pair */
diff --git a/bundles/org.eclipse.swt/Eclipse SWT/win32/org/eclipse/swt/widgets/Label.java b/bundles/org.eclipse.swt/Eclipse SWT/win32/org/eclipse/swt/widgets/Label.java
index ce060c9..ac4aab6 100644
--- a/bundles/org.eclipse.swt/Eclipse SWT/win32/org/eclipse/swt/widgets/Label.java
+++ b/bundles/org.eclipse.swt/Eclipse SWT/win32/org/eclipse/swt/widgets/Label.java
@@ -313,10 +313,24 @@
 	if ((alignment & (SWT.LEFT | SWT.RIGHT | SWT.CENTER)) == 0) return;
 	style &= ~(SWT.LEFT | SWT.RIGHT | SWT.CENTER);
 	style |= alignment & (SWT.LEFT | SWT.RIGHT | SWT.CENTER);
-	updateStyleBits();
+	updateStyleBits(getEnabled());
 	OS.InvalidateRect (handle, null, true);
 }
 
+@Override
+public void setEnabled (boolean enabled) {
+	/*
+	 * Style may need to be changed if Display#disabledLabelForegroundPixel
+	 * is active. At the same time, #setEnabled() will cause a repaint with
+	 * current style. Therefore, style needs to be changed before #setEnabled().
+	 * Note that adding redraw() after #setEnabled() is a worse solution
+	 * because it still causes brief old style painting in #setEnabled().
+	 */
+	updateStyleBits(enabled);
+
+	super.setEnabled(enabled);
+}
+
 /**
  * Sets the receiver's image to the argument, which may be
  * null indicating that no image should be displayed.
@@ -337,7 +351,7 @@
 	if (image != null && image.isDisposed()) error(SWT.ERROR_INVALID_ARGUMENT);
 	this.image = image;
 	isImageMode = (image != null);
-	updateStyleBits();
+	updateStyleBits(getEnabled());
 	OS.InvalidateRect (handle, null, true);
 }
 
@@ -377,7 +391,7 @@
 	if (string == null) error (SWT.ERROR_NULL_ARGUMENT);
 	if ((style & SWT.SEPARATOR) != 0) return;
 	isImageMode = false;
-	updateStyleBits();
+	updateStyleBits(getEnabled());
 	/*
 	* Feature in Windows.  For some reason, SetWindowText() for
 	* static controls redraws the control, even when the text has
@@ -394,9 +408,12 @@
 	}
 }
 
-void updateStyleBits() {
+void updateStyleBits(boolean isEnabled) {
 	boolean useOwnerDraw = isImageMode;
 
+	if (!useOwnerDraw && (display.disabledLabelForegroundPixel != -1) && !isEnabled)
+		useOwnerDraw = true;
+
 	int oldBits = OS.GetWindowLong(handle, OS.GWL_STYLE);
 
 	int newBits = oldBits;
@@ -571,6 +588,19 @@
 	if ((style & SWT.RIGHT) != 0)  flags |= OS.DT_RIGHT;
 	if ((style & SWT.WRAP) != 0)   flags |= OS.DT_WORDBREAK;
 
+	// Mnemonics are usually not shown on Labels until Alt is pressed.
+	long uiState = OS.SendMessage (handle, OS.WM_QUERYUISTATE, 0, 0);
+	if ((uiState & OS.UISF_HIDEACCEL) != 0)
+		flags |= OS.DT_HIDEPREFIX;
+
+	if (!getEnabled()) {
+		int foregroundPixel = OS.GetSysColor(OS.COLOR_GRAYTEXT);
+		if (display.disabledLabelForegroundPixel != -1)
+			foregroundPixel = display.disabledLabelForegroundPixel;
+
+		OS.SetTextColor(struct.hDC, foregroundPixel);
+	}
+
 	char [] buffer = text.toCharArray ();
 	OS.DrawText (struct.hDC, buffer, buffer.length, rect, flags);
 }
diff --git a/tests/org.eclipse.swt.tests.win32/ManualTests/org/eclipse/swt/tests/win32/snippets/Bug536008_DarkDisabledLabel.java b/tests/org.eclipse.swt.tests.win32/ManualTests/org/eclipse/swt/tests/win32/snippets/Bug536008_DarkDisabledLabel.java
index 0cb65e8..a3337ec 100644
--- a/tests/org.eclipse.swt.tests.win32/ManualTests/org/eclipse/swt/tests/win32/snippets/Bug536008_DarkDisabledLabel.java
+++ b/tests/org.eclipse.swt.tests.win32/ManualTests/org/eclipse/swt/tests/win32/snippets/Bug536008_DarkDisabledLabel.java
@@ -66,6 +66,8 @@
 
 		Color backColor  = new Color(display, 0x30, 0x30, 0x30);
 		Color foreColor  = new Color(display, 0xD0, 0xD0, 0xD0);
+		Color labelColor = new Color(display, 0x80, 0x80, 0x80);
+		display.setData("org.eclipse.swt.internal.win32.Label.disabledForegroundColor", labelColor);
 
 		int margin = 10;
 		int cx = 60;