### Eclipse Workspace Patch 1.0 #P org.eclipse.gef Index: src/org/eclipse/gef/ui/palette/PaletteMessages.java =================================================================== RCS file: /cvsroot/tools/org.eclipse.gef/plugins/org.eclipse.gef/src/org/eclipse/gef/ui/palette/PaletteMessages.java,v retrieving revision 1.23 diff -u -r1.23 PaletteMessages.java --- src/org/eclipse/gef/ui/palette/PaletteMessages.java 28 Sep 2005 17:17:19 -0000 1.23 +++ src/org/eclipse/gef/ui/palette/PaletteMessages.java 31 Mar 2008 20:37:41 -0000 @@ -249,6 +249,11 @@ public static String TOOLTIP_PIN_FIGURE; /** + * The String "Unpin" + */ +public static String TOOLTIP_UNPIN_FIGURE; + +/** * The String "&Dock On" */ public static String DOCK_LABEL; Index: src/org/eclipse/gef/ui/palette/PaletteEditPartFactory.java =================================================================== RCS file: /cvsroot/tools/org.eclipse.gef/plugins/org.eclipse.gef/src/org/eclipse/gef/ui/palette/PaletteEditPartFactory.java,v retrieving revision 1.23 diff -u -r1.23 PaletteEditPartFactory.java --- src/org/eclipse/gef/ui/palette/PaletteEditPartFactory.java 25 Feb 2008 21:33:15 -0000 1.23 +++ src/org/eclipse/gef/ui/palette/PaletteEditPartFactory.java 31 Mar 2008 20:37:41 -0000 @@ -14,12 +14,13 @@ import org.eclipse.gef.EditPartFactory; import org.eclipse.gef.internal.ui.palette.editparts.DrawerEditPart; import org.eclipse.gef.internal.ui.palette.editparts.GroupEditPart; -import org.eclipse.gef.internal.ui.palette.editparts.PaletteStackEditPart; +import org.eclipse.gef.internal.ui.palette.editparts.PinnablePaletteStackEditPart; import org.eclipse.gef.internal.ui.palette.editparts.SeparatorEditPart; import org.eclipse.gef.internal.ui.palette.editparts.SliderPaletteEditPart; import org.eclipse.gef.internal.ui.palette.editparts.TemplateEditPart; import org.eclipse.gef.internal.ui.palette.editparts.ToolEntryEditPart; import org.eclipse.gef.internal.ui.palette.editparts.ToolbarEditPart; +import org.eclipse.gef.internal.ui.palette.editparts.PaletteStackEditPart; import org.eclipse.gef.palette.PaletteContainer; import org.eclipse.gef.palette.PaletteDrawer; import org.eclipse.gef.palette.PaletteEntry; @@ -29,6 +30,7 @@ import org.eclipse.gef.palette.PaletteStack; import org.eclipse.gef.palette.PaletteTemplateEntry; import org.eclipse.gef.palette.PaletteToolbar; +import org.eclipse.gef.ui.palette.editparts.PaletteEditPart; /** * Factory to create EditParts for different PaletteEntries. @@ -95,8 +97,12 @@ * @param model the PaletteStack * @return the newly created EditPart */ -protected EditPart createStackEditPart(EditPart parentEditPart, Object model) { - return new PaletteStackEditPart((PaletteStack)model); +protected EditPart createStackEditPart(EditPart parentEditPart, Object model) { + if (parentEditPart instanceof PaletteEditPart + && ((PaletteEditPart) parentEditPart).isToolbarItem()) { + return new PaletteStackEditPart((PaletteStack) model); + } + return new PinnablePaletteStackEditPart((PaletteStack) model); } /** Index: src/org/eclipse/gef/ui/palette/messages.properties =================================================================== RCS file: /cvsroot/tools/org.eclipse.gef/plugins/org.eclipse.gef/src/org/eclipse/gef/ui/palette/messages.properties,v retrieving revision 1.22 diff -u -r1.22 messages.properties --- src/org/eclipse/gef/ui/palette/messages.properties 28 Sep 2005 17:17:19 -0000 1.22 +++ src/org/eclipse/gef/ui/palette/messages.properties 31 Mar 2008 20:37:41 -0000 @@ -65,6 +65,7 @@ SETTINGS_ICONS_VIEW_LABEL_CAPS=&Icons Only PINNED=&Pinned TOOLTIP_PIN_FIGURE=Pin Open +TOOLTIP_UNPIN_FIGURE=Unpin DOCK_LABEL=&Dock On LEFT_LABEL=&Left RIGHT_LABEL=&Right Index: src/org/eclipse/gef/internal/ui/palette/editparts/PaletteStackEditPart.java =================================================================== RCS file: /cvsroot/tools/org.eclipse.gef/plugins/org.eclipse.gef/src/org/eclipse/gef/internal/ui/palette/editparts/PaletteStackEditPart.java,v retrieving revision 1.17 diff -u -r1.17 PaletteStackEditPart.java --- src/org/eclipse/gef/internal/ui/palette/editparts/PaletteStackEditPart.java 25 Feb 2008 21:33:14 -0000 1.17 +++ src/org/eclipse/gef/internal/ui/palette/editparts/PaletteStackEditPart.java 31 Mar 2008 20:37:41 -0000 @@ -42,7 +42,6 @@ import org.eclipse.gef.GraphicalEditPart; import org.eclipse.gef.Request; import org.eclipse.gef.RequestConstants; -import org.eclipse.gef.internal.ui.palette.PaletteColorUtil; import org.eclipse.gef.palette.PaletteEntry; import org.eclipse.gef.palette.PaletteListener; import org.eclipse.gef.palette.PaletteStack; @@ -53,13 +52,13 @@ import org.eclipse.gef.ui.palette.editparts.PaletteEditPart; /** - * The EditPart for a PaletteStack. + * The EditPart for a PaletteStack to be used on the toolbar. * * @author Whitney Sorenson * @since 3.0 */ -public class PaletteStackEditPart - extends PaletteEditPart +public class PaletteStackEditPart + extends PaletteEditPart implements IPaletteStackEditPart { private static final Dimension EMPTY_DIMENSION = new Dimension(0, 0); @@ -106,7 +105,6 @@ }; private Clickable activeFigure; -private Clickable clickableFigure; private RolloverArrow arrowFigure; private Figure contentsFigure; private Menu menu; @@ -171,69 +169,48 @@ */ public IFigure createFigure() { - IFigure stackFigure; arrowFigure = new RolloverArrow(); - if (isToolbarItem()) { - // the entire stack figure is clickable on the toolbar - stackFigure = new Clickable() { - public boolean hasFocus() { - return false; - } - public Dimension getPreferredSize(int wHint, int hHint) { - if (PaletteStackEditPart.this.getChildren().isEmpty()) - return EMPTY_DIMENSION; - return super.getPreferredSize(wHint, hHint); - } - }; - ((Clickable)stackFigure).setRolloverEnabled(true); - stackFigure.setBorder(BORDER_TOGGLE); - - // Set up the arrow figure. Disable the arrow figure so clicks go to the stack figure. - arrowFigure.setBackgroundColor(ColorConstants.black); - arrowFigure.setEnabled(false); - - clickableFigure = ((Clickable)stackFigure); - } else { - // the stack figure is not clickable on the palette so that drag and drop still works - stackFigure = new Figure() { - public Dimension getPreferredSize(int wHint, int hHint) { - if (PaletteStackEditPart.this.getChildren().isEmpty()) - return EMPTY_DIMENSION; - return super.getPreferredSize(wHint, hHint); - } - }; - - // Set up the arrow figure. - arrowFigure.setBackgroundColor(PaletteColorUtil.WIDGET_DARK_SHADOW); - - clickableFigure = arrowFigure; - } - - contentsFigure = new Figure(); - StackLayout stackLayout = new StackLayout(); - // make it so the stack layout does not allow the invisible figures to contribute - // to its bounds - stackLayout.setObserveVisibility(true); - contentsFigure.setLayoutManager(stackLayout); - - stackFigure.add(contentsFigure); - stackFigure.add(arrowFigure); + Clickable stackFigure = new Clickable() { + public boolean hasFocus() { + return false; + } + public Dimension getPreferredSize(int wHint, int hHint) { + if (PaletteStackEditPart.this.getChildren().isEmpty()) + return EMPTY_DIMENSION; + return super.getPreferredSize(wHint, hHint); + } + }; + stackFigure.setRolloverEnabled(true); + stackFigure.setBorder(BORDER_TOGGLE); + + // Set up the arrow figure. Disable the arrow figure so clicks go to the stack figure. + arrowFigure.setBackgroundColor(ColorConstants.black); + arrowFigure.setEnabled(false); + + contentsFigure = new Figure(); + StackLayout stackLayout = new StackLayout(); + // make it so the stack layout does not allow the invisible figures to contribute + // to its bounds + stackLayout.setObserveVisibility(true); + contentsFigure.setLayoutManager(stackLayout); + + stackFigure.add(contentsFigure); + stackFigure.add(arrowFigure); - getClickableFigure().addChangeListener(clickableArrowListener); - getClickableFigure().addActionListener(actionListener); + stackFigure.addChangeListener(clickableArrowListener); + stackFigure.addActionListener(actionListener); return stackFigure; } /** - * Returns the Clickable figure. This differs depending on - * whether or not this palette stack is on the palette toolbar. + * Returns the Clickable figure. * * @return the Clickable figure */ private Clickable getClickableFigure() { - return clickableFigure; + return (Clickable) getFigure(); } /** Index: src/org/eclipse/gef/internal/ui/palette/editparts/GroupEditPart.java =================================================================== RCS file: /cvsroot/tools/org.eclipse.gef/plugins/org.eclipse.gef/src/org/eclipse/gef/internal/ui/palette/editparts/GroupEditPart.java,v retrieving revision 1.10 diff -u -r1.10 GroupEditPart.java --- src/org/eclipse/gef/internal/ui/palette/editparts/GroupEditPart.java 25 Feb 2008 21:33:14 -0000 1.10 +++ src/org/eclipse/gef/internal/ui/palette/editparts/GroupEditPart.java 31 Mar 2008 20:37:40 -0000 @@ -11,7 +11,6 @@ package org.eclipse.gef.internal.ui.palette.editparts; import org.eclipse.draw2d.Figure; -import org.eclipse.draw2d.FlowLayout; import org.eclipse.draw2d.IFigure; import org.eclipse.draw2d.LayoutManager; import org.eclipse.draw2d.ToolbarLayout; @@ -53,7 +52,7 @@ if (layout == PaletteViewerPreferences.LAYOUT_COLUMNS) { manager = new ColumnsLayout(); } else if (layout == PaletteViewerPreferences.LAYOUT_ICONS) { - FlowLayout flow = new FlowLayout(); + PaletteContainerFlowLayout flow = new PaletteContainerFlowLayout(); flow.setMajorSpacing(0); flow.setMinorSpacing(0); manager = flow; Index: src/org/eclipse/gef/internal/ui/palette/editparts/ColumnsLayout.java =================================================================== RCS file: /cvsroot/tools/org.eclipse.gef/plugins/org.eclipse.gef/src/org/eclipse/gef/internal/ui/palette/editparts/ColumnsLayout.java,v retrieving revision 1.9 diff -u -r1.9 ColumnsLayout.java --- src/org/eclipse/gef/internal/ui/palette/editparts/ColumnsLayout.java 31 Mar 2005 21:44:12 -0000 1.9 +++ src/org/eclipse/gef/internal/ui/palette/editparts/ColumnsLayout.java 31 Mar 2008 20:37:40 -0000 @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2000, 2005 IBM Corporation and others. + * Copyright (c) 2000, 2008 IBM Corporation and others. * 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 @@ -13,7 +13,6 @@ import java.util.Iterator; import java.util.List; -import org.eclipse.draw2d.FlowLayout; import org.eclipse.draw2d.IFigure; import org.eclipse.draw2d.geometry.Dimension; @@ -24,7 +23,7 @@ * @author Pratik Shah */ public class ColumnsLayout - extends FlowLayout + extends PaletteContainerFlowLayout { private Dimension defaultConstraint = null; @@ -70,9 +69,12 @@ List children = figure.getParent().getChildren(); for (Iterator iter = children.iterator(); iter.hasNext();) { IFigure child = (IFigure) iter.next(); - Dimension childSize = child.getPreferredSize(cachedConstraint.width, - cachedConstraint.height); - cachedConstraint.width = Math.max(cachedConstraint.width, childSize.width); + Dimension childSize = (child instanceof PinnablePaletteStackFigure) ? ((PinnablePaletteStackFigure) child) + .getHeaderPreferredSize(cachedConstraint.width, + cachedConstraint.height) + : child.getPreferredSize(cachedConstraint.width, + cachedConstraint.height); + cachedConstraint.width = Math.max(cachedConstraint.width, childSize.width); } cachedConstraint.height = hHint; } Index: src/org/eclipse/gef/internal/ui/palette/editparts/ToolEntryEditPart.java =================================================================== RCS file: /cvsroot/tools/org.eclipse.gef/plugins/org.eclipse.gef/src/org/eclipse/gef/internal/ui/palette/editparts/ToolEntryEditPart.java,v retrieving revision 1.30 diff -u -r1.30 ToolEntryEditPart.java --- src/org/eclipse/gef/internal/ui/palette/editparts/ToolEntryEditPart.java 10 Mar 2008 21:15:32 -0000 1.30 +++ src/org/eclipse/gef/internal/ui/palette/editparts/ToolEntryEditPart.java 31 Mar 2008 20:37:41 -0000 @@ -61,7 +61,7 @@ if (enabled) { getButtonModel().setArmed(false); getButtonModel().setPressed(false); - ((PaletteStackEditPart)getParent()).openMenu(); + ((IPaletteStackEditPart)getParent()).openMenu(); getViewer().getEditDomain().loadDefaultTool(); } } @@ -84,7 +84,7 @@ } protected boolean handleButtonDown(int button) { - if (getParent() instanceof PaletteStackEditPart) + if (getParent() instanceof IPaletteStackEditPart) enableTimer(); if (button == 2 && isInState(STATE_INITIAL)) @@ -181,13 +181,13 @@ disableTimer(); // win hack because button down is delayed - if (getParent() instanceof PaletteStackEditPart && SWT.getPlatform().equals("win32")) { //$NON-NLS-1$ + if (getParent() instanceof IPaletteStackEditPart && SWT.getPlatform().equals("win32")) { //$NON-NLS-1$ Point nds = getPaletteViewer().getControl().toControl(event.display.getCursorLocation()); if (mouseDownLoc != null && (Math.abs(nds.x - mouseDownLoc.x) + Math.abs(nds.y - mouseDownLoc.y)) < WIN_THRESHOLD) { getButtonModel().setArmed(false); getButtonModel().setPressed(false); - ((PaletteStackEditPart)getParent()).openMenu(); + ((IPaletteStackEditPart)getParent()).openMenu(); getViewer().getEditDomain().loadDefaultTool(); event.doit = false; return false; @@ -400,7 +400,6 @@ public void setToolSelected(boolean value) { getButtonModel().setSelected(value); - getFigure().setOpaque(value); } public void restoreState(IMemento memento) { @@ -452,7 +451,7 @@ rect.width = labelFigure.getPreferredSize().width + 17; rect.x += 11; } - rect.intersect(labelFigure.getBounds()); + rect.intersect(labelFigure.getBounds().getExpanded(-1, -1)); return rect; } } Index: src/org/eclipse/gef/internal/ui/palette/editparts/ToolbarEditPart.java =================================================================== RCS file: /cvsroot/tools/org.eclipse.gef/plugins/org.eclipse.gef/src/org/eclipse/gef/internal/ui/palette/editparts/ToolbarEditPart.java,v retrieving revision 1.1 diff -u -r1.1 ToolbarEditPart.java --- src/org/eclipse/gef/internal/ui/palette/editparts/ToolbarEditPart.java 25 Feb 2008 21:33:14 -0000 1.1 +++ src/org/eclipse/gef/internal/ui/palette/editparts/ToolbarEditPart.java 31 Mar 2008 20:37:41 -0000 @@ -71,7 +71,7 @@ return PaletteViewerPreferences.LAYOUT_ICONS; } -protected boolean isToolbarItem() { +public boolean isToolbarItem() { return true; } Index: src/org/eclipse/gef/internal/ui/palette/editparts/DrawerFigure.java =================================================================== RCS file: /cvsroot/tools/org.eclipse.gef/plugins/org.eclipse.gef/src/org/eclipse/gef/internal/ui/palette/editparts/DrawerFigure.java,v retrieving revision 1.41 diff -u -r1.41 DrawerFigure.java --- src/org/eclipse/gef/internal/ui/palette/editparts/DrawerFigure.java 25 Feb 2008 21:33:14 -0000 1.41 +++ src/org/eclipse/gef/internal/ui/palette/editparts/DrawerFigure.java 31 Mar 2008 20:37:40 -0000 @@ -10,6 +10,7 @@ *******************************************************************************/ package org.eclipse.gef.internal.ui.palette.editparts; +import java.util.Iterator; import java.util.List; import org.eclipse.swt.graphics.Color; @@ -28,10 +29,8 @@ import org.eclipse.draw2d.CompoundBorder; import org.eclipse.draw2d.Figure; import org.eclipse.draw2d.FigureUtilities; -import org.eclipse.draw2d.FlowLayout; import org.eclipse.draw2d.Graphics; import org.eclipse.draw2d.IFigure; -import org.eclipse.draw2d.ImageFigure; import org.eclipse.draw2d.Label; import org.eclipse.draw2d.LayoutManager; import org.eclipse.draw2d.MarginBorder; @@ -46,9 +45,7 @@ import org.eclipse.draw2d.geometry.Insets; import org.eclipse.draw2d.geometry.Rectangle; -import org.eclipse.gef.internal.InternalImages; import org.eclipse.gef.internal.ui.palette.PaletteColorUtil; -import org.eclipse.gef.ui.palette.PaletteMessages; import org.eclipse.gef.ui.palette.PaletteViewerPreferences; import org.eclipse.gef.ui.palette.editparts.PaletteToolbarLayout; @@ -63,12 +60,8 @@ protected static final Color FG_COLOR = FigureUtilities.mixColors( PaletteColorUtil.WIDGET_NORMAL_SHADOW, PaletteColorUtil.WIDGET_BACKGROUND); -private static final Color PIN_HOTSPOT_COLOR = FigureUtilities.mixColors( - PaletteColorUtil.WIDGET_LIST_BACKGROUND, - PaletteColorUtil.WIDGET_NORMAL_SHADOW, 0.60); - /** Scrollpane border constant **/ -protected static final Border SCROLL_PANE_BORDER = new MarginBorder(2); +protected static final Border SCROLL_PANE_BORDER = new MarginBorder(2, 0, 2, 0); /** Title margin border constant **/ protected static final Border TITLE_MARGIN_BORDER = new MarginBorder(4, 2, 2, 2); /** Toggle button border constant**/ @@ -87,51 +80,6 @@ private boolean showPin = true, skipNextEvent; private EditPartTipHelper tipHelper; -/** - * This is the figure for the pinned and unpinned button. - */ -private static class PinFigure extends Toggle { - - private static Label tooltip = new Label(PaletteMessages.TOOLTIP_PIN_FIGURE); - - public PinFigure() { - super(new ImageFigure(InternalImages.get(InternalImages.IMG_UNPINNED))); - setRolloverEnabled(true); - setRequestFocusEnabled(false); - setToolTip(tooltip); - setOpaque(false); - - addChangeListener(new ChangeListener() { - public void handleStateChanged(ChangeEvent e) { - if (e.getPropertyName().equals(ButtonModel.SELECTED_PROPERTY)) { - if (isSelected()) { - ((ImageFigure) (getChildren().get(0))).setImage(InternalImages - .get(InternalImages.IMG_PINNED)); - } else { - ((ImageFigure) (getChildren().get(0))).setImage(InternalImages - .get(InternalImages.IMG_UNPINNED)); - } - } - } - }); - } - - protected void paintFigure(Graphics graphics) { - super.paintFigure(graphics); - - ButtonModel model = getModel(); - if (isRolloverEnabled() && model.isMouseOver()) { - graphics.setBackgroundColor(PIN_HOTSPOT_COLOR); - graphics.fillRoundRectangle(getClientArea().getCopy().shrink(1, 1), 3, 3); - } - } - - public void setDrawerExpandedState(boolean expanded) { - setEnabled(expanded); - setToolTip(expanded ? tooltip : null); - } - -} /** * This is the figure for the entire drawer label button. @@ -448,11 +396,20 @@ } else { if (scrollpane.getParent() == this) remove(scrollpane); + + // collapse all pinnable palette stack children that aren't pinned + for (Iterator iterator = getContentPane().getChildren().iterator(); iterator.hasNext();) { + Object child = iterator.next(); + if (child instanceof PinnablePaletteStackFigure + && !((PinnablePaletteStackFigure) child).isPinnedOpen()) { + ((PinnablePaletteStackFigure) child).setExpanded(false); + } + } + } if (pinFigure != null) { pinFigure.setVisible(isExpanded() && showPin); - pinFigure.setDrawerExpandedState(isExpanded()); } } @@ -509,7 +466,7 @@ if (layoutMode == PaletteViewerPreferences.LAYOUT_COLUMNS) { manager = new ColumnsLayout(); } else if (layoutMode == PaletteViewerPreferences.LAYOUT_ICONS) { - FlowLayout fl = new FlowLayout(); + PaletteContainerFlowLayout fl = new PaletteContainerFlowLayout(); fl.setMinorSpacing(0); fl.setMajorSpacing(0); manager = fl; Index: src/org/eclipse/gef/internal/ui/palette/editparts/DrawerEditPart.java =================================================================== RCS file: /cvsroot/tools/org.eclipse.gef/plugins/org.eclipse.gef/src/org/eclipse/gef/internal/ui/palette/editparts/DrawerEditPart.java,v retrieving revision 1.26 diff -u -r1.26 DrawerEditPart.java --- src/org/eclipse/gef/internal/ui/palette/editparts/DrawerEditPart.java 25 Feb 2008 21:33:14 -0000 1.26 +++ src/org/eclipse/gef/internal/ui/palette/editparts/DrawerEditPart.java 31 Mar 2008 20:37:40 -0000 @@ -77,6 +77,8 @@ } }); + fig.getScrollpane().getContents().addLayoutListener(getPaletteAnimator()); + return fig; } Index: src/org/eclipse/gef/ui/parts/PaletteViewerKeyHandler.java =================================================================== RCS file: /cvsroot/tools/org.eclipse.gef/plugins/org.eclipse.gef/src/org/eclipse/gef/ui/parts/PaletteViewerKeyHandler.java,v retrieving revision 1.31 diff -u -r1.31 PaletteViewerKeyHandler.java --- src/org/eclipse/gef/ui/parts/PaletteViewerKeyHandler.java 30 Oct 2005 23:54:56 -0000 1.31 +++ src/org/eclipse/gef/ui/parts/PaletteViewerKeyHandler.java 31 Mar 2008 20:37:41 -0000 @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2000, 2005 IBM Corporation and others. + * Copyright (c) 2000, 2008 IBM Corporation and others. * 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 @@ -22,11 +22,12 @@ import org.eclipse.gef.EditPart; import org.eclipse.gef.internal.ui.palette.editparts.DrawerEditPart; import org.eclipse.gef.internal.ui.palette.editparts.GroupEditPart; -import org.eclipse.gef.internal.ui.palette.editparts.PaletteStackEditPart; +import org.eclipse.gef.internal.ui.palette.editparts.IPaletteStackEditPart; import org.eclipse.gef.internal.ui.palette.editparts.TemplateEditPart; import org.eclipse.gef.internal.ui.palette.editparts.ToolEntryEditPart; import org.eclipse.gef.palette.PaletteStack; import org.eclipse.gef.ui.palette.PaletteViewer; +import org.eclipse.gef.ui.palette.editparts.PaletteEditPart; /** * KeyHandler for the {@link org.eclipse.gef.ui.palette.PaletteViewer Palette}. @@ -73,7 +74,7 @@ : event.keyCode == SWT.ARROW_LEFT; return (result || event.keyCode == SWT.ARROW_UP) && (getFocusEditPart().getParent() instanceof DrawerEditPart - || (getFocusEditPart().getParent() instanceof PaletteStackEditPart + || (getFocusEditPart().getParent() instanceof IPaletteStackEditPart && getFocusEditPart().getParent().getParent() instanceof DrawerEditPart)); } @@ -87,10 +88,10 @@ if (isCollapsedDrawer(palettePart)) { navList.add(palettePart); return; - } else if (stackPart instanceof PaletteStackEditPart + } else if (stackPart instanceof IPaletteStackEditPart && stackPart.getChildren().contains(palettePart)) { // we only want to add the top level item to the navlist - if (((PaletteStack)((PaletteStackEditPart)stackPart).getModel()) + if (((PaletteStack)((PaletteEditPart)stackPart).getModel()) .getActiveEntry().equals(palettePart.getModel())) navList.add(palettePart); } else if ((palettePart instanceof ToolEntryEditPart @@ -103,7 +104,7 @@ List children = palettePart.getChildren(); for (int k = 0; k < children.size(); k++) { EditPart ep = (EditPart)children.get(k); - if (ep instanceof PaletteStackEditPart) + if (ep instanceof IPaletteStackEditPart) stackPart = ep; buildNavigationList(ep, exclusion, navList, stackPart); } @@ -142,7 +143,7 @@ siblingsList.add(focusPart); return siblingsList; } - if (parent instanceof GroupEditPart || parent instanceof PaletteStackEditPart) { + if (parent instanceof GroupEditPart || parent instanceof IPaletteStackEditPart) { EditPart grandParent = parent.getParent(); buildNavigationList(grandParent, grandParent, siblingsList, grandParent); } else @@ -176,7 +177,7 @@ * Editpart's parent contains a context menu, false otherwise. */ boolean isContextMenu(EditPart part) { - return part.getParent() instanceof PaletteStackEditPart; + return part.getParent() instanceof IPaletteStackEditPart; } /** @@ -272,7 +273,7 @@ } private void openContextMenu() { - ((PaletteStackEditPart)getFocusEditPart().getParent()).openMenu(); + ((IPaletteStackEditPart)getFocusEditPart().getParent()).openMenu(); } } Index: src/org/eclipse/gef/ui/palette/editparts/PaletteEditPart.java =================================================================== RCS file: /cvsroot/tools/org.eclipse.gef/plugins/org.eclipse.gef/src/org/eclipse/gef/ui/palette/editparts/PaletteEditPart.java,v retrieving revision 1.28 diff -u -r1.28 PaletteEditPart.java --- src/org/eclipse/gef/ui/palette/editparts/PaletteEditPart.java 25 Feb 2008 21:33:15 -0000 1.28 +++ src/org/eclipse/gef/ui/palette/editparts/PaletteEditPart.java 31 Mar 2008 20:37:41 -0000 @@ -39,7 +39,6 @@ import org.eclipse.gef.palette.PaletteContainer; import org.eclipse.gef.palette.PaletteEntry; import org.eclipse.gef.palette.PaletteSeparator; -import org.eclipse.gef.palette.PaletteToolbar; import org.eclipse.gef.tools.SelectEditPartTracker; import org.eclipse.gef.ui.palette.PaletteMessages; import org.eclipse.gef.ui.palette.PaletteViewer; @@ -433,7 +432,7 @@ * @return true if this item is on the palette toolbar; false otherwise * @since 3.4 */ -protected boolean isToolbarItem() { +public boolean isToolbarItem() { if (getParent() instanceof PaletteEditPart) { return ((PaletteEditPart) getParent()).isToolbarItem(); } Index: src/org/eclipse/gef/internal/ui/palette/editparts/PinnablePaletteStackEditPart.java =================================================================== RCS file: src/org/eclipse/gef/internal/ui/palette/editparts/PinnablePaletteStackEditPart.java diff -N src/org/eclipse/gef/internal/ui/palette/editparts/PinnablePaletteStackEditPart.java --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ src/org/eclipse/gef/internal/ui/palette/editparts/PinnablePaletteStackEditPart.java 1 Jan 1970 00:00:00 -0000 @@ -0,0 +1,210 @@ +/******************************************************************************* + * Copyright (c) 2008 IBM Corporation and others. + * 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: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +package org.eclipse.gef.internal.ui.palette.editparts; + +import java.beans.PropertyChangeEvent; +import java.util.Iterator; +import java.util.List; + +import org.eclipse.draw2d.IFigure; + +import org.eclipse.gef.EditPart; +import org.eclipse.gef.GraphicalEditPart; +import org.eclipse.gef.Request; +import org.eclipse.gef.palette.PaletteListener; +import org.eclipse.gef.palette.PaletteStack; +import org.eclipse.gef.palette.ToolEntry; +import org.eclipse.gef.ui.palette.PaletteViewer; +import org.eclipse.gef.ui.palette.editparts.PaletteEditPart; + +/** + * The EditPart for a pinnable PaletteStack to be used in a drawer or group. + * Some of this code has been take from PaletteStackEditPart, + * but they are significantly different to warrant two editpart classes. + * + * @author Whitney Sorenson, crevells + * @since 3.4 + */ +public class PinnablePaletteStackEditPart + extends PaletteEditPart + implements IPaletteStackEditPart { + +// listen to see if active tool is changed in the palette +private PaletteListener paletteListener = new PaletteListener() { + + public void activeToolChanged(PaletteViewer palette, ToolEntry tool) { + if (!getStackFigure().isPinnedOpen() + && getStack().getChildren().contains(tool)) { + if (!getStack().getActiveEntry().equals(tool)) { + getStack().setActiveEntry(tool); + } + } + if (!getStackFigure().isPinnedOpen()) { + getStackFigure().setExpanded(false); + } + } +}; + +/** + * Creates a new PaletteStackEditPart with the given PaletteStack as its model. + * + * @param model + * the PaletteStack to associate with this EditPart. + */ +public PinnablePaletteStackEditPart(PaletteStack model) { + super(model); +} + +/** + * @see org.eclipse.gef.EditPart#activate() + */ +public void activate() { + // in case the model is out of sync + checkActiveEntrySync(); + getPaletteViewer().addPaletteListener(paletteListener); + super.activate(); +} + +/** + * Called when the active entry has changed. + * + * @param oldValue + * the old model value (can be null) + * @param newValue + * the new model value (can be null) + */ +private void activeEntryChanged(Object oldValue, Object newValue) { + GraphicalEditPart part = null; + IFigure oldFigure = null; + IFigure newFigure = null; + int index = -1; + + if (oldValue != null) { + part = (GraphicalEditPart) getViewer().getEditPartRegistry().get( + oldValue); + // if part is null, its no longer a child. + if (part != null) { + oldFigure = part.getFigure(); + + // preserve the original order of the palette stack children + index = getModelChildren().indexOf(part.getModel()); + } + } + + if (newValue != null) { + part = (GraphicalEditPart) getViewer().getEditPartRegistry().get( + newValue); + newFigure = part.getFigure(); + } + + getStackFigure().activeEntryChanged(oldFigure, index, newFigure); +} + +private void checkActiveEntrySync() { + if (getStackFigure().getActiveFigure() == null) + activeEntryChanged(null, getStack().getActiveEntry()); +} + +public IFigure createFigure() { + return new PinnablePaletteStackFigure(); +} + +private PinnablePaletteStackFigure getStackFigure() { + return (PinnablePaletteStackFigure) getFigure(); +} + +public void deactivate() { + getPaletteViewer().removePaletteListener(paletteListener); + super.deactivate(); +} + +public void eraseTargetFeedback(Request request) { + Iterator children = getChildren().iterator(); + + while (children.hasNext()) { + PaletteEditPart part = (PaletteEditPart) children.next(); + part.eraseTargetFeedback(request); + } + super.eraseTargetFeedback(request); +} + +public IFigure getContentPane() { + // not completely accurate, but is there any other way? + return getStackFigure().getContentPane(); +} + +protected void removeChildVisual(EditPart childEditPart) { + IFigure child = ((GraphicalEditPart) childEditPart).getFigure(); + getStackFigure().getContentPane(child).remove(child); +} + +protected void addChild(EditPart childEP, int index) { + index = updateIndexBasedOnActiveFigure(index, childEP); + super.addChild(childEP, index); +} + +protected void reorderChild(EditPart childEP, int index) { + IFigure childFigure = ((GraphicalEditPart) childEP).getFigure(); + if (childFigure == getStackFigure().getActiveFigure()) { + // no need to reorder figures if this is the active figure + List children = getChildren(); + children.remove(childEP); + children.add(index, childEP); + } else { + removeChildVisual(childEP); + List children = getChildren(); + children.remove(childEP); + children.add(index, childEP); + index = updateIndexBasedOnActiveFigure(index, childEP); + addChildVisual(childEP, index); + } +} + +private int updateIndexBasedOnActiveFigure(int index, EditPart childEP) { + for (int i = 0; i < index; i++) { + Object ep = getChildren().get(i); + if (((GraphicalEditPart) ep).getFigure() == getStackFigure() + .getActiveFigure()) { + return index - 1; + } + } + return index; +} + +private PaletteStack getStack() { + return (PaletteStack) getModel(); +} + +public void propertyChange(PropertyChangeEvent event) { + if (event.getPropertyName().equals(PaletteStack.PROPERTY_ACTIVE_ENTRY)) + activeEntryChanged(event.getOldValue(), event.getNewValue()); + else + super.propertyChange(event); +} + +protected void refreshChildren() { + super.refreshChildren(); + checkActiveEntrySync(); +} + +protected void refreshVisuals() { + getStackFigure().setLayoutMode(getLayoutSetting()); +} + +public void openMenu() { + getStackFigure().setExpanded(true); +} + +public boolean isExpanded() { + return getStackFigure().isExpanded(); +} + +} Index: src/org/eclipse/gef/internal/ui/palette/editparts/PinFigure.java =================================================================== RCS file: src/org/eclipse/gef/internal/ui/palette/editparts/PinFigure.java diff -N src/org/eclipse/gef/internal/ui/palette/editparts/PinFigure.java --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ src/org/eclipse/gef/internal/ui/palette/editparts/PinFigure.java 1 Jan 1970 00:00:00 -0000 @@ -0,0 +1,78 @@ +/******************************************************************************* + * Copyright (c) 2008 IBM Corporation and others. + * 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: + * IBM Corporation - initial API and implementation + *******************************************************************************/ + +package org.eclipse.gef.internal.ui.palette.editparts; + +import org.eclipse.swt.graphics.Color; + +import org.eclipse.draw2d.ButtonModel; +import org.eclipse.draw2d.ChangeEvent; +import org.eclipse.draw2d.ChangeListener; +import org.eclipse.draw2d.FigureUtilities; +import org.eclipse.draw2d.Graphics; +import org.eclipse.draw2d.ImageFigure; +import org.eclipse.draw2d.Label; +import org.eclipse.draw2d.Toggle; + +import org.eclipse.gef.internal.InternalImages; +import org.eclipse.gef.internal.ui.palette.PaletteColorUtil; +import org.eclipse.gef.ui.palette.PaletteMessages; + +/** + * This is the figure for the pinned and unpinned toggle. + * + * @author crevells + * @since 3.4 + */ +public class PinFigure + extends Toggle { + +private static final Color PIN_HOTSPOT_COLOR = FigureUtilities.mixColors( + PaletteColorUtil.WIDGET_LIST_BACKGROUND, + PaletteColorUtil.WIDGET_NORMAL_SHADOW, 0.60); + +public PinFigure() { + super(new ImageFigure(InternalImages.get(InternalImages.IMG_UNPINNED))); + setRolloverEnabled(true); + setRequestFocusEnabled(false); + setToolTip(new Label(PaletteMessages.TOOLTIP_PIN_FIGURE)); + setOpaque(false); + + addChangeListener(new ChangeListener() { + + public void handleStateChanged(ChangeEvent e) { + if (e.getPropertyName().equals(ButtonModel.SELECTED_PROPERTY)) { + if (isSelected()) { + ((ImageFigure) (getChildren().get(0))) + .setImage(InternalImages.get(InternalImages.IMG_PINNED)); + ((Label)getToolTip()).setText(PaletteMessages.TOOLTIP_UNPIN_FIGURE); + } else { + ((ImageFigure) (getChildren().get(0))) + .setImage(InternalImages + .get(InternalImages.IMG_UNPINNED)); + ((Label)getToolTip()).setText(PaletteMessages.TOOLTIP_PIN_FIGURE); + } + } + } + }); +} + +protected void paintFigure(Graphics graphics) { + super.paintFigure(graphics); + + ButtonModel model = getModel(); + if (isRolloverEnabled() && model.isMouseOver()) { + graphics.setBackgroundColor(PIN_HOTSPOT_COLOR); + graphics.fillRoundRectangle(getClientArea().getCopy().shrink(1, 1), 3, + 3); + } +} +} Index: src/org/eclipse/gef/internal/ui/palette/editparts/IPaletteStackEditPart.java =================================================================== RCS file: src/org/eclipse/gef/internal/ui/palette/editparts/IPaletteStackEditPart.java diff -N src/org/eclipse/gef/internal/ui/palette/editparts/IPaletteStackEditPart.java --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ src/org/eclipse/gef/internal/ui/palette/editparts/IPaletteStackEditPart.java 1 Jan 1970 00:00:00 -0000 @@ -0,0 +1,29 @@ +/******************************************************************************* + * Copyright (c) 2008 IBM Corporation and others. + * 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: + * IBM Corporation - initial API and implementation + *******************************************************************************/ + +package org.eclipse.gef.internal.ui.palette.editparts; + +/** + * An interface to define the common behavior between all palette stack + * editparts (i.e. the type on the palette toolbar and the type in a drawer or + * group on the palette pane). + * + * @author crevells + * @since 3.4 + */ +public interface IPaletteStackEditPart { + +/** + * Opens/expands the palette stack. + */ +void openMenu(); + +} Index: src/org/eclipse/gef/internal/ui/palette/editparts/PinnablePaletteStackFigure.java =================================================================== RCS file: src/org/eclipse/gef/internal/ui/palette/editparts/PinnablePaletteStackFigure.java diff -N src/org/eclipse/gef/internal/ui/palette/editparts/PinnablePaletteStackFigure.java --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ src/org/eclipse/gef/internal/ui/palette/editparts/PinnablePaletteStackFigure.java 1 Jan 1970 00:00:00 -0000 @@ -0,0 +1,580 @@ +/******************************************************************************* + * Copyright (c) 2008 IBM Corporation and others. + * 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: + * IBM Corporation - initial API and implementation + *******************************************************************************/ + +package org.eclipse.gef.internal.ui.palette.editparts; + +import java.util.Iterator; +import java.util.List; + +import org.eclipse.swt.graphics.Color; + +import org.eclipse.draw2d.AbstractHintLayout; +import org.eclipse.draw2d.AbstractLayout; +import org.eclipse.draw2d.Animation; +import org.eclipse.draw2d.BorderLayout; +import org.eclipse.draw2d.ButtonModel; +import org.eclipse.draw2d.ChangeEvent; +import org.eclipse.draw2d.ChangeListener; +import org.eclipse.draw2d.Figure; +import org.eclipse.draw2d.FigureUtilities; +import org.eclipse.draw2d.FlowLayout; +import org.eclipse.draw2d.Graphics; +import org.eclipse.draw2d.IFigure; +import org.eclipse.draw2d.MarginBorder; +import org.eclipse.draw2d.StackLayout; +import org.eclipse.draw2d.Toggle; +import org.eclipse.draw2d.ToolbarLayout; +import org.eclipse.draw2d.geometry.Dimension; +import org.eclipse.draw2d.geometry.Point; +import org.eclipse.draw2d.geometry.PointList; +import org.eclipse.draw2d.geometry.Rectangle; + +import org.eclipse.gef.internal.ui.palette.PaletteColorUtil; +import org.eclipse.gef.ui.palette.PaletteViewerPreferences; + +/** + * A pinnable palette stack figure. + * + * @author crevells + * @since 3.4 + */ +public class PinnablePaletteStackFigure + extends Figure { + +private static final Color COLOR_WIDGET_BACKGROUND_LIST_BACKGROUND_85 = FigureUtilities + .mixColors(PaletteColorUtil.WIDGET_BACKGROUND, + PaletteColorUtil.WIDGET_LIST_BACKGROUND, 0.85); + +private static final Color COLOR_WIDGET_BACKGROUND_LIST_BACKGROUND_40 = FigureUtilities + .mixColors(PaletteColorUtil.WIDGET_BACKGROUND, + PaletteColorUtil.WIDGET_LIST_BACKGROUND, 0.40); + +private static final Color COLOR_WIDGET_BACKGROUND_NORMAL_SHADOW_65 = FigureUtilities + .mixColors(PaletteColorUtil.WIDGET_BACKGROUND, + PaletteColorUtil.WIDGET_NORMAL_SHADOW, 0.65); + +private static final Color COLOR_WIDGET_BACKGROUND_NORMAL_SHADOW_40 = FigureUtilities + .mixColors(PaletteColorUtil.WIDGET_BACKGROUND, + PaletteColorUtil.WIDGET_NORMAL_SHADOW, 0.40); + +private static final Color COLOR_WIDGET_BACKGROUND_NORMAL_SHADOW_80 = FigureUtilities + .mixColors(PaletteColorUtil.WIDGET_BACKGROUND, + PaletteColorUtil.WIDGET_NORMAL_SHADOW, 0.80); + +private static final Dimension EMPTY_DIMENSION = new Dimension(0, 0); + +/** + * A toggle with a triangle figure. + */ +class RolloverArrow + extends Toggle { + +RolloverArrow() { + super(); + setRolloverEnabled(true); + setBorder(null); + setOpaque(false); + setPreferredSize(11, -1); +} + +/** + * @return false so that the focus rectangle is not drawn. + */ +public boolean hasFocus() { + return false; +} + +public void paintFigure(Graphics graphics) { + Rectangle rect = getBounds().getCopy(); + + graphics.translate(getLocation()); + + // fill the arrow + int[] points = new int[8]; + + if (isSelected() || layoutMode == PaletteViewerPreferences.LAYOUT_ICONS + || layoutMode == PaletteViewerPreferences.LAYOUT_COLUMNS) { + // pointing down + points[0] = 4; + points[1] = rect.height / 2; + points[2] = 9; + points[3] = rect.height / 2; + points[4] = 6; + points[5] = rect.height / 2 + 3; + points[6] = 4; + points[7] = rect.height / 2; + } else { + // pointing to the right + points[0] = 5; + points[1] = rect.height / 2 - 2; + points[2] = 8; + points[3] = rect.height / 2 + 1; + points[4] = 5; + points[5] = rect.height / 2 + 4; + points[6] = 5; + points[7] = rect.height / 2 - 2; + } + + graphics.fillPolygon(points); + + graphics.translate(getLocation().getNegated()); +} +} + +/** + * Layout manager for the palette stack figure that handles the layout of the + * headerFigure, expandablePane, and + * pinFigure when in list or details layout mode. + */ +private class PaletteStackListLayout + extends AbstractHintLayout { + +protected boolean isSensitiveVertically(IFigure container) { + return false; +} + +protected Dimension calculatePreferredSize(IFigure parent, int wHint, int hHint) { + Dimension headerSize = headerFigure.getPreferredSize(wHint, hHint); + + if (((PinnablePaletteStackFigure) parent).isExpanded()) { + Dimension paneSize = expandablePane.getPreferredSize(wHint, hHint); + return new Dimension(Math.max(headerSize.width, paneSize.width), + headerSize.height + paneSize.height); + } else { + return headerSize; + } +} + +public void layout(IFigure parent) { + Rectangle clientArea = Rectangle.SINGLETON; + parent.getClientArea(clientArea); + int wHint = clientArea.width; + int hHint = -1; + + Rectangle rect = new Rectangle(); + rect.setSize(headerFigure.getPreferredSize(wHint, hHint)); + rect.setLocation(clientArea.getTopLeft()); + headerFigure.setBounds(rect); + + if (((PinnablePaletteStackFigure) parent).isExpanded()) { + rect.translate(0, rect.height); + rect.setSize(expandablePane.getPreferredSize(wHint, hHint)); + expandablePane.setBounds(rect); + + rect.setSize(pinFigure.getPreferredSize()); + rect.setLocation(headerFigure.getBounds().right() + - rect.getSize().width, headerFigure.getBounds().getCenter().y + - (rect.getSize().height / 2)); + pinFigure.setBounds(rect); + + } + +} +} + +/** + * Layout manager for the palette stack figure that handles the layout of the + * headerFigure, expandablePane, and + * pinFigure when in icons or columns layout mode. + */ +private class PaletteStackIconLayout + extends AbstractLayout { + +protected Dimension calculatePreferredSize(IFigure parent, int wHint, int hHint) { + return parent.getSize(); +} + +public void layout(IFigure parent) { + if (((PinnablePaletteStackFigure) parent).isExpanded()) { + headerFigure.setBounds(headerBoundsLayoutHint); + + Rectangle paneBounds = parent.getClientArea(); + paneBounds.y += headerBoundsLayoutHint.height; + paneBounds.height -= headerBoundsLayoutHint.height; + expandablePane.setBounds(paneBounds); + + Rectangle pinBounds = Rectangle.SINGLETON; + Dimension pinSize = pinFigure.getPreferredSize(); + pinBounds.setSize(pinSize); + int pinFigureAreaHeight = expandablePane.getInsets().top; + pinBounds.setLocation(expandablePane.getClientArea().right() + - pinSize.width, (paneBounds.y + pinFigureAreaHeight / 2) + - (pinSize.height / 2)); + pinFigure.setBounds(pinBounds); + } else { + headerFigure.setBounds(parent.getClientArea()); + } +} +} + +/** + * listens to selection events on the arrow figure + */ +private ChangeListener clickableArrowListener = new ChangeListener() { + + public void handleStateChanged(ChangeEvent event) { + if (event.getPropertyName().equals(ButtonModel.SELECTED_PROPERTY)) { + + Animation.markBegin(); + handleExpandStateChanged(); + Animation.run(150); + + // Now collapse other stacks when they are not pinned open or in the + // case of columns and icons layout mode (where only one stack can + // be expanded at a time for layout reasons). + if (isExpanded()) { + boolean collapseOtherStacks = (layoutMode == PaletteViewerPreferences.LAYOUT_COLUMNS || layoutMode == PaletteViewerPreferences.LAYOUT_ICONS); + + for (Iterator iterator = getParent().getChildren().iterator(); iterator + .hasNext();) { + Object childFigure = iterator.next(); + if (childFigure instanceof PinnablePaletteStackFigure + && childFigure != PinnablePaletteStackFigure.this) { + + if (collapseOtherStacks + || (((PinnablePaletteStackFigure) childFigure) + .isExpanded() && !((PinnablePaletteStackFigure) childFigure) + .isPinnedOpen())) { + + ((PinnablePaletteStackFigure) childFigure) + .setExpanded(false); + } + } + } + + // The auto-collapsing of drawers is handled in the + // PaletteAnimator. + // If a stack is expanded when there is not enough room to fit + // the + // expanded stack than other drawers should be collapsed. + // However, + // when the animation is run the first time in this method the + // drawer layout has not yet completed so other drawers are not + // collapsed. This 'second pass' of the animation will ensure + // that + // drawers get collapsed if necessary as a result of the newly + // expanded stack. + Animation.markBegin(); + revalidate(); + Animation.run(150); + } + } + } +}; + +private IFigure headerFigure; + +private IFigure activeToolFigure; + +private PinFigure pinFigure; + +private RolloverArrow arrowFigure; + +private IFigure expandablePane; + +private int layoutMode = -1; + +private Rectangle headerBoundsLayoutHint = new Rectangle(); + +public PinnablePaletteStackFigure() { + super(); + + arrowFigure = new RolloverArrow(); + arrowFigure.setBackgroundColor(PaletteColorUtil.WIDGET_DARK_SHADOW); + arrowFigure.addChangeListener(clickableArrowListener); + + headerFigure = new Figure(); + headerFigure.add(arrowFigure); + + pinFigure = new PinFigure(); + + expandablePane = new Figure(); + + add(headerFigure); +} + +protected void paintFigure(Graphics g) { + super.paintFigure(g); + + if (!isExpanded()) { + return; + } + + Rectangle headerBounds = headerFigure.getBounds().getCopy(); + Rectangle paneBounds = expandablePane.getClientArea(); + + // fill expandable pane background + g.setBackgroundColor(COLOR_WIDGET_BACKGROUND_LIST_BACKGROUND_40); + g.fillRectangle(paneBounds); + + if (layoutMode == PaletteViewerPreferences.LAYOUT_ICONS + || layoutMode == PaletteViewerPreferences.LAYOUT_COLUMNS) { + + int pinHeight = expandablePane.getInsets().top; + Rectangle pinAreaBounds = new Rectangle(paneBounds.x, expandablePane + .getBounds().y, paneBounds.width, pinHeight); + + // fill background colors + g.setForegroundColor(COLOR_WIDGET_BACKGROUND_LIST_BACKGROUND_40); + g.setBackgroundColor(COLOR_WIDGET_BACKGROUND_LIST_BACKGROUND_85); + g.fillGradient(headerBounds, true); + + g.setBackgroundColor(COLOR_WIDGET_BACKGROUND_LIST_BACKGROUND_85); + g.fillRectangle(pinAreaBounds); + + // draw white lines + g.setForegroundColor(PaletteColorUtil.WIDGET_LIST_BACKGROUND); + g.drawLine(headerBounds.getTopLeft().getTranslated(1, 1), headerBounds + .getTopRight().getTranslated(-1, 1)); + g.drawLine(headerBounds.getBottomLeft().getTranslated(1, 0), + headerBounds.getTopLeft().getTranslated(1, 1)); + g.drawLine(headerBounds.getBottomRight().getTranslated(-1, 0), + headerBounds.getTopRight().getTranslated(-1, 1)); + + g.drawLine(pinAreaBounds.getTopLeft().getTranslated(0, 1), + pinAreaBounds.getTopRight().getTranslated(-1, 1)); + g.drawLine(pinAreaBounds.getBottomLeft().getTranslated(0, -2), + pinAreaBounds.getBottomRight().getTranslated(-1, -2)); + + // draw grey border around the whole palette stack + PointList points = new PointList(); + points.addPoint(headerBounds.getBottomLeft()); + points.addPoint(headerBounds.getTopLeft().getTranslated(0, 2)); + points.addPoint(headerBounds.getTopLeft().getTranslated(1, 1)); + points.addPoint(headerBounds.getTopLeft().getTranslated(2, 0)); + points.addPoint(headerBounds.getTopRight().getTranslated(-2, 0)); + points.addPoint(headerBounds.getTopRight().getTranslated(-1, 1)); + points.addPoint(headerBounds.getTopRight().getTranslated(0, 2)); + points.addPoint(headerBounds.getBottomRight()); + points.addPoint(pinAreaBounds.getTopRight().getTranslated(-1, 0)); + points.addPoint(paneBounds.getBottomRight().getTranslated(-1, -1)); + points.addPoint(paneBounds.getBottomLeft().getTranslated(0, -1)); + points.addPoint(pinAreaBounds.getTopLeft().getTranslated(0, 0)); + points.addPoint(headerBounds.getBottomLeft()); + + g.setForegroundColor(COLOR_WIDGET_BACKGROUND_NORMAL_SHADOW_40); + g.drawPolygon(points); + + g.setForegroundColor(COLOR_WIDGET_BACKGROUND_NORMAL_SHADOW_80); + Point pt = headerBounds.getTopLeft().getTranslated(0, 1); + g.drawPoint(pt.x, pt.y); + pt = headerBounds.getTopLeft().getTranslated(1, 0); + g.drawPoint(pt.x, pt.y); + pt = headerBounds.getTopRight().getTranslated(-1, 0); + g.drawPoint(pt.x, pt.y); + pt = headerBounds.getTopRight().getTranslated(0, 1); + g.drawPoint(pt.x, pt.y); + } else { + + // fill header background + g.setBackgroundColor(COLOR_WIDGET_BACKGROUND_LIST_BACKGROUND_85); + g.fillRectangle(headerBounds); + + // draw top and bottom border lines of header figure + g.setForegroundColor(COLOR_WIDGET_BACKGROUND_NORMAL_SHADOW_65); + g.drawLine(headerBounds.getTopLeft(), headerBounds.getTopRight()); + g.setForegroundColor(PaletteColorUtil.WIDGET_LIST_BACKGROUND); + g.drawLine(headerBounds.getBottomLeft().getTranslated(0, -2), + headerBounds.getBottomRight().getTranslated(0, -2)); + + // draw bottom border line of expandable pane + g.setForegroundColor(COLOR_WIDGET_BACKGROUND_NORMAL_SHADOW_65); + g.drawLine(paneBounds.getBottomLeft().getTranslated(0, -1), paneBounds + .getBottomRight().getTranslated(0, -1)); + } + +} + +/** + * @return The content pane for this figure, i.e. the Figure to which children + * can be added. + */ +public IFigure getContentPane(IFigure figure) { + if (figure == activeToolFigure) { + return headerFigure; + } + return getContentPane(); +} + +public IFigure getContentPane() { + return expandablePane; +} + +public IFigure getActiveFigure() { + return activeToolFigure; +} + +/** + * @return true if the drawer is expanded + */ +public boolean isExpanded() { + return arrowFigure.getModel().isSelected(); +} + +/** + * @return true if the drawer is expanded and is pinned (i.e., it + * can't be automatically collapsed) + */ +public boolean isPinnedOpen() { + return isExpanded() && pinFigure.getModel().isSelected(); +} + +public void setExpanded(boolean value) { + arrowFigure.setSelected(value); + if (!value) { + pinFigure.setSelected(false); + } +} + +public void setLayoutMode(int newLayoutMode) { + if (this.layoutMode == newLayoutMode) { + return; + } + + this.layoutMode = newLayoutMode; + + // Only one stack can be expanded in icons and layout mode, therefore for + // consistency let's always collapse stacks when changing the layout modes. + setExpanded(false); + + if (newLayoutMode == PaletteViewerPreferences.LAYOUT_LIST + || newLayoutMode == PaletteViewerPreferences.LAYOUT_DETAILS) { + + headerFigure.setLayoutManager(new StackLayout() { + + public void layout(IFigure figure) { + Rectangle r = figure.getClientArea(); + List children = figure.getChildren(); + IFigure child; + for (int i = 0; i < children.size(); i++) { + child = (IFigure) children.get(i); + if (child == arrowFigure) { + Rectangle.SINGLETON.setBounds(r); + Rectangle.SINGLETON.width = 11; + child.setBounds(Rectangle.SINGLETON); + } else { + child.setBounds(r); + } + } + } + }); + + expandablePane.setLayoutManager(new ToolbarLayout()); + expandablePane.setBorder(new MarginBorder(1, 0, 1, 0)); + setLayoutManager(new PaletteStackListLayout()); + + } else { + + headerFigure.setLayoutManager(new BorderLayout()); + if (activeToolFigure != null) { + headerFigure.setConstraint(activeToolFigure, BorderLayout.CENTER); + } + headerFigure.setConstraint(arrowFigure, BorderLayout.RIGHT); + + setLayoutManager(new PaletteStackIconLayout()); + + // account for space used by pin figure + expandablePane.setBorder(new MarginBorder(18, 2, 2, 2)); + + if (layoutMode == PaletteViewerPreferences.LAYOUT_COLUMNS) { + expandablePane.setLayoutManager(new ColumnsLayout()); + } else { // LAYOUT_ICONS + FlowLayout fl = new FlowLayout(); + fl.setMinorSpacing(0); + fl.setMajorSpacing(0); + expandablePane.setLayoutManager(fl); + } + } +} + +public void activeEntryChanged(IFigure oldFigure, int oldFigureIndex, + IFigure newFigure) { + + if (oldFigure != null) { + // if figure is null, its no longer a child. + expandablePane.add(oldFigure, oldFigureIndex); + } + + if (newFigure != null) { + activeToolFigure = newFigure; + headerFigure.add(activeToolFigure, BorderLayout.CENTER, 0); + } else { + activeToolFigure = null; + } +} + +private void handleExpandStateChanged() { + if (isExpanded()) { + if (expandablePane.getParent() != this) { + add(expandablePane); + add(pinFigure); + } + } else { + if (expandablePane.getParent() == this) { + remove(expandablePane); + remove(pinFigure); + } + } +} + +/** + * Gets the preferred size of the expandable pane figure. Used by + * PaletteContainerFlowLayout when the layout is icons or columns + * mode. + * + * @param wHint + * width hint + * @param hHint + * height hint + * @return the preferred size of the expandable pane figure or (0,0) if the pane + * is collapsed + */ +public Dimension getExpandedContainerPreferredSize(int wHint, int hHint) { + if (isExpanded()) { + return expandablePane.getPreferredSize(wHint, hHint); + } else { + return EMPTY_DIMENSION; + } +} + +/** + * Sets the header bounds layout hint. Set by + * PaletteContainerFlowLayout when the layout is icons or columns + * mode and used by PaletteStackIconLayout. + * + * @param rect + * the new value + */ +public void setHeaderBoundsLayoutHint(Rectangle rect) { + headerBoundsLayoutHint.setBounds(rect); +} + +/** + * Gets the preferred size of the header figure. Used by + * PaletteContainerFlowLayout and ColumnsLayout + * when the layout is icons or columns mode. + * + * @param wHint + * width hint + * @param hHint + * height hint + * @return the preferred size of the header figure + */ +public Dimension getHeaderPreferredSize(int wHint, int hHint) { + return headerFigure.getPreferredSize(wHint, hHint); +} + +public boolean containsPoint(int x, int y) { + return headerFigure.containsPoint(x, y) + || (isExpanded() && expandablePane.containsPoint(x, y)); +} + +} Index: src/org/eclipse/gef/internal/ui/palette/editparts/PaletteContainerFlowLayout.java =================================================================== RCS file: src/org/eclipse/gef/internal/ui/palette/editparts/PaletteContainerFlowLayout.java diff -N src/org/eclipse/gef/internal/ui/palette/editparts/PaletteContainerFlowLayout.java --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ src/org/eclipse/gef/internal/ui/palette/editparts/PaletteContainerFlowLayout.java 1 Jan 1970 00:00:00 -0000 @@ -0,0 +1,202 @@ +/******************************************************************************* + * Copyright (c) 2008 IBM Corporation and others. + * 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: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +package org.eclipse.gef.internal.ui.palette.editparts; + +import java.util.List; + +import org.eclipse.draw2d.FlowLayout; +import org.eclipse.draw2d.IFigure; +import org.eclipse.draw2d.geometry.Dimension; +import org.eclipse.draw2d.geometry.Rectangle; + +/** + * Extends FlowLayout to allow the pane of a pinnable stack in + * icon mode to occupy the row following the row in which the icon of the + * palette stack header appears. + * + * @author crevells + * @since 3.4 + */ +public class PaletteContainerFlowLayout + extends FlowLayout { + +/** + * Constructs a PaletteContainerFlowLayout with horizontal orientation. + */ +public PaletteContainerFlowLayout() { +} + +/** + * Constructs a PaletteContainerFlowLayout whose orientation is given in the + * input. + * + * @param isHorizontal + * true if the layout should be horizontal + */ +public PaletteContainerFlowLayout(boolean isHorizontal) { + setHorizontal(isHorizontal); +} + +/** + * Overridden to include the size of the expanded pane of an expanded pinnable + * palette stack. + * + * @see org.eclipse.draw2d.AbstractLayout#calculatePreferredSize(IFigure, int, + * int) + */ +protected Dimension calculatePreferredSize(IFigure container, int wHint, + int hHint) { + + Dimension prefSize = super.calculatePreferredSize(container, wHint, hHint); + + List children = container.getChildren(); + IFigure child; + + // Build the sizes for each row, and update prefSize accordingly + Dimension expandedPaneSize = null; + for (int i = 0; i < children.size(); i++) { + child = (IFigure) children.get(i); + + if (child instanceof PinnablePaletteStackFigure + && ((PinnablePaletteStackFigure) child).isExpanded()) { + + // Subtract out the insets from the hints + if (wHint > -1) + wHint = Math.max(0, wHint - container.getInsets().getWidth()); + if (hHint > -1) + hHint = Math.max(0, hHint - container.getInsets().getHeight()); + + // Figure out the new hint that we are interested in based on the + // orientation. Ignore the other hint (by setting it to -1). NOTE: + // The children of the parent figure will then be asked to ignore + // that hint as well. + if (isHorizontal()) { + hHint = -1; + } else { + wHint = -1; + } + + expandedPaneSize = ((PinnablePaletteStackFigure) child) + .getExpandedContainerPreferredSize(wHint, hHint); + + break; // there can only be one expanded stack + } + } + + if (expandedPaneSize != null) { + // increment height to account for expanded stack + prefSize.height += transposer.t(expandedPaneSize).height; + prefSize.union(getBorderPreferredSize(container)); + } + + return prefSize; +} + +/** + * Overridden to handle PinnablePaletteStackFigure. + * + * @see FlowLayout#getChildSize(IFigure, int, int) + */ +protected Dimension getChildSize(IFigure child, int wHint, int hHint) { + if (child instanceof PinnablePaletteStackFigure) { + return ((PinnablePaletteStackFigure) child).getHeaderPreferredSize( + wHint, hHint); + } else { + return child.getPreferredSize(wHint, hHint); + } +} + +/** + * Overridden to include the size of the expanded pane of an expanded pinnable + * palette stack during the layout. + * + * @see FlowLayout#layoutRow(IFigure) + */ +protected void layoutRow(IFigure parent) { + int majorAdjustment = 0; + int minorAdjustment = 0; + int correctMajorAlignment = majorAlignment; + int correctMinorAlignment = minorAlignment; + + majorAdjustment = data.area.width - data.rowWidth + getMinorSpacing(); + + switch (correctMajorAlignment) { + case ALIGN_LEFTTOP: + majorAdjustment = 0; + break; + case ALIGN_CENTER: + majorAdjustment /= 2; + break; + case ALIGN_RIGHTBOTTOM: + break; + } + + int expandedPaneHeight = 0; + for (int j = 0; j < data.rowCount; j++) { + if (fill) { + data.bounds[j].height = data.rowHeight; + } else { + minorAdjustment = data.rowHeight - data.bounds[j].height; + switch (correctMinorAlignment) { + case ALIGN_LEFTTOP: + minorAdjustment = 0; + break; + case ALIGN_CENTER: + minorAdjustment /= 2; + break; + case ALIGN_RIGHTBOTTOM: + break; + } + data.bounds[j].y += minorAdjustment; + } + data.bounds[j].x += majorAdjustment; + + IFigure child = data.row[j]; + setBoundsOfChild(parent, data.row[j], transposer.t(data.bounds[j])); + + if (child instanceof PinnablePaletteStackFigure + && ((PinnablePaletteStackFigure) child).isExpanded()) { + + int wHint = -1; + int hHint = -1; + if (isHorizontal()) + wHint = parent.getClientArea().width; + else + hHint = parent.getClientArea().height; + + expandedPaneHeight = ((PinnablePaletteStackFigure) child) + .getExpandedContainerPreferredSize(wHint, hHint).height; + child.setBounds(new Rectangle(data.area.x, data.area.y + data.rowY, + data.area.width, data.rowHeight + expandedPaneHeight)); + } + } + data.rowY += getMajorSpacing() + data.rowHeight + expandedPaneHeight; + initRow(); +} + +/** + * Overridden to set the bounds for PinnablePaletteStackFigures. + * + * @see FlowLayout#setBoundsOfChild(IFigure, IFigure, Rectangle) + */ +protected void setBoundsOfChild(IFigure parent, IFigure child, Rectangle bounds) { + + if (child instanceof PinnablePaletteStackFigure + && ((PinnablePaletteStackFigure) child).isExpanded()) { + parent.getClientArea(Rectangle.SINGLETON); + bounds.translate(Rectangle.SINGLETON.x, Rectangle.SINGLETON.y); + ((PinnablePaletteStackFigure) child).setHeaderBoundsLayoutHint(bounds); + } else { + super.setBoundsOfChild(parent, child, bounds); + } +} + +} #P org.eclipse.draw2d Index: src/org/eclipse/draw2d/FlowLayout.java =================================================================== RCS file: /cvsroot/tools/org.eclipse.gef/plugins/org.eclipse.draw2d/src/org/eclipse/draw2d/FlowLayout.java,v retrieving revision 1.19 diff -u -r1.19 FlowLayout.java --- src/org/eclipse/draw2d/FlowLayout.java 30 Mar 2005 21:27:45 -0000 1.19 +++ src/org/eclipse/draw2d/FlowLayout.java 31 Mar 2008 20:37:42 -0000 @@ -60,15 +60,15 @@ protected int minorSpacing = 5; /** The spacing along the major axis. */ protected int majorSpacing = 5; -private WorkingData data = null; +protected WorkingData data = null; /** * Holds the necessary information for layout calculations. */ -class WorkingData { - int rowHeight, rowWidth, rowCount, rowX, rowY, maxWidth; - Rectangle bounds[], area; - IFigure row[]; +protected class WorkingData { + public int rowHeight, rowWidth, rowCount, rowX, rowY, maxWidth; + public Rectangle bounds[], area; + public IFigure row[]; } /** @@ -220,7 +220,7 @@ /** * Initializes the state of row data, which is internal to the layout process. */ -private void initRow() { +protected void initRow() { data.rowX = 0; data.rowHeight = 0; data.rowWidth = 0; @@ -233,7 +233,7 @@ * @param parent the parent figure * @since 2.0 */ -private void initVariables(IFigure parent) { +protected void initVariables(IFigure parent) { data.row = new IFigure[parent.getChildren().size()]; data.bounds = new Rectangle[data.row.length]; data.maxWidth = data.area.width;