/******************************************************************************* * Copyright (c) 2006 Chris Gross. 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: schtoo@schtoo.com(Chris Gross) - initial API and implementation ******************************************************************************/ package org.eclipse.nebula.widgets.pshelf; import org.eclipse.swt.SWT; import org.eclipse.swt.graphics.Color; import org.eclipse.swt.graphics.Font; import org.eclipse.swt.graphics.FontData; import org.eclipse.swt.graphics.GC; import org.eclipse.swt.graphics.Point; import org.eclipse.swt.graphics.RGB; import org.eclipse.swt.widgets.Control; import org.eclipse.swt.widgets.Display; /** * <p> * NOTE: THIS WIDGET AND ITS API ARE STILL UNDER DEVELOPMENT. THIS IS A PRE-RELEASE ALPHA * VERSION. USERS SHOULD EXPECT API CHANGES IN FUTURE VERSIONS. * </p> * * @author cgross */ public class RedmondShelfRenderer extends AbstractRenderer { private Color[] initialColors; // to dispose created colors private int textMargin = 2; private int margin = 4; private PShelf parent; private int spacing = 8; private Font initialFont; private Font initialOpenFont; private Color gradient1; private Color gradient2; private Font font; private Font selectedFont; private Color selectedGradient1; private Color selectedGradient2; private Color hoverGradient1; private Color hoverGradient2; private Color lineColor; private Color selectedForeground; private Color foreground; /** * {@inheritDoc} */ public Point computeSize(GC gc, int wHint, int hHint, Object value) { PShelfItem item = (PShelfItem)value; int h = 0; gc.setFont(font); if (item.getImage() == null){ h = gc.getFontMetrics().getHeight() + (2*(textMargin)); } else { h = Math.max(item.getImage().getBounds().height,gc.getFontMetrics().getHeight() + (2*textMargin)); } gc.setFont(selectedFont); h = Math.max(h,gc.getFontMetrics().getHeight() + (2*textMargin)); h += 2*margin; if (h % 2 != 0) h ++; return new Point(wHint,h); } /** * {@inheritDoc} */ public void paint(GC gc, Object value) { PShelfItem item = (PShelfItem)value; //Color back = parent.getBackground(); Color fore = parent.getForeground(); if (isSelected()){ gc.setForeground(selectedGradient1); gc.setBackground(selectedGradient2); } else { if (isHover()){ gc.setForeground(hoverGradient1); gc.setBackground(hoverGradient2); } else { gc.setForeground(gradient1); gc.setBackground(gradient2); } } gc.fillGradientRectangle(getBounds().x,getBounds().y,getBounds().width,getBounds().height,true); if ((parent.getStyle() & SWT.SIMPLE) != 0) { if (!isSelected()){ gc.setForeground(lineColor); gc.drawLine(0,getBounds().y,getBounds().width -1,getBounds().y); } } else { if (parent.getItems()[0] != item) { gc.setForeground(lineColor); gc.drawLine(0,getBounds().y,getBounds().width -1,getBounds().y); } if (isSelected()){ gc.setForeground(lineColor); gc.drawLine(0,getBounds().y + getBounds().height -1,getBounds().width -1,getBounds().y + getBounds().height -1); } } boolean imageLeft = true; if ((parent.getStyle() & SWT.SIMPLE) != 0) { imageLeft = !isSelected(); } int x = 6; if (item.getImage() != null && imageLeft){ int y2 = (getBounds().height - item.getImage().getBounds().height)/2; if ((getBounds().height - item.getImage().getBounds().height) % 2 != 0) y2 ++; gc.drawImage(item.getImage(),x,getBounds().y + y2); x += item.getImage().getBounds().width + spacing; } if (isSelected()){ gc.setFont(selectedFont); gc.setForeground(selectedForeground != null ? selectedForeground : fore); } else { gc.setFont(font); gc.setForeground(foreground != null ? foreground : fore); } int y2 = (getBounds().height - gc.getFontMetrics().getHeight())/2; if ((getBounds().height - gc.getFontMetrics().getHeight()) % 2 != 0) y2 ++; int textWidth = getBounds().width - 12; if (item.getImage() != null){ textWidth -= item.getImage().getBounds().width; textWidth -= 6; } gc.drawString(getShortString(gc,item.getText(),textWidth),x,getBounds().y +y2,true); if (item.getImage() != null && !imageLeft){ int y3 = (getBounds().height - item.getImage().getBounds().height)/2; if ((getBounds().height - item.getImage().getBounds().height) % 2 != 0) y3 ++; gc.drawImage(item.getImage(),getBounds().width - 6 - item.getImage().getBounds().width,getBounds().y + y3); } if (isFocus()){ gc.drawFocus(1,1,getBounds().width-2,getBounds().height-1); } } public void initialize(Control control) { this.parent = (PShelf)control; FontData fd = parent.getFont().getFontData()[0]; initialFont = new Font(parent.getDisplay(), fd.getName(), fd.getHeight(),SWT.BOLD); //parent.setFont(initialFont); Color baseColor = parent.getDisplay().getSystemColor(SWT.COLOR_TITLE_BACKGROUND_GRADIENT); Color color1 = createNewBlendedColor(baseColor,parent.getDisplay().getSystemColor(SWT.COLOR_WHITE),30); baseColor = createNewBlendedColor(parent.getDisplay().getSystemColor(SWT.COLOR_TITLE_BACKGROUND_GRADIENT),parent.getDisplay().getSystemColor(SWT.COLOR_WHITE),80); Color color2 = createNewSaturatedColor(baseColor,.01f); if ((parent.getStyle() & SWT.SIMPLE) != 0) { gradient1 = color1; gradient2 = color2; } else { selectedGradient1 = color1; selectedGradient2 = color2; } baseColor.dispose(); lineColor = createNewSaturatedColor(parent.getDisplay().getSystemColor(SWT.COLOR_LIST_SELECTION),.02f); baseColor = parent.getDisplay().getSystemColor(SWT.COLOR_LIST_SELECTION); color1 = createNewBlendedColor(baseColor,parent.getDisplay().getSystemColor(SWT.COLOR_WHITE),70); baseColor = createNewBlendedColor(parent.getDisplay().getSystemColor(SWT.COLOR_LIST_SELECTION),parent.getDisplay().getSystemColor(SWT.COLOR_BLACK),80); color2 = createNewSaturatedColor(baseColor,.02f); if ((parent.getStyle() & SWT.SIMPLE) != 0) { selectedGradient1 = color1; selectedGradient2 = color2; } else { gradient1 = color1; gradient2 = color2; } baseColor.dispose(); //initialOpenFont = FontUtils.createFont(parent.getFont(),4,SWT.BOLD); if ((parent.getStyle() & SWT.SIMPLE) != 0) initialOpenFont = new Font(parent.getDisplay(),"Arial",12,SWT.BOLD); else initialOpenFont = new Font(parent.getDisplay(), initialFont.getFontData()); font = initialFont; selectedFont = initialOpenFont; Color inverseColor = parent.getDisplay().getSystemColor(SWT.COLOR_LIST_SELECTION_TEXT); if ((parent.getStyle() & SWT.SIMPLE) != 0) selectedForeground = inverseColor; else foreground = inverseColor; // the other color left null, foreground color of the parent will be used for it baseColor = createNewReverseColor(parent.getDisplay().getSystemColor(SWT.COLOR_TITLE_BACKGROUND)); hoverGradient1 = createNewBlendedColor(baseColor,parent.getDisplay().getSystemColor(SWT.COLOR_WHITE),30); Color baseColor2 = createNewBlendedColor(baseColor,parent.getDisplay().getSystemColor(SWT.COLOR_WHITE),99); hoverGradient2 = createNewSaturatedColor(baseColor2,.00f); baseColor2.dispose(); baseColor.dispose(); initialColors = new Color[] { gradient1, gradient2, selectedGradient1, selectedGradient2, hoverGradient1, hoverGradient2, lineColor }; } public void dispose() { initialFont.dispose(); initialOpenFont.dispose(); for (int i = 0; i < initialColors.length; i++) { initialColors[i].dispose(); } super.dispose(); } public Color getLineColor() { return lineColor; } public void setLineColor(Color lineColor) { this.lineColor = lineColor; } public Font getFont() { return font; } public void setFont(Font font) { this.font = font; } public Color getGradient1() { return gradient1; } public void setGradient1(Color gradient1) { this.gradient1 = gradient1; } public Color getGradient2() { return gradient2; } public void setGradient2(Color gradient2) { this.gradient2 = gradient2; } public Color getHoverGradient1() { return hoverGradient1; } public void setHoverGradient1(Color hoverGradient1) { this.hoverGradient1 = hoverGradient1; } public Color getHoverGradient2() { return hoverGradient2; } public void setHoverGradient2(Color hoverGradient2) { this.hoverGradient2 = hoverGradient2; } public Font getSelectedFont() { return selectedFont; } public void setSelectedFont(Font selectedFont) { this.selectedFont = selectedFont; } public Color getSelectedForeground() { return selectedForeground; } /** Sets text color for the selected item. * @param selectedForeground Can be <code>null</code>, foreground color of the parent is used in that case. */ public void setSelectedForeground(Color selectedForeground) { this.selectedForeground = selectedForeground; } public Color getForeground() { return foreground; } /** Sets text color for non-selected items. * @param foreground Can be <code>null</code>, foreground color of the parent is used in that case. */ public void setForeground(Color foreground) { this.foreground = foreground; } public Color getSelectedGradient1() { return selectedGradient1; } public void setSelectedGradient1(Color selectedGradient1) { this.selectedGradient1 = selectedGradient1; } public Color getSelectedGradient2() { return selectedGradient2; } public void setSelectedGradient2(Color selectedGradient2) { this.selectedGradient2 = selectedGradient2; } private static String getShortString(GC gc, String t, int width) { if (t == null) { return null; } if (t.equals("")) { return ""; } if (width >= gc.stringExtent(t).x) { return t; } int w = gc.stringExtent("...").x; String text = t; int l = text.length(); int pivot = l / 2; int s = pivot; int e = pivot + 1; while (s >= 0 && e < l) { String s1 = text.substring(0, s); String s2 = text.substring(e, l); int l1 = gc.stringExtent(s1).x; int l2 = gc.stringExtent(s2).x; if (l1 + w + l2 < width) { text = s1 + "..." + s2; break; } s--; e++; } if (s == 0 || e == l) { text = text.substring(0, 1) + "..." + text.substring(l - 1, l); } return text; } private static int blend(int v1, int v2, int ratio) { return (ratio * v1 + (100 - ratio) * v2) / 100; } private static RGB blend(RGB c1, RGB c2, int ratio) { int r = blend(c1.red, c2.red, ratio); int g = blend(c1.green, c2.green, ratio); int b = blend(c1.blue, c2.blue, ratio); return new RGB(r, g, b); } private static Color createNewBlendedColor(Color c1, Color c2, int ratio) { Color newColor = new Color(Display.getCurrent(), blend(c1.getRGB(), c2.getRGB(), ratio)); return newColor; } private static Color createNewReverseColor(Color c) { Color newColor = new Color(Display.getCurrent(), 255 - c.getRed(), 255 - c.getGreen(), 255 - c.getBlue()); return newColor; } private static RGB saturate(RGB rgb, float saturation) { float[] hsb = rgb.getHSB(); hsb[1] += saturation; if(hsb[1] > 1.0f) { hsb[1] = 1.0f; } if(hsb[1] < 0f) { hsb[1] = 0f; } // hue is 0.0..360.0, saturation and brightness 0.0..1.0 hsb[0] += 360.0 * saturation; if(hsb[0] > 360.0f) { hsb[0] = 360.0f; } if(hsb[0] < 0f) { hsb[0] = 0f; } return new RGB(hsb[0], hsb[1], hsb[2]); } private static Color createNewSaturatedColor(Color c, float saturation) { RGB newRGB = saturate(c.getRGB(), saturation); return new Color(Display.getCurrent(), newRGB); } }