diff options
author | Silenio Quarti <silenio> | 2006-04-26 14:57:18 +0000 |
---|---|---|
committer | Silenio Quarti <silenio> | 2006-04-26 14:57:18 +0000 |
commit | 8f00f299b7757fe42d6925916d2c9d689cd31e9d (patch) | |
tree | a2b30ed55edfd95075d497c35f2e7db327b62b1b /bundles/org.eclipse.swt/Eclipse SWT Theme | |
parent | 36ded620c7508f4cbe34e3f788ea5ed8718a3698 (diff) | |
download | eclipse.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')
28 files changed, 2714 insertions, 0 deletions
diff --git a/bundles/org.eclipse.swt/Eclipse SWT Theme/gtk/org/eclipse/swt/internal/theme/ButtonDrawData.java b/bundles/org.eclipse.swt/Eclipse SWT Theme/gtk/org/eclipse/swt/internal/theme/ButtonDrawData.java new file mode 100644 index 0000000000..6ea2ce6612 --- /dev/null +++ b/bundles/org.eclipse.swt/Eclipse SWT Theme/gtk/org/eclipse/swt/internal/theme/ButtonDrawData.java @@ -0,0 +1,210 @@ +package org.eclipse.swt.internal.theme; + +import org.eclipse.swt.*; +import org.eclipse.swt.graphics.*; +import org.eclipse.swt.internal.*; +import org.eclipse.swt.internal.gtk.*; + +public class ButtonDrawData extends DrawData { + +public ButtonDrawData() { + state = new int[1]; +} + + +void draw(Theme theme, GC gc, Rectangle bounds) { + int state = this.state[DrawData.WIDGET_WHOLE]; + + int /*long*/ drawable = gc.getGCData().drawable; + if ((style & SWT.RADIO) != 0) { + int /*long*/ radioButtonHandle = theme.radioButtonHandle; + int /*long*/ gtkStyle = OS.gtk_widget_get_style (radioButtonHandle); + theme.transferClipping (gc, gtkStyle); + int indicator_size = theme.getWidgetProperty(radioButtonHandle, "indicator-size"); + int indicator_spacing = theme.getWidgetProperty(radioButtonHandle, "indicator-spacing"); + int interior_focus = theme.getWidgetProperty(radioButtonHandle, "interior-focus"); + int focus_line_width = theme.getWidgetProperty(radioButtonHandle, "focus-line-width"); + int focus_padding = theme.getWidgetProperty(radioButtonHandle, "focus-padding"); + int border_width = OS.gtk_container_get_border_width(radioButtonHandle); + + int x = bounds.x + indicator_spacing + border_width; + int y = bounds.y + (bounds.height - indicator_size) / 2; + + if (interior_focus == 0) { + x += focus_line_width + focus_padding; + } + + int shadow_type; + if ((state & DrawData.GRAYED) != 0) { + shadow_type = OS.GTK_SHADOW_ETCHED_IN; + } else if ((state & DrawData.SELECTED) != 0) { + shadow_type = OS.GTK_SHADOW_IN; + } else { + shadow_type = OS.GTK_SHADOW_OUT; + } + + byte[] detail = Converter.wcsToMbcs(null, "radiobutton", true); + if ((state & DrawData.HOT) != 0) { + int prelight_x, prelight_y, prelight_width, prelight_height; + prelight_x = bounds.x + border_width; + prelight_y = bounds.y + border_width; + prelight_width = bounds.width - (2 * border_width); + prelight_height = bounds.height - (2 * border_width); + OS.gtk_paint_flat_box(gtkStyle, drawable, OS.GTK_STATE_PRELIGHT, OS.GTK_SHADOW_ETCHED_OUT, null, radioButtonHandle, detail, prelight_x, prelight_y, prelight_width, prelight_height); + } + int state_type = getStateType(DrawData.WIDGET_WHOLE); + OS.gtk_paint_option(gtkStyle, drawable, state_type, shadow_type, null, radioButtonHandle, detail, x, y, indicator_size, indicator_size); + if (clientArea != null) { + clientArea.x = bounds.x + 2 * indicator_spacing + border_width + indicator_size; + clientArea.y = bounds.y + border_width; + clientArea.width = bounds.width - (2 * indicator_spacing + 2 * border_width + indicator_size); + clientArea.height = bounds.height - 2 * border_width; + } + return; + } + + if ((style & SWT.CHECK) != 0) { + int /*long*/ checkButtonHandle = theme.checkButtonHandle; + int /*long*/ gtkStyle = OS.gtk_widget_get_style (checkButtonHandle); + theme.transferClipping (gc, gtkStyle); + int indicator_size = theme.getWidgetProperty(checkButtonHandle, "indicator-size"); + int indicator_spacing = theme.getWidgetProperty(checkButtonHandle, "indicator-spacing"); + int interior_focus = theme.getWidgetProperty(checkButtonHandle, "interior-focus"); + int focus_line_width = theme.getWidgetProperty(checkButtonHandle, "focus-line-width"); + int focus_padding = theme.getWidgetProperty(checkButtonHandle, "focus-padding"); + int border_width = OS.gtk_container_get_border_width(checkButtonHandle); + + int x = bounds.x + indicator_spacing + border_width; + int y = bounds.y + (bounds.height - indicator_size) / 2; + + if (interior_focus == 0) { + x += focus_line_width + focus_padding; + } + + int shadow_type; + if ((state & DrawData.GRAYED) != 0) { + shadow_type = OS.GTK_SHADOW_ETCHED_IN; + } else if ((state & DrawData.SELECTED) != 0) { + shadow_type = OS.GTK_SHADOW_IN; + } else { + shadow_type = OS.GTK_SHADOW_OUT; + } + + byte[] detail = Converter.wcsToMbcs(null, "checkbutton", true); + if ((state & DrawData.HOT) != 0) { + int prelight_x, prelight_y, prelight_width, prelight_height; + prelight_x = bounds.x + border_width; + prelight_y = bounds.y + border_width; + prelight_width = bounds.width - (2 * border_width); + prelight_height = bounds.height - (2 * border_width); + OS.gtk_paint_flat_box(gtkStyle, drawable, OS.GTK_STATE_PRELIGHT, OS.GTK_SHADOW_ETCHED_OUT, null, checkButtonHandle, detail, prelight_x, prelight_y, prelight_width, prelight_height); + } + int state_type = getStateType(DrawData.WIDGET_WHOLE); + OS.gtk_paint_check(gtkStyle, drawable, state_type, shadow_type, null, checkButtonHandle, detail, x, y, indicator_size, indicator_size); + if (clientArea != null) { + clientArea.x = bounds.x + 2 * indicator_spacing + border_width + indicator_size; + clientArea.y = bounds.y + border_width; + clientArea.width = bounds.width - (2 * indicator_spacing + 2 * border_width + indicator_size); + clientArea.height = bounds.height - 2 * border_width; + } + return; + } + + + if ((style & SWT.PUSH) != 0) { + int /*long*/ buttonHandle = theme.buttonHandle; + int /*long*/ gtkStyle = OS.gtk_widget_get_style (buttonHandle); + theme.transferClipping (gc, gtkStyle); + int focus_line_width = theme.getWidgetProperty(buttonHandle, "focus-line-width"); + int focus_padding = theme.getWidgetProperty(buttonHandle, "focus-padding"); + int border_width = OS.gtk_container_get_border_width(buttonHandle); + + GtkBorder default_border = new GtkBorder(); + int default_border_ptr = theme.getWidgetProperty(buttonHandle, "default-border"); + if (default_border_ptr != 0) { + OS.memmove(default_border, default_border_ptr, GdkRectangle.sizeof); + } else { + default_border.left = default_border.right = default_border.top = default_border.bottom = 1; + } + + GtkBorder default_outside_border = new GtkBorder(); + int default_outside_border_ptr = theme.getWidgetProperty(buttonHandle, "default-outside-border"); + if (default_outside_border_ptr != 0) { + OS.memmove(default_outside_border, default_outside_border_ptr, GdkRectangle.sizeof); + } else { + default_outside_border.left = default_outside_border.right = default_outside_border.top = default_outside_border.bottom = 0; + } + + int x = bounds.x + border_width; + int y = bounds.y + border_width; + int width = bounds.width - border_width * 2; + int height = bounds.height - border_width * 2; + + int relief = OS.gtk_button_get_relief(buttonHandle); + byte[] detail = Converter.wcsToMbcs(null, (state & DrawData.DEFAULTED) != 0 ? "buttondefault" : "button", true); + if ((state & DrawData.DEFAULTED) != 0 && relief == OS.GTK_RELIEF_NORMAL) { + OS.gtk_paint_box(gtkStyle, drawable, OS.GTK_STATE_NORMAL, OS.GTK_SHADOW_IN, null, buttonHandle, detail, x, y, width, height); + x += default_border.left; + y += default_border.top; + width -= default_border.left + default_border.right; + height -= default_border.top + default_border.bottom; + } else if ((state & DrawData.DEFAULTED) != 0) { + x += default_outside_border.left; + y += default_outside_border.top; + width -= default_outside_border.left + default_outside_border.right; + height -= default_outside_border.top + default_outside_border.bottom; + } + + int shadow_type = OS.GTK_SHADOW_OUT; + if ((state & (DrawData.SELECTED | DrawData.PRESSED)) != 0) shadow_type = OS.GTK_SHADOW_IN; + int state_type = getStateType(DrawData.WIDGET_WHOLE); + + if (relief != OS.GTK_RELIEF_NONE || ((state & (DrawData.PRESSED | DrawData.HOT)) != 0)) { + OS.gtk_paint_box(gtkStyle, drawable, state_type, shadow_type, null, buttonHandle, detail, x, y, width, height); + } + + if ((state & DrawData.FOCUSED) != 0) { + int child_displacement_y = theme.getWidgetProperty(buttonHandle, "child-displacement-y"); + int child_displacement_x = theme.getWidgetProperty(buttonHandle, "child-displacement-x"); + int displace_focus = 0; + if (OS.GTK_VERSION >= OS.VERSION (2, 6, 0)) { + displace_focus = theme.getWidgetProperty(buttonHandle, "displace-focus"); + } + int interior_focus = theme.getWidgetProperty(buttonHandle, "interior-focus"); + + if (interior_focus != 0) { + int xthickness = OS.gtk_style_get_xthickness(gtkStyle); + int ythickness = OS.gtk_style_get_ythickness(gtkStyle); + x += xthickness + focus_padding; + y += ythickness + focus_padding; + width -= 2 * (xthickness + focus_padding); + height -= 2 * (ythickness + focus_padding); + } else { + x -= focus_line_width + focus_padding; + y -= focus_line_width + focus_padding; + width += 2 * (focus_line_width + focus_padding); + height += 2 * (focus_line_width + focus_padding); + } + + if ((state & DrawData.PRESSED) != 0 && displace_focus != 0) { + x += child_displacement_x; + y += child_displacement_y; + } + + OS.gtk_paint_focus(gtkStyle, drawable, state_type, null, buttonHandle, detail, x, y, width, height); + } + if (clientArea != null) { + clientArea.x = bounds.x + border_width; + clientArea.y = bounds.y + border_width; + clientArea.width = bounds.width - 2 * border_width; + clientArea.height = bounds.height - 2 * border_width; + } + return; + } +} + +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/gtk/org/eclipse/swt/internal/theme/ComboDrawData.java b/bundles/org.eclipse.swt/Eclipse SWT Theme/gtk/org/eclipse/swt/internal/theme/ComboDrawData.java new file mode 100644 index 0000000000..b839c51570 --- /dev/null +++ b/bundles/org.eclipse.swt/Eclipse SWT Theme/gtk/org/eclipse/swt/internal/theme/ComboDrawData.java @@ -0,0 +1,114 @@ +package org.eclipse.swt.internal.theme; + +import org.eclipse.swt.graphics.*; +import org.eclipse.swt.internal.*; +import org.eclipse.swt.internal.gtk.*; + +public class ComboDrawData extends DrawData { + + static final int ARROW_HEIGHT = 6; + static final int MIN_ARROW_SIZE = 15; + +public ComboDrawData() { + state = new int[2]; +} + +void draw(Theme theme, GC gc, Rectangle bounds) { + int /*long*/ buttonHandle = theme.buttonHandle; + int /*long*/ gtkStyle = OS.gtk_widget_get_style(buttonHandle); + int /*long*/ drawable = gc.getGCData().drawable; + theme.transferClipping(gc, gtkStyle); + + int x = bounds.x; + int y = bounds.y ; + int width = bounds.width; + int height = bounds.height; + + int shadow_type = OS.GTK_SHADOW_OUT; + if ((state[DrawData.COMBO_ARROW] & DrawData.PRESSED) != 0) shadow_type = OS.GTK_SHADOW_IN; + int state_type = getStateType(DrawData.COMBO_ARROW); + + int relief = OS.gtk_button_get_relief(buttonHandle); + int interior_focus = theme.getWidgetProperty(buttonHandle, "interior-focus"); + int focus_line_width = theme.getWidgetProperty(buttonHandle, "focus-line-width"); + int focus_padding = theme.getWidgetProperty(buttonHandle, "focus-padding"); + int xthickness = OS.gtk_style_get_xthickness(gtkStyle); + int ythickness = OS.gtk_style_get_xthickness(gtkStyle); + int arrow_width = MIN_ARROW_SIZE; + int arrow_height = ARROW_HEIGHT; + int x_border = xthickness + focus_padding; + int y_border = ythickness + focus_padding; + if (interior_focus == 0) { + x_border += focus_line_width; + y_border += focus_line_width; + } + int arrow_button_width = arrow_width + x_border * 2; + int arrow_button_x = x + width - arrow_button_width; + int arrow_x = arrow_button_x + (arrow_button_width - arrow_width) / 2; + int arrow_y = y + (height - arrow_height) / 2 + 1; + if (relief != OS.GTK_RELIEF_NONE || ((state[DrawData.COMBO_ARROW] & (DrawData.PRESSED | DrawData.HOT)) != 0)) { + byte[] detail = Converter.wcsToMbcs(null, "button", true); + OS.gtk_paint_box(gtkStyle, drawable, state_type, shadow_type, null, buttonHandle, detail, arrow_button_x, y, arrow_button_width, height); + } + byte[] arrow_detail = Converter.wcsToMbcs(null, "arrow", true); + int /*long*/ arrowHandle = theme.arrowHandle; + OS.gtk_paint_arrow(gtkStyle, drawable, state_type, OS.GTK_SHADOW_OUT, null, arrowHandle, arrow_detail, OS.GTK_ARROW_DOWN, true, arrow_x, arrow_y, arrow_width, arrow_height); + + int /*long*/ entryHandle = theme.entryHandle; + gtkStyle = OS.gtk_widget_get_style(entryHandle); + theme.transferClipping(gc, gtkStyle); + state_type = getStateType(DrawData.WIDGET_WHOLE); + byte[] detail = Converter.wcsToMbcs(null, "entry", true); + OS.gtk_paint_shadow(gtkStyle, drawable, OS.GTK_STATE_NORMAL, OS.GTK_SHADOW_IN, null, entryHandle, detail, x, y, width - arrow_button_width, height); + xthickness = OS.gtk_style_get_xthickness(gtkStyle); + ythickness = OS.gtk_style_get_xthickness(gtkStyle); + x += xthickness; + y += ythickness; + width -= 2 * xthickness; + height -= 2 * ythickness; + detail = Converter.wcsToMbcs(null, "entry_bg", true); + OS.gtk_paint_flat_box(gtkStyle, drawable, state_type, OS.GTK_SHADOW_NONE, null, entryHandle, detail, x, y, width - arrow_button_width, height); + + if (clientArea != null) { + clientArea.x = x; + clientArea.y = y; + clientArea.width = width - arrow_button_width; + clientArea.height = height; + } +} + +int getStateType(int part) { + if (part == DrawData.WIDGET_WHOLE) { + int state_type = OS.GTK_STATE_NORMAL; + if ((state[DrawData.WIDGET_WHOLE] & DrawData.DISABLED) != 0) { + state_type = OS.GTK_STATE_INSENSITIVE; + } + return state_type; + } + return super.getStateType(part); +} + +int hit(Theme theme, Point position, Rectangle bounds) { + if (!bounds.contains(position)) return DrawData.WIDGET_NOWHERE; + int /*long*/ buttonHandle = theme.buttonHandle; + int /*long*/ gtkStyle = OS.gtk_widget_get_style(buttonHandle); + int interior_focus = theme.getWidgetProperty(buttonHandle, "interior-focus"); + int focus_line_width = theme.getWidgetProperty(buttonHandle, "focus-line-width"); + int focus_padding = theme.getWidgetProperty(buttonHandle, "focus-padding"); + int xthickness = OS.gtk_style_get_xthickness(gtkStyle); + int ythickness = OS.gtk_style_get_xthickness(gtkStyle); + int arrow_width = MIN_ARROW_SIZE; + int x_border = xthickness + focus_padding; + int y_border = ythickness + focus_padding; + if (interior_focus == 0) { + x_border += focus_line_width; + y_border += focus_line_width; + } + int arrow_button_width = arrow_width + x_border * 2; + int arrow_button_x = bounds.x + bounds.width - arrow_button_width; + Rectangle arrowRect = new Rectangle(arrow_button_x, bounds.y, arrow_button_width, bounds.height); + if (arrowRect.contains(position)) return DrawData.COMBO_ARROW; + return DrawData.WIDGET_WHOLE; +} + +} diff --git a/bundles/org.eclipse.swt/Eclipse SWT Theme/gtk/org/eclipse/swt/internal/theme/DrawData.java b/bundles/org.eclipse.swt/Eclipse SWT Theme/gtk/org/eclipse/swt/internal/theme/DrawData.java new file mode 100644 index 0000000000..bc1651c081 --- /dev/null +++ b/bundles/org.eclipse.swt/Eclipse SWT Theme/gtk/org/eclipse/swt/internal/theme/DrawData.java @@ -0,0 +1,181 @@ +package org.eclipse.swt.internal.theme; + +import org.eclipse.swt.graphics.*; +import org.eclipse.swt.internal.*; +import org.eclipse.swt.internal.gtk.*; + +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) { + int /*long*/ drawable = gc.getGCData().drawable; + Rectangle rect = image.getBounds(); + int state_type = getStateType(DrawData.WIDGET_WHOLE); + if (state_type == OS.GTK_STATE_NORMAL) { + gc.drawImage(image, 0, 0, rect.width, rect.height, bounds.x, bounds.y, bounds.width, bounds.height); + } else { + int /*long*/ pixbuf = Theme.createPixbuf(image); + int /*long*/ source = OS.gtk_icon_source_new(); + if (source != 0) { + OS.gtk_icon_source_set_pixbuf(source, pixbuf); + //TODO - always uses buttonHandle + int /*long*/ buttonHandle = theme.buttonHandle; + int /*long*/ gtkStyle = OS.gtk_widget_get_style (buttonHandle); + theme.transferClipping(gc, gtkStyle); + int /*long*/ rendered = OS.gtk_style_render_icon(gtkStyle, source, OS.GTK_TEXT_DIR_NONE, state_type, -1, buttonHandle, null); + OS.g_object_unref(pixbuf); + //TODO - stretching + if (rendered != 0) { + OS.gdk_draw_pixbuf(drawable, gc.handle, rendered, 0, 0, bounds.x, bounds.y, bounds.width, bounds.height, OS.GDK_RGB_DITHER_NORMAL, 0, 0); + OS.g_object_unref(rendered); + } + OS.gtk_icon_source_free(source); + } + } +} + +void drawText(Theme theme, String text, int flags, GC gc, Rectangle bounds) { + int /*long*/ widget = getTextHandle(theme); + int /*long*/ gtkStyle = OS.gtk_widget_get_style(widget); + int /*long*/ drawable = gc.getGCData().drawable; + theme.transferClipping (gc, gtkStyle); + byte[] buffer = Converter.wcsToMbcs(null, text, true); + int /*long*/ layout = OS.gtk_widget_create_pango_layout(widget, buffer); + int[] width = new int[1], height = new int[1]; + OS.pango_layout_get_size(layout, width, height); + OS.pango_layout_set_width(layout, bounds.width * OS.PANGO_SCALE); + int x = bounds.x; + int y = bounds.y; + if ((flags & DrawData.DRAW_LEFT) != 0) { + OS.pango_layout_set_alignment(layout, OS.PANGO_ALIGN_LEFT); + } + if ((flags & DrawData.DRAW_HCENTER) != 0) { + OS.pango_layout_set_alignment(layout, OS.PANGO_ALIGN_CENTER); + } + if ((flags & DrawData.DRAW_RIGHT) != 0) { + OS.pango_layout_set_alignment(layout, OS.PANGO_ALIGN_RIGHT); + } + if ((flags & DrawData.DRAW_VCENTER) != 0) { + y += (bounds.height - OS.PANGO_PIXELS(height[0])) / 2; + } + if ((flags & DrawData.DRAW_BOTTOM) != 0) { + y += bounds.height - OS.PANGO_PIXELS(height[0]); + } + int state_type = getStateType(DrawData.WIDGET_WHOLE); + byte[] detail = Converter.wcsToMbcs(null, "label", true); + OS.gtk_paint_layout(gtkStyle, drawable, state_type, false, null, widget, detail, x, y, layout); + OS.g_object_unref(layout); +} + +Rectangle getBounds(int part, Rectangle bounds) { + return new Rectangle(bounds.x, bounds.y, bounds.width, bounds.height); +} + +int getStateType(int part) { + int state = this.state[part]; + int state_type = OS.GTK_STATE_NORMAL; + if ((state & DrawData.DISABLED) != 0) { + state_type = OS.GTK_STATE_INSENSITIVE; + } else { + if ((state & DrawData.SELECTED) != 0) state_type = OS.GTK_STATE_ACTIVE; + if ((state & DrawData.HOT) != 0) { + if ((state & DrawData.PRESSED) != 0) { + state_type = OS.GTK_STATE_ACTIVE; + } else { + state_type = OS.GTK_STATE_PRELIGHT; + } + } + } + return state_type; +} + +int /*long*/ getTextHandle(Theme theme) { + return theme.labelHandle; +} + +int hit(Theme theme, Point position, Rectangle bounds) { + return -1; +} + +Rectangle measureText(Theme theme, String text, int flags, GC gc, Rectangle bounds) { + int /*long*/ widget = getTextHandle(theme); + byte[] buffer = Converter.wcsToMbcs(null, text, true); + int /*long*/ layout = OS.gtk_widget_create_pango_layout(widget, buffer); + if (bounds != null) OS.pango_layout_set_width(layout, bounds.width); + if ((flags & DrawData.DRAW_LEFT) != 0) { + OS.pango_layout_set_alignment(layout, OS.PANGO_ALIGN_LEFT); + } + if ((flags & DrawData.DRAW_HCENTER) != 0) { + OS.pango_layout_set_alignment(layout, OS.PANGO_ALIGN_CENTER); + } + if ((flags & DrawData.DRAW_RIGHT) != 0) { + OS.pango_layout_set_alignment(layout, OS.PANGO_ALIGN_RIGHT); + } + int[] width = new int[1], height = new int[1]; + OS.pango_layout_get_size(layout, width, height); + OS.g_object_unref(layout); + return new Rectangle(0, 0, OS.PANGO_PIXELS(width[0]), OS.PANGO_PIXELS(height[0])); +} + +} diff --git a/bundles/org.eclipse.swt/Eclipse SWT Theme/gtk/org/eclipse/swt/internal/theme/ExpanderDrawData.java b/bundles/org.eclipse.swt/Eclipse SWT Theme/gtk/org/eclipse/swt/internal/theme/ExpanderDrawData.java new file mode 100644 index 0000000000..7a43a03a09 --- /dev/null +++ b/bundles/org.eclipse.swt/Eclipse SWT Theme/gtk/org/eclipse/swt/internal/theme/ExpanderDrawData.java @@ -0,0 +1,39 @@ +package org.eclipse.swt.internal.theme; + +import org.eclipse.swt.*; +import org.eclipse.swt.graphics.*; +import org.eclipse.swt.internal.*; +import org.eclipse.swt.internal.gtk.*; + +public class ExpanderDrawData extends DrawData { + +public ExpanderDrawData() { + state = new int[1]; +} + +void draw(Theme theme, GC gc, Rectangle bounds) { + int /*long*/ treeHandle = theme.treeHandle; + int /*long*/ gtkStyle = OS.gtk_widget_get_style (treeHandle); + int /*long*/ drawable = gc.getGCData().drawable; + theme.transferClipping(gc, gtkStyle); + int state_type = getStateType(DrawData.WIDGET_WHOLE); + int expander_style = OS.GTK_EXPANDER_COLAPSED; + if ((this.style & SWT.DOWN) != 0) expander_style = OS.GTK_EXPANDER_EXPANDED; + byte[] detail = Converter.wcsToMbcs(null, "treeview", true); + int expander_size = theme.getWidgetProperty(treeHandle, "expander-size"); + int x = bounds.x + expander_size / 2; + int y = bounds.y + expander_size / 2; + OS.gtk_paint_expander(gtkStyle, drawable, state_type, null, treeHandle, detail, x, y, expander_style); +} + +int hit(Theme theme, Point position, Rectangle bounds) { + if (!bounds.contains(position)) return DrawData.WIDGET_NOWHERE; + int /*long*/ treeHandle = theme.treeHandle; + int expander_size = theme.getWidgetProperty(treeHandle, "expander-size"); + if (new Rectangle(bounds.x, bounds.y, expander_size, expander_size).contains(position)) { + return DrawData.WIDGET_WHOLE; + } + return DrawData.WIDGET_NOWHERE; +} + +} diff --git a/bundles/org.eclipse.swt/Eclipse SWT Theme/gtk/org/eclipse/swt/internal/theme/GroupDrawData.java b/bundles/org.eclipse.swt/Eclipse SWT Theme/gtk/org/eclipse/swt/internal/theme/GroupDrawData.java new file mode 100644 index 0000000000..4404a9e101 --- /dev/null +++ b/bundles/org.eclipse.swt/Eclipse SWT Theme/gtk/org/eclipse/swt/internal/theme/GroupDrawData.java @@ -0,0 +1,58 @@ +package org.eclipse.swt.internal.theme; + +import org.eclipse.swt.graphics.*; +import org.eclipse.swt.internal.*; +import org.eclipse.swt.internal.gtk.*; + +public class GroupDrawData extends DrawData { + public int headerWidth; + public int headerHeight; + public Rectangle headerArea; + + static final int GROUP_X = 2; + static final int GROUP_PAD = 1; + +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) { + int /*long*/ frameHandle = theme.frameHandle; + int /*long*/ gtkStyle = OS.gtk_widget_get_style (frameHandle); + int /*long*/ drawable = gc.getGCData().drawable; + theme.transferClipping(gc, gtkStyle); + int xthickness = OS.gtk_style_get_xthickness(gtkStyle); + int ythickness = OS.gtk_style_get_ythickness(gtkStyle); + int x = bounds.x, y = bounds.y + headerHeight / 2, width = bounds.width, height = bounds.height - headerHeight / 2; + byte[] detail = Converter.wcsToMbcs(null, "frame", true); + int gap_x = xthickness + GROUP_X, gap_width = headerWidth + GROUP_PAD * 2, gap_side = OS.GTK_POS_TOP; + int state_type = getStateType(DrawData.WIDGET_WHOLE); + OS.gtk_paint_shadow_gap(gtkStyle, drawable, state_type, OS.GTK_SHADOW_ETCHED_IN, null, frameHandle, detail, x, y, width, height, gap_side, gap_x, gap_width); + if (headerArea != null) { + headerArea.x = bounds.x + gap_x + GROUP_PAD; + headerArea.y = bounds.y; + headerArea.width = headerWidth; + headerArea.height = headerHeight; + } + if (clientArea != null) { + clientArea.x = bounds.x + xthickness; + clientArea.y = bounds.y + ythickness + headerHeight; + clientArea.width = bounds.width - 2 * xthickness; + clientArea.height = bounds.height - 2 * ythickness - headerHeight; + } +} + +int getStateType(int part) { + int state = this.state[part]; + int state_type = OS.GTK_STATE_NORMAL; + if ((state & DrawData.DISABLED) != 0) state_type = OS.GTK_STATE_INSENSITIVE; + return state_type; +} + +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/gtk/org/eclipse/swt/internal/theme/ProgressBarDrawData.java b/bundles/org.eclipse.swt/Eclipse SWT Theme/gtk/org/eclipse/swt/internal/theme/ProgressBarDrawData.java new file mode 100644 index 0000000000..2015009041 --- /dev/null +++ b/bundles/org.eclipse.swt/Eclipse SWT Theme/gtk/org/eclipse/swt/internal/theme/ProgressBarDrawData.java @@ -0,0 +1,51 @@ +package org.eclipse.swt.internal.theme; + +import org.eclipse.swt.*; +import org.eclipse.swt.graphics.*; +import org.eclipse.swt.internal.*; +import org.eclipse.swt.internal.gtk.*; + +public class ProgressBarDrawData extends RangeDrawData { + +public ProgressBarDrawData() { + state = new int[1]; +} + +void draw(Theme theme, GC gc, Rectangle bounds) { + int /*long*/ progressHandle = theme.progressHandle; + int /*long*/ gtkStyle = OS.gtk_widget_get_style (progressHandle); + int /*long*/ drawable = gc.getGCData().drawable; + theme.transferClipping(gc, gtkStyle); + byte[] detail = Converter.wcsToMbcs(null, "trough", true); + int x = bounds.x, y = bounds.y, width = bounds.width, height = bounds.height; + OS.gtk_paint_box(gtkStyle, drawable, getStateType(DrawData.WIDGET_WHOLE), OS.GTK_SHADOW_IN, null, progressHandle, detail, x, y, width, height); + int xthichness = OS.gtk_style_get_xthickness(gtkStyle); + int ythichness = OS.gtk_style_get_ythickness(gtkStyle); + if ((style & SWT.VERTICAL) != 0) { + OS.gtk_progress_bar_set_orientation(progressHandle, OS.GTK_PROGRESS_BOTTOM_TO_TOP); + x += xthichness; + width -= xthichness * 2; + height -= ythichness * 2; + height *= selection / (float)Math.max(1, (maximum - minimum)); + y += bounds.height - ythichness - height; + } else { + OS.gtk_progress_bar_set_orientation(progressHandle, OS.GTK_PROGRESS_LEFT_TO_RIGHT); + x += xthichness; + y += ythichness; + width -= xthichness * 2; + height -= ythichness * 2; + width *= selection / (float)Math.max(1, maximum - minimum); + } + detail = Converter.wcsToMbcs(null, "bar", true); + OS.gtk_paint_box(gtkStyle, drawable, OS.GTK_STATE_PRELIGHT, OS.GTK_SHADOW_OUT, null, progressHandle, detail, x, y, width, height); +} + +int getStateType(int part) { + return OS.GTK_STATE_NORMAL; +} + +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/gtk/org/eclipse/swt/internal/theme/RangeDrawData.java b/bundles/org.eclipse.swt/Eclipse SWT Theme/gtk/org/eclipse/swt/internal/theme/RangeDrawData.java new file mode 100644 index 0000000000..8581329112 --- /dev/null +++ b/bundles/org.eclipse.swt/Eclipse SWT Theme/gtk/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/gtk/org/eclipse/swt/internal/theme/ScaleDrawData.java b/bundles/org.eclipse.swt/Eclipse SWT Theme/gtk/org/eclipse/swt/internal/theme/ScaleDrawData.java new file mode 100644 index 0000000000..85c0a9c654 --- /dev/null +++ b/bundles/org.eclipse.swt/Eclipse SWT Theme/gtk/org/eclipse/swt/internal/theme/ScaleDrawData.java @@ -0,0 +1,21 @@ +package org.eclipse.swt.internal.theme; + +import org.eclipse.swt.graphics.*; + +public class ScaleDrawData extends RangeDrawData { + public int increment; + public int pageIncrement; + +public ScaleDrawData() { + state = new int[4]; +} + +void draw(Theme theme, GC gc, Rectangle bounds) { + +} + +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/gtk/org/eclipse/swt/internal/theme/ScrollBarDrawData.java b/bundles/org.eclipse.swt/Eclipse SWT Theme/gtk/org/eclipse/swt/internal/theme/ScrollBarDrawData.java new file mode 100644 index 0000000000..0bdfa8b6a8 --- /dev/null +++ b/bundles/org.eclipse.swt/Eclipse SWT Theme/gtk/org/eclipse/swt/internal/theme/ScrollBarDrawData.java @@ -0,0 +1,21 @@ +package org.eclipse.swt.internal.theme; + +import org.eclipse.swt.graphics.*; + +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) { +} + +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/gtk/org/eclipse/swt/internal/theme/TabFolderDrawData.java b/bundles/org.eclipse.swt/Eclipse SWT Theme/gtk/org/eclipse/swt/internal/theme/TabFolderDrawData.java new file mode 100644 index 0000000000..9ace86c180 --- /dev/null +++ b/bundles/org.eclipse.swt/Eclipse SWT Theme/gtk/org/eclipse/swt/internal/theme/TabFolderDrawData.java @@ -0,0 +1,57 @@ +package org.eclipse.swt.internal.theme; + +import org.eclipse.swt.SWT; +import org.eclipse.swt.graphics.*; +import org.eclipse.swt.internal.*; +import org.eclipse.swt.internal.gtk.*; + +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 /*long*/ notebookHandle = theme.notebookHandle; + int /*long*/ gtkStyle = OS.gtk_widget_get_style (notebookHandle); + int /*long*/ drawable = gc.getGCData().drawable; + theme.transferClipping(gc, gtkStyle); + int x = bounds.x, y = bounds.y, width = bounds.width, height = bounds.height; + height -= tabsHeight; + int gap_x = selectedX, gap_width = selectedWidth, gap_side = OS.GTK_POS_TOP; + if ((style & SWT.BOTTOM) != 0) { + gap_side = OS.GTK_POS_BOTTOM; + } else { + y += tabsHeight; + } + byte[] detail = Converter.wcsToMbcs(null, "notebook", true); + OS.gtk_paint_box_gap(gtkStyle, drawable, getStateType(DrawData.WIDGET_WHOLE), OS.GTK_SHADOW_OUT, null, notebookHandle, detail, x, y, width, height, gap_side, gap_x, gap_width); + 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; + } + } +} + +int getStateType(int part) { + return OS.GTK_STATE_NORMAL; +} + +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/gtk/org/eclipse/swt/internal/theme/TabItemDrawData.java b/bundles/org.eclipse.swt/Eclipse SWT Theme/gtk/org/eclipse/swt/internal/theme/TabItemDrawData.java new file mode 100644 index 0000000000..b2d07980bb --- /dev/null +++ b/bundles/org.eclipse.swt/Eclipse SWT Theme/gtk/org/eclipse/swt/internal/theme/TabItemDrawData.java @@ -0,0 +1,93 @@ +package org.eclipse.swt.internal.theme; + +import org.eclipse.swt.SWT; +import org.eclipse.swt.graphics.*; +import org.eclipse.swt.internal.*; +import org.eclipse.swt.internal.gtk.*; + +public class TabItemDrawData extends DrawData { + + public TabFolderDrawData parent; + public int position; + + static final int TAB_CURVATURE = 1; + +public TabItemDrawData() { + state = new int[1]; +} + +Rectangle computeTrim(Theme theme, GC gc) { + int /*long*/ notebookHandle = theme.notebookHandle; + int /*long*/ gtkStyle = OS.gtk_widget_get_style(notebookHandle); + int hborder, vborder; + if (OS.GTK_VERSION >= OS.VERSION(2, 4, 0)) { + hborder = theme.getWidgetProperty(notebookHandle, "tab-hborder"); + vborder = theme.getWidgetProperty(notebookHandle, "tab-vborder"); + } else { + hborder = 2; + vborder = 2; + } + int focus_width = theme.getWidgetProperty(notebookHandle, "focus-line-width"); + int xthickness = OS.gtk_style_get_xthickness(gtkStyle); + int ythickness = OS.gtk_style_get_ythickness(gtkStyle); + int borderX = xthickness + TAB_CURVATURE + focus_width + hborder; + int borderY = ythickness + TAB_CURVATURE + focus_width + vborder; + int x = clientArea.x - borderX; + int y = clientArea.y - borderY; + int width = clientArea.width + 2 * borderX; + int height = clientArea.height + 2 * borderY; + return new Rectangle(x, y, width, height); +} + +void draw(Theme theme, GC gc, Rectangle bounds) { + int /*long*/ notebookHandle = theme.notebookHandle; + int /*long*/ gtkStyle = OS.gtk_widget_get_style (notebookHandle); + int /*long*/ drawable = gc.getGCData().drawable; + theme.transferClipping(gc, gtkStyle); + int x = bounds.x, y = bounds.y, width = bounds.width, height = bounds.height; + if ((state[DrawData.WIDGET_WHOLE] & DrawData.SELECTED) == 0) { + if ((parent.style & SWT.BOTTOM) == 0) { + y += TAB_CURVATURE; + } + height -= TAB_CURVATURE; + } + int gap_side = OS.GTK_POS_BOTTOM; + if ((parent.style & SWT.BOTTOM) != 0) { + gap_side = OS.GTK_POS_TOP; + } + int state_type = getStateType(DrawData.WIDGET_WHOLE); + byte[] detail = Converter.wcsToMbcs(null, "tab", true); + OS.gtk_paint_extension(gtkStyle, drawable, state_type, OS.GTK_SHADOW_OUT, null, notebookHandle, detail, x, y, width, height, gap_side); + if (clientArea != null) { + int hborder, vborder; + if (OS.GTK_VERSION >= OS.VERSION(2, 4, 0)) { + hborder = theme.getWidgetProperty(notebookHandle, "tab-hborder"); + vborder = theme.getWidgetProperty(notebookHandle, "tab-vborder"); + } else { + hborder = 2; + vborder = 2; + } + int focus_line_width = theme.getWidgetProperty(notebookHandle, "focus-line-width"); + int xthickness = OS.gtk_style_get_xthickness(gtkStyle); + int ythickness = OS.gtk_style_get_ythickness(gtkStyle); + int borderX = xthickness + TAB_CURVATURE + focus_line_width + hborder; + int borderY = ythickness + TAB_CURVATURE + focus_line_width + vborder; + clientArea.x = bounds.x + borderX; + clientArea.y = bounds.y + borderY; + clientArea.width = bounds.width - 2 * borderX; + clientArea.height = bounds.height - 2 * borderY; + } +} + +int getStateType(int part) { + int state = this.state[part]; + int state_type = OS.GTK_STATE_ACTIVE; + if ((state & DrawData.SELECTED) != 0) state_type = OS.GTK_STATE_NORMAL; + return state_type; +} + +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/gtk/org/eclipse/swt/internal/theme/Theme.java b/bundles/org.eclipse.swt/Eclipse SWT Theme/gtk/org/eclipse/swt/internal/theme/Theme.java new file mode 100644 index 0000000000..2c6fe4a07e --- /dev/null +++ b/bundles/org.eclipse.swt/Eclipse SWT Theme/gtk/org/eclipse/swt/internal/theme/Theme.java @@ -0,0 +1,257 @@ +package org.eclipse.swt.internal.theme; + +import org.eclipse.swt.*; +import org.eclipse.swt.graphics.*; +import org.eclipse.swt.internal.*; +import org.eclipse.swt.internal.gtk.*; + +public class Theme { + Device device; + + int /*long*/ shellHandle, fixedHandle, buttonHandle, arrowHandle, + frameHandle, entryHandle, checkButtonHandle, radioButtonHandle, + notebookHandle, treeHandle, progressHandle, toolbarHandle, + labelHandle, separatorHandle; + +public Theme(Device device) { + this.device = device; + shellHandle = OS.gtk_window_new (OS.GTK_WINDOW_TOPLEVEL); + fixedHandle = OS.gtk_fixed_new(); + buttonHandle = OS.gtk_button_new(); + arrowHandle = OS.gtk_arrow_new(OS.GTK_ARROW_DOWN, OS.GTK_SHADOW_NONE); + checkButtonHandle = OS.gtk_check_button_new(); + frameHandle = OS.gtk_check_button_new(); + entryHandle = OS.gtk_entry_new(); + radioButtonHandle = OS.gtk_radio_button_new(0); + notebookHandle = OS.gtk_notebook_new(); + progressHandle = OS.gtk_progress_bar_new(); + toolbarHandle = OS.gtk_toolbar_new(); + treeHandle = OS.gtk_tree_view_new_with_model(0); + separatorHandle = OS.gtk_vseparator_new(); + labelHandle = OS.gtk_label_new(null); + OS.gtk_container_add (fixedHandle, labelHandle); + OS.gtk_container_add (fixedHandle, frameHandle); + OS.gtk_container_add (fixedHandle, entryHandle); + OS.gtk_container_add (fixedHandle, separatorHandle); + OS.gtk_container_add (fixedHandle, arrowHandle); + OS.gtk_container_add (fixedHandle, toolbarHandle); + OS.gtk_container_add (fixedHandle, progressHandle); + OS.gtk_container_add (fixedHandle, checkButtonHandle); + OS.gtk_container_add (fixedHandle, radioButtonHandle); + OS.gtk_container_add (fixedHandle, buttonHandle); + OS.gtk_container_add (fixedHandle, treeHandle); + OS.gtk_container_add (fixedHandle, notebookHandle); + OS.gtk_container_add (shellHandle, fixedHandle); + OS.gtk_widget_realize (separatorHandle); + OS.gtk_widget_realize (labelHandle); + OS.gtk_widget_realize (frameHandle); + OS.gtk_widget_realize (entryHandle); + OS.gtk_widget_realize (arrowHandle); + OS.gtk_widget_realize (buttonHandle); + OS.gtk_widget_realize (treeHandle); + OS.gtk_widget_realize (notebookHandle); + OS.gtk_widget_realize (checkButtonHandle); + OS.gtk_widget_realize (radioButtonHandle); + OS.gtk_widget_realize (progressHandle); + OS.gtk_widget_realize (toolbarHandle); + OS.gtk_widget_realize (shellHandle); +} + +//TODO - share this code +static int /*long*/ createPixbuf(Image image) { + int [] w = new int [1], h = new int [1]; + OS.gdk_drawable_get_size (image.pixmap, w, h); + int /*long*/ colormap = OS.gdk_colormap_get_system (); + int /*long*/ pixbuf; + boolean hasMask = image.mask != 0 && OS.gdk_drawable_get_depth (image.mask) == 1; + if (hasMask) { + pixbuf = OS.gdk_pixbuf_new (OS.GDK_COLORSPACE_RGB, true, 8, w [0], h [0]); + if (pixbuf == 0) SWT.error (SWT.ERROR_NO_HANDLES); + OS.gdk_pixbuf_get_from_drawable (pixbuf, image.pixmap, colormap, 0, 0, 0, 0, w [0], h [0]); + int /*long*/ maskPixbuf = OS.gdk_pixbuf_new(OS.GDK_COLORSPACE_RGB, false, 8, w [0], h [0]); + if (maskPixbuf == 0) SWT.error (SWT.ERROR_NO_HANDLES); + OS.gdk_pixbuf_get_from_drawable(maskPixbuf, image.mask, 0, 0, 0, 0, 0, w [0], h [0]); + int stride = OS.gdk_pixbuf_get_rowstride(pixbuf); + int /*long*/ pixels = OS.gdk_pixbuf_get_pixels(pixbuf); + byte[] line = new byte[stride]; + int maskStride = OS.gdk_pixbuf_get_rowstride(maskPixbuf); + int /*long*/ maskPixels = OS.gdk_pixbuf_get_pixels(maskPixbuf); + byte[] maskLine = new byte[maskStride]; + for (int y=0; y<h[0]; y++) { + int /*long*/ offset = pixels + (y * stride); + OS.memmove(line, offset, stride); + int /*long*/ maskOffset = maskPixels + (y * maskStride); + OS.memmove(maskLine, maskOffset, maskStride); + for (int x=0; x<w[0]; x++) { + if (maskLine[x * 3] == 0) { + line[x * 4 + 3] = 0; + } + } + OS.memmove(offset, line, stride); + } + OS.g_object_unref(maskPixbuf); + } else { + ImageData data = image.getImageData (); + boolean hasAlpha = data.getTransparencyType () == SWT.TRANSPARENCY_ALPHA; + pixbuf = OS.gdk_pixbuf_new (OS.GDK_COLORSPACE_RGB, hasAlpha, 8, w [0], h [0]); + if (pixbuf == 0) SWT.error (SWT.ERROR_NO_HANDLES); + OS.gdk_pixbuf_get_from_drawable (pixbuf, image.pixmap, colormap, 0, 0, 0, 0, w [0], h [0]); + if (hasAlpha) { + byte [] alpha = data.alphaData; + int stride = OS.gdk_pixbuf_get_rowstride (pixbuf); + int /*long*/ pixels = OS.gdk_pixbuf_get_pixels (pixbuf); + byte [] line = new byte [stride]; + for (int y = 0; y < h [0]; y++) { + int /*long*/ offset = pixels + (y * stride); + OS.memmove (line, offset, stride); + for (int x = 0; x < w [0]; x++) { + line [x*4+3] = alpha [y*w [0]+x]; + } + OS.memmove (offset, line, stride); + } + } + } + return pixbuf; +} + +void checkTheme() { + if (isDisposed()) SWT.error(SWT.ERROR_GRAPHIC_DISPOSED); +} + +public Rectangle computeTrim(GC gc, DrawData data) { + 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 () { + if (shellHandle == 0) return; + OS.gtk_widget_destroy(shellHandle); + shellHandle = fixedHandle = buttonHandle = arrowHandle = + frameHandle = entryHandle = checkButtonHandle = radioButtonHandle = + notebookHandle = treeHandle = progressHandle = toolbarHandle = + labelHandle = separatorHandle = 0; +} + +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); +} + +int getWidgetProperty(int /*long*/ handle, String name) { + byte[] propertyName = Converter.wcsToMbcs(null, name, true); + int[] result = new int[1]; + OS.gtk_widget_style_get(handle, propertyName, result, 0); + return result[0]; +} + +void transferClipping(GC gc, int /*long*/ style) { + GCData data = gc.getGCData(); + int /*long*/ clipRgn = data.clipRgn; + int /*long*/ damageRgn = data.damageRgn; + int /*long*/ clipping = clipRgn; + if (damageRgn != 0) { + if (clipping != 0) { + clipping = OS.gdk_region_new(); + OS.gdk_region_union(clipping, clipRgn); + OS.gdk_region_intersect(clipping, damageRgn); + } else { + clipping = damageRgn; + } + } + int /*long*/ [] curGC = new int /*long*/ [1]; + for (int i = 0; i < 5; i++) { + OS.gtk_style_get_fg_gc (style, i, curGC); + if (curGC[0] != 0) OS.gdk_gc_set_clip_region (curGC[0], clipping); + OS.gtk_style_get_bg_gc (style, i, curGC); + if (curGC[0] != 0) OS.gdk_gc_set_clip_region (curGC[0], clipping); + OS.gtk_style_get_light_gc (style, i, curGC); + if (curGC[0] != 0) OS.gdk_gc_set_clip_region (curGC[0], clipping); + OS.gtk_style_get_dark_gc (style, i, curGC); + if (curGC[0] != 0) OS.gdk_gc_set_clip_region (curGC[0], clipping); + OS.gtk_style_get_mid_gc (style, i, curGC); + if (curGC[0] != 0) OS.gdk_gc_set_clip_region (curGC[0], clipping); + OS.gtk_style_get_text_gc (style, i, curGC); + if (curGC[0] != 0) OS.gdk_gc_set_clip_region (curGC[0], clipping); + OS.gtk_style_get_text_aa_gc (style, i, curGC); + if (curGC[0] != 0) OS.gdk_gc_set_clip_region (curGC[0], clipping); + } + OS.gtk_style_get_black_gc (style, curGC); + if (curGC[0] != 0) OS.gdk_gc_set_clip_region (curGC[0], clipping); + OS.gtk_style_get_white_gc (style, curGC); + if (curGC[0] != 0) OS.gdk_gc_set_clip_region (curGC[0], clipping); + if (clipping != clipRgn && clipping != damageRgn) { + OS.gdk_region_destroy(clipping); + } +} +} diff --git a/bundles/org.eclipse.swt/Eclipse SWT Theme/gtk/org/eclipse/swt/internal/theme/ToolBarDrawData.java b/bundles/org.eclipse.swt/Eclipse SWT Theme/gtk/org/eclipse/swt/internal/theme/ToolBarDrawData.java new file mode 100644 index 0000000000..8ab2f1b751 --- /dev/null +++ b/bundles/org.eclipse.swt/Eclipse SWT Theme/gtk/org/eclipse/swt/internal/theme/ToolBarDrawData.java @@ -0,0 +1,37 @@ +package org.eclipse.swt.internal.theme; + +import org.eclipse.swt.graphics.*; +import org.eclipse.swt.internal.*; +import org.eclipse.swt.internal.gtk.*; + +public class ToolBarDrawData extends DrawData { + +public ToolBarDrawData() { + state = new int[1]; +} + +void draw(Theme theme, GC gc, Rectangle bounds) { + int /*long*/ toolbarHandle = theme.toolbarHandle; + int /*long*/ gtkStyle = OS.gtk_widget_get_style (toolbarHandle); + int /*long*/ drawable = gc.getGCData().drawable; + theme.transferClipping(gc, gtkStyle); + int x = bounds.x, y = bounds.y, width = bounds.width, height = bounds.height; + byte[] detail = Converter.wcsToMbcs(null, "toolbar", true); + OS.gtk_paint_box(gtkStyle, drawable, getStateType(DrawData.WIDGET_WHOLE), OS.GTK_SHADOW_NONE, null, toolbarHandle, detail, x, y, width, height); + if (clientArea != null) { + clientArea.x = bounds.x; + clientArea.y = bounds.y; + clientArea.width = bounds.width; + clientArea.height = bounds.height; + } +} + +int getStateType(int part) { + return OS.GTK_STATE_NORMAL; +} + +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/gtk/org/eclipse/swt/internal/theme/ToolItemDrawData.java b/bundles/org.eclipse.swt/Eclipse SWT Theme/gtk/org/eclipse/swt/internal/theme/ToolItemDrawData.java new file mode 100644 index 0000000000..0203eb8de7 --- /dev/null +++ b/bundles/org.eclipse.swt/Eclipse SWT Theme/gtk/org/eclipse/swt/internal/theme/ToolItemDrawData.java @@ -0,0 +1,156 @@ +package org.eclipse.swt.internal.theme; + +import org.eclipse.swt.*; +import org.eclipse.swt.graphics.*; +import org.eclipse.swt.internal.*; +import org.eclipse.swt.internal.gtk.*; + +public class ToolItemDrawData extends DrawData { + + public ToolBarDrawData parent; + + static final int ARROW_WIDTH = 8; + static final int ARROW_HEIGHT = 6; + +public ToolItemDrawData() { + state = new int[2]; +} + +Rectangle computeTrim(Theme theme, GC gc) { + int /*long*/ buttonHandle = theme.buttonHandle; + int /*long*/ gtkStyle = OS.gtk_widget_get_style(buttonHandle); + int focus_width = theme.getWidgetProperty(buttonHandle, "focus-line-width"); + int focus_padding = theme.getWidgetProperty(buttonHandle, "focus-padding"); + int xthickness = OS.gtk_style_get_xthickness(gtkStyle); + int ythickness = OS.gtk_style_get_ythickness(gtkStyle); + int borderX = xthickness + focus_width + focus_padding; + int borderY = ythickness + focus_width + focus_padding; + int x = clientArea.x - borderX; + int y = clientArea.y - borderY; + int width = clientArea.width + 2 * borderX; + int height = clientArea.height + 2 * borderY; + if ((style & SWT.DROP_DOWN) != 0) { + width += ARROW_WIDTH; + } + return new Rectangle(x, y, width, height); +} + +void draw(Theme theme, GC gc, Rectangle bounds) { + int state = this.state[DrawData.WIDGET_WHOLE]; + int /*long*/ drawable = gc.getGCData().drawable; + + if ((style & SWT.SEPARATOR) != 0) { + int state_type = getStateType(DrawData.WIDGET_WHOLE); + int /*long*/ separatorHandle = theme.separatorHandle; + byte[] detail = Converter.wcsToMbcs(null, "vseparator", true); + int /*long*/ gtkStyle = OS.gtk_widget_get_style (separatorHandle); + theme.transferClipping(gc, gtkStyle); + if ((parent.style & SWT.VERTICAL) != 0) { + OS.gtk_paint_hline(gtkStyle, drawable, state_type, null, separatorHandle, detail, bounds.x, bounds.x + bounds.width, bounds.y + bounds.height / 2); + } else { + OS.gtk_paint_vline(gtkStyle, drawable, state_type, null, separatorHandle, detail, bounds.y, bounds.y + bounds.height, bounds.x + bounds.width / 2); + } + return; + } + + int /*long*/ buttonHandle = theme.buttonHandle; + int /*long*/ gtkStyle = OS.gtk_widget_get_style (buttonHandle); + theme.transferClipping (gc, gtkStyle); + int focus_line_width = theme.getWidgetProperty(buttonHandle, "focus-line-width"); + int focus_padding = theme.getWidgetProperty(buttonHandle, "focus-padding"); + int border_width = OS.gtk_container_get_border_width(buttonHandle); + + int x = bounds.x + border_width; + int y = bounds.y + border_width; + int width = bounds.width - border_width * 2; + int height = bounds.height - border_width * 2; + + byte[] detail = null; + if ((style & (SWT.PUSH | SWT.DROP_DOWN)) != 0) { + detail = Converter.wcsToMbcs(null, "button", true); + } else if ((style & (SWT.CHECK | SWT.RADIO)) != 0) { + detail = Converter.wcsToMbcs(null, "togglebutton", true); + } + + int[] relief = new int[1]; + int /*long*/ toolbarHandle = theme.toolbarHandle; + OS.gtk_widget_style_get(toolbarHandle, OS.button_relief, relief, 0); + + int shadow_type = OS.GTK_SHADOW_OUT; + if ((state & (DrawData.SELECTED | DrawData.PRESSED)) != 0) shadow_type = OS.GTK_SHADOW_IN; + int state_type = getStateType(DrawData.WIDGET_WHOLE); + + if (relief[0] != OS.GTK_RELIEF_NONE || ((state & (DrawData.PRESSED | DrawData.HOT | DrawData.SELECTED)) != 0)) { + OS.gtk_paint_box(gtkStyle, drawable, state_type, shadow_type, null, buttonHandle, detail, x, y, width, height); + } + + if (clientArea != null) { + clientArea.x = bounds.x + border_width; + clientArea.y = bounds.y + border_width; + clientArea.width = bounds.width - 2 * border_width; + clientArea.height = bounds.height - 2 * border_width; + } + + int xthickness = OS.gtk_style_get_xthickness(gtkStyle); + int interior_focus = theme.getWidgetProperty(buttonHandle, "interior-focus"); + if ((style & SWT.DROP_DOWN) != 0) { + int arrow_width = ARROW_WIDTH; + int arrow_height = ARROW_HEIGHT; + int arrow_x = x + width - arrow_width - xthickness - focus_padding; + if (interior_focus == 0) arrow_x -= focus_line_width; + int arrow_y = y + (height - arrow_height) / 2; + byte[] arrow_detail = Converter.wcsToMbcs(null, "arrow", true); + OS.gtk_paint_arrow(gtkStyle, drawable, state_type, OS.GTK_SHADOW_NONE, null, theme.arrowHandle, arrow_detail, OS.GTK_ARROW_DOWN, true, arrow_x, arrow_y, arrow_width, arrow_height); + if (clientArea != null) { + clientArea.width -= bounds.x + bounds.width - arrow_x; + } + } + + if ((state & DrawData.FOCUSED) != 0) { + int child_displacement_y = theme.getWidgetProperty(buttonHandle, "child-displacement-y"); + int child_displacement_x = theme.getWidgetProperty(buttonHandle, "child-displacement-x"); + int displace_focus = 0; + if (OS.GTK_VERSION >= OS.VERSION (2, 6, 0)) { + displace_focus = theme.getWidgetProperty(buttonHandle, "displace-focus"); + } + + if (interior_focus != 0) { + int ythickness = OS.gtk_style_get_ythickness(gtkStyle); + x += xthickness + focus_padding; + y += ythickness + focus_padding; + width -= 2 * (xthickness + focus_padding); + height -= 2 * (ythickness + focus_padding); + } else { + x -= focus_line_width + focus_padding; + y -= focus_line_width + focus_padding; + width += 2 * (focus_line_width + focus_padding); + height += 2 * (focus_line_width + focus_padding); + } + + if ((state & (DrawData.PRESSED | DrawData.SELECTED)) != 0 && displace_focus != 0) { + x += child_displacement_x; + y += child_displacement_y; + } + + OS.gtk_paint_focus(gtkStyle, drawable, state_type, null, buttonHandle, detail, x, y, width, height); + } +} + +int hit(Theme theme, Point position, Rectangle bounds) { + if (!bounds.contains(position)) return DrawData.WIDGET_NOWHERE; + if ((style & SWT.DROP_DOWN) != 0) { + int /*long*/ buttonHandle = theme.buttonHandle; + int /*long*/ gtkStyle = OS.gtk_widget_get_style (buttonHandle); + int xthickness = OS.gtk_style_get_xthickness(gtkStyle); + int interior_focus = theme.getWidgetProperty(buttonHandle, "interior-focus"); + int focus_line_width = theme.getWidgetProperty(buttonHandle, "focus-line-width"); + int focus_padding = theme.getWidgetProperty(buttonHandle, "focus-padding"); + int arrow_width = ARROW_WIDTH; + int arrow_x = bounds.x + bounds.width - arrow_width - xthickness - focus_padding; + if (interior_focus == 0) arrow_x -= focus_line_width; + if (arrow_x <= position.x) return DrawData.TOOLITEM_ARROW; + } + return DrawData.WIDGET_WHOLE; +} + +} 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; +} + +} |