summaryrefslogtreecommitdiffstats
path: root/bundles/org.eclipse.swt/Eclipse SWT Theme
diff options
context:
space:
mode:
authorSilenio Quarti <silenio>2006-04-26 14:46:49 +0000
committerSilenio Quarti <silenio>2006-04-26 14:46:49 +0000
commit36ded620c7508f4cbe34e3f788ea5ed8718a3698 (patch)
treebddbc89099612038084daf677df099ab1c82fe08 /bundles/org.eclipse.swt/Eclipse SWT Theme
parente8c8fc165f050f47ac2b161e31aa754f630d6915 (diff)
downloadeclipse.platform.swt-36ded620c7508f4cbe34e3f788ea5ed8718a3698.tar.gz
eclipse.platform.swt-36ded620c7508f4cbe34e3f788ea5ed8718a3698.tar.xz
eclipse.platform.swt-36ded620c7508f4cbe34e3f788ea5ed8718a3698.zip
37706 - Support native theme drawing API in SWT (internal)
Diffstat (limited to 'bundles/org.eclipse.swt/Eclipse SWT Theme')
-rw-r--r--bundles/org.eclipse.swt/Eclipse SWT Theme/carbon/org/eclipse/swt/internal/theme/ButtonDrawData.java80
-rw-r--r--bundles/org.eclipse.swt/Eclipse SWT Theme/carbon/org/eclipse/swt/internal/theme/ComboDrawData.java91
-rw-r--r--bundles/org.eclipse.swt/Eclipse SWT Theme/carbon/org/eclipse/swt/internal/theme/DrawData.java180
-rw-r--r--bundles/org.eclipse.swt/Eclipse SWT Theme/carbon/org/eclipse/swt/internal/theme/ExpanderDrawData.java67
-rw-r--r--bundles/org.eclipse.swt/Eclipse SWT Theme/carbon/org/eclipse/swt/internal/theme/GroupDrawData.java68
-rw-r--r--bundles/org.eclipse.swt/Eclipse SWT Theme/carbon/org/eclipse/swt/internal/theme/ProgressBarDrawData.java45
-rw-r--r--bundles/org.eclipse.swt/Eclipse SWT Theme/carbon/org/eclipse/swt/internal/theme/RangeDrawData.java13
-rw-r--r--bundles/org.eclipse.swt/Eclipse SWT Theme/carbon/org/eclipse/swt/internal/theme/ScaleDrawData.java67
-rw-r--r--bundles/org.eclipse.swt/Eclipse SWT Theme/carbon/org/eclipse/swt/internal/theme/ScrollBarDrawData.java147
-rw-r--r--bundles/org.eclipse.swt/Eclipse SWT Theme/carbon/org/eclipse/swt/internal/theme/TabFolderDrawData.java81
-rw-r--r--bundles/org.eclipse.swt/Eclipse SWT Theme/carbon/org/eclipse/swt/internal/theme/TabItemDrawData.java97
-rw-r--r--bundles/org.eclipse.swt/Eclipse SWT Theme/carbon/org/eclipse/swt/internal/theme/Theme.java104
-rw-r--r--bundles/org.eclipse.swt/Eclipse SWT Theme/carbon/org/eclipse/swt/internal/theme/ToolBarDrawData.java19
-rw-r--r--bundles/org.eclipse.swt/Eclipse SWT Theme/carbon/org/eclipse/swt/internal/theme/ToolItemDrawData.java110
14 files changed, 1169 insertions, 0 deletions
diff --git a/bundles/org.eclipse.swt/Eclipse SWT Theme/carbon/org/eclipse/swt/internal/theme/ButtonDrawData.java b/bundles/org.eclipse.swt/Eclipse SWT Theme/carbon/org/eclipse/swt/internal/theme/ButtonDrawData.java
new file mode 100644
index 0000000000..5f44c179e7
--- /dev/null
+++ b/bundles/org.eclipse.swt/Eclipse SWT Theme/carbon/org/eclipse/swt/internal/theme/ButtonDrawData.java
@@ -0,0 +1,80 @@
+package org.eclipse.swt.internal.theme;
+
+import org.eclipse.swt.*;
+import org.eclipse.swt.graphics.*;
+import org.eclipse.swt.internal.carbon.OS;
+import org.eclipse.swt.internal.carbon.HIThemeButtonDrawInfo;
+import org.eclipse.swt.internal.carbon.CGRect;
+
+public class ButtonDrawData extends DrawData {
+
+public ButtonDrawData() {
+ state = new int[1];
+}
+
+HIThemeButtonDrawInfo getInfo () {
+ int state = this.state[DrawData.WIDGET_WHOLE];
+ HIThemeButtonDrawInfo info = new HIThemeButtonDrawInfo();
+ info.version = 0;
+ if ((style & SWT.PUSH) != 0) info.kind = OS.kThemePushButton;
+ if ((style & SWT.CHECK) != 0) info.kind = OS.kThemeCheckBox;
+ if ((style & SWT.RADIO) != 0) info.kind = OS.kThemeRadioButton;
+ if ((state & DrawData.SELECTED) != 0) {
+ info.value = OS.kThemeButtonOn;
+ } else {
+ info.value = OS.kThemeButtonOff;
+ }
+ if ((state & DrawData.PRESSED) != 0) {
+ info.state = OS.kThemeStatePressed;
+ } else {
+ if ((state & DrawData.ACTIVE) != 0) {
+ info.state = (state & DrawData.DISABLED) == 0 ? OS.kThemeStateActive : OS.kThemeStateUnavailable;
+ } else {
+ info.state = (state & DrawData.DISABLED) == 0 ? OS.kThemeStateInactive : OS.kThemeStateUnavailableInactive;
+ }
+ }
+ if ((state & DrawData.DEFAULTED) != 0) info.adornment |= OS.kThemeAdornmentDefault;
+ if ((state & DrawData.FOCUSED) != 0) info.adornment |= OS.kThemeAdornmentFocus;
+ return info;
+}
+
+void draw(Theme theme, GC gc, Rectangle bounds) {
+ HIThemeButtonDrawInfo info = getInfo();
+ CGRect rect = new CGRect();
+ rect.x = bounds.x;
+ rect.y = bounds.y;
+ rect.width = bounds.width;
+ rect.height = bounds.height;
+ CGRect backRect = new CGRect();
+ OS.HIThemeGetButtonBackgroundBounds(rect, info, backRect);
+ rect.x += (rect.x - backRect.x);
+ rect.y += (rect.y - backRect.y);
+ rect.width -= (backRect.width - rect.width);
+ rect.height -= (backRect.height - rect.height);
+ CGRect labelRect = clientArea != null ? new CGRect() : null;
+ OS.HIThemeDrawButton(rect, info, gc.handle, OS.kHIThemeOrientationNormal, labelRect);
+ if (clientArea != null) {
+ clientArea.x = (int)labelRect.x;
+ clientArea.y = (int)labelRect.y;
+ clientArea.width = (int)labelRect.width;
+ clientArea.height = (int)labelRect.height;
+ }
+}
+
+int hit(Theme theme, Point position, Rectangle bounds) {
+ HIThemeButtonDrawInfo info = getInfo();
+ CGRect rect = new CGRect();
+ rect.x = bounds.x;
+ rect.y = bounds.y;
+ rect.width = bounds.width;
+ rect.height = bounds.height;
+ CGRect backRect = new CGRect();
+ OS.HIThemeGetButtonBackgroundBounds(rect, info, backRect);
+ rect.x += (rect.x - backRect.x);
+ rect.y += (rect.y - backRect.y);
+ rect.width -= (backRect.width - rect.width);
+ rect.height -= (backRect.height - rect.height);
+ return new Rectangle((int)rect.x, (int)rect.y, (int)rect.width, (int)rect.height).contains(position) ? DrawData.WIDGET_WHOLE : DrawData.WIDGET_NOWHERE;
+}
+
+}
diff --git a/bundles/org.eclipse.swt/Eclipse SWT Theme/carbon/org/eclipse/swt/internal/theme/ComboDrawData.java b/bundles/org.eclipse.swt/Eclipse SWT Theme/carbon/org/eclipse/swt/internal/theme/ComboDrawData.java
new file mode 100644
index 0000000000..dac4c4061e
--- /dev/null
+++ b/bundles/org.eclipse.swt/Eclipse SWT Theme/carbon/org/eclipse/swt/internal/theme/ComboDrawData.java
@@ -0,0 +1,91 @@
+package org.eclipse.swt.internal.theme;
+
+import org.eclipse.swt.*;
+import org.eclipse.swt.graphics.*;
+import org.eclipse.swt.internal.carbon.OS;
+import org.eclipse.swt.internal.carbon.CGRect;
+import org.eclipse.swt.internal.carbon.HIThemeButtonDrawInfo;
+
+public class ComboDrawData extends DrawData {
+
+public ComboDrawData() {
+ state = new int[2];
+}
+
+HIThemeButtonDrawInfo getInfo() {
+ int state = this.state[DrawData.WIDGET_WHOLE];
+ HIThemeButtonDrawInfo info = new HIThemeButtonDrawInfo();
+ info.version = 0;
+ info.kind = OS.kThemeComboBox;
+ if ((style & SWT.READ_ONLY) != 0) info.kind = OS.kThemePopupButton;
+ if ((state & DrawData.DISABLED) != 0) {
+ info.state = (state & DrawData.ACTIVE) != 0 ? OS.kThemeStateUnavailable : OS.kThemeStateUnavailableInactive;
+ } else {
+ if (((style & SWT.READ_ONLY) != 0 && (state & DrawData.PRESSED) != 0) || ((style & SWT.READ_ONLY) == 0 && (this.state[DrawData.COMBO_ARROW] & DrawData.PRESSED) != 0)) {
+ info.state = OS.kThemeStatePressed;
+ } else {
+ info.state = (state & DrawData.ACTIVE) != 0 ? OS.kThemeStateActive : OS.kThemeStateInactive;
+ }
+ }
+ if ((state & DrawData.FOCUSED) != 0) info.adornment |= OS.kThemeAdornmentFocus;
+ return info;
+}
+
+void draw(Theme theme, GC gc, Rectangle bounds) {
+ HIThemeButtonDrawInfo info = getInfo();
+ CGRect rect = new CGRect();
+ rect.x = bounds.x;
+ rect.y = bounds.y;
+ rect.width = bounds.width;
+ rect.height = bounds.height;
+ int inset = 0, arrowWidth = 0;
+ if ((style & SWT.READ_ONLY) == 0) {
+ int[] metric = new int[1];
+ OS.GetThemeMetric(OS.kThemeMetricFocusRectOutset, metric);
+ inset = metric[0];
+ OS.GetThemeMetric(OS.kThemeMetricComboBoxLargeDisclosureWidth, metric);
+ arrowWidth = metric[0];
+ rect.x += inset;
+ rect.y += inset;
+ rect.width -= 2 * inset;
+ rect.height -= 2 * inset;
+ } else {
+ CGRect backRect = new CGRect();
+ OS.HIThemeGetButtonBackgroundBounds(rect, info, backRect);
+ rect.x += (rect.x - backRect.x);
+ rect.y += (rect.y - backRect.y);
+ rect.width -= (backRect.width - rect.width);
+ rect.height -= (backRect.height - rect.height);
+ }
+ CGRect labelRect = clientArea != null && (style & SWT.READ_ONLY) != 0 ? new CGRect() : null;
+ OS.HIThemeDrawButton(rect, info, gc.handle, OS.kHIThemeOrientationNormal, labelRect);
+ if (clientArea != null) {
+ if ((style & SWT.READ_ONLY) != 0) {
+ clientArea.x = (int)labelRect.x;
+ clientArea.y = (int)labelRect.y;
+ clientArea.width = (int)labelRect.width;
+ clientArea.height = (int)labelRect.height;
+ } else {
+ clientArea.x = (int)bounds.x + inset;
+ clientArea.y = (int)bounds.y + inset;
+ clientArea.width = (int)bounds.width - (2 * inset) - arrowWidth;
+ clientArea.height = (int)bounds.height - (2 * inset);
+ }
+ }
+}
+
+int hit(Theme theme, Point position, Rectangle bounds) {
+ if (!bounds.contains(position)) return DrawData.WIDGET_NOWHERE;
+ if ((style & SWT.READ_ONLY) == 0) {
+ int[] metric = new int[1];
+ OS.GetThemeMetric(OS.kThemeMetricFocusRectOutset, metric);
+ int inset = metric[0];
+ OS.GetThemeMetric(OS.kThemeMetricComboBoxLargeDisclosureWidth, metric);
+ int arrowWidth = metric[0];
+ Rectangle arrowRect = new Rectangle(bounds.x + bounds.width - inset - arrowWidth, bounds.y - inset, arrowWidth, bounds.height - inset * 2);
+ if (arrowRect.contains(position)) return DrawData.COMBO_ARROW;
+ }
+ return DrawData.WIDGET_WHOLE;
+}
+
+}
diff --git a/bundles/org.eclipse.swt/Eclipse SWT Theme/carbon/org/eclipse/swt/internal/theme/DrawData.java b/bundles/org.eclipse.swt/Eclipse SWT Theme/carbon/org/eclipse/swt/internal/theme/DrawData.java
new file mode 100644
index 0000000000..cbd29fc86c
--- /dev/null
+++ b/bundles/org.eclipse.swt/Eclipse SWT Theme/carbon/org/eclipse/swt/internal/theme/DrawData.java
@@ -0,0 +1,180 @@
+package org.eclipse.swt.internal.theme;
+
+import org.eclipse.swt.graphics.*;
+import org.eclipse.swt.internal.carbon.OS;
+import org.eclipse.swt.internal.carbon.CGRect;
+import org.eclipse.swt.internal.carbon.HIThemeTextInfo;
+
+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;
+
+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) {
+ Image drawImage = image;
+ Rectangle rect = drawImage.getBounds();
+ int state = this.state[DrawData.WIDGET_WHOLE];
+ if (OS.VERSION >= 0x1040) {
+ if ((state & (DrawData.PRESSED | DrawData.DISABLED)) != 0) {
+ int transform = OS.kHITransformNone;
+ if ((state & DrawData.DISABLED) != 0) {
+ transform = OS.kHITransformDisabled;
+ } else {
+ if ((state & DrawData.PRESSED) != 0) {
+ transform = OS.kHITransformSelected;
+ }
+ }
+ if (transform != OS.kHITransformNone) {
+ int[] buffer = new int[1];
+ OS.HICreateTransformedCGImage(drawImage.handle, transform, buffer);
+ if (buffer[0] != 0) {
+ //TODO - get device
+ //TODO - is data needed
+ drawImage = Image.carbon_new(null, drawImage.type, buffer[0], 0);
+ }
+ }
+ }
+ }
+ gc.drawImage(drawImage, 0, 0, rect.width, rect.height, bounds.x, bounds.y, bounds.width, bounds.height);
+ if (drawImage != image) {
+ drawImage.dispose();
+ }
+}
+
+void drawText(Theme theme, String text, int flags, GC gc, Rectangle bounds) {
+ int state = this.state[DrawData.WIDGET_WHOLE];
+ char[] chars = new char[text.length()];
+ text.getChars(0, chars.length, chars, 0);
+ int ptr = OS.CFStringCreateWithCharacters(OS.kCFAllocatorDefault, chars, chars.length);
+ OS.CGContextSaveGState(gc.handle);
+ if ((state & DrawData.DISABLED) != 0) {
+ //TODO - find out disable color
+ OS.CGContextSetFillColor(gc.handle, new float[]{0.5f, 0.5f, 0.5f, 1});
+ } else {
+ if ((state & DrawData.ACTIVE) != 0) {
+ OS.CGContextSetFillColor(gc.handle, new float[]{0, 0, 0, 1});
+ } else {
+ //TODO - find out inative color
+ OS.CGContextSetFillColor(gc.handle, new float[]{0.6f, 0.6f, 0.6f, 1});
+ }
+ }
+ CGRect rect = new CGRect();
+ rect.x = bounds.x;
+ rect.y = bounds.y;
+ rect.width = bounds.width;
+ rect.height = bounds.height;
+ HIThemeTextInfo info = getTextInfo(flags);
+ OS.HIThemeDrawTextBox(ptr, rect, info, gc.handle, OS.kHIThemeOrientationNormal);
+ OS.CGContextRestoreGState(gc.handle);
+ OS.CFRelease(ptr);
+}
+
+Rectangle getBounds(int part, Rectangle bounds) {
+ return new Rectangle(bounds.x, bounds.y, bounds.width, bounds.height);
+}
+
+int getFontId() {
+ return OS.kThemeSmallSystemFont;
+}
+
+HIThemeTextInfo getTextInfo(int flags) {
+ int state = this.state[DrawData.WIDGET_WHOLE];
+ HIThemeTextInfo info = new HIThemeTextInfo();
+ if ((state & DrawData.PRESSED) != 0) {
+ info.state = OS.kThemeStatePressed;
+ } else {
+ if ((state & DrawData.ACTIVE) != 0) {
+ info.state = (state & DrawData.DISABLED) == 0 ? OS.kThemeStateActive : OS.kThemeStateUnavailable;
+ } else {
+ info.state = (state & DrawData.DISABLED) == 0 ? OS.kThemeStateInactive : OS.kThemeStateUnavailableInactive;
+ }
+ }
+ info.state = info.state;
+ info.fontID = (short)getFontId();
+ if ((flags & DrawData.DRAW_LEFT) != 0) info.horizontalFlushness = OS.kHIThemeTextHorizontalFlushLeft;
+ if ((flags & DrawData.DRAW_HCENTER) != 0) info.horizontalFlushness = OS.kHIThemeTextHorizontalFlushCenter;
+ if ((flags & DrawData.DRAW_RIGHT) != 0) info.horizontalFlushness = OS.kHIThemeTextHorizontalFlushRight;
+ if ((flags & DrawData.DRAW_TOP) != 0) info.verticalFlushness = OS.kHIThemeTextVerticalFlushTop;
+ if ((flags & DrawData.DRAW_VCENTER) != 0) info.verticalFlushness = OS.kHIThemeTextVerticalFlushCenter;
+ if ((flags & DrawData.DRAW_BOTTOM) != 0) info.verticalFlushness = OS.kHIThemeTextVerticalFlushBottom;
+ info.truncationMaxLines = 0;
+ info.truncationPosition = 0;
+ info.options = 0;
+ return info;
+}
+
+int hit(Theme theme, Point position, Rectangle bounds) {
+ return -1;
+}
+
+Rectangle measureText(Theme theme, String text, int flags, GC gc, Rectangle bounds) {
+ //TODO - decide if should take only width and return only width/height
+ char[] chars = new char[text.length()];
+ text.getChars(0, chars.length, chars, 0);
+ int ptr = OS.CFStringCreateWithCharacters(OS.kCFAllocatorDefault, chars, chars.length);
+ int width = bounds != null ? bounds.width : 0;
+ float[] outWidth = new float[1], outHeight = new float[1];
+ HIThemeTextInfo info = getTextInfo(flags);
+ OS.HIThemeGetTextDimensions(ptr, width, info, outWidth, outHeight, null);
+ OS.CFRelease(ptr);
+ return new Rectangle(0, 0, (int)outWidth[0], (int)outHeight[0]);
+}
+
+}
diff --git a/bundles/org.eclipse.swt/Eclipse SWT Theme/carbon/org/eclipse/swt/internal/theme/ExpanderDrawData.java b/bundles/org.eclipse.swt/Eclipse SWT Theme/carbon/org/eclipse/swt/internal/theme/ExpanderDrawData.java
new file mode 100644
index 0000000000..d7eed30d70
--- /dev/null
+++ b/bundles/org.eclipse.swt/Eclipse SWT Theme/carbon/org/eclipse/swt/internal/theme/ExpanderDrawData.java
@@ -0,0 +1,67 @@
+package org.eclipse.swt.internal.theme;
+
+import org.eclipse.swt.*;
+import org.eclipse.swt.graphics.*;
+import org.eclipse.swt.internal.carbon.OS;
+import org.eclipse.swt.internal.carbon.CGRect;
+import org.eclipse.swt.internal.carbon.HIThemeButtonDrawInfo;
+
+public class ExpanderDrawData extends DrawData {
+
+public ExpanderDrawData() {
+ state = new int[1];
+}
+
+HIThemeButtonDrawInfo getInfo() {
+ int state = this.state[DrawData.WIDGET_WHOLE];
+ HIThemeButtonDrawInfo info = new HIThemeButtonDrawInfo();
+ info.version = 0;
+ info.kind = OS.kThemeDisclosureTriangle;
+ if ((style & SWT.DOWN) != 0) {
+ info.value = OS.kThemeButtonOn;
+ } else {
+ info.value = OS.kThemeButtonOff;
+ }
+ if ((state & DrawData.PRESSED) != 0) {
+ info.state = OS.kThemeStatePressed;
+ } else {
+ if ((state & DrawData.ACTIVE) != 0) {
+ info.state = (state & DrawData.DISABLED) == 0 ? OS.kThemeStateActive : OS.kThemeStateUnavailable;
+ } else {
+ info.state = (state & DrawData.DISABLED) == 0 ? OS.kThemeStateInactive : OS.kThemeStateUnavailableInactive;
+ }
+ }
+ return info;
+}
+
+void draw(Theme theme, GC gc, Rectangle bounds) {
+ HIThemeButtonDrawInfo info = getInfo();
+ CGRect rect = new CGRect();
+ rect.x = bounds.x;
+ rect.y = bounds.y;
+ rect.width = bounds.width;
+ rect.height = bounds.height;
+ CGRect backRect = new CGRect();
+ OS.HIThemeGetButtonBackgroundBounds(rect, info, backRect);
+ rect.x += (rect.x - backRect.x);
+ rect.y += (rect.y - backRect.y);
+ int[] metric = new int[1];
+ OS.GetThemeMetric(OS.kThemeMetricDisclosureTriangleWidth, metric);
+ rect.width = metric[0];
+ OS.GetThemeMetric(OS.kThemeMetricDisclosureTriangleHeight, metric);
+ rect.height = metric[0];
+ OS.HIThemeDrawButton(rect, info, gc.handle, OS.kHIThemeOrientationNormal, null);
+}
+
+int hit(Theme theme, Point position, Rectangle bounds) {
+ if (!bounds.contains(position)) return DrawData.WIDGET_NOWHERE;
+ int[] metric = new int[1];
+ OS.GetThemeMetric(OS.kThemeMetricDisclosureTriangleWidth, metric);
+ int width = metric[0];
+ OS.GetThemeMetric(OS.kThemeMetricDisclosureTriangleHeight, metric);
+ int height = metric[0];
+ if (new Rectangle(bounds.x, bounds.y, width, height).contains(position)) return DrawData.WIDGET_WHOLE;
+ return DrawData.WIDGET_NOWHERE;
+}
+
+}
diff --git a/bundles/org.eclipse.swt/Eclipse SWT Theme/carbon/org/eclipse/swt/internal/theme/GroupDrawData.java b/bundles/org.eclipse.swt/Eclipse SWT Theme/carbon/org/eclipse/swt/internal/theme/GroupDrawData.java
new file mode 100644
index 0000000000..193dd92fca
--- /dev/null
+++ b/bundles/org.eclipse.swt/Eclipse SWT Theme/carbon/org/eclipse/swt/internal/theme/GroupDrawData.java
@@ -0,0 +1,68 @@
+package org.eclipse.swt.internal.theme;
+
+import org.eclipse.swt.*;
+import org.eclipse.swt.graphics.*;
+import org.eclipse.swt.internal.carbon.OS;
+import org.eclipse.swt.internal.carbon.CGRect;
+import org.eclipse.swt.internal.carbon.HIThemeGroupBoxDrawInfo;
+
+public class GroupDrawData extends DrawData {
+ public int headerWidth;
+ public int headerHeight;
+ public Rectangle headerArea;
+
+public GroupDrawData() {
+ state = new int[1];
+}
+
+HIThemeGroupBoxDrawInfo getInfo () {
+ int state = this.state[DrawData.WIDGET_WHOLE];
+ HIThemeGroupBoxDrawInfo info = new HIThemeGroupBoxDrawInfo();
+ info.version = 0;
+ info.kind = OS.kHIThemeGroupBoxKindPrimary;
+ if ((style & SWT.READ_ONLY) != 0) info.kind = OS.kThemePopupButton;
+ if ((state & DrawData.DISABLED) != 0) {
+ info.state = (state & DrawData.ACTIVE) != 0 ? OS.kThemeStateUnavailable : OS.kThemeStateUnavailableInactive;
+ } else {
+ if ((state & DrawData.PRESSED) != 0) {
+ info.state = OS.kThemeStatePressed;
+ } else {
+ info.state = (state & DrawData.ACTIVE) != 0 ? OS.kThemeStateActive : OS.kThemeStateInactive;
+ }
+ }
+ return info;
+}
+
+void draw(Theme theme, GC gc, Rectangle bounds) {
+ HIThemeGroupBoxDrawInfo info = getInfo();
+ int headerHeight = this.headerHeight + 1;
+ CGRect rect = new CGRect();
+ rect.x = bounds.x;
+ rect.y = bounds.y + headerHeight;
+ rect.width = bounds.width;
+ rect.height = bounds.height - headerHeight;
+ OS.HIThemeDrawGroupBox(rect, info, gc.handle, OS.kHIThemeOrientationNormal);
+ int[] metric = new int[1];
+ if (headerArea != null) {
+ OS.GetThemeMetric(OS.kThemeMetricLargeTabCapsWidth, metric);
+ int capsWidth = metric[0];
+ headerArea.x = bounds.x + capsWidth;
+ headerArea.y = bounds.y;
+ headerArea.width = bounds.width - capsWidth * 2;
+ headerArea.height = this.headerHeight;
+ }
+ if (clientArea != null) {
+ OS.GetThemeMetric(OS.kThemeMetricPrimaryGroupBoxContentInset, metric);
+ int inset = metric[0];
+ clientArea.x = bounds.x + inset;
+ clientArea.y = bounds.y + inset + headerHeight;
+ clientArea.width = bounds.width - (2 * inset);
+ clientArea.height = bounds.height - (2 * inset) - headerHeight;
+ }
+}
+
+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/carbon/org/eclipse/swt/internal/theme/ProgressBarDrawData.java b/bundles/org.eclipse.swt/Eclipse SWT Theme/carbon/org/eclipse/swt/internal/theme/ProgressBarDrawData.java
new file mode 100644
index 0000000000..09445f0041
--- /dev/null
+++ b/bundles/org.eclipse.swt/Eclipse SWT Theme/carbon/org/eclipse/swt/internal/theme/ProgressBarDrawData.java
@@ -0,0 +1,45 @@
+package org.eclipse.swt.internal.theme;
+
+import org.eclipse.swt.*;
+import org.eclipse.swt.graphics.*;
+import org.eclipse.swt.internal.carbon.OS;
+import org.eclipse.swt.internal.carbon.HIThemeTrackDrawInfo;
+import org.eclipse.swt.internal.carbon.ProgressTrackInfo;
+
+public class ProgressBarDrawData extends RangeDrawData {
+
+public ProgressBarDrawData() {
+ state = new int[1];
+}
+
+HIThemeTrackDrawInfo getInfo() {
+ int state = this.state[DrawData.WIDGET_WHOLE];
+ HIThemeTrackDrawInfo info = new HIThemeTrackDrawInfo();
+ info.min = minimum;
+ info.max = maximum;
+ info.value = selection;
+ info.kind = OS.kThemeProgressBarMedium;
+ info.attributes = OS.kThemeTrackShowThumb;
+ if ((style & SWT.HORIZONTAL) != 0) info.attributes |= OS.kThemeTrackHorizontal;
+ info.enableState = OS.kThemeTrackInactive;
+ if ((state & DrawData.ACTIVE) != 0) info.enableState = OS.kThemeTrackActive;
+ if ((state & DrawData.DISABLED) != 0) info.enableState = OS.kThemeTrackDisabled;
+ info.progress = new ProgressTrackInfo();
+ return info;
+}
+
+void draw(Theme theme, GC gc, Rectangle bounds) {
+ HIThemeTrackDrawInfo info = getInfo();
+ info.bounds_x = bounds.x;
+ info.bounds_y = bounds.y;
+ info.bounds_width = bounds.width;
+ info.bounds_height = bounds.height;
+ info.progress = new ProgressTrackInfo();
+ OS.HIThemeDrawTrack(info, null, gc.handle, OS.kHIThemeOrientationNormal);
+}
+
+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/carbon/org/eclipse/swt/internal/theme/RangeDrawData.java b/bundles/org.eclipse.swt/Eclipse SWT Theme/carbon/org/eclipse/swt/internal/theme/RangeDrawData.java
new file mode 100644
index 0000000000..8581329112
--- /dev/null
+++ b/bundles/org.eclipse.swt/Eclipse SWT Theme/carbon/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/carbon/org/eclipse/swt/internal/theme/ScaleDrawData.java b/bundles/org.eclipse.swt/Eclipse SWT Theme/carbon/org/eclipse/swt/internal/theme/ScaleDrawData.java
new file mode 100644
index 0000000000..4dc599aa0e
--- /dev/null
+++ b/bundles/org.eclipse.swt/Eclipse SWT Theme/carbon/org/eclipse/swt/internal/theme/ScaleDrawData.java
@@ -0,0 +1,67 @@
+package org.eclipse.swt.internal.theme;
+
+import org.eclipse.swt.*;
+import org.eclipse.swt.graphics.*;
+import org.eclipse.swt.internal.carbon.OS;
+import org.eclipse.swt.internal.carbon.CGPoint;
+import org.eclipse.swt.internal.carbon.HIThemeTrackDrawInfo;
+import org.eclipse.swt.internal.carbon.SliderTrackInfo;
+
+public class ScaleDrawData extends RangeDrawData {
+ public int increment;
+ public int pageIncrement;
+
+public ScaleDrawData() {
+ state = new int[4];
+}
+
+HIThemeTrackDrawInfo getInfo() {
+ int upTrackState = this.state[DrawData.SCALE_UP_TRACK];
+ int downTrackState = this.state[DrawData.SCALE_DOWN_TRACK];
+ int thumbState = this.state[DrawData.SCALE_THUMB];
+ HIThemeTrackDrawInfo info = new HIThemeTrackDrawInfo();
+ info.min = minimum;
+ info.max = Math.max(minimum, maximum);
+ info.value = selection;
+ info.kind = OS.kThemeSliderMedium;
+ info.attributes = OS.kThemeTrackShowThumb;
+ if ((style & SWT.HORIZONTAL) != 0) info.attributes |= OS.kThemeTrackHorizontal;
+ info.enableState = OS.kThemeTrackInactive;
+ if ((this.state[DrawData.WIDGET_WHOLE] & DrawData.ACTIVE) != 0) info.enableState = OS.kThemeTrackActive;
+ if ((this.state[DrawData.WIDGET_WHOLE] & DrawData.DISABLED) != 0) info.enableState = OS.kThemeTrackDisabled;
+ info.slider = new SliderTrackInfo();
+ int state = 0;
+ if ((upTrackState & DrawData.PRESSED) != 0) state |= OS.kThemeLeftInsideArrowPressed;
+ if ((downTrackState & DrawData.PRESSED) != 0) state |= OS.kThemeRightInsideArrowPressed;
+ if ((thumbState & DrawData.PRESSED) != 0) state |= OS.kThemeThumbPressed;
+ info.slider.pressState = (byte)state;
+ return info;
+}
+
+void draw(Theme theme, GC gc, Rectangle bounds) {
+ HIThemeTrackDrawInfo info = getInfo();
+ info.bounds_x = bounds.x;
+ info.bounds_y = bounds.y;
+ info.bounds_width = bounds.width;
+ info.bounds_height = bounds.height;
+ OS.HIThemeDrawTrack(info, null, gc.handle, OS.kHIThemeOrientationNormal);
+}
+
+int hit(Theme theme, Point position, Rectangle bounds) {
+ if (!bounds.contains(position)) return DrawData.WIDGET_NOWHERE;
+ CGPoint pt = new CGPoint();
+ pt.x = position.x;
+ pt.y = position.y;
+ short[] part = new short[1];
+ HIThemeTrackDrawInfo info = getInfo();
+ if (OS.HIThemeHitTestTrack(info, pt, part)) {
+ switch (part[0]) {
+ case 22: return DrawData.SCALE_UP_TRACK;
+ case 23: return DrawData.SCALE_DOWN_TRACK;
+ case 129: return DrawData.SCALE_THUMB;
+ }
+ }
+ return DrawData.WIDGET_NOWHERE;
+}
+
+}
diff --git a/bundles/org.eclipse.swt/Eclipse SWT Theme/carbon/org/eclipse/swt/internal/theme/ScrollBarDrawData.java b/bundles/org.eclipse.swt/Eclipse SWT Theme/carbon/org/eclipse/swt/internal/theme/ScrollBarDrawData.java
new file mode 100644
index 0000000000..b6dbe969a4
--- /dev/null
+++ b/bundles/org.eclipse.swt/Eclipse SWT Theme/carbon/org/eclipse/swt/internal/theme/ScrollBarDrawData.java
@@ -0,0 +1,147 @@
+package org.eclipse.swt.internal.theme;
+
+import org.eclipse.swt.*;
+import org.eclipse.swt.graphics.*;
+import org.eclipse.swt.internal.carbon.OS;
+import org.eclipse.swt.internal.carbon.CGPoint;
+import org.eclipse.swt.internal.carbon.CGRect;
+import org.eclipse.swt.internal.carbon.HIThemeTrackDrawInfo;
+import org.eclipse.swt.internal.carbon.ScrollBarTrackInfo;
+import org.eclipse.swt.internal.carbon.HIScrollBarTrackInfo;
+
+public class ScrollBarDrawData extends RangeDrawData {
+ public int thumb;
+ public int increment;
+ public int pageIncrement;
+
+public ScrollBarDrawData() {
+ state = new int[6];
+}
+
+HIScrollBarTrackInfo getArrowsInfo() {
+ int upArrowState = this.state[DrawData.SCROLLBAR_UP_ARROW];
+ int downArrowState = this.state[DrawData.SCROLLBAR_DOWN_ARROW];
+ int upTrackState = this.state[DrawData.SCROLLBAR_UP_TRACK];
+ int downTrackState = this.state[DrawData.SCROLLBAR_DOWN_TRACK];
+ int thumbState = this.state[DrawData.SCROLLBAR_THUMB];
+ int state = 0;
+ if ((upArrowState & DrawData.PRESSED) != 0) state |= OS.kThemeLeftOutsideArrowPressed;
+ if ((downArrowState & DrawData.PRESSED) != 0) state |= OS.kThemeRightOutsideArrowPressed;
+ if ((upTrackState & DrawData.PRESSED) != 0) state |= OS.kThemeLeftInsideArrowPressed;
+ if ((downTrackState & DrawData.PRESSED) != 0) state |= OS.kThemeRightInsideArrowPressed;
+ if ((thumbState & DrawData.PRESSED) != 0) state |= OS.kThemeThumbPressed;
+ int enableState = OS.kThemeTrackInactive;
+ if ((this.state[DrawData.WIDGET_WHOLE] & DrawData.ACTIVE) != 0) enableState = OS.kThemeTrackActive;
+ if ((this.state[DrawData.WIDGET_WHOLE] & DrawData.DISABLED) != 0) enableState = OS.kThemeTrackDisabled;
+ HIScrollBarTrackInfo scrollInfo = new HIScrollBarTrackInfo();
+ scrollInfo.pressState = (byte)state;
+ scrollInfo.enableState = (byte)enableState;
+ scrollInfo.viewsize = thumb;
+ return scrollInfo;
+}
+
+HIThemeTrackDrawInfo getInfo() {
+ int upArrowState = this.state[DrawData.SCROLLBAR_UP_ARROW];
+ int downArrowState = this.state[DrawData.SCROLLBAR_DOWN_ARROW];
+ int upTrackState = this.state[DrawData.SCROLLBAR_UP_TRACK];
+ int downTrackState = this.state[DrawData.SCROLLBAR_DOWN_TRACK];
+ int thumbState = this.state[DrawData.SCROLLBAR_THUMB];
+ HIThemeTrackDrawInfo info = new HIThemeTrackDrawInfo();
+ info.min = minimum;
+ info.max = Math.max(minimum, maximum - thumb);
+ info.value = selection;
+ info.kind = OS.kThemeScrollBarMedium;
+ info.attributes = OS.kThemeTrackShowThumb;
+ if ((style & SWT.HORIZONTAL) != 0) info.attributes |= OS.kThemeTrackHorizontal;
+ info.enableState = OS.kThemeTrackInactive;
+ if ((this.state[DrawData.WIDGET_WHOLE] & DrawData.ACTIVE) != 0) info.enableState = OS.kThemeTrackActive;
+ if ((this.state[DrawData.WIDGET_WHOLE] & DrawData.DISABLED) != 0) info.enableState = OS.kThemeTrackDisabled;
+ info.scrollbar = new ScrollBarTrackInfo();
+ int state = 0;
+ if ((upArrowState & DrawData.PRESSED) != 0) state |= OS.kThemeLeftOutsideArrowPressed;
+ if ((downArrowState & DrawData.PRESSED) != 0) state |= OS.kThemeRightOutsideArrowPressed;
+ if ((upTrackState & DrawData.PRESSED) != 0) state |= OS.kThemeLeftInsideArrowPressed;
+ if ((downTrackState & DrawData.PRESSED) != 0) state |= OS.kThemeRightInsideArrowPressed;
+ if ((thumbState & DrawData.PRESSED) != 0) state |= OS.kThemeThumbPressed;
+ info.scrollbar.pressState = (byte)state;
+ info.scrollbar.viewsize = thumb;
+ return info;
+}
+
+
+Rectangle getBounds(int part, Rectangle bounds) {
+ HIThemeTrackDrawInfo info = getInfo();
+ info.bounds_x = bounds.x;
+ info.bounds_y = bounds.y;
+ info.bounds_width = bounds.width;
+ info.bounds_height = bounds.height;
+ CGRect rect = new CGRect();
+ short partCode = 0;
+ switch (part) {
+ case DrawData.SCROLLBAR_UP_ARROW: partCode = 20; break;
+ case DrawData.SCROLLBAR_DOWN_ARROW: partCode = 21; break;
+ case DrawData.SCROLLBAR_UP_TRACK: partCode = 22; break;
+ case DrawData.SCROLLBAR_THUMB: partCode = 129; break;
+ case DrawData.SCROLLBAR_DOWN_TRACK: partCode = 23; break;
+ }
+ OS.HIThemeGetTrackPartBounds(info, partCode, rect);
+ return new Rectangle((int)rect.x, (int)rect.y, (int)rect.width, (int)rect.height);
+}
+
+int getSelection (Point position, Rectangle bounds) {
+ HIThemeTrackDrawInfo info = getInfo();
+ info.bounds_x = bounds.x;
+ info.bounds_y = bounds.y;
+ info.bounds_width = bounds.width;
+ info.bounds_height = bounds.height;
+ CGPoint pt = new CGPoint();
+ pt.x = position.x;
+ pt.y = position.y;
+ float[] relativePosition = new float[1];
+ OS.HIThemeGetTrackThumbPositionFromOffset(info, pt, relativePosition);
+ int[] selection = new int[1];
+ OS.HIThemeGetTrackLiveValue(info, relativePosition[0], selection);
+ return (int)selection[0];
+}
+
+void draw(Theme theme, GC gc, Rectangle bounds) {
+ HIThemeTrackDrawInfo info = getInfo();
+ info.bounds_x = bounds.x;
+ info.bounds_y = bounds.y;
+ info.bounds_width = bounds.width;
+ info.bounds_height = bounds.height;
+ OS.HIThemeDrawTrack(info, null, gc.handle, OS.kHIThemeOrientationNormal);
+}
+
+int hit(Theme theme, Point position, Rectangle bounds) {
+ CGPoint pt = new CGPoint();
+ pt.x = position.x;
+ pt.y = position.y;
+ CGRect rect = new CGRect();
+ rect.x = bounds.x;
+ rect.y = bounds.y;
+ rect.width = bounds.width;
+ rect.height = bounds.height;
+ short[] part = new short[1];
+ HIScrollBarTrackInfo scrollInfo = getArrowsInfo();
+ OS.HIThemeHitTestScrollBarArrows(rect, scrollInfo, (style & SWT.HORIZONTAL) != 0, pt, null, part);
+ switch (part[0]) {
+ case 20: return DrawData.SCROLLBAR_UP_ARROW;
+ case 21: return DrawData.SCROLLBAR_DOWN_ARROW;
+ }
+ HIThemeTrackDrawInfo info = getInfo();
+ info.bounds_x = bounds.x;
+ info.bounds_y = bounds.y;
+ info.bounds_width = bounds.width;
+ info.bounds_height = bounds.height;
+ if (OS.HIThemeHitTestTrack(info, pt, part)) {
+ switch (part[0]) {
+ case 22: return DrawData.SCROLLBAR_UP_TRACK;
+ case 23: return DrawData.SCROLLBAR_DOWN_TRACK;
+ case 129: return DrawData.SCROLLBAR_THUMB;
+ }
+ }
+ return DrawData.WIDGET_NOWHERE;
+}
+
+}
diff --git a/bundles/org.eclipse.swt/Eclipse SWT Theme/carbon/org/eclipse/swt/internal/theme/TabFolderDrawData.java b/bundles/org.eclipse.swt/Eclipse SWT Theme/carbon/org/eclipse/swt/internal/theme/TabFolderDrawData.java
new file mode 100644
index 0000000000..cc4f5cd92c
--- /dev/null
+++ b/bundles/org.eclipse.swt/Eclipse SWT Theme/carbon/org/eclipse/swt/internal/theme/TabFolderDrawData.java
@@ -0,0 +1,81 @@
+package org.eclipse.swt.internal.theme;
+
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.graphics.*;
+import org.eclipse.swt.internal.carbon.OS;
+import org.eclipse.swt.internal.carbon.HIThemeTabPaneDrawInfo;
+import org.eclipse.swt.internal.carbon.CGRect;
+
+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) {
+ int[] metric = new int[1];
+ OS.GetThemeMetric(OS.kThemeMetricLargeTabHeight, metric);
+ int tabHeight = metric[0];
+ OS.GetThemeMetric(OS.kThemeMetricLargeTabCapsWidth, metric);
+ int capsWidth = metric[0];
+ CGRect rect = new CGRect();
+ rect.x = bounds.x;
+ rect.y = bounds.y;
+ rect.width = bounds.width;
+ rect.height = bounds.height;
+ if ((style & SWT.BOTTOM) != 0) {
+ rect.height -= tabHeight / 2;
+ } else {
+ rect.y += (capsWidth + tabHeight) / 2;
+ rect.height -= (capsWidth + tabHeight) / 2;
+ }
+ HIThemeTabPaneDrawInfo info = getInfo();
+ OS.HIThemeDrawTabPane(rect, info, gc.handle, OS.kHIThemeOrientationNormal);
+ if (tabsArea != null) {
+ tabsArea.x = bounds.x + capsWidth + ((bounds.width - capsWidth * 2) - tabsWidth) / 2;
+ tabsArea.y = bounds.y;
+ tabsArea.width = bounds.width - capsWidth * 2;
+ tabsArea.height = tabHeight;
+ if ((style & SWT.BOTTOM) != 0) {
+ tabsArea.y += bounds.height - tabHeight;
+ } else {
+ tabsArea.y += capsWidth / 2;
+ }
+ }
+}
+
+HIThemeTabPaneDrawInfo getInfo() {
+ int state = this.state[DrawData.WIDGET_WHOLE];
+ HIThemeTabPaneDrawInfo info = new HIThemeTabPaneDrawInfo();
+ info.version = 1;
+ info.direction = OS.kThemeTabNorth;
+ if ((style & SWT.BOTTOM) != 0) info.direction = OS.kThemeTabSouth;
+ if ((style & SWT.TOP) != 0) info.direction = OS.kThemeTabNorth;
+ if ((state & DrawData.PRESSED) != 0) {
+ info.state = OS.kThemeStatePressed;
+ } else {
+ if ((state & DrawData.ACTIVE) != 0) {
+ info.state = (state & DrawData.DISABLED) == 0 ? OS.kThemeStateActive : OS.kThemeStateUnavailable;
+ } else {
+ info.state = (state & DrawData.DISABLED) == 0 ? OS.kThemeStateInactive : OS.kThemeStateUnavailableInactive;
+ }
+ }
+ return info;
+}
+
+
+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/carbon/org/eclipse/swt/internal/theme/TabItemDrawData.java b/bundles/org.eclipse.swt/Eclipse SWT Theme/carbon/org/eclipse/swt/internal/theme/TabItemDrawData.java
new file mode 100644
index 0000000000..495daa825e
--- /dev/null
+++ b/bundles/org.eclipse.swt/Eclipse SWT Theme/carbon/org/eclipse/swt/internal/theme/TabItemDrawData.java
@@ -0,0 +1,97 @@
+package org.eclipse.swt.internal.theme;
+
+import org.eclipse.swt.*;
+import org.eclipse.swt.graphics.*;
+import org.eclipse.swt.internal.carbon.OS;
+import org.eclipse.swt.internal.carbon.HIThemeTabDrawInfo;
+import org.eclipse.swt.internal.carbon.CGRect;
+
+public class TabItemDrawData extends DrawData {
+
+ public TabFolderDrawData parent;
+ public int position;
+
+public TabItemDrawData() {
+ state = new int[1];
+}
+
+Rectangle computeTrim(Theme theme, GC gc) {
+ int[] metric = new int[1];
+ OS.GetThemeMetric(OS.kThemeMetricLargeTabCapsWidth, metric);
+ int x = clientArea.x - metric[0];
+ int y = clientArea.y - metric[0];
+ int width = clientArea.width + metric[0] * 2;
+ int height = clientArea.height + metric[0] * 2;
+ return new Rectangle(x, y, width, height);
+}
+
+void draw(Theme theme, GC gc, Rectangle bounds) {
+ CGRect rect = new CGRect();
+ rect.x = bounds.x;
+ rect.y = bounds.y;
+ rect.width = bounds.width;
+ rect.height = bounds.height;
+ CGRect labelRect = clientArea != null ? new CGRect() : null;
+ HIThemeTabDrawInfo info = getInfo();
+ OS.HIThemeDrawTab(rect, info, gc.handle, OS.kHIThemeOrientationNormal, labelRect);
+ if (clientArea != null) {
+ clientArea.x = (int)labelRect.x;
+ clientArea.y = (int)labelRect.y;
+ clientArea.width = (int)labelRect.width;
+ clientArea.height = (int)labelRect.height;
+ }
+}
+
+HIThemeTabDrawInfo getInfo() {
+ int state = this.state[DrawData.WIDGET_WHOLE];
+ HIThemeTabDrawInfo info = new HIThemeTabDrawInfo();
+ info.version = 1;
+ if ((state & DrawData.DISABLED) == 0) {
+ if ((state & DrawData.ACTIVE) != 0) {
+ if ((state & DrawData.SELECTED) != 0) {
+ info.style = OS.kThemeTabFront;
+ } else {
+ if ((state & DrawData.PRESSED) != 0) {
+ info.style = OS.kThemeTabNonFrontPressed;
+ } else {
+ info.style = OS.kThemeTabNonFront;
+ }
+ }
+ } else {
+ if ((state & DrawData.SELECTED) != 0) {
+ info.style = OS.kThemeTabFrontInactive;
+ } else {
+ info.style = OS.kThemeTabNonFrontInactive;
+ }
+ }
+ } else {
+ if ((state & DrawData.ACTIVE) != 0) {
+ info.style = OS.kThemeTabFrontUnavailable;
+ } else {
+ info.style = OS.kThemeTabNonFrontUnavailable;
+ }
+ }
+ info.direction = OS.kThemeTabNorth;
+ if ((parent.style & SWT.BOTTOM) != 0) info.direction = OS.kThemeTabSouth;
+ if ((parent.style & SWT.TOP) != 0) info.direction = OS.kThemeTabNorth;
+ info.size = 0;
+ if ((state & DrawData.FOCUSED) != 0) info.adornment = OS.kHIThemeTabAdornmentFocus;
+ info.adornment |= OS.kHIThemeTabAdornmentTrailingSeparator;
+ info.position = OS.kHIThemeTabPositionMiddle;
+ if ((position & SWT.RIGHT) != 0 && (position & SWT.LEFT) != 0) {
+ info.position = OS.kHIThemeTabPositionOnly;
+ } else if ((position & SWT.LEFT) != 0) {
+ info.position = OS.kHIThemeTabPositionFirst;
+ info.adornment |= OS.kHIThemeTabAdornmentTrailingSeparator;
+ } else if ((position & SWT.RIGHT) != 0) {
+ info.position = OS.kHIThemeTabPositionLast;
+ }
+ return info;
+}
+
+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/carbon/org/eclipse/swt/internal/theme/Theme.java b/bundles/org.eclipse.swt/Eclipse SWT Theme/carbon/org/eclipse/swt/internal/theme/Theme.java
new file mode 100644
index 0000000000..3539365a63
--- /dev/null
+++ b/bundles/org.eclipse.swt/Eclipse SWT Theme/carbon/org/eclipse/swt/internal/theme/Theme.java
@@ -0,0 +1,104 @@
+package org.eclipse.swt.internal.theme;
+
+import org.eclipse.swt.*;
+import org.eclipse.swt.graphics.*;
+
+public class Theme {
+
+ Device device;
+
+public Theme(Device device) {
+ if (device == null) SWT.error(SWT.ERROR_NULL_ARGUMENT);
+ this.device = device;
+}
+
+void checkTheme() {
+ if (isDisposed()) SWT.error(SWT.ERROR_GRAPHIC_DISPOSED);
+}
+
+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);
+}
+
+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/carbon/org/eclipse/swt/internal/theme/ToolBarDrawData.java b/bundles/org.eclipse.swt/Eclipse SWT Theme/carbon/org/eclipse/swt/internal/theme/ToolBarDrawData.java
new file mode 100644
index 0000000000..902e971871
--- /dev/null
+++ b/bundles/org.eclipse.swt/Eclipse SWT Theme/carbon/org/eclipse/swt/internal/theme/ToolBarDrawData.java
@@ -0,0 +1,19 @@
+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) {
+}
+
+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/carbon/org/eclipse/swt/internal/theme/ToolItemDrawData.java b/bundles/org.eclipse.swt/Eclipse SWT Theme/carbon/org/eclipse/swt/internal/theme/ToolItemDrawData.java
new file mode 100644
index 0000000000..97f4bedacf
--- /dev/null
+++ b/bundles/org.eclipse.swt/Eclipse SWT Theme/carbon/org/eclipse/swt/internal/theme/ToolItemDrawData.java
@@ -0,0 +1,110 @@
+package org.eclipse.swt.internal.theme;
+
+import org.eclipse.swt.*;
+import org.eclipse.swt.graphics.*;
+import org.eclipse.swt.internal.carbon.OS;
+import org.eclipse.swt.internal.carbon.CGRect;
+import org.eclipse.swt.internal.carbon.HIThemeSeparatorDrawInfo;
+import org.eclipse.swt.internal.carbon.HIThemePopupArrowDrawInfo;
+
+public class ToolItemDrawData extends DrawData {
+
+ public ToolBarDrawData parent;
+
+ static final int ARROW_WIDTH = 9;
+ static final int INSET = 3;
+
+public ToolItemDrawData() {
+ state = new int[2];
+}
+
+Rectangle computeTrim(Theme theme, GC gc) {
+ int x = clientArea.x - INSET;
+ int y = clientArea.y - INSET;
+ int width = clientArea.width + INSET * 2;
+ int height = clientArea.height + INSET * 2;
+ if ((style & SWT.DROP_DOWN) != 0) {
+ width += ARROW_WIDTH;
+ }
+ return new Rectangle(x, y, width, height);
+}
+
+void draw(Theme theme, GC gc, Rectangle bounds) {
+ CGRect rect = new CGRect();
+ rect.x = bounds.x;
+ rect.y = bounds.y;
+ rect.width = bounds.width;
+ rect.height = bounds.height;
+ if ((style & SWT.SEPARATOR) != 0) {
+ HIThemeSeparatorDrawInfo info = getSeparatorInfo();
+ OS.HIThemeDrawSeparator (rect, info, gc.handle, OS.kHIThemeOrientationNormal);
+ } else {
+ if ((state[DrawData.WIDGET_WHOLE] & DrawData.SELECTED) != 0) {
+ OS.CGContextSaveGState (gc.handle);
+ OS.CGContextSetFillColor (gc.handle, new float[]{0.025f, 0.025f, 0.025f, 0.025f});
+ OS.CGContextFillRect (gc.handle, rect);
+ OS.CGContextSetStrokeColor (gc.handle, new float[]{0.2f, 0.2f, 0.2f, 0.2f});
+ rect.x += 0.5f;
+ rect.y += 0.5f;
+ rect.width -= 1;
+ rect.height -= 1;
+ OS.CGContextStrokeRect (gc.handle, rect);
+ OS.CGContextRestoreGState (gc.handle);
+ }
+ }
+ if (clientArea != null) {
+ clientArea.x = bounds.x;
+ clientArea.y = bounds.y;
+ clientArea.width = bounds.width;
+ clientArea.height = bounds.height;
+ }
+ if ((style & SWT.DROP_DOWN) != 0) {
+ rect.y = bounds.y + rect.height / 2 - 1;
+ rect.x = bounds.x + rect.width - ARROW_WIDTH;
+ HIThemePopupArrowDrawInfo info = getArrowInfo();
+ OS.HIThemeDrawPopupArrow (rect, info, gc.handle, OS.kHIThemeOrientationNormal);
+ if (clientArea != null) {
+ clientArea.width -= ARROW_WIDTH;
+ }
+ }
+}
+
+HIThemePopupArrowDrawInfo getArrowInfo() {
+ HIThemePopupArrowDrawInfo info = new HIThemePopupArrowDrawInfo();
+ int state = this.state[DrawData.TOOLITEM_ARROW];
+ if ((state & DrawData.PRESSED) != 0) {
+ info.state = OS.kThemeStatePressed;
+ } else {
+ if ((state & DrawData.ACTIVE) != 0) {
+ info.state = (state & DrawData.DISABLED) == 0 ? OS.kThemeStateActive : OS.kThemeStateUnavailable;
+ } else {
+ info.state = (state & DrawData.DISABLED) == 0 ? OS.kThemeStateInactive : OS.kThemeStateUnavailableInactive;
+ }
+ }
+ info.orientation = (short) OS.kThemeArrowDown;
+ info.size = (short) OS.kThemeArrow5pt;
+ return info;
+}
+
+HIThemeSeparatorDrawInfo getSeparatorInfo() {
+ HIThemeSeparatorDrawInfo info = new HIThemeSeparatorDrawInfo();
+ int state = this.state[DrawData.WIDGET_WHOLE];
+ if ((state & DrawData.ACTIVE) != 0) {
+ info.state = (state & DrawData.DISABLED) == 0 ? OS.kThemeStateActive : OS.kThemeStateUnavailable;
+ } else {
+ info.state = (state & DrawData.DISABLED) == 0 ? OS.kThemeStateInactive : OS.kThemeStateUnavailableInactive;
+ }
+ return info;
+}
+
+int hit(Theme theme, Point position, Rectangle bounds) {
+ if (!bounds.contains(position)) return DrawData.WIDGET_NOWHERE;
+ if ((style & SWT.DROP_DOWN) != 0) {
+ if (bounds.x + bounds.width - ARROW_WIDTH <= position.x) {
+ return DrawData.TOOLITEM_ARROW;
+ }
+ }
+ return DrawData.WIDGET_WHOLE;
+}
+
+}