001: /*******************************************************************************
002: * Copyright (c) 2003, 2007 IBM Corporation and others.
003: * All rights reserved. This program and the accompanying materials
004: * are made available under the terms of the Eclipse Public License v1.0
005: * which accompanies this distribution, and is available at
006: * http://www.eclipse.org/legal/epl-v10.html
007: *
008: * Contributors:
009: * IBM Corporation - initial API and implementation
010: *******************************************************************************/package org.eclipse.ui.internal;
011:
012: import org.eclipse.jface.action.IContributionItem;
013: import org.eclipse.jface.action.ToolBarManager;
014: import org.eclipse.jface.resource.JFaceResources;
015: import org.eclipse.swt.SWT;
016: import org.eclipse.swt.events.SelectionAdapter;
017: import org.eclipse.swt.events.SelectionEvent;
018: import org.eclipse.swt.graphics.Font;
019: import org.eclipse.swt.graphics.Point;
020: import org.eclipse.swt.graphics.Rectangle;
021: import org.eclipse.swt.widgets.Composite;
022: import org.eclipse.swt.widgets.Control;
023: import org.eclipse.swt.widgets.CoolBar;
024: import org.eclipse.swt.widgets.CoolItem;
025: import org.eclipse.swt.widgets.Menu;
026: import org.eclipse.swt.widgets.MenuItem;
027: import org.eclipse.swt.widgets.ToolBar;
028: import org.eclipse.swt.widgets.ToolItem;
029: import org.eclipse.ui.internal.layout.LayoutUtil;
030:
031: public class PerspectiveBarManager extends ToolBarManager {
032:
033: /**
034: * The symbolic font name for the small font (value <code>"org.eclipse.jface.smallfont"</code>).
035: */
036: public static final String SMALL_FONT = "org.eclipse.ui.smallFont"; //$NON-NLS-1$
037:
038: public PerspectiveBarManager(int style) {
039: super (style);
040: }
041:
042: public ToolBar createControl(Composite parent) {
043: ToolBar control = super .createControl(parent);
044:
045: if (control != null && !control.isDisposed()) {
046: control.setFont(getFont());
047: }
048:
049: return control;
050: }
051:
052: // TODO begin refactor this out? it is not good that we know we are inside a
053: // CoolBar
054: private CoolBar coolBar;
055: private Menu chevronMenu = null;
056:
057: public void handleChevron(SelectionEvent event) {
058: CoolItem item = (CoolItem) event.widget;
059: //ToolBar toolbar = (ToolBar)getControl();
060: Control control = getControl();
061: if (!(control instanceof ToolBar)) {
062: return; // currently we only deal with toolbar items
063: }
064: /* Retrieve the current bounding rectangle for the selected cool item. */
065: Rectangle itemBounds = item.getBounds();
066: /* Convert to display coordinates (i.e. was relative to CoolBar). */
067: Point pt = coolBar.toDisplay(new Point(itemBounds.x,
068: itemBounds.y));
069: itemBounds.x = pt.x;
070: itemBounds.y = pt.y;
071: /* Retrieve the total number of buttons in the toolbar. */
072: ToolBar toolBar = (ToolBar) control;
073: ToolItem[] tools = toolBar.getItems();
074: int toolCount = tools.length;
075: int i = 0;
076: while (i < toolCount) {
077: /*
078: * Starting from the leftmost tool, retrieve the tool's bounding
079: * rectangle.
080: */
081: Rectangle toolBounds = tools[i].getBounds();
082: /* Convert to display coordinates (i.e. was relative to ToolBar). */
083: pt = toolBar
084: .toDisplay(new Point(toolBounds.x, toolBounds.y));
085: toolBounds.x = pt.x;
086: toolBounds.y = pt.y;
087: /*
088: * Figure out the visible portion of the tool by looking at the
089: * intersection of the tool bounds with the cool item bounds.
090: */
091: Rectangle intersection = itemBounds
092: .intersection(toolBounds);
093: /*
094: * If the tool is not completely within the cool item bounds, then
095: * the tool is at least partially hidden, and all remaining tools
096: * are completely hidden.
097: */
098: if (!intersection.equals(toolBounds)) {
099: break;
100: }
101: i++;
102: }
103:
104: /* Create a pop-up menu with items for each of the hidden buttons. */
105: // Out with the old...
106: if (chevronMenu != null && !chevronMenu.isDisposed())
107: chevronMenu.dispose();
108:
109: // ...In with the new
110: chevronMenu = new Menu(coolBar);
111:
112: for (int j = i; j < toolCount; j++) {
113: ToolItem tool = tools[j];
114: MenuItem menuItem = new MenuItem(chevronMenu, SWT.NONE);
115: if (tool.getSelection()) {
116: menuItem.setEnabled(false);
117: }
118:
119: // Show the full text of the perspective name in the chevron menu.
120: if (tool.getData() instanceof PerspectiveBarContributionItem) {
121: menuItem.setText(((PerspectiveBarContributionItem) tool
122: .getData()).getPerspective().getLabel());
123: } else {
124: menuItem.setText(tool.getText());
125: }
126: menuItem.setImage(tool.getImage());
127:
128: menuItem.setData("IContributionItem", tool.getData()); //$NON-NLS-1$
129:
130: menuItem.addSelectionListener(new SelectionAdapter() {
131: public void widgetSelected(SelectionEvent e) {
132: //rotate the selected item in and the other items right
133: // don't touch the "Open" item
134: MenuItem menuItem = (MenuItem) e.widget;
135: Object item = menuItem.getData("IContributionItem"); //$NON-NLS-1$
136: if (item instanceof PerspectiveBarContributionItem) {
137: PerspectiveBarContributionItem contribItem = (PerspectiveBarContributionItem) item;
138: update(false);
139: contribItem.select();
140: }
141: }
142: });
143: }
144: /*
145: * Display the pop-up menu immediately below the chevron, with the left
146: * edges aligned. Need to convert the given point to display
147: * coordinates in order to pass them to Menu.setLocation (i.e. was
148: * relative to CoolBar).
149: */
150: pt = coolBar.toDisplay(new Point(event.x, event.y));
151: chevronMenu.setLocation(pt.x, pt.y);
152: chevronMenu.setVisible(true);
153: }
154:
155: /* (non-Javadoc)
156: * @see org.eclipse.jface.action.ToolBarManager#relayout(org.eclipse.swt.widgets.ToolBar, int, int)
157: */
158: protected void relayout(ToolBar toolBar, int oldCount, int newCount) {
159: super .relayout(toolBar, oldCount, newCount);
160:
161: if (getControl() != null) {
162: LayoutUtil.resize(getControl());
163: }
164: }
165:
166: void setParent(CoolBar cool) {
167: this .coolBar = cool;
168: }
169:
170: // TODO end refactor this out?
171:
172: private Font getFont() {
173: return JFaceResources.getFont(SMALL_FONT);
174: }
175:
176: /**
177: * Method to select a PerspectiveBarContributionItem and ensure
178: * that it is visible. It updates the MRU list.
179: * @param contribItem the PerspectiveBarContributionItem to select
180: */
181: void select(PerspectiveBarContributionItem contribItem) {
182: if (contribItem.getToolItem() == null) {
183: return;
184: }
185: // check if not visible and ensure visible
186: if (getControl().isVisible()
187: && !isItemVisible(contribItem.getToolItem())) {
188: ensureVisible(contribItem);
189: }
190: }
191:
192: /**
193: * Method that adds a PerspectiveBarContributionItem and
194: * ensures it is visible
195: * @param item the PerspectiveBarContributionItem to be added
196: */
197: public void addItem(PerspectiveBarContributionItem item) {
198: insert(1, item);
199: update(false);
200: }
201:
202: /**
203: * Method to remove a PerspectiveBarContributionItem from the toolbar
204: * and from the MRU and sequence lists when necessary
205: * @param item the PerspectiveBarContributionItem to be removed
206: */
207: public void removeItem(PerspectiveBarContributionItem item) {
208: remove(item);
209: }
210:
211: /**
212: * Re-insert the item at the beginning of the perspective bar,
213: * ensuring that it is visible to the user.
214: *
215: * @param contribItem
216: */
217: private void ensureVisible(
218: PerspectiveBarContributionItem contribItem) {
219: relocate(contribItem, 1);
220: }
221:
222: void relocate(PerspectiveBarContributionItem contribItem, int index) {
223: PerspectiveBarContributionItem newItem = new PerspectiveBarContributionItem(
224: contribItem.getPerspective(), contribItem.getPage());
225:
226: removeItem(contribItem);
227: contribItem.dispose();
228: contribItem = null;
229:
230: insert(index, newItem);
231: update(false);
232: }
233:
234: /**
235: * @return true if the toolItem is visible on the screen, false otherwise.
236: */
237: private boolean isItemVisible(ToolItem toolItem) {
238: Rectangle barBounds = getControl().getBounds();
239: Rectangle itemBounds = toolItem.getBounds();
240: return (barBounds.intersection(itemBounds).equals(itemBounds));
241: }
242:
243: /**
244: * This method ensures that the selected item in the toolbar is visible.
245: */
246: public void arrangeToolbar() {
247: // check if the tool bar is visible
248: if (!getControl().isVisible()) {
249: return;
250: }
251:
252: // the tool bar should contain at least the new perspective button
253: // and 2 other buttons
254: if (getControl().getItemCount() < 3) {
255: return;
256: }
257:
258: // Find the selected item and make sure it is visible.
259: IContributionItem[] items = getItems();
260: for (int i = 2; i < items.length; i++) {
261: PerspectiveBarContributionItem contribItem = (PerspectiveBarContributionItem) items[i];
262: if (contribItem.getToolItem().getSelection()) {
263: if (!isItemVisible(contribItem.getToolItem())) {
264: ensureVisible(contribItem);
265: break;
266: }
267: }
268: }
269: }
270: }
|