aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRaymond Lam2011-11-01 01:20:17 (EDT)
committerFelipe Heidrich2011-11-11 10:51:56 (EST)
commit4b8def71d48644f2eecf0ad1acd6947c48451ff6 (patch)
tree7b7b964b4068e976d02e6e15efe6490a0d0f3a15
parentafa64269dcd7778f6eb01e1cb2d17a3455e7a43e (diff)
downloadeclipse.platform.swt-4b8def71d48644f2eecf0ad1acd6947c48451ff6.zip
eclipse.platform.swt-4b8def71d48644f2eecf0ad1acd6947c48451ff6.tar.gz
eclipse.platform.swt-4b8def71d48644f2eecf0ad1acd6947c48451ff6.tar.bz2
Glassify the ToolBar and ToolItem widgets.
-rw-r--r--bundles/org.eclipse.swt/Eclipse SWT/win32/org/eclipse/swt/widgets/ToolBar.java40
-rw-r--r--bundles/org.eclipse.swt/Eclipse SWT/win32/org/eclipse/swt/widgets/ToolItem.java164
-rw-r--r--bundles/org.eclipse.swt/Eclipse SWT/win32/org/eclipse/swt/widgets/Widget.java42
3 files changed, 246 insertions, 0 deletions
diff --git a/bundles/org.eclipse.swt/Eclipse SWT/win32/org/eclipse/swt/widgets/ToolBar.java b/bundles/org.eclipse.swt/Eclipse SWT/win32/org/eclipse/swt/widgets/ToolBar.java
index 9cb33cf..4ffc715 100644
--- a/bundles/org.eclipse.swt/Eclipse SWT/win32/org/eclipse/swt/widgets/ToolBar.java
+++ b/bundles/org.eclipse.swt/Eclipse SWT/win32/org/eclipse/swt/widgets/ToolBar.java
@@ -1531,6 +1531,14 @@ LRESULT wmNotifyChild (NMHDR hdr, int /*long*/ wParam, int /*long*/ lParam) {
// }
switch (nmcd.dwDrawStage) {
case OS.CDDS_PREERASE: {
+ if (this.getBufferredPaint()) {
+ // if buffered painting is on, erase the background the Aero/Glass way
+ RECT rect = new RECT ();
+ OS.SetRect (rect, nmcd.left, nmcd.top, nmcd.right, nmcd.bottom);
+ drawBackground (nmcd.hdc, rect);
+ return new LRESULT (OS.CDRF_SKIPDEFAULT);
+ }
+
/*
* Bug in Windows. When a tool bar does not have the style
* TBSTYLE_FLAT, the rectangle to be erased in CDDS_PREERASE
@@ -1546,6 +1554,25 @@ LRESULT wmNotifyChild (NMHDR hdr, int /*long*/ wParam, int /*long*/ lParam) {
}
return new LRESULT (OS.CDRF_SKIPDEFAULT);
}
+ case OS.CDDS_PREPAINT: {
+ if (this.getBufferredPaint()) {
+ // this will trigger the CDDS_ITEMPREPAINT notifications so that we can draw each
+ // ToolItem individually
+ return new LRESULT (OS.CDRF_NOTIFYITEMDRAW);
+ }
+ break;
+ }
+ case OS.CDDS_ITEMPREPAINT: {
+ if (this.getBufferredPaint()) {
+ // each ToolItem knows how to draw themself in an Aero/Glass friendly manner
+ ToolItem childItem = items[nmcd.dwItemSpec];
+ if (childItem != null) {
+ childItem.wmBufferedPaint(this.handle, wParam, lParam);
+ }
+ return new LRESULT (OS.CDRF_SKIPDEFAULT);
+ }
+ break;
+ }
}
break;
case OS.TBN_HOTITEMCHANGE:
@@ -1590,4 +1617,17 @@ LRESULT wmNotifyChild (NMHDR hdr, int /*long*/ wParam, int /*long*/ lParam) {
return super.wmNotifyChild (hdr, wParam, lParam);
}
+boolean getBufferredPaint() {
+ Shell shell = getShell ();
+ if (((shell.style & SWT.TRIM_FILL) != 0) && ((this.style & SWT.TRIM_FILL) != 0)) {
+ return true;
+ }
+ return false;
+}
+
+LRESULT wmBufferedPaint (int /*long*/ hWnd, int /*long*/ wParam, int /*long*/ lParam) {
+ // toolbar items are owner-draw during buffered painting
+ return null;
+}
+
}
diff --git a/bundles/org.eclipse.swt/Eclipse SWT/win32/org/eclipse/swt/widgets/ToolItem.java b/bundles/org.eclipse.swt/Eclipse SWT/win32/org/eclipse/swt/widgets/ToolItem.java
index c8caddb..bd965b8 100644
--- a/bundles/org.eclipse.swt/Eclipse SWT/win32/org/eclipse/swt/widgets/ToolItem.java
+++ b/bundles/org.eclipse.swt/Eclipse SWT/win32/org/eclipse/swt/widgets/ToolItem.java
@@ -46,6 +46,9 @@ public class ToolItem extends Item {
int id;
short cx;
+ // added to support the owner-draw operations performed in an Aero/Glass environment
+ static final int MARGIN = 4;
+
/**
* Constructs a new instance of this class given its parent
* (which must be a <code>ToolBar</code>) and a style value
@@ -1018,4 +1021,165 @@ LRESULT wmCommandChild (int /*long*/ wParam, int /*long*/ lParam) {
return null;
}
+/**
+ * Owner-draw painting of the ToolItem. Used in a shell where Aero/Glass painting has been turned on.
+ */
+LRESULT wmBufferedPaint (int /*long*/ hWnd, int /*long*/ wParam, int /*long*/ lParam) {
+ // cast the lParam into a NMCUSTOMDRAW structure
+ NMCUSTOMDRAW nmcd = new NMCUSTOMDRAW ();
+ OS.MoveMemory (nmcd, lParam, NMCUSTOMDRAW.sizeof);
+ int hDC = nmcd.hdc;
+ RECT rectClient = new RECT ();
+ OS.SetRect (rectClient, nmcd.left, nmcd.top, nmcd.right, nmcd.bottom);
+
+ // setup the constants that are used during drawing
+ final boolean drawImage = image != null;
+ final boolean drawText = text.length () != 0;
+ final boolean drawTextBelow = (parent.style & SWT.RIGHT) == 0;
+ final boolean drawDepressed = this.determineButtonState(nmcd) == OS.TS_HOTCHECKED || this.determineButtonState(nmcd) == OS.TS_CHECKED || this.determineButtonState(nmcd) == OS.TS_PRESSED;
+ final int margin = drawText && drawImage && !drawTextBelow ? MARGIN : 0;
+ final int width = rectClient.right - rectClient.left;
+ final int height = rectClient.bottom - rectClient.top;
+ final TCHAR textBuffer = new TCHAR (parent.getCodePage (), text, true);
+
+ // determine the image width and height
+ int imageWidth = 0, imageHeight = 0;
+ if (drawImage) {
+ Rectangle imageRect = image.getBounds ();
+ imageWidth = imageRect.width;
+ imageHeight = imageRect.height;
+ }
+
+ // determine the text width and height
+ int textWidth = 0, textHeight = 0, flags = 0;
+ if (drawText) {
+ RECT rect2 = new RECT ();
+ flags = OS.DT_CALCRECT | OS.DT_EDITCONTROL | OS.DT_EXPANDTABS;
+ if ((style & SWT.LEFT) != 0) flags |= OS.DT_LEFT;
+ if ((style & SWT.CENTER) != 0) flags |= OS.DT_CENTER;
+ if ((style & SWT.RIGHT) != 0) flags |= OS.DT_RIGHT;
+ if ((style & SWT.WRAP) != 0) {
+ flags |= OS.DT_WORDBREAK;
+ rect2.right = Math.max (0, width - imageWidth - margin);
+ }
+
+ OS.DrawText (hDC, textBuffer, -1, rect2, flags);
+ textWidth = rect2.right - rect2.left;
+ textHeight = rect2.bottom - rect2.top;
+ }
+
+ // calculate the image (x,y) coordinate
+ int x = rectClient.left;
+ int y = rectClient.top;
+ if (drawTextBelow) {
+ x += Math.max (0, (width - imageWidth) / 2);
+ y += Math.max (0, (height - imageHeight - textHeight) / 2);
+ } else if ((style & SWT.CENTER) != 0) {
+ x += Math.max (0, (width - imageWidth - textWidth - margin) / 2);
+ y += Math.max (0, (height - imageHeight) / 2);
+ } else if ((style & SWT.RIGHT) != 0) {
+ x += width - imageWidth - textWidth - margin;
+ y += Math.max (0, (height - imageHeight) / 2);
+ } else {
+ x += margin;
+ y += Math.max (0, (height - imageHeight) / 2);
+ }
+ if (drawDepressed) {
+ x++;
+ y--;
+ }
+
+ // draw the image, if needed
+ if (drawImage) {
+ GCData data = new GCData();
+ data.device = display;
+ GC gc = GC.win32_new (hDC, data);
+ Image image = getEnabled () ? this.image : (this.disabledImage != null) ? this.disabledImage : this.image;
+ gc.drawImage (image, x, y);
+ gc.dispose ();
+ }
+
+ // calculate the text (x,y) coordinate
+ if (drawTextBelow) {
+ x = rectClient.left + MARGIN;
+ y = height - textHeight - MARGIN;
+ } else {
+ x += imageWidth + MARGIN;
+ y = rectClient.top + Math.max (0, (height - textHeight) / 2);
+ }
+ if (drawDepressed) {
+ x++;
+ y--;
+ }
+
+ // draw the text, if needed
+ if (drawText) {
+ flags &= ~OS.DT_CALCRECT;
+ rectClient.left = x;
+ rectClient.right += rectClient.left;
+ rectClient.top = y;
+ rectClient.bottom += rectClient.top;
+
+ int color = 0x000000;
+ int /*long*/ hFont = OS.SendMessage(parent.handle, OS.WM_GETFONT, 0, 0);
+ this.drawBufferredText(hDC, textBuffer, rectClient, hFont, color, flags);
+ }
+
+ // draw the outline of the tool item
+ drawItemOutline(hDC, nmcd);
+
+ return LRESULT.ZERO;
+}
+
+/**
+ * Draws the outline of the ToolItem. This will make the ToolItem appear as pressed, checked, hot or normal depending
+ * on the UI state of the toolbar item.
+ * @param hDC - device context to paint in
+ * @param nmcd - the NMCUSTOMDRAW structure passed into owner-draw toolbar items
+ */
+void drawItemOutline(int hDC, NMCUSTOMDRAW nmcd) {
+ RECT rectClient = new RECT();
+ OS.SetRect (rectClient, nmcd.left, nmcd.top, nmcd.right, nmcd.bottom);
+
+ // setup the theme parameters
+ int /*long*/ hTheme = OS.OpenThemeData(0, "Toolbar;".toCharArray());
+ int btnState = determineButtonState(nmcd);
+
+ // draw the button outline, depending on if it's a regular button or a drop-down button
+ if ((style & SWT.DROP_DOWN) != 0) {
+ // drop-down button: left half is a button with a right edge that is not rounded
+ int dropDownWidth = OS.GetSystemMetrics(OS.SM_CXVSCROLL);
+ rectClient.right -= dropDownWidth;
+ OS.DrawThemeBackground(hTheme, hDC, OS.TP_SPLITBUTTON, btnState, rectClient, null);
+
+ // drop-down button: right half is where the arrow is drawn
+ rectClient.left = rectClient.right;
+ rectClient.right += dropDownWidth;
+ OS.DrawThemeBackground(hTheme, hDC, OS.TP_SPLITBUTTONDROPDOWN, btnState, rectClient, null);
+ } else {
+ // regular button
+ OS.DrawThemeBackground(hTheme, hDC, OS.TP_BUTTON, btnState, rectClient, null);
+ }
+
+ OS.CloseThemeData(hTheme);
+}
+
+/**
+ * Translates the item state into the equivalent button state.
+ * @param nmcd - the NMCUSTOMDRAW structure passed into owner-draw toolbar items
+ * @return
+ */
+int determineButtonState(NMCUSTOMDRAW nmcd) {
+ int btnState = OS.TS_NORMAL;
+
+ // translate the button state depending on the incoming item state
+ if ((nmcd.uItemState & OS.CDIS_HOT) != 0 && (nmcd.uItemState & OS.CDIS_CHECKED) != 0) { btnState = OS.TS_HOTCHECKED; }
+ else if ((nmcd.uItemState & OS.CDIS_HOT) != 0 && (nmcd.uItemState & OS.CDIS_SELECTED) != 0) {btnState = OS.TS_PRESSED; }
+ else if ((nmcd.uItemState & OS.CDIS_HOT) != 0) { btnState = OS.TS_HOT; }
+ else if ((nmcd.uItemState & OS.CDIS_SELECTED) != 0) { btnState = OS.TS_PRESSED; }
+ else if ((nmcd.uItemState & OS.CDIS_CHECKED) != 0) { btnState = OS.TS_CHECKED; }
+
+ return btnState;
}
+
+} \ No newline at end of file
diff --git a/bundles/org.eclipse.swt/Eclipse SWT/win32/org/eclipse/swt/widgets/Widget.java b/bundles/org.eclipse.swt/Eclipse SWT/win32/org/eclipse/swt/widgets/Widget.java
index fb2abeb..f776911 100644
--- a/bundles/org.eclipse.swt/Eclipse SWT/win32/org/eclipse/swt/widgets/Widget.java
+++ b/bundles/org.eclipse.swt/Eclipse SWT/win32/org/eclipse/swt/widgets/Widget.java
@@ -2682,4 +2682,46 @@ LRESULT wmXButtonUp (int /*long*/ hwnd, int /*long*/ wParam, int /*long*/ lParam
}
return result;
}
+
+public int getThemeGlowSize () {
+ int /*long*/ hTheme = OS.OpenThemeData(0, "CompositedWindow::Window;".toCharArray());
+ int [] glowSize = new int[1];
+ OS.GetThemeInt(hTheme, 0, 0, OS.TMT_TEXTGLOWSIZE, glowSize);
+ OS.CloseThemeData(hTheme);
+ return glowSize[0] > 0 ? glowSize[0] : 12;
+}
+
+public void drawBufferredText(int targetDC, TCHAR textBuffer, RECT rect, int hFont, int color, int dwFlags) {
+ // set up the buffered device context - the background is painted entirely black and its alpha
+ // is set to zero, resulting in a device context that is 100% transparent (if nothing is drawn to this DC,
+ // the glass background will just render through)
+ int /*long*/ [] hdcBuffered = new int /*long*/ [1];
+ int /*long*/ hBufferedPaint = OS.BeginBufferedPaint(targetDC, rect, OS.BPBF_TOPDOWNDIB, null, hdcBuffered);
+ OS.PatBlt(hdcBuffered[0], 0, 0, rect.right /* - rect.left */, rect.bottom /* - rect.top */, OS.BLACKNESS);
+ OS.BufferedPaintSetAlpha(hBufferedPaint, rect, (byte)0x00);
+
+ // setup the DTTOPTS structure for calling into DrawThemeTextEx - note how we call getThemeGlowSize()
+ // to apply a glow around the text we are drawing to enhance readability of the text against a glass background
+ DTTOPTS dttOpts = new DTTOPTS();
+ dttOpts.dwSize = DTTOPTS.sizeof;
+ dttOpts.dwFlags = OS.DTT_COMPOSITED | OS.DTT_GLOWSIZE | OS.DTT_TEXTCOLOR;
+ dttOpts.crText = color;
+ dttOpts.iGlowSize = getThemeGlowSize ();
+
+ OS.SetTextColor(hdcBuffered[0], color);
+ if (hFont != 0) {
+ hFont = OS.SelectObject(hdcBuffered[0], hFont);
+ }
+
+ // draw the text using the special DrawThemeTextEx call
+ int /*long*/ hTheme = OS.OpenThemeData(0, "ControlPanelStyle;".toCharArray());
+ OS.DrawThemeTextEx(hTheme, hdcBuffered[0], 0, 0, textBuffer.chars, textBuffer.length(), dwFlags, rect, dttOpts);
+ OS.CloseThemeData(hTheme);
+
+ if (hFont != 0) {
+ OS.SelectObject(hdcBuffered[0], hFont);
+ }
+ OS.EndBufferedPaint(hBufferedPaint, true);
+
+}
}