/******************************************************************************* * Copyright (c) 2000, 2012 IBM Corporation and others. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html * * Contributors: * IBM Corporation - initial API and implementation *******************************************************************************/ 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.cairo.Cairo; 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]; } @Override Rectangle computeTrim(Theme theme, GC gc) { long /*int*/ buttonHandle = theme.buttonHandle; long /*int*/ 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); } @Override void draw(Theme theme, GC gc, Rectangle bounds) { int state = this.state[DrawData.WIDGET_WHOLE]; long /*int*/ drawable = gc.getGCData().drawable; if ((style & SWT.SEPARATOR) != 0) { int state_type = getStateType(DrawData.WIDGET_WHOLE); long /*int*/ separatorHandle = theme.separatorHandle; byte[] detail = Converter.wcsToMbcs(null, "vseparator", true); long /*int*/ gtkStyle = OS.gtk_widget_get_style (separatorHandle); theme.transferClipping(gc, gtkStyle); if ((parent.style & SWT.VERTICAL) != 0) { if (OS.GTK3) { long /*int*/ cairo = OS.gdk_cairo_create (drawable); long /*int*/ context = OS.gtk_widget_get_style_context (separatorHandle); OS.gtk_render_line (context, cairo, bounds.x, bounds.y + bounds.height / 2, bounds.x + bounds.width, bounds.y + bounds.height / 2); Cairo.cairo_destroy(cairo); } else { OS.gtk_paint_hline(gtkStyle, drawable, state_type, null, separatorHandle, detail, bounds.x, bounds.x + bounds.width, bounds.y + bounds.height / 2); } } else { if (OS.GTK3) { long /*int*/ cairo = OS.gdk_cairo_create (drawable); long /*int*/ context = OS.gtk_widget_get_style_context (separatorHandle); OS.gtk_render_line (context, cairo, bounds.x + bounds.width / 2, bounds.y, bounds.x + bounds.width / 2, bounds.y + bounds.height); Cairo.cairo_destroy (cairo); } else { OS.gtk_paint_vline(gtkStyle, drawable, state_type, null, separatorHandle, detail, bounds.y, bounds.y + bounds.height, bounds.x + bounds.width / 2); } } return; } long /*int*/ buttonHandle = theme.buttonHandle; long /*int*/ 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]; long /*int*/ 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)) { gtk_render_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); gtk_render_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 = 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; } gtk_render_focus (gtkStyle, drawable, state_type, null, buttonHandle, detail, x, y, width, height); } } @Override int hit(Theme theme, Point position, Rectangle bounds) { if (!bounds.contains(position)) return DrawData.WIDGET_NOWHERE; if ((style & SWT.DROP_DOWN) != 0) { long /*int*/ buttonHandle = theme.buttonHandle; long /*int*/ 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; } }