/******************************************************************************* * Copyright (c) Emil Crumhorn - Hexapixel.com - emil.crumhorn@gmail.com * 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: * emil.crumhorn@gmail.com - initial API and implementation *******************************************************************************/ package com.hexapixel.widgets.ribbon; import java.util.ArrayList; import java.util.List; import org.eclipse.swt.SWT; import org.eclipse.swt.events.PaintEvent; import org.eclipse.swt.events.PaintListener; import org.eclipse.swt.graphics.Color; import org.eclipse.swt.graphics.GC; import org.eclipse.swt.graphics.Point; import org.eclipse.swt.graphics.Rectangle; import org.eclipse.swt.widgets.Composite; import org.eclipse.swt.widgets.Control; import org.eclipse.swt.widgets.Event; import org.eclipse.swt.widgets.Layout; import com.hexapixel.widgets.generic.ColorCache; class RibbonTabComposite extends Composite { public static final int GROUP_HEIGHT = 85; public static final int TAB_HEIGHT = 18; // down to the top border but not including top border private Color mBorderBottom = ColorCache.getInstance().getColor(192, 249, 255); private Color mBorderBottomFadeoff1 = ColorCache.getInstance().getColor(150, 170, 196); private Color mBorderBottomFadeoff2 = ColorCache.getInstance().getColor(166, 188, 217); private Color mBorderBottomFadeoff3 = ColorCache.getInstance().getColor(177, 200, 231); private Color mTopTop = ColorCache.getInstance().getColor(219, 230, 244); private Color mTopBottom = ColorCache.getInstance().getColor(207, 221, 239); private Color mMidTop = ColorCache.getInstance().getColor(201, 217, 237); private Color mMidBottom = ColorCache.getInstance().getColor(216, 232, 245); private Color mBottomTop = ColorCache.getInstance().getColor(217, 232, 246); private Color mBottomBottom = ColorCache.getInstance().getColor(231, 242, 255); private AbstractRibbonGroupItem mHoverItem; private AbstractRibbonGroupItem mSelectedItem; private RibbonGroup mSelectedGroup; private List<RibbonGroup> mGroups; private Rectangle mBounds; private RibbonTabFolder mParent; public RibbonTabComposite(RibbonTabFolder parent, int style) { super(parent, style | SWT.DOUBLE_BUFFERED); mParent = parent; mBounds = new Rectangle(0, 0, 0, 0); mGroups = new ArrayList<RibbonGroup>(); setLayout(new ToolbarGroupLayout()); addPaintListener(new PaintListener() { public void paintControl(PaintEvent e) { GC gc = e.gc; drawOntoGC(gc, getBounds()); } }); /* addMouseListener(new MouseListener() { public void mouseDoubleClick(MouseEvent e) { } public void mouseDown(MouseEvent e) { mParent.mouseDown(e); } public void mouseUp(MouseEvent e) { mParent.mouseUp(e); } }); */ layout(true); } // group last affected by a selection public RibbonGroup getLastSelectedGroup() { return mSelectedGroup; } public AbstractRibbonGroupItem getLastSelectedItem() { return mSelectedItem; } public AbstractRibbonGroupItem getLastHoveredItem() { return mHoverItem; } void groupAdded(RibbonGroup group) { if (!mGroups.contains(group)) mGroups.add(group); } // this method takes the bounds from outside as the method is also called in RibbonGroup to remove corner artifacts and more protected void drawOntoGC(GC gc, Rectangle bounds) { int x = bounds.x; int y = 0; int width = bounds.width; gc.setForeground(mTopTop); gc.setBackground(mTopBottom); gc.fillGradientRectangle(x, y, width, 16, true); gc.setForeground(mMidTop); gc.setBackground(mMidBottom); gc.fillGradientRectangle(x, y+16, width, 54, true); gc.setForeground(mBottomTop); gc.setBackground(mBottomBottom); gc.fillGradientRectangle(x, y+16+54, width, 18, true); gc.setForeground(mBorderBottom); gc.drawLine(x, y+17+54+17, x+width, y+17+54+17); gc.setForeground(mBorderBottomFadeoff1); gc.drawLine(x, y+17+54+17+1, x+width, y+17+54+17+1); gc.setForeground(mBorderBottomFadeoff2); gc.drawLine(x, y+17+54+17+2, x+width, y+17+54+17+2); gc.setForeground(mBorderBottomFadeoff3); gc.drawLine(x, y+17+54+17+3, x+width, y+17+54+17+3); } protected void toolItemHoverChanged(AbstractRibbonGroupItem item, RibbonGroup toolGroup) { mHoverItem = item; for (int i = 0; i < mGroups.size(); i++) { RibbonGroup group = mGroups.get(i); if (group != toolGroup) group.deHover(); } } protected void toolItemSelectionChanged(AbstractRibbonGroupItem item, RibbonGroup toolGroup) { mSelectedItem = item; } class ToolbarGroupLayout extends Layout { protected Point computeSize(Composite aComposite, int wHint, int hHint, boolean flushCache) { return getSize(); } protected void layout(final Composite aComposite, boolean flushCache) { int top = 1; int left = 0; int spacer = 2; Control [] items = aComposite.getChildren(); for (int i = 0; i < items.length; i++) { Control item = items[i]; if (item instanceof RibbonGroup) { RibbonGroup fg = (RibbonGroup) item; if (!fg.isVisible()) continue; Rectangle groupBounds = fg.getBounds(); item.setBounds(left, top, groupBounds.width, groupBounds.height); left += groupBounds.width + spacer; } } mBounds = new Rectangle(1, 1, left, 86); } } public Rectangle getBounds() { checkWidget(); return mParent.getClientArea(); } public Rectangle getActualBounds() { return mBounds; } protected void scrollWheelUpdate(Point mouse) { Control [] children = getChildren(); if (children != null) { for (Control child : children) { if (child instanceof RibbonGroup) { RibbonGroup rg = (RibbonGroup) child; if (isInside(mouse.x, mouse.y, rg.getBounds())) { Event fakeMove = new Event(); fakeMove.x = mouse.x; fakeMove.y = mouse.y; fakeMove.widget = rg; rg.notifyListeners(SWT.MouseMove, fakeMove); } rg.redraw(); } } } } private boolean isInside(int x, int y, Rectangle rect) { if (rect == null) { return false; } return x >= rect.x && y >= rect.y && x <= (rect.x + rect.width-1) && y <= (rect.y + rect.height-1); } @Override public Point getSize() { checkWidget(); return new Point(mBounds.width, mBounds.height); } @Override public void dispose() { for (int i = 0; i < mGroups.size(); i++) mGroups.get(i).dispose(); mGroups.clear(); super.dispose(); } }