org.eclipse.rap.internal.design.example.stacks.ViewStackPresentation.java Source code

Java tutorial

Introduction

Here is the source code for org.eclipse.rap.internal.design.example.stacks.ViewStackPresentation.java

Source

/*******************************************************************************
 * 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;
    }

}