org.eclipse.jface.action.ToolBarContributionItem Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of org.eclipse.jface Show documentation
Show all versions of org.eclipse.jface Show documentation
This is org.eclipse.jface jar used by Scout SDK
The newest version!
/*******************************************************************************
* Copyright (c) 2000, 2015 IBM Corporation and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* IBM Corporation - initial API and implementation
*******************************************************************************/
package org.eclipse.jface.action;
import java.util.ArrayList;
import java.util.Iterator;
import org.eclipse.jface.internal.provisional.action.IToolBarContributionItem;
import org.eclipse.core.runtime.Assert;
import org.eclipse.jface.util.Policy;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.DisposeEvent;
import org.eclipse.swt.events.SelectionAdapter;
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 = null;
/**
* The widget created for this item; null
before creation
* and after disposal.
*/
private CoolItem coolItem = null;
/**
* 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 = false;
/**
* 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 = null;
/**
* 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 = 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;
}
// 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(new SelectionAdapter() {
@Override
public void widgetSelected(SelectionEvent event) {
if (event.detail == SWT.ARROW) {
handleChevron(event);
}
}
});
}
// Handle for disposal
coolItem.addDisposeListener(event -> handleWidgetDispose(event));
// 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;
for (int i = 0; i < wraps.length; i++) {
adjustedWrapIndices[i + 1] = wraps[i];
}
} 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 (int i = 0; i < items.length; ++i) {
Rectangle itemBounds = items[i].getBounds();
if (!((itemBounds.x + itemBounds.width <= toolBarBounds.width) && (itemBounds.y
+ itemBounds.height <= toolBarBounds.height))) {
hidden.add(items[i]);
}
}
// Create a pop-up menu with items for each of the hidden buttons.
if (chevronMenuManager != null) {
chevronMenuManager.dispose();
}
chevronMenuManager = new MenuManager();
for (Iterator i = hidden.iterator(); i.hasNext();) {
ToolItem toolItem = i.next();
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 (int i = 0; i < contributionItems.length; i++) {
IContributionItem contributionItem = contributionItems[i];
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);
}
}
}
}