All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.eclipse.jface.action.ToolBarContributionItem Maven / Gradle / Ivy

/*******************************************************************************
 * Copyright (c) 2000, 2015 IBM Corporation and others.
 *
 * This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License 2.0
 * which accompanies this distribution, and is available at
 * https://www.eclipse.org/legal/epl-2.0/
 *
 * SPDX-License-Identifier: EPL-2.0
 *
 * Contributors:
 *     IBM Corporation - initial API and implementation
 *******************************************************************************/

package org.eclipse.jface.action;

import static org.eclipse.swt.events.SelectionListener.widgetSelectedAdapter;

import java.util.ArrayList;

import org.eclipse.core.runtime.Assert;
import org.eclipse.jface.internal.provisional.action.IToolBarContributionItem;
import org.eclipse.jface.util.Policy;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.DisposeEvent;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.graphics.Point;
import org.eclipse.swt.graphics.Rectangle;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.CoolBar;
import org.eclipse.swt.widgets.CoolItem;
import org.eclipse.swt.widgets.Event;
import org.eclipse.swt.widgets.Listener;
import org.eclipse.swt.widgets.Menu;
import org.eclipse.swt.widgets.ToolBar;
import org.eclipse.swt.widgets.ToolItem;

/**
 * The ToolBarContributionItem class provides a wrapper for tool
 * bar managers when used in cool bar managers. It extends
 * ContributionItem but and provides some additional methods to
 * customize the size of the cool item and to retrieve the underlying tool bar
 * manager.
 * 

* This class may be instantiated; it is not intended to be subclassed. *

* * @since 3.0 * @noextend This class is not intended to be subclassed by clients. */ public class ToolBarContributionItem extends ContributionItem implements IToolBarContributionItem { /** * A constant used by setMinimumItemsToShow and * getMinimumItemsToShow to indicate that all tool items should be * shown in the cool item. */ public static final int SHOW_ALL_ITEMS = -1; /** * The pull down menu used to list all hidden tool items if the current size is * less than the preffered size. */ private MenuManager chevronMenuManager; /** * The widget created for this item; null before creation and after * disposal. */ private CoolItem coolItem; /** * Current height of cool item */ private int currentHeight = -1; /** * Current width of cool item. */ private int currentWidth = -1; /** * A flag indicating that this item has been disposed. This prevents future * method invocations from doing things they shouldn't. */ private boolean disposed; /** * Mininum number of tool items to show in the cool item widget. */ private int minimumItemsToShow = SHOW_ALL_ITEMS; /** * The tool bar manager used to manage the tool items contained in the cool item * widget. */ private ToolBarManager toolBarManager; /** * Enable/disable chevron support. */ private boolean useChevron = true; /** * Convenience method equivalent to * ToolBarContributionItem(new ToolBarManager(), null). */ public ToolBarContributionItem() { this(new ToolBarManager(), null); } /** * Convenience method equivalent to * ToolBarContributionItem(toolBarManager, null). * * @param toolBarManager the tool bar manager */ public ToolBarContributionItem(IToolBarManager toolBarManager) { this(toolBarManager, null); } /** * Creates a tool bar contribution item. * * @param toolBarManager the tool bar manager to wrap * @param id the contribution item id, or null if none */ public ToolBarContributionItem(IToolBarManager toolBarManager, String id) { super(id); Assert.isTrue(toolBarManager instanceof ToolBarManager); this.toolBarManager = (ToolBarManager) toolBarManager; } /** * Checks whether this contribution item has been disposed. If it has, and the * tracing options are active, then it prints some debugging information. * * @return true if the item is disposed; false * otherwise. * */ private final boolean checkDisposed() { if (disposed) { if (Policy.TRACE_TOOLBAR) { System.out.println("Method invocation on a disposed tool bar contribution item."); //$NON-NLS-1$ new Exception().printStackTrace(System.out); } return true; } return false; } @Override public void dispose() { // Dispose of the ToolBar and all its contributions if (toolBarManager != null) { toolBarManager.dispose(); toolBarManager.removeAll(); toolBarManager = null; } /* * We need to dispose the cool item or we might be left holding a cool item with * a disposed control. */ if ((coolItem != null) && (!coolItem.isDisposed())) { coolItem.dispose(); coolItem = null; } if (chevronMenuManager != null) { chevronMenuManager.dispose(); } // Mark this item as disposed. disposed = true; } @Override public void fill(CoolBar coolBar, int index) { if (checkDisposed()) { return; } if (coolItem == null && coolBar != null) { ToolBar oldToolBar = toolBarManager.getControl(); ToolBar toolBar = toolBarManager.createControl(coolBar); if ((oldToolBar != null) && (oldToolBar.equals(toolBar))) { // We are using an old tool bar, so we need to update. toolBarManager.update(true); } // Do not create a coolItem if the toolbar is empty if (toolBar.getItemCount() < 1) { return; } int flags = SWT.DROP_DOWN; if (index >= 0) { coolItem = new CoolItem(coolBar, flags, index); } else { coolItem = new CoolItem(coolBar, flags); } // sets the back reference coolItem.setData(this); // Add the toolbar to the CoolItem widget coolItem.setControl(toolBar); // Handle Context Menu // ToolBarManager.createControl can actually return a pre-existing control. // Only add the listener if the toolbar was newly created (bug 62097). if (oldToolBar != toolBar) { toolBar.addListener(SWT.MenuDetect, event -> { // if the toolbar does not have its own context menu then // handle the event if (toolBarManager.getContextMenuManager() == null) { handleContextMenu(event); } }); } // Handle for chevron clicking if (getUseChevron()) { // Chevron Support coolItem.addSelectionListener(widgetSelectedAdapter(event -> { if (event.detail == SWT.ARROW) { handleChevron(event); } })); } // Handle for disposal coolItem.addDisposeListener(this::handleWidgetDispose); // Sets the size of the coolItem updateSize(true); } } /** * Returns a consistent set of wrap indices. The return value will always * include at least one entry and the first entry will always be zero. * CoolBar.getWrapIndices() is inconsistent in whether or not it returns an * index for the first row. */ private int[] getAdjustedWrapIndices(int[] wraps) { int[] adjustedWrapIndices; if (wraps.length == 0) { adjustedWrapIndices = new int[] { 0 }; } else { if (wraps[0] != 0) { adjustedWrapIndices = new int[wraps.length + 1]; adjustedWrapIndices[0] = 0; System.arraycopy(wraps, 0, adjustedWrapIndices, 1, wraps.length); } else { adjustedWrapIndices = wraps; } } return adjustedWrapIndices; } /** * Returns the current height of the corresponding cool item. * * @return the current height */ @Override public int getCurrentHeight() { if (checkDisposed()) { return -1; } return currentHeight; } /** * Returns the current width of the corresponding cool item. * * @return the current size */ @Override public int getCurrentWidth() { if (checkDisposed()) { return -1; } return currentWidth; } /** * Returns the minimum number of tool items to show in the cool item. * * @return the minimum number of tool items to show, or * SHOW_ALL_ITEMS if a value was not set * @see #setMinimumItemsToShow(int) */ @Override public int getMinimumItemsToShow() { if (checkDisposed()) { return -1; } return minimumItemsToShow; } /** * Returns the internal tool bar manager of the contribution item. * * @return the tool bar manager, or null if one is not defined. * @see IToolBarManager */ @Override public IToolBarManager getToolBarManager() { if (checkDisposed()) { return null; } return toolBarManager; } /** * Returns whether chevron support is enabled. * * @return true if chevron support is enabled, false * otherwise */ @Override public boolean getUseChevron() { if (checkDisposed()) { return false; } return useChevron; } /** * Create and display the chevron menu. */ private void handleChevron(SelectionEvent event) { CoolItem item = (CoolItem) event.widget; Control control = item.getControl(); if ((control instanceof ToolBar) == false) { return; } CoolBar coolBar = item.getParent(); ToolBar toolBar = (ToolBar) control; Rectangle toolBarBounds = toolBar.getBounds(); ToolItem[] items = toolBar.getItems(); ArrayList hidden = new ArrayList<>(); for (ToolItem toolItem : items) { Rectangle itemBounds = toolItem.getBounds(); if (!((itemBounds.x + itemBounds.width <= toolBarBounds.width) && (itemBounds.y + itemBounds.height <= toolBarBounds.height))) { hidden.add(toolItem); } } // Create a pop-up menu with items for each of the hidden buttons. if (chevronMenuManager != null) { chevronMenuManager.dispose(); } chevronMenuManager = new MenuManager(); for (ToolItem toolItem : hidden) { IContributionItem data = (IContributionItem) toolItem.getData(); if (data instanceof ActionContributionItem) { ActionContributionItem contribution = new ActionContributionItem( ((ActionContributionItem) data).getAction()); chevronMenuManager.add(contribution); } else if (data instanceof SubContributionItem) { IContributionItem innerData = ((SubContributionItem) data).getInnerItem(); if (innerData instanceof ActionContributionItem) { ActionContributionItem contribution = new ActionContributionItem( ((ActionContributionItem) innerData).getAction()); chevronMenuManager.add(contribution); } } else if (data.isSeparator()) { chevronMenuManager.add(new Separator()); } } Menu popup = chevronMenuManager.createContextMenu(coolBar); Point chevronPosition = coolBar.toDisplay(event.x, event.y); popup.setLocation(chevronPosition.x, chevronPosition.y); popup.setVisible(true); } /** * Handles the event when the toobar item does not have its own context menu. * * @param event the event object */ private void handleContextMenu(Event event) { ToolBar toolBar = toolBarManager.getControl(); // If parent has a menu then use that one Menu parentMenu = toolBar.getParent().getMenu(); if ((parentMenu != null) && (!parentMenu.isDisposed())) { toolBar.setMenu(parentMenu); // Hook listener to remove menu once it has disapeared parentMenu.addListener(SWT.Hide, new Listener() { @Override public void handleEvent(Event innerEvent) { ToolBar innerToolBar = toolBarManager.getControl(); if (innerToolBar != null) { innerToolBar.setMenu(null); Menu innerParentMenu = innerToolBar.getParent().getMenu(); if (innerParentMenu != null) { innerParentMenu.removeListener(SWT.Hide, this); } } } }); } } /** * Handles the disposal of the widget. * * @param event the event object */ private void handleWidgetDispose(DisposeEvent event) { coolItem = null; } /** * A contribution item is visible iff its internal state is visible or * the tool bar manager contains something other than group markers and * separators. * * @return true if the tool bar manager contains something other * than group marks and separators, and the internal state is set to be * visible. */ @Override public boolean isVisible() { if (checkDisposed()) { return false; } boolean visibleItem = false; if (toolBarManager != null) { IContributionItem[] contributionItems = toolBarManager.getItems(); for (IContributionItem item : contributionItems) { IContributionItem contributionItem = item; if ((!contributionItem.isGroupMarker()) && (!contributionItem.isSeparator())) { visibleItem = true; break; } } } return (visibleItem || super.isVisible()); } @Override public void saveWidgetState() { if (checkDisposed()) { return; } if (coolItem == null) { return; } // 1. Save current size CoolBar coolBar = coolItem.getParent(); boolean isLastOnRow = false; int lastIndex = coolBar.getItemCount() - 1; int coolItemIndex = coolBar.indexOf(coolItem); int[] wrapIndicies = getAdjustedWrapIndices(coolBar.getWrapIndices()); // Traverse through all wrap indicies backwards for (int row = wrapIndicies.length - 1; row >= 0; row--) { if (wrapIndicies[row] <= coolItemIndex) { int nextRow = row + 1; int nextRowStartIndex; if (nextRow > (wrapIndicies.length - 1)) { nextRowStartIndex = lastIndex + 1; } else { nextRowStartIndex = wrapIndicies[nextRow]; } // Check to see if its the last item on the row if (coolItemIndex == (nextRowStartIndex - 1)) { isLastOnRow = true; } break; } } // Save the preferred size as actual size for the last item on a row int nCurrentWidth; if (isLastOnRow) { nCurrentWidth = coolItem.getPreferredSize().x; } else { nCurrentWidth = coolItem.getSize().x; } setCurrentWidth(nCurrentWidth); setCurrentHeight(coolItem.getSize().y); } /** * Sets the current height of the cool item. Update(SIZE) should be called to * adjust the widget. * * @param currentHeight the current height to set */ @Override public void setCurrentHeight(int currentHeight) { if (checkDisposed()) { return; } this.currentHeight = currentHeight; } /** * Sets the current width of the cool item. Update(SIZE) should be called to * adjust the widget. * * @param currentWidth the current width to set */ @Override public void setCurrentWidth(int currentWidth) { if (checkDisposed()) { return; } this.currentWidth = currentWidth; } /** * Sets the minimum number of tool items to show in the cool item. If this * number is less than the total tool items, a chevron will appear and the * hidden tool items appear in a drop down menu. By default, all the tool items * are shown in the cool item. * * @param minimumItemsToShow the minimum number of tool items to show. * @see #getMinimumItemsToShow() * @see #setUseChevron(boolean) */ @Override public void setMinimumItemsToShow(int minimumItemsToShow) { if (checkDisposed()) { return; } this.minimumItemsToShow = minimumItemsToShow; } /** * Enables or disables chevron support for the cool item. By default, chevron * support is enabled. * * @param value true to enable chevron support, false * otherwise. */ @Override public void setUseChevron(boolean value) { if (checkDisposed()) { return; } useChevron = value; } @Override public void update(String propertyName) { if (checkDisposed()) { return; } if (coolItem != null) { IToolBarManager manager = getToolBarManager(); if (manager != null) { manager.update(true); } if ((propertyName == null) || propertyName.equals(ICoolBarManager.SIZE)) { updateSize(true); } } } /** * Updates the cool items' preferred, minimum, and current size. The preferred * size is calculated based on the tool bar size and extra trim. * * @param changeCurrentSize true if the current size should be * changed to the preferred size, false to * not change the current size */ private void updateSize(boolean changeCurrentSize) { if (checkDisposed()) { return; } // cannot set size if coolItem is null if (coolItem == null || coolItem.isDisposed()) { return; } boolean locked = false; CoolBar coolBar = coolItem.getParent(); try { // Fix odd behaviour with locked tool bars if (coolBar != null) { if (coolBar.getLocked()) { coolBar.setLocked(false); locked = true; } } ToolBar toolBar = (ToolBar) coolItem.getControl(); if ((toolBar == null) || (toolBar.isDisposed()) || (toolBar.getItemCount() <= 0)) { // if the toolbar does not contain any items then dispose of // coolItem coolItem.setData(null); Control control = coolItem.getControl(); if ((control != null) && !control.isDisposed()) { control.dispose(); coolItem.setControl(null); } if (!coolItem.isDisposed()) { coolItem.dispose(); } } else { // If the toolbar item exists then adjust the size of the cool // item Point toolBarSize = toolBar.computeSize(SWT.DEFAULT, SWT.DEFAULT); // Set the preffered size to the size of the toolbar plus trim Point preferredSize = coolItem.computeSize(toolBarSize.x, toolBarSize.y); coolItem.setPreferredSize(preferredSize); // note setMinimumSize must be called before setSize, see PR // 15565 // Set minimum size if (getMinimumItemsToShow() != SHOW_ALL_ITEMS) { int toolItemWidth = toolBar.getItems()[0].getWidth(); int minimumWidth = toolItemWidth * getMinimumItemsToShow(); coolItem.setMinimumSize(minimumWidth, toolBarSize.y); } else { coolItem.setMinimumSize(toolBarSize.x, toolBarSize.y); } if (changeCurrentSize) { // Set current size to preferred size coolItem.setSize(preferredSize); } } } finally { // If the cool bar was locked, then set it back to locked if ((locked) && (coolBar != null)) { coolBar.setLocked(true); } } } }




© 2015 - 2025 Weber Informatics LLC | Privacy Policy