| /******************************************************************************* |
| * Copyright (c) 2003, 2006 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.ui.internal; |
| |
| import org.eclipse.jface.action.IContributionItem; |
| import org.eclipse.jface.action.ToolBarManager; |
| import org.eclipse.jface.resource.JFaceResources; |
| import org.eclipse.swt.SWT; |
| import org.eclipse.swt.events.SelectionAdapter; |
| import org.eclipse.swt.events.SelectionEvent; |
| import org.eclipse.swt.graphics.Font; |
| import org.eclipse.swt.graphics.Point; |
| import org.eclipse.swt.graphics.Rectangle; |
| import org.eclipse.swt.widgets.Composite; |
| import org.eclipse.swt.widgets.Control; |
| import org.eclipse.swt.widgets.CoolBar; |
| import org.eclipse.swt.widgets.CoolItem; |
| import org.eclipse.swt.widgets.Display; |
| import org.eclipse.swt.widgets.Menu; |
| import org.eclipse.swt.widgets.MenuItem; |
| import org.eclipse.swt.widgets.ToolBar; |
| import org.eclipse.swt.widgets.ToolItem; |
| import org.eclipse.ui.internal.layout.LayoutUtil; |
| |
| public class PerspectiveBarManager extends ToolBarManager { |
| |
| /** |
| * The symbolic font name for the small font (value <code>"org.eclipse.jface.smallfont"</code>). |
| */ |
| public static final String SMALL_FONT = "org.eclipse.ui.smallFont"; //$NON-NLS-1$ |
| |
| public PerspectiveBarManager(int style) { |
| super(style); |
| } |
| |
| public ToolBar createControl(Composite parent) { |
| ToolBar control = super.createControl(parent); |
| |
| if (control != null && !control.isDisposed()) { |
| control.setFont(getFont()); |
| } |
| |
| return control; |
| } |
| |
| public PerspectiveBarManager(ToolBar toolbar) { |
| super(toolbar); |
| |
| if (toolbar != null && !toolbar.isDisposed()) { |
| toolbar.setFont(getFont()); |
| } |
| } |
| |
| // TODO begin refactor this out? it is not good that we know we are inside a |
| // CoolBar |
| private CoolBar coolBar; |
| |
| private Menu popup; |
| |
| public void handleChevron(SelectionEvent event) { |
| /* |
| * If the popup menu is already there, then pop it down. This doesn't |
| * work... still need to figure this out. |
| */ |
| if (popup != null) { |
| popup.dispose(); |
| popup = null; |
| return; |
| } |
| CoolItem item = (CoolItem) event.widget; |
| //ToolBar toolbar = (ToolBar)getControl(); |
| Control control = getControl(); |
| if (!(control instanceof ToolBar)) { |
| return; // currently we only deal with toolbar items |
| } |
| /* Retrieve the current bounding rectangle for the selected cool item. */ |
| Rectangle itemBounds = item.getBounds(); |
| /* Convert to display coordinates (i.e. was relative to CoolBar). */ |
| Point pt = coolBar.toDisplay(new Point(itemBounds.x, itemBounds.y)); |
| itemBounds.x = pt.x; |
| itemBounds.y = pt.y; |
| /* Retrieve the total number of buttons in the toolbar. */ |
| ToolBar toolBar = (ToolBar) control; |
| ToolItem[] tools = toolBar.getItems(); |
| int toolCount = tools.length; |
| int i = 0; |
| while (i < toolCount) { |
| /* |
| * Starting from the leftmost tool, retrieve the tool's bounding |
| * rectangle. |
| */ |
| Rectangle toolBounds = tools[i].getBounds(); |
| /* Convert to display coordinates (i.e. was relative to ToolBar). */ |
| pt = toolBar.toDisplay(new Point(toolBounds.x, toolBounds.y)); |
| toolBounds.x = pt.x; |
| toolBounds.y = pt.y; |
| /* |
| * Figure out the visible portion of the tool by looking at the |
| * intersection of the tool bounds with the cool item bounds. |
| */ |
| Rectangle intersection = itemBounds.intersection(toolBounds); |
| /* |
| * If the tool is not completely within the cool item bounds, then |
| * the tool is at least partially hidden, and all remaining tools |
| * are completely hidden. |
| */ |
| if (!intersection.equals(toolBounds)) { |
| break; |
| } |
| i++; |
| } |
| /* Create a pop-up menu with items for each of the hidden buttons. */ |
| popup = new Menu(coolBar); |
| |
| for (int j = i; j < toolCount; j++) { |
| ToolItem tool = tools[j]; |
| MenuItem menuItem = new MenuItem(popup, SWT.NONE); |
| if (tool.getSelection()) { |
| menuItem.setEnabled(false); |
| } |
| |
| // Show the full text of the perspective name in the chevron menu. |
| if (tool.getData() instanceof PerspectiveBarContributionItem) { |
| menuItem.setText(((PerspectiveBarContributionItem) tool |
| .getData()).getPerspective().getLabel()); |
| } else { |
| menuItem.setText(tool.getText()); |
| } |
| menuItem.setImage(tool.getImage()); |
| |
| menuItem.setData("IContributionItem", tool.getData()); //$NON-NLS-1$ |
| |
| menuItem.addSelectionListener(new SelectionAdapter() { |
| public void widgetSelected(SelectionEvent e) { |
| //rotate the selected item in and the other items right |
| // don't touch the "Open" item |
| MenuItem menuItem = (MenuItem) e.widget; |
| Object item = menuItem.getData("IContributionItem"); //$NON-NLS-1$ |
| if (item instanceof PerspectiveBarContributionItem) { |
| PerspectiveBarContributionItem contribItem = (PerspectiveBarContributionItem) item; |
| update(false); |
| contribItem.select(); |
| } |
| } |
| }); |
| } |
| /* |
| * Display the pop-up menu immediately below the chevron, with the left |
| * edges aligned. Need to convert the given point to display |
| * coordinates in order to pass them to Menu.setLocation (i.e. was |
| * relative to CoolBar). |
| */ |
| pt = coolBar.toDisplay(new Point(event.x, event.y)); |
| popup.setLocation(pt.x, pt.y); |
| popup.setVisible(true); |
| Display display = coolBar.getDisplay(); |
| while (popup != null && !popup.isDisposed() && popup.isVisible()) { |
| if (!display.readAndDispatch()) { |
| display.sleep(); |
| } |
| } |
| if (popup != null) { |
| popup.dispose(); |
| popup = null; |
| } |
| } |
| |
| /* (non-Javadoc) |
| * @see org.eclipse.jface.action.ToolBarManager#relayout(org.eclipse.swt.widgets.ToolBar, int, int) |
| */ |
| protected void relayout(ToolBar toolBar, int oldCount, int newCount) { |
| super.relayout(toolBar, oldCount, newCount); |
| |
| if (getControl() != null) { |
| LayoutUtil.resize(getControl()); |
| } |
| } |
| |
| void setParent(CoolBar cool) { |
| this.coolBar = cool; |
| } |
| |
| // TODO end refactor this out? |
| |
| private Font getFont() { |
| return JFaceResources.getFont(SMALL_FONT); |
| } |
| |
| /** |
| * Method to select a PerspectiveBarContributionItem and ensure |
| * that it is visible. It updates the MRU list. |
| * @param contribItem the PerspectiveBarContributionItem to select |
| */ |
| void select(PerspectiveBarContributionItem contribItem) { |
| if (contribItem.getToolItem() == null) { |
| return; |
| } |
| // check if not visible and ensure visible |
| if (getControl().isVisible() |
| && !isItemVisible(contribItem.getToolItem())) { |
| ensureVisible(contribItem); |
| } |
| } |
| |
| /** |
| * Method that adds a PerspectiveBarContributionItem and |
| * ensures it is visible |
| * @param item the PerspectiveBarContributionItem to be added |
| */ |
| public void addItem(PerspectiveBarContributionItem item) { |
| insert(1, item); |
| update(false); |
| } |
| |
| /** |
| * Method to remove a PerspectiveBarContributionItem from the toolbar |
| * and from the MRU and sequence lists when necessary |
| * @param item the PerspectiveBarContributionItem to be removed |
| */ |
| public void removeItem(PerspectiveBarContributionItem item) { |
| remove(item); |
| } |
| |
| /** |
| * Re-insert the item at the beginning of the perspective bar, |
| * ensuring that it is visible to the user. |
| * |
| * @param contribItem |
| */ |
| private void ensureVisible(PerspectiveBarContributionItem contribItem) { |
| relocate(contribItem, 1); |
| } |
| |
| void relocate(PerspectiveBarContributionItem contribItem, int index) { |
| PerspectiveBarContributionItem newItem = new PerspectiveBarContributionItem( |
| contribItem.getPerspective(), contribItem.getPage()); |
| |
| removeItem(contribItem); |
| contribItem.dispose(); |
| contribItem = null; |
| |
| insert(index, newItem); |
| update(false); |
| } |
| |
| /** |
| * @return true if the toolItem is visible on the screen, false otherwise. |
| */ |
| private boolean isItemVisible(ToolItem toolItem) { |
| Rectangle barBounds = getControl().getBounds(); |
| Rectangle itemBounds = toolItem.getBounds(); |
| return (barBounds.intersection(itemBounds).equals(itemBounds)); |
| } |
| |
| /** |
| * This method ensures that the selected item in the toolbar is visible. |
| */ |
| public void arrangeToolbar() { |
| // check if the tool bar is visible |
| if (!getControl().isVisible()) { |
| return; |
| } |
| |
| // the tool bar should contain at least the new perspective button |
| // and 2 other buttons |
| if (getControl().getItemCount() < 3) { |
| return; |
| } |
| |
| // Find the selected item and make sure it is visible. |
| IContributionItem[] items = getItems(); |
| for (int i = 2; i < items.length; i++) { |
| PerspectiveBarContributionItem contribItem = (PerspectiveBarContributionItem) items[i]; |
| if (contribItem.getToolItem().getSelection()) { |
| if (!isItemVisible(contribItem.getToolItem())) { |
| ensureVisible(contribItem); |
| break; |
| } |
| } |
| } |
| } |
| } |