package org.eclipse.swt.nebula.presentations.shelf.tab; import org.eclipse.swt.SWT; import org.eclipse.swt.events.DisposeEvent; import org.eclipse.swt.events.DisposeListener; import org.eclipse.swt.events.PaintEvent; import org.eclipse.swt.events.PaintListener; import org.eclipse.swt.graphics.Color; import org.eclipse.swt.graphics.Font; import org.eclipse.swt.graphics.GC; import org.eclipse.swt.graphics.Pattern; import org.eclipse.swt.graphics.Point; import org.eclipse.swt.graphics.Rectangle; import org.eclipse.swt.graphics.Region; import org.eclipse.swt.nebula.widgets.pgroup.internal.GraphicUtils; import org.eclipse.swt.widgets.Canvas; import org.eclipse.swt.widgets.Composite; import org.eclipse.swt.widgets.Event; import org.eclipse.swt.widgets.Listener; import java.util.ArrayList; import java.util.Iterator; import java.util.List; public class TabBar extends Canvas { private List items = new ArrayList(); private TabBarItem selectedItem; private Color tabBorder; private Color tabGradient1; private Color tabGradient2; private Color selectedTabBorder; private Color selectedTabGradient1; private Color selectedTabGradient2; private Color bottom; private Color initialForeground; private Color selectedForeground; private Font initialFont; private TabBarItemRenderer renderer = new TabBarItemRenderer(); private int horzMargin = 15; private int itemSpacing = 6; private int itemHeight = 0; private int itemWidth = 0; private int barHeight = 10; private static int checkStyle(int style) { int mask = SWT.LEFT_TO_RIGHT | SWT.RIGHT_TO_LEFT | SWT.RIGHT; return (style & mask) | SWT.DOUBLE_BUFFERED; } public TabBar(Composite parent, int style) { super(parent, checkStyle(style)); initListeners(); initColors(); } private void initColors() { Color baseColor = getDisplay().getSystemColor(SWT.COLOR_TITLE_BACKGROUND_GRADIENT); //tabGradient1 = GraphicUtils.createNewBlendedColor(baseColor,getDisplay().getSystemColor(SWT.COLOR_WHITE),30); tabGradient1 = getDisplay().getSystemColor(SWT.COLOR_WIDGET_LIGHT_SHADOW); baseColor = GraphicUtils.createNewBlendedColor(getDisplay().getSystemColor(SWT.COLOR_TITLE_BACKGROUND_GRADIENT),getDisplay().getSystemColor(SWT.COLOR_WHITE),80); tabGradient2 = GraphicUtils.createNewSaturatedColor(baseColor,.01f); baseColor.dispose(); baseColor = getDisplay().getSystemColor(SWT.COLOR_LIST_SELECTION); tabBorder = GraphicUtils.createNewBlendedColor(baseColor,getDisplay().getSystemColor(SWT.COLOR_WHITE),70); selectedTabGradient1 = GraphicUtils.createNewBlendedColor(baseColor,getDisplay().getSystemColor(SWT.COLOR_WHITE),70); //selectedTabGradient1 = getDisplay().getSystemColor(SWT.COLOR_WIDGET_LIGHT_SHADOW); baseColor = GraphicUtils.createNewBlendedColor(getDisplay().getSystemColor(SWT.COLOR_LIST_SELECTION),getDisplay().getSystemColor(SWT.COLOR_BLACK),80); selectedTabGradient2 = GraphicUtils.createNewSaturatedColor(baseColor,.02f); //selectedTabGradient2 = getDisplay().getSystemColor(SWT.COLOR_WIDGET_NORMAL_SHADOW); //setBackground(GraphicUtils.createNewBlendedColor(selectedTabGradient2, getDisplay().getSystemColor(SWT.COLOR_WHITE),20)); baseColor.dispose(); selectedTabBorder = getDisplay().getSystemColor(SWT.COLOR_WIDGET_DARK_SHADOW); bottom = selectedTabGradient2;//getDisplay().getSystemColor(SWT.COLOR_WIDGET_NORMAL_SHADOW); initialFont = new Font(getDisplay(),"Arial",11,SWT.BOLD); setFont(initialFont); initialForeground = GraphicUtils.createNewBlendedColor(getDisplay().getSystemColor(SWT.COLOR_LIST_SELECTION),getDisplay().getSystemColor(SWT.COLOR_BLACK),80); //foreground = getDisplay().getSystemColor(SWT.COLOR_LIST_SELECTION); setForeground(initialForeground); selectedForeground = GraphicUtils.createNewBlendedColor(tabGradient1,getDisplay().getSystemColor(SWT.COLOR_WHITE),10); } private void initListeners() { addPaintListener(new PaintListener() { public void paintControl(PaintEvent e) { onPaint(e); } }); addDisposeListener(new DisposeListener() { public void widgetDisposed(DisposeEvent e) { onDispose(); } }); addListener(SWT.MouseMove, new Listener() { public void handleEvent(Event e) { onMouseMove(e); } }); addListener(SWT.MouseDown, new Listener() { public void handleEvent(Event e) { onMouseDown(e); } }); } private void onMouseDown(Event e) { if (e.button != 1) return; TabBarItem item = getItem(new Point(e.x,e.y)); if (item == null) return; selectedItem = item; redraw(); e = new Event(); e.item = item; item.notifyListeners(SWT.Selection, e); } private void onMouseMove(Event e) { TabBarItem item = getItem(new Point(e.x,e.y)); if (item == null) { setCursor(null); } else { if (item == selectedItem) { setCursor(null); } else { setCursor(getDisplay().getSystemCursor(SWT.CURSOR_HAND)); } } } private void onDispose() { tabBorder.dispose(); tabGradient1.dispose(); tabGradient2.dispose(); selectedTabBorder.dispose(); selectedTabGradient1.dispose(); selectedTabGradient2.dispose(); bottom.dispose(); initialFont.dispose(); initialForeground.dispose(); selectedForeground.dispose(); } private void onPaint(PaintEvent e) { GC gc = e.gc; int y = getBounds().height - barHeight; int totalWidth = horzMargin + (itemWidth * items.size()) + (itemSpacing * items.size()) - itemSpacing + horzMargin; int croppedWidth = Math.max(totalWidth,getBounds().width); // Region reg = createRoundedTopRegion(0,y,croppedWidth,getClientArea().height - y); // gc.setClipping(reg); Pattern p = new Pattern(getDisplay(), 0, y, 0, y + barHeight, bottom, 255, getBackground(), 0); gc.setBackgroundPattern(p); gc.fillRectangle(0, y,croppedWidth, barHeight); p.dispose(); // reg.dispose(); gc.setClipping((Region)null); gc.setBackgroundPattern(null); int x = horzMargin; if ((getStyle() & SWT.RIGHT) != 0) { if (getBounds().width > totalWidth) { x += getBounds().width - totalWidth; } } y = (getBounds().height - barHeight) - itemHeight; for (Iterator iterator = items.iterator(); iterator.hasNext();) { TabBarItem item = (TabBarItem)iterator.next(); renderer.setBounds(new Rectangle(x,y,itemWidth,itemHeight)); renderer.setSelected(item == selectedItem); renderer.paint(gc, item); x += itemWidth + itemSpacing; } } public TabBarItem getItem(Point point) { int tabStartY = getBounds().height - barHeight - itemHeight; if (point.y < tabStartY) return null; if (point.y > tabStartY + itemHeight - 1) return null; int totalWidth = horzMargin + (itemWidth * items.size()) + (itemSpacing * items.size()) - itemSpacing + horzMargin; int x = horzMargin; if ((getStyle() & SWT.RIGHT) != 0) { if (getBounds().width > totalWidth) { x += getBounds().width - totalWidth; } } for (Iterator iterator = items.iterator(); iterator.hasNext();) { TabBarItem item = (TabBarItem)iterator.next(); if (point.x >= x && point.x < x + itemWidth) { return item; } x += itemWidth + itemSpacing; } return null; } public TabBarItem[] getItems() { return (TabBarItem[])items.toArray(new TabBarItem[]{}); } void updateItemSize() { for (Iterator iterator = items.iterator(); iterator.hasNext();) { TabBarItem item = (TabBarItem)iterator.next(); Point size = renderer.computeSize(item); itemWidth = Math.max(itemWidth,size.x); itemHeight = Math.max(itemHeight,size.y); } } Region createRoundedTopRegion(int xOffset, int yOffset, int width, int height) { Region reg = new Region(getDisplay()); reg.add(xOffset, yOffset, width, height); reg.subtract(xOffset + 0, yOffset + 0, 5, 1); reg.subtract(xOffset + 0, yOffset + 1, 3, 1); reg.subtract(xOffset + 0, yOffset + 2, 2, 1); reg.subtract(xOffset + 0, yOffset + 3, 1, 1); reg.subtract(xOffset + 0, yOffset + 4, 1, 1); reg.subtract(xOffset + width - 5, yOffset + 0, 5, 1); reg.subtract(xOffset + width - 3, yOffset + 1, 3, 1); reg.subtract(xOffset + width - 2, yOffset + 2, 2, 1); reg.subtract(xOffset + width - 1, yOffset + 3, 1, 1); reg.subtract(xOffset + width - 1, yOffset + 4, 1, 1); return reg; } /** * {@inheritDoc} */ @Override public Point computeSize(int wHint, int hHint, boolean changed) { int w = wHint; int h = hHint; if (wHint == SWT.DEFAULT) w = 400; if (hHint == SWT.DEFAULT) h = barHeight + itemHeight + 5; return new Point(w,h); } void newItem(TabBarItem item, int index) { if (index != -1) { items.add(index, item); } else { items.add(item); } if (selectedItem == null) selectedItem = item; redraw(); } public void setSelection(TabBarItem item) { checkWidget(); selectedItem = item; redraw(); } /** * @return the tabBorder */ Color getTabBorder() { return tabBorder; } /** * @param tabBorder the tabBorder to set */ void setTabBorder(Color tabBorder) { this.tabBorder = tabBorder; } /** * @return the tabGradient1 */ Color getTabGradient1() { return tabGradient1; } /** * @param tabGradient1 the tabGradient1 to set */ void setTabGradient1(Color tabGradient1) { this.tabGradient1 = tabGradient1; } /** * @return the tabGradient2 */ Color getTabGradient2() { return tabGradient2; } /** * @param tabGradient2 the tabGradient2 to set */ void setTabGradient2(Color tabGradient2) { this.tabGradient2 = tabGradient2; } /** * @return the selectedTabBorder */ Color getSelectedTabBorder() { return selectedTabBorder; } /** * @param selectedTabBorder the selectedTabBorder to set */ void setSelectedTabBorder(Color selectedTabBorder) { this.selectedTabBorder = selectedTabBorder; } /** * @return the selectedTabGradient1 */ Color getSelectedTabGradient1() { return selectedTabGradient1; } /** * @param selectedTabGradient1 the selectedTabGradient1 to set */ void setSelectedTabGradient1(Color selectedTabGradient1) { this.selectedTabGradient1 = selectedTabGradient1; } /** * @return the selectedTabGradient2 */ Color getSelectedTabGradient2() { return selectedTabGradient2; } /** * @param selectedTabGradient2 the selectedTabGradient2 to set */ void setSelectedTabGradient2(Color selectedTabGradient2) { this.selectedTabGradient2 = selectedTabGradient2; } /** * @return the selectedForeground */ Color getSelectedForeground() { return selectedForeground; } /** * {@inheritDoc} */ @Override public Rectangle getClientArea() { Rectangle client = new Rectangle(5,5,getSize().x,getSize().y - 5 - barHeight); int totalWidth = horzMargin + (itemWidth * items.size()) + (itemSpacing * items.size()) - itemSpacing + horzMargin; client.width -= totalWidth; client.height -= 5; return client; } }