package rocks.inspectit.ui.rcp.util; import org.eclipse.jface.resource.CompositeImageDescriptor; import org.eclipse.swt.SWT; import org.eclipse.swt.graphics.Color; import org.eclipse.swt.graphics.GC; import org.eclipse.swt.graphics.Image; import org.eclipse.swt.graphics.ImageData; import org.eclipse.swt.graphics.Point; import org.eclipse.swt.graphics.RGB; import org.eclipse.swt.widgets.Display; import org.eclipse.ui.forms.FormColors; /** * An arrow image descriptor. The images color is related to the list fore- and background color. * This makes the arrow visible even in high contrast mode. If <code>ltr</code> is true the arrow * points to the right, otherwise it points to the left. * <p> * <b>IMPORTANT:</b> The class is licensed under the Eclipse Public License v1.0 as it contains the * code from the {@link org.eclipse.jdt.internal.ui.javaeditor.breadcrumb.BreadcrumbItem} class * belonging to the Eclipse Rich Client Platform. EPL v1.0 license can be found * <a href="https://www.eclipse.org/legal/epl-v10.html">here</a>. * <p> * Please relate to the LICENSEEXCEPTIONS.txt file for more information about license exceptions * that apply regarding to InspectIT and Eclipse RCP and/or EPL Components. */ public class AccessibleArrowImage extends CompositeImageDescriptor { /** * Arrow size. */ private static final int ARROW_SIZE = 5; /** * Left to right arrow boolean. */ private final boolean fLTR; /** * Default constructor. * * @param ltr * Left to right arrow. */ public AccessibleArrowImage(boolean ltr) { fLTR = ltr; } /** * Draw the composite images. * <p> * Subclasses must implement this framework method to paint images within the given bounds using * one or more calls to the <code>drawImage</code> framework method. * </p> * * @param width * the width * @param height * the height * @see org.eclipse.jface.resource.CompositeImageDescriptor#drawCompositeImage(int, int) */ @Override protected void drawCompositeImage(int width, int height) { Display display = Display.getDefault(); Image image = new Image(display, ARROW_SIZE, ARROW_SIZE * 2); GC gc = new GC(image); Color triangle = createColor(SWT.COLOR_LIST_FOREGROUND, SWT.COLOR_LIST_BACKGROUND, 20, display); Color aliasing = createColor(SWT.COLOR_LIST_FOREGROUND, SWT.COLOR_LIST_BACKGROUND, 30, display); gc.setBackground(triangle); if (fLTR) { gc.fillPolygon(new int[] { mirror(0), 0, mirror(ARROW_SIZE), ARROW_SIZE, mirror(0), ARROW_SIZE * 2 }); } else { gc.fillPolygon(new int[] { ARROW_SIZE, 0, 0, ARROW_SIZE, ARROW_SIZE, ARROW_SIZE * 2 }); } gc.setForeground(aliasing); gc.drawLine(mirror(0), 1, mirror(ARROW_SIZE - 1), ARROW_SIZE); gc.drawLine(mirror(ARROW_SIZE - 1), ARROW_SIZE, mirror(0), (ARROW_SIZE * 2) - 1); gc.dispose(); triangle.dispose(); aliasing.dispose(); ImageData imageData = image.getImageData(); for (int y = 1; y < ARROW_SIZE; y++) { for (int x = 0; x < y; x++) { imageData.setAlpha(mirror(x), y, 255); } } for (int y = 0; y < ARROW_SIZE; y++) { for (int x = 0; x <= y; x++) { imageData.setAlpha(mirror(x), (ARROW_SIZE * 2) - y - 1, 255); } } int offset = 0; if (!fLTR) { offset = -1; } drawImage(imageData, ((width / 2) - (ARROW_SIZE / 2)) + offset, (height / 2) - ARROW_SIZE - 1); image.dispose(); } /** * Returns correct number of pixels depending on the arrow orientation. If arrow is set to be * from left to right original parameter values i returned. if not then the mirrored value is * returned. * * @param x * Pixels. * @return Returns correct number of pixels depending on the arrow orientation. If arrow is set * to be from left to right original parameter values i returned. if not then the * mirrored value is returned. */ private int mirror(int x) { if (fLTR) { return x; } return ARROW_SIZE - x - 1; } /** * Return the size of this composite image. * <p> * Subclasses must implement this framework method. * </p> * * @return the x and y size of the image expressed as a point object */ @Override protected Point getSize() { return new Point(10, 16); } /** * Blends two colors with the given ration. The colors are represented by int values as colors * as defined in the {@link SWT} class. * * @param color1 * First color. * @param color2 * Second color. * @param ratio * Percentage of the first color in the blend (0-100). * @param display * {@link Display} * @return New color. * @see FormColors#blend(RGB, RGB, int) */ private Color createColor(int color1, int color2, int ratio, Display display) { RGB rgb1 = display.getSystemColor(color1).getRGB(); RGB rgb2 = display.getSystemColor(color2).getRGB(); RGB blend = FormColors.blend(rgb2, rgb1, ratio); return new Color(display, blend); } }