Java tutorial
/******************************************************************************* * Copyright (c) 2009, 2014 EclipseSource 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: * EclipseSource - initial API and implementation ******************************************************************************/ package org.eclipse.rap.internal.design.example.stacks; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; import org.eclipse.jface.action.IToolBarManager; import org.eclipse.rap.internal.design.example.ILayoutSetConstants; import org.eclipse.rap.internal.design.example.Messages; import org.eclipse.rap.internal.design.example.builder.StackPresentationBuider; import org.eclipse.rap.rwt.RWT; import org.eclipse.rap.ui.interactiondesign.ConfigurableStack; import org.eclipse.rap.ui.interactiondesign.ConfigurationAction; import org.eclipse.rap.ui.interactiondesign.IConfigurationChangeListener; import org.eclipse.rap.ui.interactiondesign.PresentationFactory; import org.eclipse.rap.ui.interactiondesign.layout.ElementBuilder; import org.eclipse.swt.SWT; import org.eclipse.swt.events.ControlAdapter; import org.eclipse.swt.events.ControlEvent; import org.eclipse.swt.events.DisposeEvent; import org.eclipse.swt.events.DisposeListener; import org.eclipse.swt.events.MouseAdapter; import org.eclipse.swt.events.MouseEvent; import org.eclipse.swt.events.SelectionAdapter; import org.eclipse.swt.events.SelectionEvent; import org.eclipse.swt.graphics.Color; import org.eclipse.swt.graphics.Image; import org.eclipse.swt.graphics.Point; import org.eclipse.swt.graphics.Rectangle; import org.eclipse.swt.layout.FormAttachment; import org.eclipse.swt.layout.FormData; import org.eclipse.swt.layout.FormLayout; import org.eclipse.swt.layout.RowLayout; import org.eclipse.swt.widgets.Button; import org.eclipse.swt.widgets.Composite; import org.eclipse.swt.widgets.Control; import org.eclipse.swt.widgets.Display; import org.eclipse.swt.widgets.Event; import org.eclipse.swt.widgets.Label; import org.eclipse.swt.widgets.Listener; import org.eclipse.swt.widgets.Menu; import org.eclipse.swt.widgets.MenuItem; import org.eclipse.ui.IPropertyListener; import org.eclipse.ui.ISaveablePart; import org.eclipse.ui.IWorkbench; import org.eclipse.ui.IWorkbenchPage; import org.eclipse.ui.IWorkbenchPart; import org.eclipse.ui.IWorkbenchPartConstants; import org.eclipse.ui.IWorkbenchPartReference; import org.eclipse.ui.IWorkbenchWindow; import org.eclipse.ui.PlatformUI; import org.eclipse.ui.internal.PartPane; import org.eclipse.ui.internal.presentations.PresentablePart; import org.eclipse.ui.presentations.IPartMenu; import org.eclipse.ui.presentations.IPresentablePart; import org.eclipse.ui.presentations.IStackPresentationSite; import org.eclipse.ui.presentations.StackDropResult; public class ViewStackPresentation extends ConfigurableStack { private static final String VARIANT_PART_INACTIVE = "partInactive"; //$NON-NLS-1$ private static final String VARIANT_PART_ACTIVE = "partActive"; //$NON-NLS-1$ private static final String VARIANT_PART_INACTIVE_ACTIVE = "partInActiveActive"; //$NON-NLS-1$ private static final int BUTTON_SPACING = 6; private static final String ID_CLOSE = "close"; //$NON-NLS-1$ private static final String BUTTON_ID = "buttonId"; //$NON-NLS-1$ private static final int WIDTH_SPACING = 65; private static final int HEIGHT_SPACING = 15; private Control presentationControl; private IPresentablePart currentPart; private ElementBuilder stackBuilder; private Composite tabBg; private Composite confArea; private Button confButton; private Label confCorner; private final Map<IPresentablePart, Composite> partButtonMap; private final List<IPresentablePart> partList; private final List<Composite> buttonList; private Composite toolbarBg; private int activeState; private int state; protected boolean deactivated; private Button viewMenuButton; private final Map<IPresentablePart, IPropertyListener> dirtyListenerMap; private Button overflowButton; private final List<Control> overflowButtons; private final Map<Composite, IPresentablePart> buttonPartMap; private IPresentablePart oldPart; private final boolean allActionsVisible; private Label standaloneViewTitle; private class DirtyListener implements IPropertyListener { private final IPresentablePart part; public DirtyListener(IPresentablePart part) { this.part = part; } public void propertyChanged(Object source, int propId) { if (propId == ISaveablePart.PROP_DIRTY) { handleDirtyStateChanged(); } else if (propId == IWorkbenchPartConstants.PROP_PART_NAME) { handlePartNameChanged(); } } private void handleDirtyStateChanged() { Button partButton = getPartButton(part); if (partButton != null) { String text = partButton.getText(); char lastCharacter = getLastCharacter(text); if (part.isDirty()) { // mark the part as dirty if (lastCharacter != '*') { text = text + "*"; //$NON-NLS-1$ } } else { // mark the part as clean if (lastCharacter == '*') { text = text.substring(0, text.length() - 1); } } partButton.setText(text); } } private void handlePartNameChanged() { Button partButton = getPartButton(part); if (partButton != null) { partButton.setText(part.getName()); partButton.getParent().layout(true); } if (standaloneViewTitle != null) { standaloneViewTitle.setText(part.getName()); standaloneViewTitle.getParent().layout(true); } } private Button getPartButton(IPresentablePart part) { Button result = null; Object object = partButtonMap.get(part); if (object instanceof Composite) { Control[] children = ((Composite) object).getChildren(); if (children.length > 0 && children[0] instanceof Button) { result = (Button) children[0]; } } return result; } private char getLastCharacter(String text) { char[] starArray = new char[1]; text.getChars(text.length() - 1, text.length(), starArray, 0); return starArray[0]; } } public ViewStackPresentation() { activeState = AS_INACTIVE; deactivated = false; allActionsVisible = ConfigAction.allActionsVisible(); partButtonMap = new HashMap<IPresentablePart, Composite>(); partList = new ArrayList<IPresentablePart>(); buttonList = new ArrayList<Composite>(); dirtyListenerMap = new HashMap<IPresentablePart, IPropertyListener>(); overflowButtons = new ArrayList<Control>(); buttonPartMap = new HashMap<Composite, IPresentablePart>(); } @Override public void init() { ConfigurationAction action = getConfigAction(); if (action != null) { action.addConfigurationChangeListener(new IConfigurationChangeListener() { public void toolBarChanged() { ViewToolBarRegistry registry = ViewToolBarRegistry.getInstance(); registry.fireToolBarChanged(); } public void presentationChanged(String newStackPresentationId) { // do nothing atm } }); } presentationControl = createStyledControl(); ViewToolBarRegistry registry = ViewToolBarRegistry.getInstance(); registry.addViewPartPresentation(this); } void catchToolbarChange() { layoutToolBar(); setBounds(presentationControl.getBounds()); } private void createToolBarBg() { Composite tabBar = getTabBar(); toolbarBg = new Composite(tabBar.getParent(), SWT.NONE); toolbarBg.setLayout(new FormLayout()); Image bg = stackBuilder.getImage(ILayoutSetConstants.STACK_VIEW_TOOLBAR_BG); toolbarBg.setBackgroundImage(bg); FormData fdToolBar = new FormData(); toolbarBg.setLayoutData(fdToolBar); fdToolBar.left = new FormAttachment(0); fdToolBar.right = new FormAttachment(100); fdToolBar.top = new FormAttachment(tabBar); fdToolBar.height = bg.getBounds().height; toolbarBg.moveAbove(tabBar); } private Control createStyledControl() { getParent().setData(RWT.CUSTOM_VARIANT, "compGray"); //$NON-NLS-1$ final Composite parent = new Composite(getParent(), SWT.NONE); parent.addControlListener(new ControlAdapter() { @Override public void controlResized(ControlEvent e) { setBounds(parent.getBounds()); } }); parent.setData(RWT.CUSTOM_VARIANT, "compGray"); //$NON-NLS-1$ String setID = ILayoutSetConstants.SET_ID_STACKPRESENTATION; stackBuilder = new StackPresentationBuider(parent, setID); stackBuilder.build(); return parent; } private boolean isStandalone() { return getType().equals(PresentationFactory.KEY_STANDALONE_VIEW); } @Override public void addPart(IPresentablePart newPart, Object cookie) { checkTabBg(); if (!isStandalone()) { createPartButton(newPart); partList.add(newPart); Control partControl = newPart.getControl(); if (partControl != null) { partControl.getParent().setBackgroundMode(SWT.INHERIT_NONE); partControl.setData(RWT.CUSTOM_VARIANT, "partBorder"); //$NON-NLS-1$ } tabBg.layout(true); } else { decorateStandaloneView(newPart); } // add the listener for the dirty activeState IPropertyListener listener = new DirtyListener(newPart); dirtyListenerMap.put(newPart, listener); newPart.addPropertyListener(listener); } private void decorateStandaloneView(IPresentablePart newPart) { checkTabBg(); if (getShowTitle()) { getTabBar().setVisible(true); tabBg.setVisible(true); standaloneViewTitle = new Label(tabBg, SWT.NONE); standaloneViewTitle.setData(RWT.CUSTOM_VARIANT, "standaloneView"); //$NON-NLS-1$ standaloneViewTitle.setText(newPart.getName()); hideFrameLabel(StackPresentationBuider.TOP_BORDER); } else { getTabBar().setVisible(false); hideFrameLabel(StackPresentationBuider.LEFT); hideFrameLabel(StackPresentationBuider.RIGHT); } } private void hideFrameLabel(String id) { Object labelMap = stackBuilder.getAdapter(Map.class); if (labelMap != null && (labelMap instanceof Map)) { Map map = (Map) labelMap; Object object = map.get(id); if (object != null) { Label frameLabel = (Label) object; frameLabel.setVisible(false); } } } private void layoutToolBar() { if (toolbarBg == null && tabBg != null) { createToolBarBg(); } if (currentPart != null && getPartPane(currentPart) != null) { Control toolBar = currentPart.getToolBar(); final IPartMenu viewMenu = currentPart.getMenu(); // viewmenu if (viewMenu != null) { if (viewMenuButton == null) { viewMenuButton = new Button(toolbarBg, SWT.PUSH); viewMenuButton.setData(RWT.CUSTOM_VARIANT, "clearButton"); //$NON-NLS-1$ Image icon = stackBuilder.getImage(ILayoutSetConstants.STACK_VIEW_MENU_ICON); viewMenuButton.setImage(icon); FormData fdViewMenuButton = new FormData(); viewMenuButton.setLayoutData(fdViewMenuButton); fdViewMenuButton.right = new FormAttachment(100, -4); fdViewMenuButton.top = new FormAttachment(0, 8); viewMenuButton.addSelectionListener(new SelectionAdapter() { @Override public void widgetSelected(SelectionEvent e) { Display display = viewMenuButton.getDisplay(); int height = viewMenuButton.getSize().y; Point newLoc = display.map(viewMenuButton, null, 0, height); viewMenu.showMenu(newLoc); } }); } } else if (viewMenuButton != null) { viewMenuButton.setVisible(false); viewMenuButton.dispose(); viewMenuButton = null; } // toolbar Point size = toolbarBg.getSize(); if (toolBar != null) { Point point = currentPart.getControl().getLocation(); point.y -= (size.y + 2); point.x += (size.x - toolBar.getSize().x); if (viewMenu != null) { point.x -= 20; } toolBar.setLocation(point); toolbarBg.moveBelow(toolBar); presentationControl.moveBelow(toolBar); currentPart.getControl().moveBelow(toolBar); } // toolbarbg and layer if (toolBar != null || viewMenu != null) { toolbarBg.setVisible(true); } else { toolbarBg.setVisible(false); } toolbarBg.layout(true); } handleConfigurationButton(); } /* * Deactivates the configuration button if the current part has nothing to * configure. */ private void handleConfigurationButton() { boolean hasViewMenu = false; if (currentPart != null && currentPart instanceof PresentablePart) { PresentablePart part = (PresentablePart) currentPart; if (part.getPane() != null) { hasViewMenu = part.getPane().hasViewMenu(); IToolBarManager manager = getPartToolBarManager(); boolean hasViewActions = manager != null && manager.getItems().length > 0; if ((hasViewActions || hasViewMenu) && !allActionsVisible) { if (confButton != null) { // enable conf button confButton.setEnabled(true); String buttonTooltip = Messages.get().ViewStackPresentation_ConfButtonToolTipEnabled; String toolTip = buttonTooltip + currentPart.getName(); confButton.setToolTipText(toolTip); } } else { if (confButton != null) { // disable conf button confButton.setEnabled(false); String buttonToolTip = Messages.get().ViewStackPresentation_ConfButtonToolTipDisabled; String toolTip = currentPart.getName() + buttonToolTip; confButton.setToolTipText(toolTip); } } } } } private void createPartButton(final IPresentablePart part) { Composite buttonArea = new Composite(tabBg, SWT.NONE); buttonArea.setData(RWT.CUSTOM_VARIANT, "inactiveButton"); //$NON-NLS-1$ buttonArea.setLayout(new FormLayout()); final Button partButton = new Button(buttonArea, SWT.PUSH); partButton.setData(RWT.CUSTOM_VARIANT, VARIANT_PART_INACTIVE); partButton.setText(part.getName()); partButton.setToolTipText(part.getTitleToolTip()); final IPropertyListener nameListener = new IPropertyListener() { public void propertyChanged(Object source, int propId) { if (propId == IPresentablePart.PROP_PART_NAME) { partButton.setText(part.getName()); tabBg.layout(); } else if (propId == IPresentablePart.PROP_TITLE) { partButton.setToolTipText(part.getTitleToolTip()); } } }; part.addPropertyListener(nameListener); partButton.addDisposeListener(new DisposeListener() { public void widgetDisposed(DisposeEvent event) { partButton.removeDisposeListener(this); part.removePropertyListener(nameListener); } }); FormData fdPartButton = new FormData(); partButton.setLayoutData(fdPartButton); fdPartButton.left = new FormAttachment(0); fdPartButton.top = new FormAttachment(0, 4); fdPartButton.bottom = new FormAttachment(100); partButton.addSelectionListener(new SelectionAdapter() { @Override public void widgetSelected(SelectionEvent e) { if (!currentPart.equals(part)) { selectPart(part); } activatePart(part); // move the toolbar on top currentPart.getControl().moveAbove(null); Control toolBar = currentPart.getToolBar(); if (toolBar != null) { toolBar.moveAbove(null); } } }); partButton.addListener(SWT.MouseDoubleClick, new Listener() { public void handleEvent(Event event) { handleToggleZoom(part); } }); Composite corner = new Composite(buttonArea, SWT.NONE); corner.setData(RWT.CUSTOM_VARIANT, "compTrans"); //$NON-NLS-1$ corner.setLayout(new FormLayout()); String separatorActive = ILayoutSetConstants.STACK_TAB_INACTIVE_SEPARATOR_ACTIVE; Image cornerImage = stackBuilder.getImage(separatorActive); FormData fdCorner = new FormData(); corner.setLayoutData(fdCorner); fdCorner.right = new FormAttachment(100); fdCorner.bottom = new FormAttachment(100); fdCorner.width = cornerImage.getBounds().width; fdCorner.height = cornerImage.getBounds().height; fdPartButton.height = cornerImage.getBounds().height; fdPartButton.right = new FormAttachment(corner, -8); partButtonMap.put(part, buttonArea); buttonPartMap.put(buttonArea, part); buttonList.add(buttonArea); moveToTabBarEnd(buttonArea); } private void handleToggleZoom(IPresentablePart part) { IWorkbench workbench = PlatformUI.getWorkbench(); IWorkbenchWindow window = workbench.getActiveWorkbenchWindow(); IWorkbenchPage page = window.getActivePage(); page.toggleZoom(getReference(part)); handleToolbarsOnToggleZoom(); } private void handleToolbarsOnToggleZoom() { ViewToolBarRegistry registry = ViewToolBarRegistry.getInstance(); if (state == IStackPresentationSite.STATE_MAXIMIZED) { registry.moveAllToolbarsBellow(null); } else if (state == IStackPresentationSite.STATE_RESTORED) { registry.fireToolBarChanged(); } if (currentPart != null) { currentPart.getControl().moveAbove(null); Control toolBar = currentPart.getToolBar(); if (toolBar != null) { toolBar.moveAbove(null); } } } public void hideAllToolBars(Control control) { for (int i = 0; i < partList.size(); i++) { IPresentablePart part = partList.get(i); Control toolBar = part.getToolBar(); if (toolBar != null) { toolBar.moveBelow(control); } } } protected void activatePart(IPresentablePart part) { IWorkbench workbench = PlatformUI.getWorkbench(); IWorkbenchWindow window = workbench.getActiveWorkbenchWindow(); IWorkbenchPage activePage = window.getActivePage(); IWorkbenchPart workbenchPart = getReference(part).getPart(true); if (workbenchPart != null) { if (oldPart != null) { Control toolBar = oldPart.getToolBar(); if (toolBar != null) { toolBar.setVisible(false); } } activePage.activate(workbenchPart); } } private IWorkbenchPartReference getReference(IPresentablePart part) { IWorkbenchPartReference result = null; if (part instanceof PresentablePart) { PresentablePart presentablePart = (PresentablePart) part; PartPane pane = presentablePart.getPane(); result = pane.getPartReference(); } return result; } private void makePartButtonActive(final IPresentablePart part) { Object object = partButtonMap.get(part); if (object instanceof Composite) { Composite buttonArea = (Composite) object; buttonArea.setData(RWT.CUSTOM_VARIANT, "tabInactive"); //$NON-NLS-1$ checkHideSeparator(buttonArea); Color bg = stackBuilder.getColor(ILayoutSetConstants.STACK_BUTTON_INACTIVE); buttonArea.setBackground(bg); Control[] children = buttonArea.getChildren(); buttonArea.setLayout(new FormLayout()); for (int i = 0; i < children.length; i++) { Control child = children[i]; if (child instanceof Button) { // Partbutton Button partButton = (Button) child; partButton.setData(RWT.CUSTOM_VARIANT, VARIANT_PART_ACTIVE); FormData fdButton = (FormData) partButton.getLayoutData(); FormData pos = stackBuilder.getPosition(ILayoutSetConstants.STACK_BUTTON_TOP); fdButton.top = pos.top; } else if (child instanceof Composite) { // Corner Composite corner = (Composite) child; corner.setVisible(true); String cornerDesc = ILayoutSetConstants.STACK_TAB_INACTIVE_CORNER_ACTIVE; Image cornerImage = stackBuilder.getImage(cornerDesc); corner.setBackgroundImage(null); FormData fdCorner = (FormData) corner.getLayoutData(); fdCorner.top = new FormAttachment(0); fdCorner.width = cornerImage.getBounds().width; fdCorner.height = cornerImage.getBounds().height; if (part.isCloseable()) { Button close = new Button(buttonArea, SWT.PUSH); close.setData(BUTTON_ID, ID_CLOSE); close.setData(RWT.CUSTOM_VARIANT, "viewCloseInactive"); //$NON-NLS-1$ close.addSelectionListener(new SelectionAdapter() { @Override public void widgetSelected(SelectionEvent e) { IStackPresentationSite site = getSite(); if (site.isCloseable(part)) { site.close(new IPresentablePart[] { part }); showPartButton(currentPart); } } }); FormData fdClose = new FormData(); close.setLayoutData(fdClose); fdClose.right = new FormAttachment(100, -5); fdClose.top = new FormAttachment(0, 6); fdClose.width = 7; fdClose.height = 8; close.setLayoutData(fdClose); close.moveAbove(corner); } } } showPartButton(currentPart); } } private void checkHideSeparator(Composite buttonArea) { int indexOf = buttonList.indexOf(buttonArea); for (int i = 0; i < buttonList.size(); i++) { Composite area = buttonList.get(i); Control[] children = area.getChildren(); for (int j = 0; j < children.length; j++) { if (children[j] instanceof Composite) { if (i == indexOf || (i == indexOf - 1)) { ((Composite) children[j]).setVisible(false); } else { ((Composite) children[j]).setVisible(true); } } } } } private void makePartButtonInactive(IPresentablePart part) { Object object = partButtonMap.get(part); if (object instanceof Composite) { Composite buttonArea = (Composite) object; buttonArea.setData(RWT.CUSTOM_VARIANT, "inactiveButton"); //$NON-NLS-1$ buttonArea.setBackground(null); Control[] children = buttonArea.getChildren(); for (int i = 0; i < children.length; i++) { Control child = children[i]; if (child instanceof Button) { Button button = (Button) child; // Partbutton if (button.getData(BUTTON_ID) != null) { // close button button.setVisible(false); button.dispose(); } else { // Part button button.setData(RWT.CUSTOM_VARIANT, VARIANT_PART_INACTIVE); FormData fdButton = (FormData) button.getLayoutData(); fdButton.top = new FormAttachment(0, 0); } } else if (child instanceof Composite) { // Corner Composite corner = (Composite) child; corner.setVisible(true); String sepConst = ILayoutSetConstants.STACK_TAB_INACTIVE_SEPARATOR_ACTIVE; Image cornerImage = stackBuilder.getImage(sepConst); corner.setBackgroundImage(cornerImage); FormData fdCorner = (FormData) corner.getLayoutData(); fdCorner.width = cornerImage.getBounds().width; fdCorner.height = cornerImage.getBounds().height; fdCorner.top = new FormAttachment(0, 6); } } buttonArea.getParent().layout(); } } /* * check if the tabBg exists. If not it will create it. */ private void checkTabBg() { Composite tabBar = getTabBar(); if (tabBg == null && tabBar != null) { tabBg = new Composite(tabBar, SWT.NONE); tabBg.setData(RWT.CUSTOM_VARIANT, "compTrans"); //$NON-NLS-1$ FormData fdTabBg = new FormData(); tabBg.setLayoutData(fdTabBg); fdTabBg.left = new FormAttachment(0); fdTabBg.top = new FormAttachment(0); fdTabBg.bottom = new FormAttachment(100); createConfArea(fdTabBg); FormData fdLayout = stackBuilder.getPosition(ILayoutSetConstants.STACK_TABBG_POS); RowLayout layout = new RowLayout(SWT.HORIZONTAL); layout.spacing = 0; layout.marginBottom = 0; if (!isStandalone()) { layout.marginHeight = 0; layout.marginLeft = fdLayout.width; } else { layout.marginHeight = 4; layout.marginLeft = BUTTON_SPACING; } layout.marginRight = 16; layout.marginTop = fdLayout.height; layout.marginWidth = 0; layout.wrap = false; tabBg.setLayout(layout); // calculate overflow presentationControl.addControlListener(new ControlAdapter() { @Override public void controlResized(ControlEvent e) { manageOverflow(); } }); addPartActivationListners(); } } private void addPartActivationListners() { addPartActivationListnerToControl(tabBg); Map cornerMap = (Map) stackBuilder.getAdapter(Map.class); Object corner = cornerMap.get(StackPresentationBuider.LEFT); addPartActivationListenerToCorner(corner); corner = cornerMap.get(StackPresentationBuider.RIGHT); addPartActivationListenerToCorner(corner); } private void addPartActivationListenerToCorner(Object corner) { if (corner != null && corner instanceof Label) { Label cornerLabel = (Label) corner; addPartActivationListnerToControl(cornerLabel); } } private void addPartActivationListnerToControl(Control control) { control.addMouseListener(new MouseAdapter() { @Override public void mouseUp(MouseEvent e) { activatePartWithTabbar(); } @Override public void mouseDoubleClick(MouseEvent e) { handleToggleZoom(currentPart); } }); } private void activatePartWithTabbar() { activatePart(currentPart); // move the toolbar on top currentPart.getControl().moveAbove(null); Control toolBar = currentPart.getToolBar(); if (toolBar != null) { toolBar.moveAbove(null); } } private void manageOverflow() { if (isOverflowNecessary()) { hideLastVisibleButton(); manageOverflow(); } else { showLastChildIfNecessary(0); } handleOverflowButton(); } private boolean isOverflowNecessary() { int tabChildrenSize = getTabChildrenSize(); boolean childrenBiggerThanParent = tabChildrenSize > tabBg.getBounds().width; return childrenBiggerThanParent && moreThanOneChildVisible(); } private boolean moreThanOneChildVisible() { boolean result = false; Control[] children = tabBg.getChildren(); int visibleChilds = 0; for (int i = 0; i < children.length && !result; i++) { if (children[i].isVisible()) { visibleChilds++; if (visibleChilds > 1) { result = true; } } } return result; } private void handleOverflowButton() { if (overflowButton == null) { overflowButton = new Button(tabBg.getParent(), SWT.PUSH); String stackOverflowPosition = ILayoutSetConstants.STACK_OVERFLOW_POSITION; FormData fdOverflowButton = stackBuilder.getPosition(stackOverflowPosition); overflowButton.setLayoutData(fdOverflowButton); String stackTabOverflowActive = ILayoutSetConstants.STACK_TAB_OVERFLOW_ACTIVE; Image icon = stackBuilder.getImage(stackTabOverflowActive); fdOverflowButton.height = icon.getBounds().height; fdOverflowButton.width = icon.getBounds().width; String variant = "tabOverflowInactive"; //$NON-NLS-1$ if (activeState == AS_ACTIVE_FOCUS) { variant = "tabOverflowActive"; //$NON-NLS-1$ } overflowButton.setData(RWT.CUSTOM_VARIANT, variant); overflowButton.moveAbove(tabBg); overflowButton.addSelectionListener(new SelectionAdapter() { @Override public void widgetSelected(SelectionEvent e) { performOverflow(); } }); } if (tabBgHasInvisibleButtons()) { overflowButton.setVisible(true); } else { overflowButton.setVisible(false); } } private void performOverflow() { activatePart(currentPart); Menu overflowMenu = new Menu(overflowButton); for (int i = 0; i < overflowButtons.size(); i++) { Object obj = buttonPartMap.get(overflowButtons.get(i)); final IPresentablePart part = (IPresentablePart) obj; MenuItem item = new MenuItem(overflowMenu, SWT.PUSH); if (part != null) { item.setText(part.getName()); item.addSelectionListener(new SelectionAdapter() { @Override public void widgetSelected(SelectionEvent e) { activatePart(part); showPartButton(part); } }); } } // show popup overflowButton.setMenu(overflowMenu); overflowMenu.setVisible(true); Display display = overflowButton.getDisplay(); Point newLocation = display.map(overflowButton, null, 0, 10); overflowMenu.setLocation(newLocation); } private void showPartButton(IPresentablePart part) { Control button = partButtonMap.get(part); if (button != null && !button.isDisposed() && !button.isVisible()) { overflowButtons.remove(button); moveToTabBarEnd(button); button.setVisible(true); } if (tabBg != null && !tabBg.isDisposed()) { tabBg.layout(true, true); manageOverflow(); } } private void moveToTabBarEnd(Control partButton) { Control lastInvisibleButton = getLastInvisibleButton(); if (lastInvisibleButton != null) { if (lastInvisibleButton.isVisible()) { partButton.moveBelow(lastInvisibleButton); } else { partButton.moveAbove(lastInvisibleButton); } } else { partButton.moveBelow(null); } } private void showLastChildIfNecessary(int recursionCount) { Control childToShow = getLastInvisibleButton(); if (childToShow != null && futureTabChildrenSize(childToShow) < tabBg.getBounds().width && tabBgHasInvisibleButtons()) { childToShow.setVisible(true); IPresentablePart part = buttonPartMap.get(childToShow); makePartButtonInactive(part); overflowButtons.remove(childToShow); tabBg.layout(true, true); if (recursionCount <= tabBg.getChildren().length) { int newCount = recursionCount + 1; showLastChildIfNecessary(newCount); } } } private boolean tabBgHasInvisibleButtons() { boolean result = false; Control[] children = tabBg.getChildren(); for (int i = 0; i < children.length && !result; i++) { if (!children[i].isVisible()) { result = true; } } return result; } private int futureTabChildrenSize(Control childToShow) { int result = 0; result = getTabChildrenSize(); result += childToShow.getBounds().width; result += BUTTON_SPACING; return result; } private Control getLastInvisibleButton() { Control result = null; Control[] children = tabBg.getChildren(); boolean childShowedUp = false; for (int i = children.length - 1; i >= 0 && !childShowedUp; i--) { if (children[i].isVisible()) { if (children.length >= (i + 2)) { result = children[i + 1]; } else { result = children[i]; } childShowedUp = true; } } return result; } /* * Returns the control which was hide. */ private Control hideLastVisibleButton() { Control result = null; if (tabBg != null && !tabBg.isDisposed()) { Control[] children = tabBg.getChildren(); boolean lastChildHidden = false; for (int i = children.length - 1; i >= 0 && !lastChildHidden; i--) { if (children[i].isVisible()) { if (isButtonActive(children[i])) { if (i > 0) { children[i - 1].setVisible(false); result = children[i - 1]; if (!overflowButtons.contains(children[i - 1])) { overflowButtons.add(children[i - 1]); } children[i].moveAbove(children[i - 1]); } } else { children[i].setVisible(false); result = children[i]; overflowButtons.add(children[i]); } lastChildHidden = true; tabBg.layout(true, true); } } } return result; } private boolean isButtonActive(Control control) { boolean result = false; // check against the button variant if (control instanceof Composite) { Composite buttonArea = (Composite) control; Control[] children = buttonArea.getChildren(); for (int i = 0; i < children.length && !result; i++) { if (children[i] instanceof Button) { Object data = children[i].getData(RWT.CUSTOM_VARIANT); if (data.equals(VARIANT_PART_INACTIVE_ACTIVE) || data.equals(VARIANT_PART_ACTIVE)) { result = true; } } } } return result; } private int getTabChildrenSize() { int result = 0; Control[] children = tabBg.getChildren(); for (int i = 0; i < children.length; i++) { if (children[i].isVisible() && !children[i].isDisposed()) { result += children[i].getBounds().width; result += BUTTON_SPACING; } } return result; } private void createConfArea(FormData fdTabBg) { final ConfigurationAction configAction = getConfigAction(); if (configAction != null) { confArea = new Composite(getTabBar(), SWT.NONE); Image confBg = stackBuilder.getImage(ILayoutSetConstants.STACK_CONF_BG_INACTIVE); confArea.setBackgroundImage(confBg); confArea.setLayout(new FormLayout()); confArea.setBackgroundMode(SWT.INHERIT_FORCE); FormData fdConfArea = new FormData(); confArea.setLayoutData(fdConfArea); fdConfArea.top = new FormAttachment(0); fdConfArea.bottom = new FormAttachment(100); fdConfArea.right = new FormAttachment(100); fdConfArea.width = 28; fdTabBg.right = new FormAttachment(confArea); confCorner = new Label(confArea, SWT.NONE); addPartActivationListnerToControl(confCorner); Image cornerImage = stackBuilder.getImage(ILayoutSetConstants.STACK_INACTIVE_CORNER); confCorner.setImage(cornerImage); FormData fdCorner = new FormData(); confCorner.setLayoutData(fdCorner); fdCorner.left = new FormAttachment(0); fdCorner.top = new FormAttachment(0); fdCorner.bottom = new FormAttachment(100); confButton = new Button(confArea, SWT.PUSH); Image confImage = stackBuilder.getImage(ILayoutSetConstants.STACK_CONF_INACTIVE); confButton.setImage(confImage); confButton.setData(RWT.CUSTOM_VARIANT, "clearButton"); //$NON-NLS-1$ FormData fdConfButton = stackBuilder.getPosition(ILayoutSetConstants.STACK_CONF_POSITION); confButton.setLayoutData(fdConfButton); FormData fdConfPos = stackBuilder.getPosition(ILayoutSetConstants.STACK_CONF_POS); fdConfButton.right = fdConfPos.right; addPartActivationListnerToControl(confButton); confButton.addSelectionListener(new SelectionAdapter() { @Override public void widgetSelected(SelectionEvent e) { configAction.run(); } }); } else { // make tabarea full width if no confarea exist. fdTabBg.right = new FormAttachment(100); } } @Override public void dispose() { ViewToolBarRegistry registry = ViewToolBarRegistry.getInstance(); registry.removeViewPartPresentation(this); presentationControl.dispose(); } @Override public Control getControl() { return presentationControl; } @Override public Control[] getTabList(IPresentablePart part) { ArrayList<Control> list = new ArrayList<Control>(); if (getControl() != null) { list.add(getControl()); } if (part.getToolBar() != null) { list.add(part.getToolBar()); } if (part.getControl() != null) { list.add(part.getControl()); } return list.toArray(new Control[list.size()]); } @Override public void removePart(IPresentablePart oldPart) { Object object = partButtonMap.get(oldPart); buttonPartMap.remove(object); // remove the dirtyListener Object listener = dirtyListenerMap.get(oldPart); if (listener != null && listener instanceof IPropertyListener) { oldPart.removePropertyListener((IPropertyListener) listener); } partButtonMap.remove(oldPart); buttonList.remove(object); handleButtonDispose(object); partList.remove(oldPart); oldPart.setVisible(false); tabBg.layout(); } private void handleButtonDispose(Object buttonArea) { if (buttonArea != null && !isStandalone()) { ((Composite) buttonArea).dispose(); } } @Override public void selectPart(IPresentablePart toSelect) { if (toSelect != null) { toSelect.setVisible(true); } if (currentPart != null) { oldPart = currentPart; if (currentPart instanceof PresentablePart && ((PresentablePart) currentPart).getPane() != null) { currentPart.setVisible(false); } } makePartButtonInactive(currentPart); currentPart = toSelect; currentPart.getControl().moveAbove(null); makePartButtonActive(currentPart); setBounds(presentationControl.getBounds()); } @Override public StackDropResult dragOver(Control currentControl, Point location) { return null; } @Override public void setActive(int newState) { activeState = newState; Image confBg = null; Image cornerImage = null; Image confImage = null; Image tabBgImage = null; String tabOverflow = "tabOverflowInactive"; //$NON-NLS-1$ // create the necessary images if (newState == AS_ACTIVE_FOCUS) { if (!isStandalone()) { changeSelectedActiveButton(true); } confBg = stackBuilder.getImage(ILayoutSetConstants.STACK_CONF_BG_ACTIVE); String rightActive = ILayoutSetConstants.STACK_TAB_INACTIVE_RIGHT_ACTIVE; cornerImage = stackBuilder.getImage(rightActive); confImage = stackBuilder.getImage(ILayoutSetConstants.STACK_CONF_ACTIVE); tabOverflow = "tabOverflowActive"; //$NON-NLS-1$ tabBgImage = stackBuilder.getImage(ILayoutSetConstants.STACK_TAB_BG_ACTIVE); changeStack(true); } else { if (!isStandalone()) { changeSelectedActiveButton(false); } confBg = stackBuilder.getImage(ILayoutSetConstants.STACK_CONF_BG_INACTIVE); cornerImage = stackBuilder.getImage(ILayoutSetConstants.STACK_INACTIVE_CORNER); confImage = stackBuilder.getImage(ILayoutSetConstants.STACK_CONF_INACTIVE); String stackTabInactiveBgActive = ILayoutSetConstants.STACK_TAB_INACTIVE_BG_ACTIVE; tabBgImage = stackBuilder.getImage(stackTabInactiveBgActive); changeStack(false); } // set the images if (tabBg != null) { tabBg.getParent().setBackgroundImage(tabBgImage); } if (confArea != null) { confArea.setBackgroundImage(confBg); if (confCorner != null) { confCorner.setImage(cornerImage); } if (confButton != null) { confButton.setImage(confImage); } confArea.getParent().layout(true); confArea.layout(true); } if (currentPart != null && getPartPane(currentPart) != null) { currentPart.setVisible(true); } if (overflowButton != null) { overflowButton.setData(RWT.CUSTOM_VARIANT, tabOverflow); } setBounds(presentationControl.getBounds()); } private void changeStack(boolean active) { Object adapter = stackBuilder.getAdapter(Map.class); if (adapter != null && adapter instanceof Map) { Map labelMap = (Map) adapter; Label leftLabel = (Label) labelMap.get(StackPresentationBuider.LEFT); Label rightLabel = (Label) labelMap.get(StackPresentationBuider.RIGHT); Label leftBorder = (Label) labelMap.get(StackPresentationBuider.LEFT_BORDER); Label rightBorder = (Label) labelMap.get(StackPresentationBuider.RIGHT_BORDER); Label bottomBorder = (Label) labelMap.get(StackPresentationBuider.BOTTOM_BORDER); Label topBorder = (Label) labelMap.get(StackPresentationBuider.TOP_BORDER); Image left; Image right; Image leftBorderImg; Image rightBorderImg; Image bottomBorderImg; Image topBorderImg; if (active) { String leftActive = ILayoutSetConstants.STACK_TABBAR_LEFT_ACTIVE; left = stackBuilder.getImage(leftActive); String rightActive = ILayoutSetConstants.STACK_TABBAR_RIGHT_ACTIVE; right = stackBuilder.getImage(rightActive); String bottomActive = ILayoutSetConstants.STACK_BORDER_BOTTOM_ACTIVE; bottomBorderImg = stackBuilder.getImage(bottomActive); String leftBorderActive = ILayoutSetConstants.STACK_BORDER_LEFT_ACTIVE; leftBorderImg = stackBuilder.getImage(leftBorderActive); String rightBorderActive = ILayoutSetConstants.STACK_BORDER_RIGHT_AVTIVE; rightBorderImg = stackBuilder.getImage(rightBorderActive); String stackTopStandaloneActive = ILayoutSetConstants.STACK_TOP_STANDALONE_ACTIVE; topBorderImg = stackBuilder.getImage(stackTopStandaloneActive); } else { String leftInactive = ILayoutSetConstants.STACK_TABBAR_LEFT_INACTIVE; left = stackBuilder.getImage(leftInactive); String rightInactive = ILayoutSetConstants.STACK_TABBAR_RIGHT_INACTIVE; right = stackBuilder.getImage(rightInactive); bottomBorderImg = stackBuilder.getImage(ILayoutSetConstants.STACK_BORDER_BOTTOM); leftBorderImg = stackBuilder.getImage(ILayoutSetConstants.STACK_BORDER_LEFT); rightBorderImg = stackBuilder.getImage(ILayoutSetConstants.STACK_BORDER_RIGHT); String stackTopStandaloneInactive = ILayoutSetConstants.STACK_TOP_STANDALONE_INACTIVE; topBorderImg = stackBuilder.getImage(stackTopStandaloneInactive); } leftLabel.setImage(left); rightLabel.setImage(right); leftBorder.setBackgroundImage(leftBorderImg); rightBorder.setBackgroundImage(rightBorderImg); bottomBorder.setBackgroundImage(bottomBorderImg); // top image for standalone view if (isStandalone() && topBorderImg != null) { topBorder.setBackgroundImage(topBorderImg); int height = topBorderImg.getBounds().height; FormData fdTopBorder = (FormData) topBorder.getLayoutData(); fdTopBorder.height = height; fdTopBorder.top = new FormAttachment(0, 7); FormData fdLeftBorder = (FormData) leftBorder.getLayoutData(); FormData fdRightBorder = (FormData) rightBorder.getLayoutData(); fdLeftBorder.top = new FormAttachment(0, height + 6); fdRightBorder.top = new FormAttachment(0, height + 6); topBorder.getParent().layout(true); topBorder.moveAbove(null); } } } private PartPane getPartPane(IPresentablePart part) { PartPane result = null; if (part instanceof PresentablePart) { result = ((PresentablePart) part).getPane(); } return result; } private void changeSelectedActiveButton(boolean selected) { String close = ""; //$NON-NLS-1$ Color buttonAreaBg; String font = ""; //$NON-NLS-1$ String tab = ""; //$NON-NLS-1$ if (selected) { buttonAreaBg = stackBuilder.getColor(ILayoutSetConstants.STACK_BUTTON_ACTIVE); close = "viewClose"; //$NON-NLS-1$ font = "partInActiveActive"; //$NON-NLS-1$ tab = "tabActive"; //$NON-NLS-1$ } else { buttonAreaBg = stackBuilder.getColor(ILayoutSetConstants.STACK_BUTTON_INACTIVE); close = "viewCloseInactive"; //$NON-NLS-1$ font = "partActive"; //$NON-NLS-1$ tab = "tabInactive"; //$NON-NLS-1$ } Object object = partButtonMap.get(currentPart); if (object != null && object instanceof Composite) { Composite buttonArea = (Composite) object; buttonArea.setData(RWT.CUSTOM_VARIANT, tab); buttonArea.setBackground(buttonAreaBg); Control[] children = buttonArea.getChildren(); for (int i = 0; i < children.length; i++) { Control child = children[i]; if (child instanceof Button) { Button button = (Button) child; if (button.getData(BUTTON_ID) != null) { button.setData(RWT.CUSTOM_VARIANT, close); } else { button.setData(RWT.CUSTOM_VARIANT, font); } } } } } @Override public void setBounds(Rectangle bounds) { presentationControl.setBounds(bounds); Composite tabBar = getTabBar(); if (currentPart != null && tabBar != null && getPartPane(currentPart) != null) { int newHeight = bounds.height - 16; int partBoundsY = bounds.y + 8; if (getTabBar().isVisible()) { newHeight -= (tabBar.getBounds().height); partBoundsY += tabBar.getBounds().height; } Control toolBar = currentPart.getToolBar(); if (toolbarBg != null && (toolbarBg.isVisible() || toolBar != null)) { int toolbarHeight = toolbarBg.getBounds().height; newHeight -= toolbarHeight; partBoundsY += toolbarHeight; } String stackTopStandaloneActive = ILayoutSetConstants.STACK_TOP_STANDALONE_ACTIVE; Image stackTop = stackBuilder.getImage(stackTopStandaloneActive); if (stackTop != null) { partBoundsY += 1; newHeight -= 1; } Rectangle partBounds = new Rectangle(bounds.x + 8, partBoundsY, bounds.width - 16, newHeight); currentPart.setBounds(partBounds); } layoutToolBar(); } private Composite getTabBar() { Composite result = null; Object adapter = stackBuilder.getAdapter(this.getClass()); if (adapter != null && adapter instanceof Composite) { result = (Composite) adapter; } return result; } @Override public void setState(int state) { this.state = state; } @Override public void setVisible(boolean isVisible) { if (currentPart != null && getPartPane(currentPart) != null) { currentPart.setVisible(isVisible); // Toolbar Layer deactivated = !isVisible; layoutToolBar(); setBounds(presentationControl.getBounds()); } } @Override public void showPaneMenu() { } @Override public void showSystemMenu() { } @Override public int computePreferredSize(final boolean width, final int availableParallel, final int availablePerpendicular, final int preferredResult) { int result = preferredResult; if (width) { // preferred width int minWidth = calculateMinimumWidth(); if (getSite().getState() == IStackPresentationSite.STATE_MINIMIZED || preferredResult < minWidth) { result = minWidth; } } else { // preferred height result = calculateMinimumHeight(); } return result; } /* * Returns the height of the tabbar plus a spacing */ private int calculateMinimumHeight() { int result = 0; if (tabBg != null) { tabBg.pack(); result = tabBg.getSize().y; } return result + HEIGHT_SPACING; } /* * Calculates the width of the biggest child */ private int calculateMinimumWidth() { int result = 0; if (tabBg != null) { Control[] children = tabBg.getChildren(); for (int i = 0; i < children.length; i++) { if (children[i].getSize().x >= result) { result = children[i].getSize().x; } } } return result + WIDTH_SPACING; } }