package org.eclipse.swt.nebula.presentations.shelf; import org.eclipse.core.runtime.Platform; import org.eclipse.jface.resource.ImageDescriptor; import org.eclipse.swt.SWT; import org.eclipse.swt.events.ExpandEvent; import org.eclipse.swt.events.ExpandListener; import org.eclipse.swt.graphics.Color; import org.eclipse.swt.graphics.Image; import org.eclipse.swt.graphics.Point; import org.eclipse.swt.graphics.RGB; import org.eclipse.swt.graphics.Rectangle; import org.eclipse.swt.layout.FillLayout; import org.eclipse.swt.nebula.widgets.pgroup.PGroup; import org.eclipse.swt.nebula.widgets.pgroup.RectangleGroupStrategy; import org.eclipse.swt.widgets.Composite; import org.eclipse.swt.widgets.Control; import org.eclipse.swt.widgets.Event; import org.eclipse.swt.widgets.Listener; import org.eclipse.ui.IPropertyListener; import org.eclipse.ui.presentations.IPresentablePart; import org.eclipse.ui.presentations.IStackPresentationSite; import org.eclipse.ui.presentations.PresentationUtil; import org.eclipse.ui.presentations.StackDropResult; import org.eclipse.ui.presentations.StackPresentation; import java.net.URL; /** * STANDALONE ONLY * * @author chris.gross@us.ibm.com * @since 2.0.0 */ public class PGroupStackPresentation extends StackPresentation { private static final String DATAKEY_ANIMATION = "Busy Anim Player"; private Composite partParent; private PGroup group; private Color toolbarBackground; private Image[] busyImages; private int minHeight = 0; /** * @param stackSite */ public PGroupStackPresentation(IStackPresentationSite stackSite, Composite parent) { super(stackSite); partParent = parent; group = new PGroup(parent,SWT.NONE); group.setStrategy(new RectangleGroupStrategy()); group.setImagePosition(SWT.LEFT | SWT.TOP); group.setBackground(group.getDisplay().getSystemColor(SWT.COLOR_LIST_BACKGROUND)); //HACK parent.setBackground(parent.getBackground()); parent.setBackgroundMode(SWT.INHERIT_DEFAULT); //HACK new Composite(group,SWT.NONE); group.setLayout(new FillLayout()); group.setExpanded(false); minHeight = group.computeSize(SWT.DEFAULT,SWT.DEFAULT).y; group.setExpanded(true); RGB sel = parent.getDisplay().getSystemColor(SWT.COLOR_LIST_SELECTION).getRGB(); RGB blendwith = new RGB(255,255,255); RGB blended = blend(sel,blendwith,20); toolbarBackground = new Color(parent.getDisplay(),blended); group.addExpandListener(new ExpandListener() { public void itemExpanded(ExpandEvent e) { getSite().setState(IStackPresentationSite.STATE_RESTORED); } public void itemCollapsed(ExpandEvent e) { getSite().setState(IStackPresentationSite.STATE_MINIMIZED); } }); PresentationUtil.addDragListener(group,new Listener() { public void handleEvent(Event event) { getSite().setState(IStackPresentationSite.STATE_RESTORED); getSite().dragStart(getSite().getSelectedPart(), new Point(event.x, event.y), false); } }); //init busy images busyImages = new Image[8]; for (int i = 0; i < 8; i++) { URL imgURL = Platform.getBundle("org.eclipse.swt.nebula.presentations.shelf").getResource("icons/busy" + (i + 1) + ".gif"); Image img = ImageDescriptor.createFromURL(imgURL).createImage(); busyImages[i] = img; } } 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); } /** * {@inheritDoc} */ @Override public void addPart(final IPresentablePart newPart, Object cookie) { updateItem(newPart); newPart.addPropertyListener(new IPropertyListener() { public void propertyChanged(Object source, int propId) { updateItem(newPart); } }); resizeSelectedPart(); } private void updateItem(final IPresentablePart part) { String dirty = ""; if (part.isDirty()) dirty = "*"; group.setText(dirty + part.getName()); if (part.getTitleImage() != group.getImage()) { group.setImage(part.getTitleImage()); boolean expanded = group.getExpanded(); group.setExpanded(false); minHeight = group.computeSize(SWT.DEFAULT,SWT.DEFAULT).y; group.setExpanded(expanded); } if (part.getToolBar() != null) { part.getToolBar().setBackground(toolbarBackground); } resizeSelectedPart(); if (part.isBusy() && group.getData(DATAKEY_ANIMATION) == null) { BusyGroupAnimation busyAnim = new BusyGroupAnimation(group); busyAnim.setImages(busyImages); group.setData(DATAKEY_ANIMATION,busyAnim); busyAnim.start(); } else if (!part.isBusy() && group.getData(DATAKEY_ANIMATION) != null) { BusyGroupAnimation busyAnim = (BusyGroupAnimation)group.getData(DATAKEY_ANIMATION); busyAnim.stop(); group.setData(DATAKEY_ANIMATION,null); group.setImage(part.getTitleImage()); } } /** * {@inheritDoc} */ @Override public void dispose() { group.dispose(); toolbarBackground.dispose(); for (int i = 0; i < busyImages.length; i++) { busyImages[i].dispose(); } } /** * {@inheritDoc} */ @Override public StackDropResult dragOver(Control currentControl, Point location) { // TODO Auto-generated method stub return null; } /** * {@inheritDoc} */ @Override public Control getControl() { return group; } /** * {@inheritDoc} */ @Override public Control[] getTabList(IPresentablePart part) { // TODO Auto-generated method stub return null; } /** * {@inheritDoc} */ @Override public void removePart(IPresentablePart oldPart) { } /** * {@inheritDoc} */ @Override public void selectPart(IPresentablePart toSelect) { toSelect.setVisible(true); if (toSelect.getToolBar() != null) toSelect.getToolBar().setVisible(true); resizeSelectedPart(); } /** * {@inheritDoc} */ @Override public void setActive(int newState) { } /** * {@inheritDoc} */ @Override public void setBounds(Rectangle bounds) { getSite().getSelectedPart().setVisible(true); group.setBounds(bounds); group.getDisplay().asyncExec(new Runnable() { public void run() { // TODO Auto-generated method stub resizeSelectedPart(); } }); resizeSelectedPart(); } private void resizeSelectedPart() { IPresentablePart part = getSite().getSelectedPart(); if (part == null) return; Control partTB = part.getToolBar(); Rectangle bounds = group.getClientArea(); Point partTBSize = new Point(0,0); if (partTB != null) { partTBSize = partTB.computeSize(bounds.width,SWT.DEFAULT); Rectangle tbBounds = new Rectangle(0,0,bounds.width,partTBSize.y); tbBounds = group.getDisplay().map(group.getChildren()[0], partTB.getParent(), tbBounds); partTB.setBounds(tbBounds); bounds.y += tbBounds.height; bounds.height -= tbBounds.height; } bounds = group.getDisplay().map(group, partParent, bounds); part.setBounds(bounds); } /** * {@inheritDoc} */ @Override public void setState(int state) { if (state == IStackPresentationSite.STATE_MINIMIZED) { group.setExpanded(false); } else if(state == IStackPresentationSite.STATE_RESTORED) { group.setExpanded(true); } } /** * {@inheritDoc} */ @Override public void setVisible(boolean isVisible) { group.setVisible(isVisible); if (getSite().getSelectedPart() == null) return; getSite().getSelectedPart().setVisible(isVisible); if (getSite().getSelectedPart().getToolBar() != null) getSite().getSelectedPart().getToolBar().setVisible(isVisible); } @Override public Point computeMinimumSize() { return new Point(100,minHeight); } /** * {@inheritDoc} */ @Override public void showPaneMenu() { } /** * {@inheritDoc} */ @Override public void showSystemMenu() { } }