Java tutorial
/******************************************************************************* * Copyright (c) 2009 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 com.sap.dirigible.ide.ui.rap.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.rwt.lifecycle.WidgetUtil; 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.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.swt.widgets.Shell; 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.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; import com.sap.dirigible.ide.ui.rap.builders.StackPresentationBuider; import com.sap.dirigible.ide.ui.rap.shared.LayoutSetConstants; @SuppressWarnings("restriction") public class ViewStackPresentation extends ConfigurableStack { private static final String HAS_NO_ACTIONS_OR_VIEWMENU_TO_CONFIGURE = Messages.ViewStackPresentation_HAS_NO_ACTIONS_OR_VIEWMENU_TO_CONFIGURE; private static final String CONFIGURE_THE_ACTIONS_AND_VIEWMENU_FROM = Messages.ViewStackPresentation_CONFIGURE_THE_ACTIONS_AND_VIEWMENU_FROM; 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 Map<IPresentablePart, Composite> partButtonMap = new HashMap<IPresentablePart, Composite>(); private List<IPresentablePart> partList = new ArrayList<IPresentablePart>(); private List<Object> buttonList = new ArrayList<Object>(); private Composite toolbarBg; private Shell toolBarLayer; private int state; protected boolean deactivated; private Button viewMenuButton; private Map<IPresentablePart, IPropertyListener> dirtyListenerMap = new HashMap<IPresentablePart, IPropertyListener>(); private Button overflowButton; private List<Control> overflowButtons = new ArrayList<Control>(); private Map<Control, IPresentablePart> buttonPartMap = new HashMap<Control, IPresentablePart>(); private IPresentablePart oldPart; private boolean allActionsVisible; // I061150: Look down for more info private class DirtyListener implements IPropertyListener { private IPresentablePart part; public DirtyListener(final IPresentablePart part) { this.part = part; } public void propertyChanged(Object source, int propId) { if (propId == ISaveablePart.PROP_DIRTY) { 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 Button getPartButton(final IPresentablePart part) { Button result = null; Control 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(final String text) { char[] starArray = new char[1]; text.getChars(text.length() - 1, text.length(), starArray, 0); return starArray[0]; } }; public ViewStackPresentation() { state = AS_INACTIVE; deactivated = false; // I061150: I have introduced the allActionsVisible variable // in order to prevent an exception that gets thrown by the // handleConfigurationButton() method. Using the static method // ConfigAction.allActionsVisible() throws an exception when // the workbench gets destroyed (sometimes) and whenever the // workbench gets recreated (when the rap web page gets refreshed). allActionsVisible = ConfigAction.allActionsVisible(); } 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(final 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(LayoutSetConstants.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); } @SuppressWarnings("deprecation") private Control createStyledControl() { getParent().setData(WidgetUtil.CUSTOM_VARIANT, "compGray"); //$NON-NLS-1$ final Composite parent = new Composite(getParent(), SWT.NONE); parent.addControlListener(new ControlAdapter() { /** * */ private static final long serialVersionUID = 977072776009331463L; public void controlResized(ControlEvent e) { setBounds(parent.getBounds()); }; }); parent.setData(WidgetUtil.CUSTOM_VARIANT, "compGray"); //$NON-NLS-1$ String setID = LayoutSetConstants.SET_ID_STACKPRESENTATION; stackBuilder = new StackPresentationBuider(parent, setID); stackBuilder.build(); return parent; } private boolean isStandalone() { return getType().equals(PresentationFactory.KEY_STANDALONE_VIEW); } @SuppressWarnings("deprecation") public void addPart(final IPresentablePart newPart, final 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(WidgetUtil.CUSTOM_VARIANT, "partBorder"); //$NON-NLS-1$ } } else { decorateStandaloneView(newPart); } // add the lsitener for the dirty state IPropertyListener listener = new DirtyListener(newPart); dirtyListenerMap.put(newPart, listener); newPart.addPropertyListener(listener); } @SuppressWarnings("deprecation") private void decorateStandaloneView(final IPresentablePart newPart) { checkTabBg(); if (getShowTitle()) { getTabBar().setVisible(true); tabBg.setVisible(true); Label title = new Label(tabBg, SWT.NONE); title.setData(WidgetUtil.CUSTOM_VARIANT, "standaloneView"); //$NON-NLS-1$ title.setText(newPart.getName()); } else { getTabBar().setVisible(false); Object labelMap = stackBuilder.getAdapter(Map.class); if (labelMap != null && (labelMap instanceof Map)) { Map<?, ?> map = (Map<?, ?>) labelMap; Label left = (Label) map.get(StackPresentationBuider.LEFT); Label right = (Label) map.get(StackPresentationBuider.RIGHT); left.setVisible(false); right.setVisible(false); } } } @SuppressWarnings("deprecation") 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(WidgetUtil.CUSTOM_VARIANT, "clearButton"); //$NON-NLS-1$ Image icon = stackBuilder.getImage(LayoutSetConstants.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() { /** * */ private static final long serialVersionUID = -8904227778922403945L; public void widgetSelected(final 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); // Toolbar Layer if (!deactivated) { getToolBarLayer(); if (toolBarLayer != null) { toolBarLayer.setVisible(false); if (state != AS_ACTIVE_FOCUS) { Display display = toolBarLayer.getDisplay(); Point newLocation = display.map(toolbarBg, null, 0, 0); toolBarLayer.setBounds(newLocation.x, newLocation.y, size.x, size.y - 1); // toolBarLayer.moveAbove( toolBar ); toolBarLayer.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 toolTip = CONFIGURE_THE_ACTIONS_AND_VIEWMENU_FROM + currentPart.getName(); confButton.setToolTipText(toolTip); } } else { if (confButton != null) { // disable conf button confButton.setEnabled(false); String toolTip = currentPart.getName() + HAS_NO_ACTIONS_OR_VIEWMENU_TO_CONFIGURE; confButton.setToolTipText(toolTip); } } } } } @SuppressWarnings("deprecation") private void createPartButton(final IPresentablePart part) { Composite buttonArea = new Composite(tabBg, SWT.NONE); buttonArea.setData(WidgetUtil.CUSTOM_VARIANT, "inactiveButton"); //$NON-NLS-1$ buttonArea.setLayout(new FormLayout()); final Button partButton = new Button(buttonArea, SWT.PUSH); partButton.setData(WidgetUtil.CUSTOM_VARIANT, VARIANT_PART_INACTIVE); partButton.setText(part.getName()); partButton.setImage(part.getTitleImage()); partButton.setToolTipText(part.getTitleToolTip()); final IPropertyListener nameListener = new IPropertyListener() { public void propertyChanged(final Object source, final 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() { /** * */ private static final long serialVersionUID = 2510007493869927900L; public void widgetDisposed(final 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() { /** * */ private static final long serialVersionUID = 1275793364909865107L; public void widgetSelected(SelectionEvent e) { if (!currentPart.equals(part)) { selectPart(part); } activatePart(part); if (toolBarLayer != null) { toolBarLayer.setVisible(false); } // 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() { /** * */ private static final long serialVersionUID = -5326419633493662414L; public void handleEvent(Event event) { IWorkbench workbench = PlatformUI.getWorkbench(); IWorkbenchWindow window = workbench.getActiveWorkbenchWindow(); IWorkbenchPage page = window.getActivePage(); page.toggleZoom(getReference(part)); if (toolBarLayer != null) { toolBarLayer.setVisible(false); } if (currentPart != null) { currentPart.getControl().moveAbove(null); Control toolBar = currentPart.getToolBar(); if (toolBar != null) { toolBar.moveAbove(null); } } } }); Composite corner = new Composite(buttonArea, SWT.NONE); corner.setData(WidgetUtil.CUSTOM_VARIANT, "compTrans"); //$NON-NLS-1$ corner.setLayout(new FormLayout()); String separatorActive = LayoutSetConstants.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); } protected void activatePart(final 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(final IPresentablePart part) { IWorkbenchPartReference result = null; if (part instanceof PresentablePart) { PresentablePart presentablePart = (PresentablePart) part; PartPane pane = presentablePart.getPane(); result = pane.getPartReference(); } return result; } @SuppressWarnings("deprecation") private void makePartButtonActive(final IPresentablePart part) { Control object = partButtonMap.get(part); if (object instanceof Composite) { Composite buttonArea = (Composite) object; buttonArea.setData(WidgetUtil.CUSTOM_VARIANT, "tabInactive"); //$NON-NLS-1$ checkHideSeparator(buttonArea); Color bg = stackBuilder.getColor(LayoutSetConstants.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(WidgetUtil.CUSTOM_VARIANT, VARIANT_PART_ACTIVE); FormData fdButton = (FormData) partButton.getLayoutData(); FormData pos = stackBuilder.getPosition(LayoutSetConstants.STACK_BUTTON_TOP); fdButton.top = pos.top; } else if (child instanceof Composite) { // Corner Composite corner = (Composite) child; corner.setVisible(true); String cornerDesc = LayoutSetConstants.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(WidgetUtil.CUSTOM_VARIANT, "viewCloseInactive"); //$NON-NLS-1$ close.addSelectionListener(new SelectionAdapter() { /** * */ private static final long serialVersionUID = 7874703475285130718L; 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); } } } buttonArea.getParent().layout(); } } private void checkHideSeparator(final Composite buttonArea) { int indexOf = buttonList.indexOf(buttonArea); for (int i = 0; i < buttonList.size(); i++) { Composite area = (Composite) 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); } } } } } @SuppressWarnings("deprecation") private void makePartButtonInactive(final IPresentablePart part) { Control object = partButtonMap.get(part); if (object instanceof Composite) { Composite buttonArea = (Composite) object; buttonArea.setData(WidgetUtil.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(WidgetUtil.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 = LayoutSetConstants.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. */ @SuppressWarnings("deprecation") private void checkTabBg() { Composite tabBar = getTabBar(); if (tabBg == null && tabBar != null) { tabBg = new Composite(tabBar, SWT.NONE); tabBg.setData(WidgetUtil.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(LayoutSetConstants.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() { /** * */ private static final long serialVersionUID = 5576373970930725957L; public void controlResized(final ControlEvent e) { manageOverflow(); }; }); } } private void manageOverflow() { int tabChildrenSize = getTabChildrenSize(); if (tabChildrenSize > tabBg.getBounds().width && moreThanOneChildVisible()) { hideLastVisibleButton(); manageOverflow(); } else { showLastChildIfNecessary(0); } handleOverflowButton(); } 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; } @SuppressWarnings("deprecation") private void handleOverflowButton() { if (overflowButton == null) { overflowButton = new Button(tabBg.getParent(), SWT.PUSH); String stackOverflowPosition = LayoutSetConstants.STACK_OVERFLOW_POSITION; FormData fdOverflowButton = stackBuilder.getPosition(stackOverflowPosition); overflowButton.setLayoutData(fdOverflowButton); String stackTabOverflowActive = LayoutSetConstants.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 (state == AS_ACTIVE_FOCUS) { variant = "tabOverflowActive"; //$NON-NLS-1$ } overflowButton.setData(WidgetUtil.CUSTOM_VARIANT, variant); overflowButton.moveAbove(tabBg); overflowButton.addSelectionListener(new SelectionAdapter() { /** * */ private static final long serialVersionUID = 2310748321926511870L; public void widgetSelected(final 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++) { final IPresentablePart part = buttonPartMap.get(overflowButtons.get(i)); MenuItem item = new MenuItem(overflowMenu, SWT.PUSH); item.setText(part.getName()); item.addSelectionListener(new SelectionAdapter() { /** * */ private static final long serialVersionUID = 799464307276740925L; public void widgetSelected(final 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(final IPresentablePart part) { Control button = partButtonMap.get(part); Control hiddenButton = hideLastVisibleButton(); if (button != null && !button.isDisposed()) { button.setVisible(true); overflowButtons.remove(button); button.moveAbove(hiddenButton); tabBg.layout(true, true); manageOverflow(); } } private void showLastChildIfNecessary(final 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(final Control childToShow) { int result = 0; result = getTabChildrenSize(); result += childToShow.getBounds().width; 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]; 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(final 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) { @SuppressWarnings("deprecation") Object data = children[i].getData(WidgetUtil.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].getSize().x + BUTTON_SPACING); } } return result; } @SuppressWarnings("deprecation") private void createConfArea(final FormData fdTabBg) { final ConfigurationAction configAction = getConfigAction(); if (configAction != null) { confArea = new Composite(getTabBar(), SWT.NONE); Image confBg = stackBuilder.getImage(LayoutSetConstants.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); Image cornerImage = stackBuilder.getImage(LayoutSetConstants.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(LayoutSetConstants.STACK_CONF_INACTIVE); confButton.setImage(confImage); confButton.setData(WidgetUtil.CUSTOM_VARIANT, "clearButton"); //$NON-NLS-1$ FormData fdConfButton = stackBuilder.getPosition(LayoutSetConstants.STACK_CONF_POSITION); confButton.setLayoutData(fdConfButton); FormData fdConfPos = stackBuilder.getPosition(LayoutSetConstants.STACK_CONF_POS); fdConfButton.right = fdConfPos.right; confButton.addSelectionListener(new SelectionAdapter() { /** * */ private static final long serialVersionUID = -9060515185384736476L; public void widgetSelected(SelectionEvent e) { activatePart(getSite().getSelectedPart()); configAction.run(); }; }); } else { // make tabarea full width if no confarea exist. fdTabBg.right = new FormAttachment(100); } } public void dispose() { ViewToolBarRegistry registry = ViewToolBarRegistry.getInstance(); registry.removeViewPartPresentation(this); if (toolBarLayer != null) { toolBarLayer.dispose(); } presentationControl.dispose(); } public Control getControl() { return presentationControl; } public Control[] getTabList(final 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 (Control[]) list.toArray(new Control[list.size()]); } public void removePart(final IPresentablePart oldPart) { Control object = partButtonMap.get(oldPart); buttonPartMap.remove(object); if (toolBarLayer != null) { toolBarLayer.setVisible(false); } // remove the dirtyListener IPropertyListener listener = dirtyListenerMap.get(oldPart); if (listener != null) { oldPart.removePropertyListener(listener); } partButtonMap.remove(oldPart); buttonList.remove(object); ((Composite) object).dispose(); partList.remove(oldPart); oldPart.setVisible(false); tabBg.layout(); } public void selectPart(final 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; if (currentPart != null) currentPart.getControl().moveAbove(null); makePartButtonActive(currentPart); setBounds(presentationControl.getBounds()); if (toolBarLayer != null) { toolBarLayer.setVisible(false); } } public StackDropResult dragOver(final Control currentControl, final Point location) { return null; } @SuppressWarnings("deprecation") public void setActive(final int newState) { state = 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(LayoutSetConstants.STACK_CONF_BG_ACTIVE); String rightActive = LayoutSetConstants.STACK_TAB_INACTIVE_RIGHT_ACTIVE; cornerImage = stackBuilder.getImage(rightActive); confImage = stackBuilder.getImage(LayoutSetConstants.STACK_CONF_ACTIVE); tabOverflow = "tabOverflowActive"; //$NON-NLS-1$ tabBgImage = stackBuilder.getImage(LayoutSetConstants.STACK_TAB_BG_ACTIVE); changeStack(true); } else { if (!isStandalone()) { changeSelectedActiveButton(false); } confBg = stackBuilder.getImage(LayoutSetConstants.STACK_CONF_BG_INACTIVE); cornerImage = stackBuilder.getImage(LayoutSetConstants.STACK_INACTIVE_CORNER); confImage = stackBuilder.getImage(LayoutSetConstants.STACK_CONF_INACTIVE); String stackTabInactiveBgActive = LayoutSetConstants.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); if (currentPart != null && getPartPane(currentPart) != null) { currentPart.setVisible(true); } confArea.layout(true); } if (overflowButton != null) { overflowButton.setData(WidgetUtil.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 = LayoutSetConstants.STACK_TABBAR_LEFT_ACTIVE; left = stackBuilder.getImage(leftActive); String rightActive = LayoutSetConstants.STACK_TABBAR_RIGHT_ACTIVE; right = stackBuilder.getImage(rightActive); String bottomActive = LayoutSetConstants.STACK_BORDER_BOTTOM_ACTIVE; bottomBorderImg = stackBuilder.getImage(bottomActive); String leftBorderActive = LayoutSetConstants.STACK_BORDER_LEFT_ACTIVE; leftBorderImg = stackBuilder.getImage(leftBorderActive); String rightBorderActive = LayoutSetConstants.STACK_BORDER_RIGHT_AVTIVE; rightBorderImg = stackBuilder.getImage(rightBorderActive); String stackTopStandaloneActive = LayoutSetConstants.STACK_TOP_STANDALONE_ACTIVE; topBorderImg = stackBuilder.getImage(stackTopStandaloneActive); } else { String leftInactive = LayoutSetConstants.STACK_TABBAR_LEFT_INACTIVE; left = stackBuilder.getImage(leftInactive); String rightInactive = LayoutSetConstants.STACK_TABBAR_RIGHT_INACTIVE; right = stackBuilder.getImage(rightInactive); bottomBorderImg = stackBuilder.getImage(LayoutSetConstants.STACK_BORDER_BOTTOM); leftBorderImg = stackBuilder.getImage(LayoutSetConstants.STACK_BORDER_LEFT); rightBorderImg = stackBuilder.getImage(LayoutSetConstants.STACK_BORDER_RIGHT); String stackTopStandaloneInactive = LayoutSetConstants.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; } @SuppressWarnings("deprecation") private void changeSelectedActiveButton(final boolean selected) { String close = ""; //$NON-NLS-1$ Color buttonAreaBg; String font = ""; //$NON-NLS-1$ String tab = ""; //$NON-NLS-1$ if (selected) { buttonAreaBg = stackBuilder.getColor(LayoutSetConstants.STACK_BUTTON_ACTIVE); close = "viewClose"; //$NON-NLS-1$ font = "partInActiveActive"; //$NON-NLS-1$ tab = "tabActive"; //$NON-NLS-1$ } else { buttonAreaBg = stackBuilder.getColor(LayoutSetConstants.STACK_BUTTON_INACTIVE); close = "viewCloseInactive"; //$NON-NLS-1$ font = "partActive"; //$NON-NLS-1$ tab = "tabInactive"; //$NON-NLS-1$ } Control object = partButtonMap.get(currentPart); if (object != null && object instanceof Composite) { Composite buttonArea = (Composite) object; buttonArea.setData(WidgetUtil.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(WidgetUtil.CUSTOM_VARIANT, close); } else { button.setData(WidgetUtil.CUSTOM_VARIANT, font); } } } } } public void setBounds(final 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 = LayoutSetConstants.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(); } @SuppressWarnings("deprecation") private Shell getToolBarLayer() { if (toolBarLayer == null && toolbarBg != null) { toolBarLayer = new Shell(toolbarBg.getShell(), SWT.NO_TRIM); toolBarLayer.setData(WidgetUtil.CUSTOM_VARIANT, "toolbarLayer"); //$NON-NLS-1$ toolBarLayer.setAlpha(200); toolBarLayer.addListener(SWT.MouseDown, new Listener() { /** * */ private static final long serialVersionUID = -2560553663509404538L; public void handleEvent(final Event event) { activatePart(currentPart); } }); } return toolBarLayer; } private Composite getTabBar() { Composite result = null; Object adapter = stackBuilder.getAdapter(this.getClass()); if (adapter != null && adapter instanceof Composite) { result = (Composite) adapter; } return result; } public void setState(final int state) { // } public void setVisible(final boolean isVisible) { if (currentPart != null && getPartPane(currentPart) != null) { currentPart.setVisible(isVisible); // Toolbar Layer deactivated = !isVisible; layoutToolBar(); if (toolBarLayer != null) { if (!isVisible) { toolBarLayer.setVisible(false); } } setBounds(presentationControl.getBounds()); } } public void showPaneMenu() { // } public void showSystemMenu() { // } 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; } }