summaryrefslogtreecommitdiffstats
path: root/bundles/org.eclipse.swt/Eclipse SWT Theme/win32
diff options
context:
space:
mode:
authorSilenio Quarti <silenio>2006-04-26 14:57:18 +0000
committerSilenio Quarti <silenio>2006-04-26 14:57:18 +0000
commit8f00f299b7757fe42d6925916d2c9d689cd31e9d (patch)
treea2b30ed55edfd95075d497c35f2e7db327b62b1b /bundles/org.eclipse.swt/Eclipse SWT Theme/win32
parent36ded620c7508f4cbe34e3f788ea5ed8718a3698 (diff)
downloadeclipse.platform.swt-8f00f299b7757fe42d6925916d2c9d689cd31e9d.tar.gz
eclipse.platform.swt-8f00f299b7757fe42d6925916d2c9d689cd31e9d.tar.xz
eclipse.platform.swt-8f00f299b7757fe42d6925916d2c9d689cd31e9d.zip
37706 - Support native theme drawing API in SWT (internal)
Diffstat (limited to 'bundles/org.eclipse.swt/Eclipse SWT Theme/win32')
-rw-r--r--bundles/org.eclipse.swt/Eclipse SWT Theme/win32/org/eclipse/swt/internal/theme/ButtonDrawData.java98
-rw-r--r--bundles/org.eclipse.swt/Eclipse SWT Theme/win32/org/eclipse/swt/internal/theme/ComboDrawData.java94
-rw-r--r--bundles/org.eclipse.swt/Eclipse SWT Theme/win32/org/eclipse/swt/internal/theme/DrawData.java168
-rw-r--r--bundles/org.eclipse.swt/Eclipse SWT Theme/win32/org/eclipse/swt/internal/theme/ExpanderDrawData.java55
-rw-r--r--bundles/org.eclipse.swt/Eclipse SWT Theme/win32/org/eclipse/swt/internal/theme/GroupDrawData.java62
-rw-r--r--bundles/org.eclipse.swt/Eclipse SWT Theme/win32/org/eclipse/swt/internal/theme/ProgressBarDrawData.java77
-rw-r--r--bundles/org.eclipse.swt/Eclipse SWT Theme/win32/org/eclipse/swt/internal/theme/RangeDrawData.java13
-rw-r--r--bundles/org.eclipse.swt/Eclipse SWT Theme/win32/org/eclipse/swt/internal/theme/ScaleDrawData.java87
-rw-r--r--bundles/org.eclipse.swt/Eclipse SWT Theme/win32/org/eclipse/swt/internal/theme/ScrollBarDrawData.java278
-rw-r--r--bundles/org.eclipse.swt/Eclipse SWT Theme/win32/org/eclipse/swt/internal/theme/TabFolderDrawData.java71
-rw-r--r--bundles/org.eclipse.swt/Eclipse SWT Theme/win32/org/eclipse/swt/internal/theme/TabItemDrawData.java119
-rw-r--r--bundles/org.eclipse.swt/Eclipse SWT Theme/win32/org/eclipse/swt/internal/theme/Theme.java103
-rw-r--r--bundles/org.eclipse.swt/Eclipse SWT Theme/win32/org/eclipse/swt/internal/theme/ToolBarDrawData.java23
-rw-r--r--bundles/org.eclipse.swt/Eclipse SWT Theme/win32/org/eclipse/swt/internal/theme/ToolItemDrawData.java158
14 files changed, 1406 insertions, 0 deletions
diff --git a/bundles/org.eclipse.swt/Eclipse SWT Theme/win32/org/eclipse/swt/internal/theme/ButtonDrawData.java b/bundles/org.eclipse.swt/Eclipse SWT Theme/win32/org/eclipse/swt/internal/theme/ButtonDrawData.java
new file mode 100644
index 0000000000..daad1145e8
--- /dev/null
+++ b/bundles/org.eclipse.swt/Eclipse SWT Theme/win32/org/eclipse/swt/internal/theme/ButtonDrawData.java
@@ -0,0 +1,98 @@
+package org.eclipse.swt.internal.theme;
+
+import org.eclipse.swt.*;
+import org.eclipse.swt.graphics.*;
+import org.eclipse.swt.internal.win32.*;
+
+public class ButtonDrawData extends DrawData {
+
+public ButtonDrawData() {
+ state = new int[1];
+}
+
+int[] getPartId(int part) {
+ int state = this.state[part];
+ int style = this.style;
+ int iPartId = 0, iStateId = 0;
+ if ((style & SWT.PUSH) != 0) {
+ iPartId = OS.BP_PUSHBUTTON;
+ iStateId = OS.PBS_NORMAL;
+ if ((state & DrawData.DEFAULTED) != 0 && (state & DrawData.ACTIVE) != 0) iStateId = OS.PBS_DEFAULTED;
+ if ((state & DrawData.HOT) != 0) iStateId = OS.PBS_HOT;
+ if ((state & DrawData.PRESSED) != 0) iStateId = OS.PBS_PRESSED;
+ if ((state & DrawData.DISABLED) != 0) iStateId = OS.PBS_DISABLED;
+ }
+ if ((style & SWT.RADIO) != 0) {
+ iPartId = OS.BP_RADIOBUTTON;
+ }
+ if ((style & SWT.CHECK) != 0) {
+ iPartId = OS.BP_CHECKBOX;
+ }
+ if ((style & (SWT.CHECK | SWT.RADIO)) != 0) {
+ if ((state & DrawData.SELECTED) != 0) {
+ iStateId = OS.CBS_CHECKEDNORMAL;
+ if ((state & DrawData.HOT) != 0) iStateId = OS.CBS_CHECKEDHOT;
+ if ((state & DrawData.PRESSED) != 0) iStateId = OS.CBS_CHECKEDPRESSED;
+ if ((state & DrawData.DISABLED) != 0) iStateId = OS.CBS_CHECKEDDISABLED;
+ } else {
+ iStateId = OS.CBS_UNCHECKEDNORMAL;
+ if ((state & DrawData.HOT) != 0) iStateId = OS.CBS_UNCHECKEDHOT;
+ if ((state & DrawData.PRESSED) != 0) iStateId = OS.CBS_UNCHECKEDPRESSED;
+ if ((state & DrawData.DISABLED) != 0) iStateId = OS.CBS_UNCHECKEDDISABLED;
+ }
+ }
+ return new int[]{iPartId, iStateId};
+}
+
+void draw(Theme theme, GC gc, Rectangle bounds) {
+ if (OS.COMCTL32_MAJOR >= 6 && OS.IsAppThemed ()) {
+ //TODO - arrow and toggle
+ int hTheme = OS.OpenThemeData(0, getClassId());
+ RECT rect = new RECT ();
+ rect.left = bounds.x;
+ rect.right = bounds.x + bounds.width;
+ rect.top = bounds.y;
+ rect.bottom = bounds.y + bounds.height;
+ int[] part = getPartId(DrawData.WIDGET_WHOLE);
+ if ((style & (SWT.CHECK | SWT.RADIO)) != 0) {
+ SIZE size = new SIZE();
+ OS.GetThemePartSize(hTheme, gc.handle, part[0], part[1], rect, 2, size);
+ rect.right = rect.left + size.cx;
+ OS.DrawThemeBackground (hTheme, gc.handle, part[0], part[1], rect, null);
+ rect.left = rect.right + 3;
+ rect.right = rect.left + bounds.width - size.cx - 3;
+ } else {
+ OS.DrawThemeBackground (hTheme, gc.handle, part[0], part[1], rect, null);
+ }
+ Rectangle clientArea = this.clientArea;
+ if (clientArea != null) {
+ RECT contentRect = new RECT();
+ OS.GetThemeBackgroundContentRect(hTheme, gc.handle, part[0], part[1], rect, contentRect);
+ clientArea.x = contentRect.left;
+ clientArea.y = contentRect.top;
+ clientArea.width = contentRect.right - contentRect.left;
+ clientArea.height = contentRect.bottom - contentRect.top;
+ }
+ OS.CloseThemeData(hTheme);
+ }
+}
+
+int hit(Theme theme, Point position, Rectangle bounds) {
+ if (!bounds.contains(position)) return DrawData.WIDGET_NOWHERE;
+ int hTheme = OS.OpenThemeData(0, getClassId());
+ RECT rect = new RECT ();
+ rect.left = bounds.x;
+ rect.right = bounds.x + bounds.width;
+ rect.top = bounds.y;
+ rect.bottom = bounds.y + bounds.height;
+ POINT pt = new POINT();
+ pt.x = position.x;
+ pt.y = position.y;
+ short[] code = new short[1];
+ int[] part = getPartId(DrawData.WIDGET_WHOLE);
+ OS.HitTestThemeBackground(hTheme, 0, part[0], part[1], 0, rect, 0, pt, code);
+ OS.CloseThemeData (hTheme);
+ return code[0] == OS.HTNOWHERE ? DrawData.WIDGET_NOWHERE : DrawData.WIDGET_WHOLE;
+}
+
+}
diff --git a/bundles/org.eclipse.swt/Eclipse SWT Theme/win32/org/eclipse/swt/internal/theme/ComboDrawData.java b/bundles/org.eclipse.swt/Eclipse SWT Theme/win32/org/eclipse/swt/internal/theme/ComboDrawData.java
new file mode 100644
index 0000000000..6e3df79c43
--- /dev/null
+++ b/bundles/org.eclipse.swt/Eclipse SWT Theme/win32/org/eclipse/swt/internal/theme/ComboDrawData.java
@@ -0,0 +1,94 @@
+package org.eclipse.swt.internal.theme;
+
+import org.eclipse.swt.graphics.*;
+import org.eclipse.swt.internal.win32.*;
+
+public class ComboDrawData extends DrawData {
+
+public ComboDrawData() {
+ state = new int[2];
+}
+
+void draw(Theme theme, GC gc, Rectangle bounds) {
+ if (OS.COMCTL32_MAJOR >= 6 && OS.IsAppThemed ()) {
+ int hTheme = OS.OpenThemeData(0, EDIT);
+ RECT rect = new RECT ();
+ rect.left = bounds.x;
+ rect.right = bounds.x + bounds.width;
+ rect.top = bounds.y;
+ rect.bottom = bounds.y + bounds.height;
+ int[] part = getPartId(DrawData.WIDGET_WHOLE);
+ OS.DrawThemeBackground (hTheme, gc.handle, part[0], part[1], rect, null);
+ RECT contentRect = new RECT();
+ OS.GetThemeBackgroundContentRect(hTheme, gc.handle, part[0], part[1], rect, contentRect);
+ Rectangle clientArea = this.clientArea;
+ if (clientArea != null) {
+ clientArea.x = contentRect.left;
+ clientArea.y = contentRect.top;
+ clientArea.width = contentRect.right - contentRect.left;
+ clientArea.height = contentRect.bottom - contentRect.top;
+ }
+ OS.CloseThemeData(hTheme);
+ hTheme = OS.OpenThemeData(0, getClassId());
+ int width = OS.GetThemeSysSize(hTheme, OS.SM_CXVSCROLL);
+ rect.left = contentRect.right - width;
+ rect.top = contentRect.top;
+ rect.right = contentRect.right;
+ rect.bottom = contentRect.bottom;
+ part = getPartId(DrawData.COMBO_ARROW);
+ OS.DrawThemeBackground (hTheme, gc.handle, part[0], part[1], rect, null);
+ OS.CloseThemeData(hTheme);
+ if (clientArea != null) {
+ clientArea.width -= width;
+ }
+ }
+}
+
+char[] getClassId() {
+ return COMBOBOX;
+}
+
+int[] getPartId(int part) {
+ int state = this.state[part];
+ int iPartId = 0, iStateId = 0;
+ switch (part) {
+ case DrawData.WIDGET_WHOLE:
+ iPartId = OS.EP_EDITTEXT;
+ iStateId = OS.ETS_NORMAL;
+ if ((state & DrawData.DISABLED) != 0) iStateId = OS.ETS_DISABLED;
+ break;
+ case DrawData.COMBO_ARROW:
+ iPartId = OS.CP_DROPDOWNBUTTON;
+ iStateId = OS.CBXS_NORMAL;
+ if ((state & DrawData.DISABLED) != 0) iStateId = OS.CBXS_DISABLED;
+ if ((state & DrawData.HOT) != 0) iStateId = OS.CBXS_HOT;
+ if ((state & DrawData.PRESSED) != 0) iStateId = OS.CBXS_PRESSED;
+ break;
+ }
+ return new int[]{iPartId, iStateId};
+}
+
+int hit(Theme theme, Point position, Rectangle bounds) {
+ if (!(OS.COMCTL32_MAJOR >= 6 && OS.IsAppThemed ())) return DrawData.WIDGET_NOWHERE;
+ if (!bounds.contains(position)) return DrawData.WIDGET_NOWHERE;
+ int hTheme = OS.OpenThemeData(0, EDIT);
+ int[] part = getPartId(DrawData.WIDGET_WHOLE);
+ int iPartId = part[0];
+ int iStateId = part[1];
+ RECT rect = new RECT ();
+ rect.left = bounds.x;
+ rect.right = bounds.x + bounds.width;
+ rect.top = bounds.y;
+ rect.bottom = bounds.y + bounds.height;
+ RECT contentRect = new RECT();
+ OS.GetThemeBackgroundContentRect(hTheme, 0, iPartId, iStateId, rect, contentRect);
+ OS.CloseThemeData(hTheme);
+ hTheme = OS.OpenThemeData(0, getClassId());
+ int width = OS.GetThemeSysSize(hTheme, OS.SM_CXVSCROLL);
+ OS.CloseThemeData(hTheme);
+ Rectangle arrowRect = new Rectangle(contentRect.right - width, contentRect.top, contentRect.bottom - contentRect.top, width);
+ if (arrowRect.contains(position)) return DrawData.COMBO_ARROW;
+ return DrawData.WIDGET_WHOLE;
+}
+
+}
diff --git a/bundles/org.eclipse.swt/Eclipse SWT Theme/win32/org/eclipse/swt/internal/theme/DrawData.java b/bundles/org.eclipse.swt/Eclipse SWT Theme/win32/org/eclipse/swt/internal/theme/DrawData.java
new file mode 100644
index 0000000000..42b1e1507b
--- /dev/null
+++ b/bundles/org.eclipse.swt/Eclipse SWT Theme/win32/org/eclipse/swt/internal/theme/DrawData.java
@@ -0,0 +1,168 @@
+package org.eclipse.swt.internal.theme;
+
+import org.eclipse.swt.*;
+import org.eclipse.swt.graphics.*;
+import org.eclipse.swt.internal.win32.*;
+
+public class DrawData {
+ public int style;
+ public int[] state;
+ public Rectangle clientArea;
+
+ /** Part states */
+ public static final int SELECTED = 1 << 1;
+ public static final int FOCUSED = 1 << 2;
+ public static final int PRESSED = 1 << 3;
+ public static final int ACTIVE = 1 << 4;
+ public static final int DISABLED = 1 << 5;
+ public static final int HOT = 1 << 6;
+ public static final int DEFAULTED = 1 << 7;
+ public static final int GRAYED = 1 << 8;
+
+ /** Text and Image drawing flags */
+ public static final int DRAW_LEFT = 1 << 4;
+ public static final int DRAW_TOP = 1 << 5;
+ public static final int DRAW_RIGHT = 1 << 6;
+ public static final int DRAW_BOTTOM = 1 << 7;
+ public static final int DRAW_HCENTER = 1 << 8;
+ public static final int DRAW_VCENTER = 1 << 9;
+
+ /** Widget parts */
+ public static final int WIDGET_NOWHERE = -1;
+ public static final int WIDGET_WHOLE = 0;
+
+ /** Scrollbar parts */
+ public static final int SCROLLBAR_UP_ARROW = 1;
+ public static final int SCROLLBAR_DOWN_ARROW = 2;
+ public static final int SCROLLBAR_LEFT_ARROW = SCROLLBAR_UP_ARROW;
+ public static final int SCROLLBAR_RIGHT_ARROW = SCROLLBAR_DOWN_ARROW;
+ public static final int SCROLLBAR_UP_TRACK = 3;
+ public static final int SCROLLBAR_DOWN_TRACK = 4;
+ public static final int SCROLLBAR_LEFT_TRACK = SCROLLBAR_UP_TRACK;
+ public static final int SCROLLBAR_RIGHT_TRACK = SCROLLBAR_DOWN_TRACK;
+ public static final int SCROLLBAR_THUMB = 5;
+
+ /** Scale parts */
+ public static final int SCALE_UP_TRACK = 1;
+ public static final int SCALE_LEFT_TRACK = SCALE_UP_TRACK;
+ public static final int SCALE_DOWN_TRACK = 2;
+ public static final int SCALE_RIGHT_TRACK = SCALE_DOWN_TRACK;
+ public static final int SCALE_THUMB = 3;
+
+ /** ToolItem parts */
+ public static final int TOOLITEM_ARROW = 1;
+
+ /** Combo parts */
+ public static final int COMBO_ARROW = 1;
+
+ static final char [] EDIT = new char [] {'E', 'D', 'I', 'T', 0};
+ static final char [] COMBOBOX = new char [] {'C', 'O', 'M', 'B', 'O', 'B', 'O', 'X', 0};
+ static final char [] BUTTON = new char [] {'B', 'U', 'T', 'T', 'O', 'N', 0};
+ static final char [] PROGRESS = new char [] {'P', 'R', 'O', 'G', 'R', 'E', 'S', 'S', 0};
+ static final char [] SCROLLBAR = new char [] {'S', 'C', 'R', 'O', 'L', 'L', 'B', 'A', 'R', 0};
+ static final char [] TAB = new char [] {'T', 'A', 'B', 0};
+ static final char [] TRACKBAR = new char [] {'T', 'R', 'A', 'C', 'K', 'B', 'A', 'R', 0};
+ static final char [] TOOLBAR = new char [] {'T', 'O', 'O', 'L', 'B', 'A', 'R', 0};
+ static final char [] TREEVIEW = new char [] {'T', 'R', 'E', 'E', 'V', 'I', 'E', 'W', 0};
+
+public DrawData() {
+ state = new int[1];
+}
+
+Rectangle computeTrim(Theme theme, GC gc) {
+ return new Rectangle(clientArea.x, clientArea.y, clientArea.width, clientArea.height);
+}
+
+void draw(Theme theme, GC gc, Rectangle bounds) {
+
+}
+
+void drawImage(Theme theme, Image image, GC gc, Rectangle bounds) {
+ if (OS.COMCTL32_MAJOR >= 6 && OS.IsAppThemed ()) {
+// int hTheme = OS.OpenThemeData(0, getClassId());
+// RECT rect = new RECT ();
+// rect.left = bounds.x;
+// rect.right = bounds.x + bounds.width;
+// rect.top = bounds.y;
+// rect.bottom = bounds.y + bounds.height;
+// //TODO - remove reference to widgets.
+// ImageList imageList = new ImageList(0);
+// int imageIndex = imageList.add(image);
+// int[] part = getPartId(DrawData.WIDGET_WHOLE);
+// OS.DrawThemeIcon(hTheme, gc.handle, part[0], part[1], rect, imageList.getHandle(), imageIndex);
+// imageList.dispose();
+// OS.CloseThemeData(hTheme);
+ Rectangle rect = image.getBounds();
+ gc.drawImage(image, 0, 0, rect.width, rect.height, bounds.x, bounds.y, bounds.width, bounds.height);
+ }
+}
+
+void drawText(Theme theme, String text, int flags, GC gc, Rectangle bounds) {
+ if (OS.COMCTL32_MAJOR >= 6 && OS.IsAppThemed ()) {
+ int hTheme = OS.OpenThemeData(0, getClassId());
+ char[] chars = new char[text.length()];
+ text.getChars(0, chars.length, chars, 0);
+ int textFlags = OS.DT_SINGLELINE;
+ if ((flags & DrawData.DRAW_LEFT) != 0) textFlags |= OS.DT_LEFT;
+ if ((flags & DrawData.DRAW_HCENTER) != 0) textFlags |= OS.DT_CENTER;
+ if ((flags & DrawData.DRAW_RIGHT) != 0) textFlags |= OS.DT_RIGHT;
+ if ((flags & DrawData.DRAW_TOP) != 0) textFlags |= OS.DT_TOP;
+ if ((flags & DrawData.DRAW_BOTTOM) != 0) textFlags |= OS.DT_BOTTOM;
+ if ((flags & DrawData.DRAW_VCENTER) != 0) textFlags |= OS.DT_VCENTER;
+ RECT rect = new RECT ();
+ rect.left = bounds.x;
+ rect.right = bounds.x + bounds.width;
+ rect.top = bounds.y;
+ rect.bottom = bounds.y + bounds.height;
+ int[] part = getPartId(DrawData.WIDGET_WHOLE);
+ int iPartId = part[0];
+ int iStateId = part[1];
+ OS.DrawThemeText(hTheme, gc.handle, iPartId, iStateId, chars, chars.length, textFlags, 0, rect);
+ OS.CloseThemeData(hTheme);
+ }
+}
+
+char[] getClassId() {
+ return BUTTON;
+}
+
+int[] getPartId(int part) {
+ return new int[]{0, 0};
+}
+
+Rectangle getBounds(int part, Rectangle bounds) {
+ return new Rectangle(bounds.x, bounds.y, bounds.width, bounds.height);
+}
+
+int hit(Theme theme, Point position, Rectangle bounds) {
+ return -1;
+}
+
+Rectangle measureText(Theme theme, String text, int flags, GC gc, Rectangle bounds) {
+ if (!(OS.COMCTL32_MAJOR >= 6 && OS.IsAppThemed ())) return new Rectangle(0, 0, 0, 0);
+ int hTheme = OS.OpenThemeData(0, getClassId());
+ char[] chars = new char[text.length()];
+ text.getChars(0, chars.length, chars, 0);
+ //TODO - constant for VCENTER and flags
+ int textFlags = 0;//OS.DT_VCENTER | OS.DT_SINGLELINE | OS.DT_CALCRECT;
+ if ((style & SWT.LEFT) != 0) textFlags |= OS.DT_LEFT;
+ if ((style & SWT.CENTER) != 0) textFlags |= OS.DT_CENTER;
+ if ((style & SWT.RIGHT) != 0) textFlags |= OS.DT_RIGHT;
+ RECT extent = new RECT();
+ RECT rect = null;
+ if (bounds != null) {
+ rect = new RECT();
+ rect.left = bounds.x;
+ rect.right = bounds.x + bounds.width;
+ rect.top = bounds.y;
+ rect.bottom = bounds.y + bounds.height;
+ }
+ int[] part = getPartId(DrawData.WIDGET_WHOLE);
+ int iPartId = part[0];
+ int iStateId = part[1];
+ OS.GetThemeTextExtent(hTheme, gc.handle, iPartId, iStateId, chars, chars.length, textFlags, rect, extent);
+ OS.CloseThemeData(hTheme);
+ return new Rectangle(extent.left, extent.top, extent.right - extent.left, extent.bottom - extent.top);
+}
+
+}
diff --git a/bundles/org.eclipse.swt/Eclipse SWT Theme/win32/org/eclipse/swt/internal/theme/ExpanderDrawData.java b/bundles/org.eclipse.swt/Eclipse SWT Theme/win32/org/eclipse/swt/internal/theme/ExpanderDrawData.java
new file mode 100644
index 0000000000..ba15d25cab
--- /dev/null
+++ b/bundles/org.eclipse.swt/Eclipse SWT Theme/win32/org/eclipse/swt/internal/theme/ExpanderDrawData.java
@@ -0,0 +1,55 @@
+package org.eclipse.swt.internal.theme;
+
+import org.eclipse.swt.*;
+import org.eclipse.swt.graphics.*;
+import org.eclipse.swt.internal.win32.*;
+
+public class ExpanderDrawData extends DrawData {
+
+public ExpanderDrawData() {
+ state = new int[1];
+}
+
+void draw(Theme theme, GC gc, Rectangle bounds) {
+ if (OS.COMCTL32_MAJOR >= 6 && OS.IsAppThemed ()) {
+ int hTheme = OS.OpenThemeData(0, getClassId());
+ int iStateId = OS.GLPS_CLOSED;
+ if ((this.style & SWT.DOWN) != 0) iStateId = OS.GLPS_OPENED;
+ SIZE size = new SIZE();
+ OS.GetThemePartSize(hTheme, gc.handle, OS.TVP_GLYPH, iStateId, null, OS.TS_TRUE, size);
+ RECT rect = new RECT ();
+ rect.left = bounds.x;
+ rect.right = rect.left + size.cx;
+ rect.top = bounds.y;
+ rect.bottom = rect.top + size.cy;
+ OS.DrawThemeBackground (hTheme, gc.handle, OS.TVP_GLYPH, iStateId, rect, null);
+ OS.CloseThemeData (hTheme);
+ }
+}
+
+char[] getClassId() {
+ return TREEVIEW;
+}
+
+int[] getPartId(int part) {
+ int iPartId = OS.TVP_GLYPH;
+ int iStateId = OS.GLPS_CLOSED;
+ if ((this.style & SWT.DOWN) != 0) iStateId = OS.GLPS_OPENED;
+ return new int[]{iPartId, iStateId};
+}
+
+int hit(Theme theme, Point position, Rectangle bounds) {
+ if (!(OS.COMCTL32_MAJOR >= 6 && OS.IsAppThemed ())) return DrawData.WIDGET_NOWHERE;
+ if (!bounds.contains(position)) return DrawData.WIDGET_NOWHERE;
+ int hTheme = OS.OpenThemeData(0, getClassId());
+ SIZE size = new SIZE();
+ int[] part = getPartId(DrawData.WIDGET_WHOLE);
+ OS.GetThemePartSize(hTheme, 0, part[0], part[1], null, OS.TS_TRUE, size);
+ OS.CloseThemeData (hTheme);
+ if (new Rectangle(bounds.x, bounds.y, size.cx, size.cy).contains(position)) {
+ return DrawData.WIDGET_WHOLE;
+ }
+ return DrawData.WIDGET_NOWHERE;
+}
+
+}
diff --git a/bundles/org.eclipse.swt/Eclipse SWT Theme/win32/org/eclipse/swt/internal/theme/GroupDrawData.java b/bundles/org.eclipse.swt/Eclipse SWT Theme/win32/org/eclipse/swt/internal/theme/GroupDrawData.java
new file mode 100644
index 0000000000..d281c8d371
--- /dev/null
+++ b/bundles/org.eclipse.swt/Eclipse SWT Theme/win32/org/eclipse/swt/internal/theme/GroupDrawData.java
@@ -0,0 +1,62 @@
+package org.eclipse.swt.internal.theme;
+
+import org.eclipse.swt.graphics.*;
+import org.eclipse.swt.internal.win32.*;
+
+public class GroupDrawData extends DrawData {
+ public int headerWidth;
+ public int headerHeight;
+ public Rectangle headerArea;
+
+public GroupDrawData() {
+ state = new int[1];
+}
+
+static final int GROUP_HEADER_X = 9;
+static final int GROUP_HEADER_PAD = 2;
+void draw(Theme theme, GC gc, Rectangle bounds) {
+ if (OS.COMCTL32_MAJOR >= 6 && OS.IsAppThemed ()) {
+ int hTheme = OS.OpenThemeData(0, getClassId());
+ RECT rect = new RECT ();
+ rect.left = bounds.x;
+ rect.right = bounds.x + bounds.width;
+ rect.top = bounds.y + this.headerHeight / 2;
+ rect.bottom = bounds.y + bounds.height;
+ int headerX = bounds.x + GROUP_HEADER_X, headerY = bounds.y;
+ int savedDC = OS.SaveDC(gc.handle);
+ OS.ExcludeClipRect (gc.handle, headerX - GROUP_HEADER_PAD, headerY, headerX + this.headerWidth + GROUP_HEADER_PAD, headerY + this.headerHeight);
+ int[] part = getPartId(DrawData.WIDGET_WHOLE);
+ OS.DrawThemeBackground(hTheme, gc.handle, part[0], part[1], rect, null);
+ OS.RestoreDC(gc.handle, savedDC);
+ Rectangle headerArea = this.headerArea;
+ if (headerArea != null) {
+ headerArea.x = headerX;
+ headerArea.y = headerY;
+ headerArea.width = this.headerWidth;
+ headerArea.height = this.headerHeight;
+ }
+ Rectangle clientArea = this.clientArea;
+ if (clientArea != null) {
+ RECT contentRect = new RECT();
+ OS.GetThemeBackgroundContentRect(hTheme, gc.handle, part[0], part[1], rect, contentRect);
+ clientArea.x = contentRect.left;
+ clientArea.y = contentRect.top;
+ clientArea.width = contentRect.right - contentRect.left;
+ clientArea.height = contentRect.bottom - contentRect.top;
+ }
+ OS.CloseThemeData(hTheme);
+ }
+}
+
+int[] getPartId(int part) {
+ int state = this.state[part];
+ int iPartId = OS.BP_GROUPBOX, iStateId = OS.GBS_NORMAL;
+ if ((state & DrawData.DISABLED) != 0) iStateId = OS.GBS_DISABLED;
+ return new int[]{iPartId, iStateId};
+}
+
+int hit(Theme theme, Point position, Rectangle bounds) {
+ return bounds.contains(position) ? DrawData.WIDGET_WHOLE : DrawData.WIDGET_NOWHERE;
+}
+
+}
diff --git a/bundles/org.eclipse.swt/Eclipse SWT Theme/win32/org/eclipse/swt/internal/theme/ProgressBarDrawData.java b/bundles/org.eclipse.swt/Eclipse SWT Theme/win32/org/eclipse/swt/internal/theme/ProgressBarDrawData.java
new file mode 100644
index 0000000000..ff2b3e4c47
--- /dev/null
+++ b/bundles/org.eclipse.swt/Eclipse SWT Theme/win32/org/eclipse/swt/internal/theme/ProgressBarDrawData.java
@@ -0,0 +1,77 @@
+package org.eclipse.swt.internal.theme;
+
+import org.eclipse.swt.*;
+import org.eclipse.swt.graphics.*;
+import org.eclipse.swt.internal.win32.*;
+
+public class ProgressBarDrawData extends RangeDrawData {
+
+public ProgressBarDrawData() {
+ state = new int[1];
+}
+
+void draw(Theme theme, GC gc, Rectangle bounds) {
+ if (OS.COMCTL32_MAJOR >= 6 && OS.IsAppThemed ()) {
+ int hTheme = OS.OpenThemeData(0, getClassId());
+ RECT rect = new RECT ();
+ rect.left = bounds.x;
+ rect.right = rect.left + bounds.width;
+ rect.top = bounds.y;
+ rect.bottom = rect.top + bounds.height;
+ int[] buffer = new int[1];
+ OS.GetThemeInt(hTheme, 0, 0, OS.PROGRESSCHUNKSIZE, buffer);
+ int chunkSize = buffer[0];
+ OS.GetThemeInt(hTheme, 0, 0, OS.PROGRESSSPACESIZE, buffer);
+ int spaceSize = buffer[0];
+ RECT content = new RECT();
+ int[] part = getPartId(DrawData.WIDGET_WHOLE);
+ if ((style & SWT.VERTICAL) != 0) {
+ OS.GetThemeBackgroundContentRect(hTheme, gc.handle, part[0], part[1], rect, content);
+ OS.DrawThemeBackground(hTheme, gc.handle, part[0], part[1], rect, null);
+ int top = content.bottom - (((content.bottom - content.top) * (selection - minimum)) / (maximum - minimum));
+ content.top = content.bottom - chunkSize;
+ while (content.top >= top) {
+ OS.DrawThemeBackground(hTheme, gc.handle, OS.PP_CHUNKVERT, 0, content, null);
+ content.bottom -= chunkSize + spaceSize;
+ content.top = content.bottom - chunkSize;
+ }
+ if (selection != 0) {
+ OS.DrawThemeBackground(hTheme, gc.handle, OS.PP_CHUNKVERT, 0, content, null);
+ }
+ } else {
+ OS.GetThemeBackgroundContentRect(hTheme, gc.handle, part[0], part[1], rect, content);
+ OS.DrawThemeBackground(hTheme, gc.handle, part[0], part[1], rect, null);
+ int right = content.left + (((content.right - content.left) * (selection - minimum)) / (maximum - minimum));
+ content.right = content.left + chunkSize;
+ while (content.right <= right) {
+ OS.DrawThemeBackground(hTheme, gc.handle, OS.PP_CHUNK, 0, content, null);
+ content.left += chunkSize + spaceSize;
+ content.right = content.left + chunkSize;
+ }
+ if (selection != 0) {
+ OS.DrawThemeBackground(hTheme, gc.handle, OS.PP_CHUNK, 0, content, null);
+ }
+ }
+ OS.CloseThemeData (hTheme);
+ }
+}
+
+char[] getClassId() {
+ return PROGRESS;
+}
+
+int[] getPartId(int part) {
+ int iPartId = 0, iStateId = 0;
+ if ((style & SWT.VERTICAL) != 0) {
+ iPartId = OS.PP_BARVERT;
+ } else {
+ iPartId = OS.PP_BAR;
+ }
+ return new int[]{iPartId, iStateId};
+}
+
+int hit(Theme theme, Point position, Rectangle bounds) {
+ return bounds.contains(position) ? DrawData.WIDGET_WHOLE : DrawData.WIDGET_NOWHERE;
+}
+
+}
diff --git a/bundles/org.eclipse.swt/Eclipse SWT Theme/win32/org/eclipse/swt/internal/theme/RangeDrawData.java b/bundles/org.eclipse.swt/Eclipse SWT Theme/win32/org/eclipse/swt/internal/theme/RangeDrawData.java
new file mode 100644
index 0000000000..8581329112
--- /dev/null
+++ b/bundles/org.eclipse.swt/Eclipse SWT Theme/win32/org/eclipse/swt/internal/theme/RangeDrawData.java
@@ -0,0 +1,13 @@
+package org.eclipse.swt.internal.theme;
+
+import org.eclipse.swt.graphics.*;
+
+public class RangeDrawData extends DrawData {
+ public int selection;
+ public int minimum;
+ public int maximum;
+
+int getSelection(Point position, Rectangle bounds) {
+ return 0;
+}
+}
diff --git a/bundles/org.eclipse.swt/Eclipse SWT Theme/win32/org/eclipse/swt/internal/theme/ScaleDrawData.java b/bundles/org.eclipse.swt/Eclipse SWT Theme/win32/org/eclipse/swt/internal/theme/ScaleDrawData.java
new file mode 100644
index 0000000000..b668a778e8
--- /dev/null
+++ b/bundles/org.eclipse.swt/Eclipse SWT Theme/win32/org/eclipse/swt/internal/theme/ScaleDrawData.java
@@ -0,0 +1,87 @@
+package org.eclipse.swt.internal.theme;
+
+import org.eclipse.swt.*;
+import org.eclipse.swt.graphics.*;
+import org.eclipse.swt.internal.win32.*;
+
+public class ScaleDrawData extends RangeDrawData {
+ public int increment;
+ public int pageIncrement;
+
+ static final int TICS_MARGIN = 10;
+
+public ScaleDrawData() {
+ state = new int[4];
+}
+
+void draw(Theme theme, GC gc, Rectangle bounds) {
+ if (OS.COMCTL32_MAJOR >= 6 && OS.IsAppThemed ()) {
+ // TODO - drawScale not done
+ int style = this.style;
+ int minimum = this.minimum;
+ int maximum = this.maximum;
+ int selection = this.selection;
+ int pageIncrement = this.pageIncrement;
+ int hTheme = OS.OpenThemeData(0, getClassId());
+ RECT rect = new RECT ();
+ rect.left = bounds.x;
+ rect.right = rect.left + bounds.width;
+ rect.top = bounds.y;
+ rect.bottom = rect.top + bounds.height;
+ SIZE size = new SIZE();
+ if ((style & SWT.VERTICAL) != 0) {
+ OS.GetThemePartSize(hTheme, gc.handle, OS.TKP_TRACKVERT, 0, null, OS.TS_TRUE, size);
+ int trackWidth = size.cx - 1;
+ OS.GetThemePartSize(hTheme, gc.handle, OS.TKP_THUMBVERT, 0, null, OS.TS_TRUE, size);
+ int thumbWidth = size.cx, thumbHeight = size.cy;
+ OS.GetThemePartSize(hTheme, gc.handle, OS.TKP_TICS, 0, rect, OS.TS_TRUE, size);
+ int ticWidth = size.cx;
+ int marginX = (thumbWidth - trackWidth) / 2;
+ int marginY = marginX;
+ marginX += TICS_MARGIN;
+ rect.left += marginX;
+ rect.top += marginY;
+ rect.right = rect.left + trackWidth;
+ rect.bottom -= marginY;
+ int trackHeight = rect.bottom - rect.top;
+ OS.DrawThemeBackground(hTheme, gc.handle, OS.TKP_TRACKVERT, 0, rect, null);
+ rect.top += ((trackHeight - thumbHeight) * (selection - minimum)) / Math.max(1, maximum - minimum);
+ rect.left -= (thumbWidth - trackWidth) / 2;
+ rect.right = rect.left + thumbWidth;
+ rect.bottom = rect.top + thumbHeight;
+ OS.DrawThemeBackground(hTheme, gc.handle, OS.TKP_THUMBVERT, 0, rect, null);
+ rect.top = bounds.y + marginY + thumbHeight / 2;
+ rect.bottom = rect.top + 1;
+ for (int sel = minimum; sel <= maximum; sel += pageIncrement) {
+ rect.left = bounds.x + TICS_MARGIN / 2;
+ rect.right = rect.left + ticWidth;
+ if (sel != minimum && sel != maximum) rect.left++;
+ rect.top = bounds.y + marginY + thumbHeight / 2;
+ rect.top += ((trackHeight - thumbHeight) * (sel - minimum)) / Math.max(1, maximum - minimum);
+ rect.bottom = rect.top + 1;
+ //TODO - why tics are ot drawn
+ OS.DrawThemeBackground(hTheme, gc.handle, OS.TKP_TICSVERT, 1, rect, null);
+ gc.drawLine(rect.left, rect.top, rect.right, rect.top);
+ rect.left = bounds.x + TICS_MARGIN + thumbWidth + 1;
+ rect.right = rect.left + ticWidth;
+ if (sel != minimum && sel != maximum) rect.right--;
+ //TODO - why tics are ot drawn
+ OS.DrawThemeBackground(hTheme, gc.handle, OS.TKP_TICSVERT, 1, rect, null);
+ gc.drawLine(rect.left, rect.top, rect.right, rect.top);
+ }
+ } else {
+
+ }
+ OS.CloseThemeData (hTheme);
+ }
+}
+
+char[] getClassId() {
+ return TRACKBAR;
+}
+
+int hit(Theme theme, Point position, Rectangle bounds) {
+ return bounds.contains(position) ? DrawData.WIDGET_WHOLE : DrawData.WIDGET_NOWHERE;
+}
+
+}
diff --git a/bundles/org.eclipse.swt/Eclipse SWT Theme/win32/org/eclipse/swt/internal/theme/ScrollBarDrawData.java b/bundles/org.eclipse.swt/Eclipse SWT Theme/win32/org/eclipse/swt/internal/theme/ScrollBarDrawData.java
new file mode 100644
index 0000000000..8acfa5015f
--- /dev/null
+++ b/bundles/org.eclipse.swt/Eclipse SWT Theme/win32/org/eclipse/swt/internal/theme/ScrollBarDrawData.java
@@ -0,0 +1,278 @@
+package org.eclipse.swt.internal.theme;
+
+import org.eclipse.swt.*;
+import org.eclipse.swt.graphics.*;
+import org.eclipse.swt.internal.win32.*;
+
+public class ScrollBarDrawData extends RangeDrawData {
+ public int thumb;
+ public int increment;
+ public int pageIncrement;
+
+public ScrollBarDrawData() {
+ state = new int[6];
+}
+
+void draw(Theme theme, GC gc, Rectangle bounds) {
+ if (OS.COMCTL32_MAJOR >= 6 && OS.IsAppThemed ()) {
+ int hTheme = OS.OpenThemeData(0, getClassId());
+ RECT rect = new RECT ();
+ if ((style & SWT.VERTICAL) != 0) {
+ int width = OS.GetThemeSysSize(hTheme, OS.SM_CXVSCROLL);
+ rect.left = bounds.x;
+ rect.right = rect.left + bounds.width;
+ rect.top = bounds.y;
+ rect.bottom = rect.top + width;
+ int[] part = getPartId(DrawData.SCROLLBAR_UP_ARROW);
+ OS.DrawThemeBackground (hTheme, gc.handle, part[0], part[1], rect, null);
+ rect.bottom = bounds.y + bounds.height;
+ rect.top = rect.bottom - width;
+ part = getPartId(DrawData.SCROLLBAR_DOWN_ARROW);
+ OS.DrawThemeBackground (hTheme, gc.handle, part[0], part[1], rect, null);
+ int totalWidth = bounds.height - 2 * width;
+ int thumbWidth = Math.max(width / 2, (totalWidth * thumb) / Math.max(1, (maximum - minimum)));//BAD
+ int thumbPos = bounds.y + width + Math.max(0, (totalWidth * selection) / Math.max(1, (maximum - minimum)));
+ rect.top = bounds.y + width;
+ rect.bottom = thumbPos;
+ part = getPartId(DrawData.SCROLLBAR_UP_TRACK);
+ OS.DrawThemeBackground (hTheme, gc.handle, part[0], part[1], rect, null);
+ rect.top = rect.bottom;
+ rect.bottom = rect.top + thumbWidth;
+ part = getPartId(DrawData.SCROLLBAR_THUMB);
+ OS.DrawThemeBackground (hTheme, gc.handle, part[0], part[1], rect, null);
+ OS.DrawThemeBackground (hTheme, gc.handle, OS.SBP_GRIPPERVERT, part[1], rect, null);
+ rect.top = rect.bottom;
+ rect.bottom = bounds.y + bounds.height - width;
+ part = getPartId(DrawData.SCROLLBAR_DOWN_TRACK);
+ OS.DrawThemeBackground (hTheme, gc.handle, part[0], part[1], rect, null);
+ } else {
+ //TODO - why SM_CXHSCROLL = 0?
+ int height = OS.GetThemeSysSize(hTheme, OS.SM_CXVSCROLL);
+ rect.top = bounds.y;
+ rect.bottom = rect.top + bounds.height;
+ rect.left = bounds.x;
+ rect.right = rect.left + height;
+ int[] part = getPartId(DrawData.SCROLLBAR_LEFT_ARROW);
+ OS.DrawThemeBackground (hTheme, gc.handle, part[0], part[1], rect, null);
+ rect.right = bounds.x + bounds.width;
+ rect.left = rect.right - height;
+ part = getPartId(DrawData.SCROLLBAR_RIGHT_ARROW);
+ OS.DrawThemeBackground (hTheme, gc.handle, part[0], part[1], rect, null);
+ int totalWidth = bounds.width - 2 * height;
+ int thumbWidth = Math.max(height / 2, (totalWidth * thumb) / (maximum - minimum));//BAD
+ int thumbPos = bounds.x + height + Math.max(0, (totalWidth * selection) / Math.max(1, (maximum - minimum)));
+ rect.left = bounds.x + height;
+ rect.right = thumbPos;
+ part = getPartId(DrawData.SCROLLBAR_UP_TRACK);
+ OS.DrawThemeBackground (hTheme, gc.handle, part[0], part[1], rect, null);
+ rect.left = rect.right;
+ rect.right = rect.left + thumbWidth;
+ part = getPartId(DrawData.SCROLLBAR_THUMB);
+ OS.DrawThemeBackground (hTheme, gc.handle, part[0], part[1], rect, null);
+ OS.DrawThemeBackground (hTheme, gc.handle, OS.SBP_GRIPPERHORZ, part[1], rect, null);
+ rect.left = rect.right;
+ rect.right = bounds.x + bounds.width - height;
+ part = getPartId(DrawData.SCROLLBAR_DOWN_TRACK);
+ OS.DrawThemeBackground (hTheme, gc.handle, part[0], part[1], rect, null);
+ }
+ OS.CloseThemeData (hTheme);
+ }
+}
+
+char[] getClassId() {
+ return SCROLLBAR;
+}
+
+int[] getPartId(int part) {
+ int iPartId = 0, iStateId = 0;
+ int state = this.state[part];
+ switch (part) {
+ case DrawData.SCROLLBAR_UP_ARROW:
+ iPartId = OS.SBP_ARROWBTN;
+ if ((style & SWT.VERTICAL) != 0) {
+ iStateId = OS.ABS_UPNORMAL;
+ if ((state & DrawData.HOT) != 0) iStateId = OS.ABS_UPHOT;
+ if ((state & DrawData.PRESSED) != 0) iStateId = OS.ABS_UPPRESSED;
+ if ((state & DrawData.DISABLED) != 0) iStateId = OS.ABS_UPDISABLED;
+ } else {
+ iStateId = OS.ABS_LEFTNORMAL;
+ if ((state & DrawData.HOT) != 0) iStateId = OS.ABS_LEFTHOT;
+ if ((state & DrawData.PRESSED) != 0) iStateId = OS.ABS_LEFTPRESSED;
+ if ((state & DrawData.DISABLED) != 0) iStateId = OS.ABS_LEFTDISABLED;
+ }
+ break;
+ case DrawData.SCROLLBAR_DOWN_ARROW:
+ iPartId = OS.SBP_ARROWBTN;
+ if ((style & SWT.VERTICAL) != 0) {
+ iStateId = OS.ABS_DOWNNORMAL;
+ if ((state & DrawData.HOT) != 0) iStateId = OS.ABS_DOWNHOT;
+ if ((state & DrawData.PRESSED) != 0) iStateId = OS.ABS_DOWNPRESSED;
+ if ((state & DrawData.DISABLED) != 0) iStateId = OS.ABS_DOWNDISABLED;
+ } else {
+ iStateId = OS.ABS_RIGHTNORMAL;
+ if ((state & DrawData.HOT) != 0) iStateId = OS.ABS_RIGHTHOT;
+ if ((state & DrawData.PRESSED) != 0) iStateId = OS.ABS_RIGHTPRESSED;
+ if ((state & DrawData.DISABLED) != 0) iStateId = OS.ABS_RIGHTDISABLED;
+ }
+ break;
+ case DrawData.WIDGET_WHOLE:
+ case DrawData.SCROLLBAR_THUMB:
+ if ((style & SWT.VERTICAL) != 0) {
+ iPartId = OS.SBP_THUMBBTNVERT;
+ } else {
+ iPartId = OS.SBP_THUMBBTNHORZ;
+ }
+ break;
+ case DrawData.SCROLLBAR_UP_TRACK:
+ if ((style & SWT.VERTICAL) != 0) {
+ iPartId = OS.SBP_UPPERTRACKVERT;
+ } else {
+ iPartId = OS.SBP_UPPERTRACKHORZ;
+ }
+ break;
+ case DrawData.SCROLLBAR_DOWN_TRACK:
+ if ((style & SWT.VERTICAL) != 0) {
+ iPartId = OS.SBP_LOWERTRACKVERT;
+ } else {
+ iPartId = OS.SBP_LOWERTRACKHORZ;
+ }
+ break;
+ }
+ if (part != DrawData.SCROLLBAR_DOWN_ARROW && part != DrawData.SCROLLBAR_UP_ARROW) {
+ iStateId = OS.SCRBS_NORMAL;
+ if ((state & DrawData.HOT) != 0) iStateId = OS.SCRBS_HOT;
+ if ((state & DrawData.PRESSED) != 0) iStateId = OS.SCRBS_PRESSED;
+ if ((state & DrawData.DISABLED) != 0) iStateId = OS.SCRBS_DISABLED;
+ }
+ return new int[]{iPartId, iStateId};
+}
+
+Rectangle getBounds(int part, Rectangle bounds) {
+ if (OS.COMCTL32_MAJOR >= 6 && OS.IsAppThemed ()) {
+ int hTheme = OS.OpenThemeData(0, getClassId());
+ if ((style & SWT.VERTICAL) != 0) {
+ int width = OS.GetThemeSysSize(hTheme, OS.SM_CXVSCROLL);
+ int totalWidth = bounds.height - 2 * width;
+ int thumbWidth = Math.max(width / 2, (totalWidth * thumb) / Math.max(1, (maximum - minimum)));//BAD
+ int thumbPos = bounds.y + width + Math.max(0, (totalWidth * selection) / Math.max(1, (maximum - minimum)));
+ switch (part) {
+ case DrawData.SCROLLBAR_DOWN_ARROW:
+ return new Rectangle(bounds.x, bounds.y + bounds.height - width, bounds.width, width);
+ case DrawData.SCROLLBAR_UP_ARROW:
+ return new Rectangle(bounds.x, bounds.y, bounds.width, width);
+ case DrawData.SCROLLBAR_UP_TRACK:
+ return new Rectangle(bounds.x, bounds.y + width, bounds.width, thumbPos - bounds.y - width);
+ case DrawData.SCROLLBAR_THUMB:
+ return new Rectangle(bounds.x, thumbPos, bounds.width, thumbWidth);
+ case DrawData.SCROLLBAR_DOWN_TRACK:
+ return new Rectangle(bounds.x, thumbPos + thumbWidth, bounds.width, bounds.y + bounds.height - width - thumbPos - thumbWidth);
+ }
+ } else {
+
+ }
+ OS.CloseThemeData (hTheme);
+ }
+ return super.getBounds(part, bounds);
+}
+
+int getSelection(Point position, Rectangle bounds) {
+ if (OS.COMCTL32_MAJOR >= 6 && OS.IsAppThemed ()) {
+ int hTheme = OS.OpenThemeData(0, getClassId());
+ if ((style & SWT.VERTICAL) != 0) {
+ int width = OS.GetThemeSysSize(hTheme, OS.SM_CXVSCROLL);
+ int totalWidth = bounds.height - 2 * width;
+ int thumbPos = bounds.y + width + Math.max(0, (totalWidth * selection) / Math.max(1, (maximum - minimum)));
+ thumbPos += position.y;
+ int selection = ((thumbPos - bounds.y - width) * (maximum - minimum)) / totalWidth;
+ return Math.max(0, Math.min(selection, maximum - thumb));
+ } else {
+
+ }
+ OS.CloseThemeData (hTheme);
+ }
+ return 0;
+}
+
+int hit(Theme theme, Point position, Rectangle bounds) {
+ if (!(OS.COMCTL32_MAJOR >= 6 && OS.IsAppThemed ())) return -1;
+ int hTheme = OS.OpenThemeData(0, getClassId());
+ //TODO - should we take a GC?
+ int hDC = 0;
+ RECT rect = new RECT ();
+ POINT pt = new POINT();
+ pt.x = position.x;
+ pt.y = position.y;
+ short[] code = new short[1];
+ try {
+ if ((style & SWT.VERTICAL) != 0) {
+ int width = OS.GetThemeSysSize(hTheme, OS.SM_CXVSCROLL);
+ rect.left = bounds.x;
+ rect.right = rect.left + bounds.width;
+ rect.top = bounds.y;
+ rect.bottom = rect.top + width;
+ int[] part = getPartId(DrawData.SCROLLBAR_UP_ARROW);
+ OS.HitTestThemeBackground(hTheme, hDC, part[0], part[1], 0, rect, 0, pt, code);
+ if (code[0] != OS.HTNOWHERE) return DrawData.SCROLLBAR_UP_ARROW;
+ rect.bottom = bounds.y + bounds.height;
+ rect.top = rect.bottom - width;
+ part = getPartId(DrawData.SCROLLBAR_DOWN_ARROW);
+ OS.HitTestThemeBackground(hTheme, hDC, part[0], part[1], 0, rect, 0, pt, code);
+ if (code[0] != OS.HTNOWHERE) return DrawData.SCROLLBAR_DOWN_ARROW;
+ int totalWidth = bounds.height - 2 * width;
+ int thumbWidth = Math.max(width / 2, (totalWidth * thumb) / Math.max(1, (maximum - minimum)));//BAD
+ int thumbPos = bounds.y + width + Math.max(0, (totalWidth * selection) / Math.max(1, (maximum - minimum)));
+ rect.top = bounds.y + width;
+ rect.bottom = thumbPos;
+ part = getPartId(DrawData.SCROLLBAR_THUMB);
+ OS.HitTestThemeBackground(hTheme, hDC, part[0], part[1], 0, rect, 0, pt, code);
+ if (code[0] != OS.HTNOWHERE) return DrawData.SCROLLBAR_UP_TRACK;
+ rect.top = rect.bottom;
+ rect.bottom = rect.top + thumbWidth;
+ part = getPartId(DrawData.SCROLLBAR_UP_TRACK);
+ OS.HitTestThemeBackground(hTheme, hDC, part[0], part[1], 0, rect, 0, pt, code);
+ if (code[0] != OS.HTNOWHERE) return DrawData.SCROLLBAR_THUMB;
+ rect.top = rect.bottom;
+ rect.bottom = bounds.y + bounds.height - width;
+ part = getPartId(DrawData.SCROLLBAR_DOWN_TRACK);
+ OS.HitTestThemeBackground(hTheme, hDC, part[0], part[1], 0, rect, 0, pt, code);
+ if (code[0] != OS.HTNOWHERE) return DrawData.SCROLLBAR_DOWN_TRACK;
+ } else {
+ int height = OS.GetThemeSysSize(hTheme, OS.SM_CXVSCROLL);//BAD - why SM_CXHSCROLL = 0?
+ rect.top = bounds.y;
+ rect.bottom = rect.top + bounds.height;
+ rect.left = bounds.x;
+ rect.right = rect.left + height;
+ int[] part = getPartId(DrawData.SCROLLBAR_LEFT_ARROW);
+ OS.HitTestThemeBackground(hTheme, hDC, part[0], part[1], 0, rect, 0, pt, code);
+ if (code[0] != OS.HTNOWHERE) return DrawData.SCROLLBAR_UP_ARROW;
+ rect.right = bounds.x + bounds.width;
+ rect.left = rect.right - height;
+ part = getPartId(DrawData.SCROLLBAR_RIGHT_ARROW);
+ OS.HitTestThemeBackground(hTheme, hDC, part[0], part[1], 0, rect, 0, pt, code);
+ if (code[0] != OS.HTNOWHERE) return DrawData.SCROLLBAR_DOWN_ARROW;
+ int totalWidth = bounds.width - 2 * height;
+ int thumbWidth = Math.max(height / 2, (totalWidth * thumb) / (maximum - minimum));//BAD
+ int thumbPos = bounds.x + height + Math.max(0, (totalWidth * selection) / Math.max(1, (maximum - minimum)));
+ rect.left = bounds.x + height;
+ rect.right = thumbPos;
+ part = getPartId(DrawData.SCROLLBAR_LEFT_TRACK);
+ OS.HitTestThemeBackground(hTheme, hDC, part[0], part[1], 0, rect, 0, pt, code);
+ if (code[0] != OS.HTNOWHERE) return DrawData.SCROLLBAR_UP_TRACK;
+ rect.left = rect.right;
+ rect.right = rect.left + thumbWidth;
+ part = getPartId(DrawData.SCROLLBAR_THUMB);
+ OS.HitTestThemeBackground(hTheme, hDC, part[0], part[1], 0, rect, 0, pt, code);
+ if (code[0] != OS.HTNOWHERE) return DrawData.SCROLLBAR_THUMB;
+ rect.left = rect.right;
+ rect.right = bounds.x + bounds.width - height;
+ part = getPartId(DrawData.SCROLLBAR_RIGHT_TRACK);
+ OS.HitTestThemeBackground(hTheme, hDC, part[0], part[1], 0, rect, 0, pt, code);
+ if (code[0] != OS.HTNOWHERE) return DrawData.SCROLLBAR_DOWN_TRACK;
+ }
+ } finally {
+ OS.CloseThemeData (hTheme);
+ }
+ return DrawData.WIDGET_NOWHERE;
+}
+
+}
diff --git a/bundles/org.eclipse.swt/Eclipse SWT Theme/win32/org/eclipse/swt/internal/theme/TabFolderDrawData.java b/bundles/org.eclipse.swt/Eclipse SWT Theme/win32/org/eclipse/swt/internal/theme/TabFolderDrawData.java
new file mode 100644
index 0000000000..67fe640ec1
--- /dev/null
+++ b/bundles/org.eclipse.swt/Eclipse SWT Theme/win32/org/eclipse/swt/internal/theme/TabFolderDrawData.java
@@ -0,0 +1,71 @@
+package org.eclipse.swt.internal.theme;
+
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.graphics.*;
+import org.eclipse.swt.internal.win32.*;
+
+public class TabFolderDrawData extends DrawData {
+ public int tabsWidth;
+ public int tabsHeight;
+ public Rectangle tabsArea;
+ public int selectedX;
+ public int selectedWidth;
+ public int spacing;
+
+public TabFolderDrawData() {
+ state = new int[1];
+ if (SWT.getPlatform().equals("gtk")) {
+ spacing = -2;
+ }
+}
+
+void draw(Theme theme, GC gc, Rectangle bounds) {
+ if (OS.COMCTL32_MAJOR >= 6 && OS.IsAppThemed ()) {
+ int hTheme = OS.OpenThemeData(0, getClassId());
+ RECT rect = new RECT ();
+ rect.left = bounds.x;
+ rect.right = bounds.x + bounds.width;
+ rect.top = bounds.y;
+ if ((style & SWT.BOTTOM) != 0) {
+ rect.bottom = bounds.y + bounds.height - tabsHeight;
+ } else {
+ rect.top += tabsHeight;
+ rect.bottom = bounds.y + bounds.height;
+ }
+ int[] part = getPartId(DrawData.WIDGET_WHOLE);
+ OS.DrawThemeBackground (hTheme, gc.handle, part[0], part[1], rect, null);
+ OS.CloseThemeData(hTheme);
+ if (tabsArea != null) {
+ tabsArea.x = bounds.x;
+ tabsArea.y = bounds.y;
+ tabsArea.width = bounds.width;
+ tabsArea.height = tabsHeight;
+ if ((style & SWT.BOTTOM) != 0) {
+ tabsArea.y += bounds.height - tabsHeight;
+ }
+ }
+ }
+}
+
+char[] getClassId() {
+ return TAB;
+}
+
+int[] getPartId(int part) {
+ int state = this.state[part];
+ int iPartId = OS.TABP_PANE, iStateId = OS.TIS_NORMAL;
+ if ((state & DrawData.DISABLED) != 0) {
+ iStateId = OS.TIS_DISABLED;
+ } else {
+ if ((state & DrawData.HOT) != 0) iStateId = OS.TIS_HOT;
+ if ((state & DrawData.SELECTED) != 0) iStateId = OS.TIS_SELECTED;
+ }
+ return new int[]{iPartId, iStateId};
+}
+
+int hit(Theme theme, Point position, Rectangle bounds) {
+ if (!bounds.contains(position)) return DrawData.WIDGET_NOWHERE;
+ return DrawData.WIDGET_WHOLE;
+}
+
+}
diff --git a/bundles/org.eclipse.swt/Eclipse SWT Theme/win32/org/eclipse/swt/internal/theme/TabItemDrawData.java b/bundles/org.eclipse.swt/Eclipse SWT Theme/win32/org/eclipse/swt/internal/theme/TabItemDrawData.java
new file mode 100644
index 0000000000..0d83c7c5a4
--- /dev/null
+++ b/bundles/org.eclipse.swt/Eclipse SWT Theme/win32/org/eclipse/swt/internal/theme/TabItemDrawData.java
@@ -0,0 +1,119 @@
+package org.eclipse.swt.internal.theme;
+
+import org.eclipse.swt.*;
+import org.eclipse.swt.graphics.*;
+import org.eclipse.swt.internal.win32.*;
+
+public class TabItemDrawData extends DrawData {
+
+ public TabFolderDrawData parent;
+ public int position;
+
+ static final int TABITEM_INSET = 2;
+ static final int TABITEM_INSET2 = 6;
+
+public TabItemDrawData() {
+ state = new int[1];
+}
+
+Rectangle computeTrim(Theme theme, GC gc) {
+ if (OS.COMCTL32_MAJOR >= 6 && OS.IsAppThemed ()) {
+ int hTheme = OS.OpenThemeData(0, getClassId());
+ int x = clientArea.x, y = clientArea.y, width = clientArea.width, height = clientArea.height;
+ if ((style & SWT.LEFT) != 0) {
+ x -= TABITEM_INSET;
+ width += TABITEM_INSET;
+ }
+ y -= TABITEM_INSET;
+ height += TABITEM_INSET;
+ RECT rect = new RECT ();
+ rect.left = x;
+ rect.right = x + width;
+ rect.top = y;
+ rect.bottom = y + height;
+ RECT extent = new RECT ();
+ int[] part = getPartId(DrawData.WIDGET_WHOLE);
+ OS.GetThemeBackgroundExtent(hTheme, gc.handle, part[0], part[1], rect, extent);
+ extent.left -= TABITEM_INSET2;
+ extent.top -= TABITEM_INSET2;
+ extent.right += TABITEM_INSET2;
+ OS.CloseThemeData(hTheme);
+ return new Rectangle(extent.left, extent.top, extent.right - extent.left, extent.bottom - extent.top);
+ }
+ return new Rectangle(0, 0, 0, 0);
+}
+
+void draw(Theme theme, GC gc, Rectangle bounds) {
+ if (OS.COMCTL32_MAJOR >= 6 && OS.IsAppThemed ()) {
+ int state = this.state[DrawData.WIDGET_WHOLE];
+ int hTheme = OS.OpenThemeData(0, getClassId());
+ int x = bounds.x, y = bounds.y, width = bounds.width, height = bounds.height;
+ if ((position & SWT.LEFT) != 0) {
+ x += TABITEM_INSET;
+ width -= TABITEM_INSET;
+ }
+ y += TABITEM_INSET;
+ height -= TABITEM_INSET;
+ if ((state & DrawData.SELECTED) != 0) {
+ //TODO - draws outside of bounds
+ x -= TABITEM_INSET;
+ y -= TABITEM_INSET;
+ width += TABITEM_INSET * 2;
+ height += TABITEM_INSET * 2;
+ }
+ RECT rect = new RECT ();
+ rect.left = x;
+ rect.right = x + width;
+ rect.top = y;
+ rect.bottom = y + height;
+ int[] part = getPartId(DrawData.WIDGET_WHOLE);
+ OS.DrawThemeBackground (hTheme, gc.handle, part[0], part[1], rect, null);
+ OS.CloseThemeData(hTheme);
+ Rectangle clientArea = this.clientArea;
+ if (clientArea != null) {
+ RECT contentRect = new RECT();
+ OS.GetThemeBackgroundContentRect(hTheme, gc.handle, part[0], part[1], rect, contentRect);
+ clientArea.x = contentRect.left;
+ clientArea.y = contentRect.top;
+ clientArea.width = contentRect.right - contentRect.left;
+ clientArea.height = contentRect.bottom - contentRect.top;
+ }
+ }
+}
+
+char[] getClassId() {
+ return TAB;
+}
+
+int[] getPartId(int part) {
+ int state = this.state[part];
+ int iPartId = OS.TABP_TABITEM, iStateId = OS.TIS_NORMAL;
+ if ((style & SWT.LEFT) != 0 && (style & SWT.RIGHT) != 0) {
+ iPartId = OS.TABP_TABITEMLEFTEDGE;
+ } else if ((style & SWT.LEFT) != 0) {
+ iPartId = OS.TABP_TABITEMLEFTEDGE;
+ } else if ((style & SWT.RIGHT) != 0) {
+ }
+ if ((state & DrawData.HOT) != 0) iStateId = OS.TIS_HOT;
+ if ((state & DrawData.FOCUSED) != 0) iStateId = OS.TIS_FOCUSED;
+ if ((state & DrawData.SELECTED) != 0) iStateId = OS.TIS_SELECTED;
+ if ((state & DrawData.DISABLED) != 0) iStateId = OS.TIS_DISABLED;
+ return new int[]{iPartId, iStateId};
+}
+
+int hit(Theme theme, Point position, Rectangle bounds) {
+ if (!bounds.contains(position)) return DrawData.WIDGET_NOWHERE;
+ int style = this.style;
+ int x = bounds.x, y = bounds.y, width = bounds.width, height = bounds.height;
+ if ((style & SWT.LEFT) != 0) {
+ x += TABITEM_INSET;
+ width -= TABITEM_INSET;
+ }
+ y += TABITEM_INSET;
+ height -= TABITEM_INSET;
+ Rectangle content = new Rectangle(x, y, width, height);
+ if (!content.contains(position)) return DrawData.WIDGET_NOWHERE;
+ return DrawData.WIDGET_WHOLE;
+}
+
+}
diff --git a/bundles/org.eclipse.swt/Eclipse SWT Theme/win32/org/eclipse/swt/internal/theme/Theme.java b/bundles/org.eclipse.swt/Eclipse SWT Theme/win32/org/eclipse/swt/internal/theme/Theme.java
new file mode 100644
index 0000000000..f69d522fdc
--- /dev/null
+++ b/bundles/org.eclipse.swt/Eclipse SWT Theme/win32/org/eclipse/swt/internal/theme/Theme.java
@@ -0,0 +1,103 @@
+package org.eclipse.swt.internal.theme;
+
+import org.eclipse.swt.*;
+import org.eclipse.swt.graphics.*;
+
+public class Theme {
+
+ Device device;
+
+public Theme(Device device) {
+ this.device = device;
+}
+
+public Rectangle computeTrim(GC gc, DrawData data) {
+ checkTheme();
+ if (gc == null) SWT.error(SWT.ERROR_NULL_ARGUMENT);
+ if (data == null) SWT.error(SWT.ERROR_NULL_ARGUMENT);
+ if (gc.isDisposed()) SWT.error(SWT.ERROR_INVALID_ARGUMENT);
+ return data.computeTrim(this, gc);
+}
+
+void checkTheme() {
+ if (isDisposed()) SWT.error(SWT.ERROR_GRAPHIC_DISPOSED);
+}
+
+public void dispose () {
+ device = null;
+}
+
+public void drawBackground(GC gc, Rectangle bounds, DrawData data) {
+ checkTheme();
+ if (gc == null) SWT.error(SWT.ERROR_NULL_ARGUMENT);
+ if (bounds == null) SWT.error(SWT.ERROR_NULL_ARGUMENT);
+ if (data == null) SWT.error(SWT.ERROR_NULL_ARGUMENT);
+ if (gc.isDisposed()) SWT.error(SWT.ERROR_INVALID_ARGUMENT);
+ data.draw(this, gc, bounds);
+}
+
+public void drawFocus(GC gc, Rectangle bounds, DrawData data) {
+ checkTheme();
+ if (gc == null) SWT.error(SWT.ERROR_NULL_ARGUMENT);
+ if (bounds == null) SWT.error(SWT.ERROR_NULL_ARGUMENT);
+ if (data == null) SWT.error(SWT.ERROR_NULL_ARGUMENT);
+ if (gc.isDisposed()) SWT.error(SWT.ERROR_INVALID_ARGUMENT);
+ gc.drawFocus(bounds.x, bounds.y, bounds.width, bounds.height);
+}
+
+public void drawImage(GC gc, Rectangle bounds, DrawData data, Image image, int flags) {
+ checkTheme();
+ if (gc == null) SWT.error(SWT.ERROR_NULL_ARGUMENT);
+ if (bounds == null) SWT.error(SWT.ERROR_NULL_ARGUMENT);
+ if (data == null) SWT.error(SWT.ERROR_NULL_ARGUMENT);
+ if (image == null) SWT.error(SWT.ERROR_NULL_ARGUMENT);
+ if (gc.isDisposed()) SWT.error(SWT.ERROR_INVALID_ARGUMENT);
+ data.drawImage(this, image, gc, bounds);
+}
+
+public void drawText(GC gc, Rectangle bounds, DrawData data, String text, int flags) {
+ checkTheme();
+ if (gc == null) SWT.error(SWT.ERROR_NULL_ARGUMENT);
+ if (bounds == null) SWT.error(SWT.ERROR_NULL_ARGUMENT);
+ if (data == null) SWT.error(SWT.ERROR_NULL_ARGUMENT);
+ if (text == null) SWT.error(SWT.ERROR_NULL_ARGUMENT);
+ if (gc.isDisposed()) SWT.error(SWT.ERROR_INVALID_ARGUMENT);
+ data.drawText(this, text, flags, gc, bounds);
+}
+
+public Rectangle getBounds(int part, Rectangle bounds, DrawData data) {
+ checkTheme();
+ if (bounds == null) SWT.error(SWT.ERROR_NULL_ARGUMENT);
+ if (data == null) SWT.error(SWT.ERROR_NULL_ARGUMENT);
+ return data.getBounds(part, bounds);
+}
+
+public int getSelection(Point offset, Rectangle bounds, RangeDrawData data) {
+ checkTheme();
+ if (offset == null) SWT.error(SWT.ERROR_NULL_ARGUMENT);
+ if (bounds == null) SWT.error(SWT.ERROR_NULL_ARGUMENT);
+ if (data == null) SWT.error(SWT.ERROR_NULL_ARGUMENT);
+ return data.getSelection(offset, bounds);
+}
+
+public int hitBackground(Point position, Rectangle bounds, DrawData data) {
+ checkTheme();
+ if (position == null) SWT.error(SWT.ERROR_NULL_ARGUMENT);
+ if (bounds == null) SWT.error(SWT.ERROR_NULL_ARGUMENT);
+ if (data == null) SWT.error(SWT.ERROR_NULL_ARGUMENT);
+ return data.hit(this, position, bounds);
+}
+
+public boolean isDisposed() {
+ return device == null;
+}
+
+public Rectangle measureText(GC gc, Rectangle bounds, DrawData data, String text, int flags) {
+ checkTheme();
+ if (gc == null) SWT.error(SWT.ERROR_NULL_ARGUMENT);
+ if (data == null) SWT.error(SWT.ERROR_NULL_ARGUMENT);
+ if (text == null) SWT.error(SWT.ERROR_NULL_ARGUMENT);
+ if (gc.isDisposed()) SWT.error(SWT.ERROR_INVALID_ARGUMENT);
+ return data.measureText(this, text, flags, gc, bounds);
+}
+}
diff --git a/bundles/org.eclipse.swt/Eclipse SWT Theme/win32/org/eclipse/swt/internal/theme/ToolBarDrawData.java b/bundles/org.eclipse.swt/Eclipse SWT Theme/win32/org/eclipse/swt/internal/theme/ToolBarDrawData.java
new file mode 100644
index 0000000000..11cce33aab
--- /dev/null
+++ b/bundles/org.eclipse.swt/Eclipse SWT Theme/win32/org/eclipse/swt/internal/theme/ToolBarDrawData.java
@@ -0,0 +1,23 @@
+package org.eclipse.swt.internal.theme;
+
+import org.eclipse.swt.graphics.*;
+
+public class ToolBarDrawData extends DrawData {
+
+public ToolBarDrawData() {
+ state = new int[1];
+}
+
+void draw(Theme theme, GC gc, Rectangle bounds) {
+}
+
+char[] getClassId() {
+ return TOOLBAR;
+}
+
+int hit(Theme theme, Point position, Rectangle bounds) {
+ if (!bounds.contains(position)) return DrawData.WIDGET_NOWHERE;
+ return DrawData.WIDGET_WHOLE;
+}
+
+}
diff --git a/bundles/org.eclipse.swt/Eclipse SWT Theme/win32/org/eclipse/swt/internal/theme/ToolItemDrawData.java b/bundles/org.eclipse.swt/Eclipse SWT Theme/win32/org/eclipse/swt/internal/theme/ToolItemDrawData.java
new file mode 100644
index 0000000000..df555a9d42
--- /dev/null
+++ b/bundles/org.eclipse.swt/Eclipse SWT Theme/win32/org/eclipse/swt/internal/theme/ToolItemDrawData.java
@@ -0,0 +1,158 @@
+package org.eclipse.swt.internal.theme;
+
+import org.eclipse.swt.*;
+import org.eclipse.swt.graphics.*;
+import org.eclipse.swt.internal.win32.*;
+
+public class ToolItemDrawData extends DrawData {
+
+ public ToolBarDrawData parent;
+
+ static final int INSET = 1;
+
+public ToolItemDrawData() {
+ state = new int[2];
+}
+
+Rectangle computeTrim(Theme theme, GC gc) {
+ if (OS.COMCTL32_MAJOR >= 6 && OS.IsAppThemed ()) {
+ int hTheme = OS.OpenThemeData(0, getClassId());
+ RECT rect = new RECT ();
+ rect.left = clientArea.x;
+ rect.right = clientArea.x + clientArea.width;
+ rect.top = clientArea.y;
+ rect.bottom = clientArea.y + clientArea.height;
+ RECT extent = new RECT ();
+ int[] part = getPartId(DrawData.WIDGET_WHOLE);
+ OS.GetThemeBackgroundExtent(hTheme, gc.handle, part[0], part[1], rect, extent);
+ OS.CloseThemeData(hTheme);
+ if ((style & SWT.DROP_DOWN) != 0) {
+ SIZE size = new SIZE();
+ part = getPartId(DrawData.TOOLITEM_ARROW);
+ OS.GetThemePartSize(hTheme, 0, part[0], part[1], null, OS.TS_TRUE, size);
+ extent.right = Math.max(extent.left, extent.right + size.cx);
+ } else {
+ extent.left -= INSET;
+ extent.top -= INSET;
+ extent.right += INSET;
+ extent.bottom += INSET;
+ }
+ return new Rectangle(extent.left, extent.top, extent.right - extent.left, extent.bottom - extent.top);
+ }
+ return new Rectangle(0, 0, 0, 0);
+}
+
+void draw(Theme theme, GC gc, Rectangle bounds) {
+ if (OS.COMCTL32_MAJOR >= 6 && OS.IsAppThemed ()) {
+ int hTheme = OS.OpenThemeData(0, getClassId());
+ RECT rect = new RECT ();
+ rect.left = bounds.x;
+ rect.right = bounds.x + bounds.width;
+ rect.top = bounds.y;
+ rect.bottom = bounds.y + bounds.height;
+ SIZE size = null;
+ int[] dropPart = null;
+ if ((style & SWT.DROP_DOWN) != 0) {
+ size = new SIZE();
+ dropPart = getPartId(DrawData.TOOLITEM_ARROW);
+ OS.GetThemePartSize(hTheme, gc.handle, dropPart[0], dropPart[1], rect, OS.TS_TRUE, size);
+ rect.right -= size.cx;
+ if (rect.right < rect.left) rect.right = rect.left;
+ }
+ int[] part = getPartId(DrawData.WIDGET_WHOLE);
+ OS.DrawThemeBackground(hTheme, gc.handle, part[0], part[1], rect, null);
+ Rectangle clientArea = this.clientArea;
+ if (clientArea != null) {
+ RECT contentRect = new RECT();
+ OS.GetThemeBackgroundContentRect(hTheme, gc.handle, part[0], part[1], rect, contentRect);
+ clientArea.x = contentRect.left;
+ clientArea.y = contentRect.top;
+ clientArea.width = contentRect.right - contentRect.left;
+ clientArea.height = contentRect.bottom - contentRect.top;
+ }
+ if ((style & SWT.DROP_DOWN) != 0) {
+ rect.left = rect.right;
+ rect.right = rect.left + size.cx;
+ OS.DrawThemeBackground(hTheme, gc.handle, dropPart[0], dropPart[1], rect, null);
+ }
+ OS.CloseThemeData(hTheme);
+ }
+}
+
+char[] getClassId() {
+ return TOOLBAR;
+}
+
+int[] getPartId(int part) {
+ int state = this.state[part];
+ int iPartId = 0, iStateId = 0;
+ switch (part) {
+ case DrawData.WIDGET_WHOLE:
+ if ((style & (SWT.PUSH | SWT.CHECK | SWT.RADIO)) != 0) {
+ iPartId = OS.TP_BUTTON;
+ } else if ((style & SWT.DROP_DOWN) != 0) {
+ iPartId = OS.TP_SPLITBUTTON;
+ } else if ((style & SWT.SEPARATOR) != 0) {
+ if ((parent.style & SWT.VERTICAL) != 0) {
+ iPartId = OS.TP_SEPARATORVERT;
+ } else {
+ iPartId = OS.TP_SEPARATOR;
+ }
+ }
+ if ((style & SWT.SEPARATOR) == 0) {
+ if ((state & DrawData.HOT) != 0) {
+ if ((style & (SWT.RADIO | SWT.CHECK)) != 0 && (state & DrawData.SELECTED) != 0) {
+ iStateId = OS.TS_HOTCHECKED;
+ } else {
+ iStateId = OS.TS_HOT;
+ }
+ }
+ if ((style & (SWT.RADIO | SWT.CHECK)) != 0 && (state & DrawData.SELECTED) != 0) {
+ iStateId = OS.TS_CHECKED;
+ }
+ if ((state & DrawData.PRESSED) != 0) iStateId = OS.TS_PRESSED;
+ if ((state & DrawData.DISABLED) != 0) iStateId = OS.TS_DISABLED;
+ }
+ break;
+ case DrawData.TOOLITEM_ARROW:
+ iPartId = OS.TP_SPLITBUTTONDROPDOWN;
+ if ((state & DrawData.HOT) != 0) iStateId = OS.TS_HOT;
+ if ((state & DrawData.PRESSED) != 0) iStateId = OS.TS_PRESSED;
+ if ((state & DrawData.DISABLED) !=0) iStateId = OS.TS_DISABLED;
+ break;
+ }
+ return new int[]{iPartId, iStateId};
+}
+
+int hit(Theme theme, Point position, Rectangle bounds) {
+ if (!bounds.contains(position)) return DrawData.WIDGET_NOWHERE;
+ int hTheme = OS.OpenThemeData(0, getClassId());
+ try {
+ RECT rect = new RECT ();
+ rect.left = bounds.x;
+ rect.right = bounds.x + bounds.width;
+ rect.top = bounds.y;
+ rect.bottom = bounds.y + bounds.height;
+ POINT pt = new POINT();
+ pt.x = position.x;
+ pt.y = position.y;
+ short[] code = new short[1];
+ int[] part = getPartId(DrawData.WIDGET_WHOLE);
+ OS.HitTestThemeBackground(hTheme, 0, part[0], part[1], 0, rect, 0, pt, code);
+ if (code[0] == OS.HTNOWHERE) return DrawData.WIDGET_NOWHERE;
+ int style = this.style;
+ if ((style & SWT.DROP_DOWN) != 0) {
+ SIZE size = new SIZE();
+ part = getPartId(DrawData.TOOLITEM_ARROW);
+ OS.GetThemePartSize(hTheme, 0, part[0], part[1], rect, OS.TS_TRUE, size);
+ rect.left = Math.max(rect.left, rect.right - size.cx);
+ OS.HitTestThemeBackground(hTheme, 0, part[0], part[1], 0, rect, 0, pt, code);
+ if (code[0] != OS.HTNOWHERE) return DrawData.TOOLITEM_ARROW;
+ }
+ } finally {
+ OS.CloseThemeData(hTheme);
+ }
+ return DrawData.WIDGET_WHOLE;
+}
+
+}