001: /*******************************************************************************
002: * Copyright (c) 2004, 2006 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.presentations.defaultpresentation;
011:
012: import org.eclipse.core.runtime.Assert;
013: import org.eclipse.jface.util.Geometry;
014: import org.eclipse.swt.SWT;
015: import org.eclipse.swt.custom.CTabFolder;
016: import org.eclipse.swt.custom.CTabFolderEvent;
017: import org.eclipse.swt.custom.CTabItem;
018: import org.eclipse.swt.events.MouseAdapter;
019: import org.eclipse.swt.events.MouseEvent;
020: import org.eclipse.swt.events.SelectionAdapter;
021: import org.eclipse.swt.events.SelectionEvent;
022: import org.eclipse.swt.graphics.Font;
023: import org.eclipse.swt.graphics.GC;
024: import org.eclipse.swt.graphics.Image;
025: import org.eclipse.swt.graphics.Point;
026: import org.eclipse.swt.graphics.Rectangle;
027: import org.eclipse.swt.widgets.Composite;
028: import org.eclipse.swt.widgets.Control;
029: import org.eclipse.swt.widgets.Event;
030: import org.eclipse.swt.widgets.Label;
031: import org.eclipse.swt.widgets.Listener;
032: import org.eclipse.swt.widgets.ToolBar;
033: import org.eclipse.swt.widgets.ToolItem;
034: import org.eclipse.ui.internal.IWorkbenchGraphicConstants;
035: import org.eclipse.ui.internal.WorkbenchImages;
036: import org.eclipse.ui.internal.WorkbenchMessages;
037: import org.eclipse.ui.internal.dnd.DragUtil;
038: import org.eclipse.ui.internal.presentations.PaneFolder;
039: import org.eclipse.ui.internal.presentations.PaneFolderButtonListener;
040: import org.eclipse.ui.internal.presentations.util.AbstractTabFolder;
041: import org.eclipse.ui.internal.presentations.util.AbstractTabItem;
042: import org.eclipse.ui.internal.presentations.util.PartInfo;
043: import org.eclipse.ui.internal.presentations.util.TabFolderEvent;
044: import org.eclipse.ui.internal.util.Util;
045:
046: /**
047: * @since 3.1
048: */
049: public class DefaultTabFolder extends AbstractTabFolder {
050:
051: private PaneFolder paneFolder;
052: private Control viewToolBar;
053: private Label titleLabel;
054:
055: private PaneFolderButtonListener buttonListener = new PaneFolderButtonListener() {
056: public void stateButtonPressed(int buttonId) {
057: fireEvent(TabFolderEvent.stackStateToEventId(buttonId));
058: }
059:
060: /**
061: * Called when a close button is pressed.
062: *
063: * @param item the tab whose close button was pressed
064: */
065: public void closeButtonPressed(CTabItem item) {
066: fireEvent(TabFolderEvent.EVENT_CLOSE, getTab(item));
067: }
068:
069: /**
070: *
071: * @since 3.0
072: */
073: public void showList(CTabFolderEvent event) {
074: event.doit = false;
075: fireEvent(TabFolderEvent.EVENT_SHOW_LIST);
076: }
077: };
078:
079: private Listener selectionListener = new Listener() {
080: public void handleEvent(Event e) {
081: AbstractTabItem item = getTab((CTabItem) e.item);
082:
083: if (item != null) {
084: fireEvent(TabFolderEvent.EVENT_TAB_SELECTED, item);
085: }
086: }
087: };
088:
089: private static DefaultTabFolderColors defaultColors = new DefaultTabFolderColors();
090:
091: private DefaultTabFolderColors[] activeShellColors = {
092: defaultColors, defaultColors, defaultColors };
093: private DefaultTabFolderColors[] inactiveShellColors = {
094: defaultColors, defaultColors, defaultColors };
095: private boolean shellActive = false;
096:
097: /**
098: * Create a new instance of the receiver
099: *
100: * @param parent
101: * @param flags
102: * @param allowMin
103: * @param allowMax
104: */
105: public DefaultTabFolder(Composite parent, int flags,
106: boolean allowMin, boolean allowMax) {
107: paneFolder = new PaneFolder(parent, flags | SWT.NO_BACKGROUND);
108: paneFolder.addButtonListener(buttonListener);
109: paneFolder.setMinimizeVisible(allowMin);
110: paneFolder.setMaximizeVisible(allowMax);
111: paneFolder.getControl().addListener(SWT.Selection,
112: selectionListener);
113: paneFolder.setTopRight(null);
114:
115: // Initialize view menu dropdown
116: {
117: ToolBar actualToolBar = new ToolBar(
118: paneFolder.getControl(), SWT.FLAT
119: | SWT.NO_BACKGROUND);
120: viewToolBar = actualToolBar;
121:
122: ToolItem pullDownButton = new ToolItem(actualToolBar,
123: SWT.PUSH);
124: Image hoverImage = WorkbenchImages
125: .getImage(IWorkbenchGraphicConstants.IMG_LCL_RENDERED_VIEW_MENU);
126: pullDownButton.setDisabledImage(hoverImage);
127: pullDownButton.setImage(hoverImage);
128: pullDownButton.setToolTipText(WorkbenchMessages.Menu);
129: actualToolBar.addMouseListener(new MouseAdapter() {
130: public void mouseDown(MouseEvent e) {
131: fireEvent(TabFolderEvent.EVENT_PANE_MENU,
132: getSelection(), getPaneMenuLocation());
133: }
134: });
135: pullDownButton.addSelectionListener(new SelectionAdapter() {
136: public void widgetSelected(SelectionEvent e) {
137: fireEvent(TabFolderEvent.EVENT_PANE_MENU,
138: getSelection(), getPaneMenuLocation());
139:
140: super .widgetSelected(e);
141: }
142: });
143: }
144:
145: // Initialize content description label
146: {
147: titleLabel = new Label(paneFolder.getControl(), SWT.NONE);
148: titleLabel.moveAbove(null);
149: titleLabel.setVisible(false);
150: attachListeners(titleLabel, false);
151: }
152:
153: attachListeners(paneFolder.getControl(), false);
154: attachListeners(paneFolder.getViewForm(), false);
155:
156: paneFolder.setTabHeight(computeTabHeight());
157:
158: viewToolBar.moveAbove(null);
159: }
160:
161: /**
162: * Changes the minimum number of characters to display in the pane folder
163: * tab. This control how much information will be displayed to the user.
164: *
165: * @param count
166: * The number of characters to display in the tab folder; this
167: * value should be a positive integer.
168: * @see org.eclipse.swt.custom.CTabFolder#setMinimumCharacters(int)
169: * @since 3.1
170: */
171: public void setMinimumCharacters(int count) {
172: paneFolder.setMinimumCharacters(count);
173: }
174:
175: public void setSimpleTabs(boolean simple) {
176: paneFolder.setSimpleTab(simple);
177: }
178:
179: /**
180: * @param item
181: * @return
182: * @since 3.1
183: */
184: protected DefaultTabItem getTab(CTabItem item) {
185: return (DefaultTabItem) item.getData();
186: }
187:
188: /* (non-Javadoc)
189: * @see org.eclipse.ui.internal.presentations.util.AbstractTabFolder#computeSize(int, int)
190: */
191: public Point computeSize(int widthHint, int heightHint) {
192: return paneFolder.computeMinimumSize();
193: }
194:
195: /* package */PaneFolder getFolder() {
196: return paneFolder;
197: }
198:
199: public AbstractTabItem getSelection() {
200: return getTab(paneFolder.getSelection());
201: }
202:
203: /* (non-Javadoc)
204: * @see org.eclipse.ui.internal.presentations.util.AbstractTabFolder#add(int)
205: */
206: public AbstractTabItem add(int index, int flags) {
207: DefaultTabItem result = new DefaultTabItem(
208: (CTabFolder) getFolder().getControl(), index, flags);
209:
210: result.getWidget().setData(result);
211:
212: return result;
213: }
214:
215: /* (non-Javadoc)
216: * @see org.eclipse.ui.internal.presentations.util.AbstractTabFolder#getContentParent()
217: */
218: public Composite getContentParent() {
219: return paneFolder.getContentParent();
220: }
221:
222: /* (non-Javadoc)
223: * @see org.eclipse.ui.internal.presentations.util.AbstractTabFolder#setContent(org.eclipse.swt.widgets.Control)
224: */
225: public void setContent(Control newContent) {
226: paneFolder.setContent(newContent);
227: }
228:
229: /* (non-Javadoc)
230: * @see org.eclipse.ui.internal.presentations.util.AbstractTabFolder#getItems()
231: */
232: public AbstractTabItem[] getItems() {
233: CTabItem[] items = paneFolder.getItems();
234:
235: AbstractTabItem[] result = new AbstractTabItem[items.length];
236:
237: for (int i = 0; i < result.length; i++) {
238: result[i] = getTab(items[i]);
239: }
240:
241: return result;
242: }
243:
244: /* (non-Javadoc)
245: * @see org.eclipse.ui.internal.presentations.util.AbstractTabFolder#getItemCount()
246: */
247: public int getItemCount() {
248: // Override retrieving all the items when we just want the count.
249: return paneFolder.getItemCount();
250: }
251:
252: /* (non-Javadoc)
253: * @see org.eclipse.ui.internal.presentations.util.AbstractTabFolder#setSelection(org.eclipse.ui.internal.presentations.util.AbstractTabItem)
254: */
255: public void setSelection(AbstractTabItem toSelect) {
256: paneFolder.setSelection(indexOf(toSelect));
257: }
258:
259: /* (non-Javadoc)
260: * @see org.eclipse.ui.internal.presentations.util.AbstractTabFolder#getToolbarParent()
261: */
262: public Composite getToolbarParent() {
263: return paneFolder.getControl();
264: }
265:
266: /* (non-Javadoc)
267: * @see org.eclipse.ui.internal.presentations.util.AbstractTabFolder#getControl()
268: */
269: public Control getControl() {
270: return paneFolder.getControl();
271: }
272:
273: public void setUnselectedCloseVisible(boolean visible) {
274: paneFolder.setUnselectedCloseVisible(visible);
275: }
276:
277: public void setUnselectedImageVisible(boolean visible) {
278: paneFolder.setUnselectedImageVisible(visible);
279: }
280:
281: /* (non-Javadoc)
282: * @see org.eclipse.ui.internal.presentations.util.AbstractTabFolder#getTabArea()
283: */
284: public Rectangle getTabArea() {
285: return Geometry.toDisplay(paneFolder.getControl(), paneFolder
286: .getTitleArea());
287: }
288:
289: /**
290: * @param enabled
291: * @since 3.1
292: */
293: public void enablePaneMenu(boolean enabled) {
294: if (enabled) {
295: paneFolder.setTopRight(viewToolBar);
296: viewToolBar.setVisible(true);
297: } else {
298: paneFolder.setTopRight(null);
299: viewToolBar.setVisible(false);
300: }
301: }
302:
303: /* (non-Javadoc)
304: * @see org.eclipse.ui.internal.presentations.util.AbstractTabFolder#setSelectedInfo(org.eclipse.ui.internal.presentations.util.PartInfo)
305: */
306: public void setSelectedInfo(PartInfo info) {
307: String newTitle = DefaultTabItem
308: .escapeAmpersands(info.contentDescription);
309:
310: if (!Util.equals(titleLabel.getText(), newTitle)) {
311: titleLabel.setText(newTitle);
312: }
313:
314: if (!info.contentDescription.equals(Util.ZERO_LENGTH_STRING)) {
315: paneFolder.setTopLeft(titleLabel);
316: titleLabel.setVisible(true);
317: } else {
318: paneFolder.setTopLeft(null);
319: titleLabel.setVisible(false);
320: }
321: }
322:
323: /* (non-Javadoc)
324: * @see org.eclipse.ui.internal.presentations.util.AbstractTabFolder#getPaneMenuLocation()
325: */
326: public Point getPaneMenuLocation() {
327: Point toolbarSize = viewToolBar.getSize();
328:
329: return viewToolBar.toDisplay(0, toolbarSize.y);
330: }
331:
332: /* (non-Javadoc)
333: * @see org.eclipse.ui.internal.presentations.util.AbstractTabFolder#getPartListLocation()
334: */
335: public Point getPartListLocation() {
336: return paneFolder.getControl().toDisplay(
337: paneFolder.getChevronLocation());
338: }
339:
340: /* (non-Javadoc)
341: * @see org.eclipse.ui.internal.presentations.util.AbstractTabFolder#getSystemMenuLocation()
342: */
343: public Point getSystemMenuLocation() {
344: Rectangle bounds = DragUtil.getDisplayBounds(paneFolder
345: .getControl());
346:
347: int idx = paneFolder.getSelectionIndex();
348: if (idx > -1) {
349: CTabItem item = paneFolder.getItem(idx);
350: Rectangle itemBounds = item.getBounds();
351:
352: bounds.x += itemBounds.x;
353: bounds.y += itemBounds.y;
354: }
355:
356: Point location = new Point(bounds.x, bounds.y
357: + paneFolder.getTabHeight());
358:
359: return location;
360: }
361:
362: /* (non-Javadoc)
363: * @see org.eclipse.ui.internal.presentations.util.AbstractTabFolder#isOnBorder(org.eclipse.swt.graphics.Point)
364: */
365: public boolean isOnBorder(Point toTest) {
366: Control content = paneFolder.getContent();
367: if (content != null) {
368: Rectangle displayBounds = DragUtil
369: .getDisplayBounds(content);
370:
371: if (paneFolder.getTabPosition() == SWT.TOP) {
372: return toTest.y >= displayBounds.y;
373: }
374:
375: if (toTest.y >= displayBounds.y
376: && toTest.y < displayBounds.y
377: + displayBounds.height) {
378: return true;
379: }
380: }
381:
382: return super .isOnBorder(toTest);
383: }
384:
385: /* (non-Javadoc)
386: * @see org.eclipse.ui.internal.presentations.util.AbstractTabFolder#layout(boolean)
387: */
388: public void layout(boolean flushCache) {
389: paneFolder.layout(flushCache);
390: super .layout(flushCache);
391: }
392:
393: /* (non-Javadoc)
394: * @see org.eclipse.ui.internal.presentations.util.AbstractTabFolder#setState(int)
395: */
396: public void setState(int state) {
397: paneFolder.setState(state);
398: super .setState(state);
399: }
400:
401: /* (non-Javadoc)
402: * @see org.eclipse.ui.internal.presentations.util.AbstractTabFolder#setActive(int)
403: */
404: public void setActive(int activeState) {
405: super .setActive(activeState);
406: updateColors();
407: }
408:
409: /* (non-Javadoc)
410: * @see org.eclipse.ui.internal.presentations.util.AbstractTabFolder#setTabPosition(int)
411: */
412: public void setTabPosition(int tabPosition) {
413: paneFolder.setTabPosition(tabPosition);
414: super .setTabPosition(tabPosition);
415: layout(true);
416: }
417:
418: public void flushToolbarSize() {
419: paneFolder.flushTopCenterSize();
420: }
421:
422: /* (non-Javadoc)
423: * @see org.eclipse.ui.internal.presentations.util.AbstractTabFolder#setToolbar(org.eclipse.swt.widgets.Control)
424: */
425: public void setToolbar(Control toolbarControl) {
426: paneFolder.setTopCenter(toolbarControl);
427: super .setToolbar(toolbarControl);
428: }
429:
430: public void setColors(DefaultTabFolderColors colors,
431: int activationState, boolean shellActivationState) {
432: Assert.isTrue(activationState < activeShellColors.length);
433:
434: if (shellActivationState) {
435: activeShellColors[activationState] = colors;
436: } else {
437: inactiveShellColors[activationState] = colors;
438: }
439:
440: if (activationState == getActive()
441: && shellActive == shellActivationState) {
442: updateColors();
443: }
444: }
445:
446: /**
447: *
448: * @since 3.1
449: */
450: private void updateColors() {
451: DefaultTabFolderColors currentColors = shellActive ? activeShellColors[getActive()]
452: : inactiveShellColors[getActive()];
453:
454: paneFolder.setSelectionForeground(currentColors.foreground);
455: paneFolder.setSelectionBackground(currentColors.background,
456: currentColors.percentages, currentColors.vertical);
457: }
458:
459: public void setColors(DefaultTabFolderColors colors,
460: int activationState) {
461: setColors(colors, activationState, true);
462: setColors(colors, activationState, false);
463: }
464:
465: /* (non-Javadoc)
466: * @see org.eclipse.ui.internal.presentations.util.AbstractTabFolder#shellActive(boolean)
467: */
468: public void shellActive(boolean isActive) {
469: this .shellActive = isActive;
470: super .shellActive(isActive);
471:
472: updateColors();
473: }
474:
475: /**
476: * @param font
477: * @since 3.1
478: */
479: public void setFont(Font font) {
480: if (font != paneFolder.getControl().getFont()) {
481: paneFolder.getControl().setFont(font);
482: layout(true);
483: paneFolder.setTabHeight(computeTabHeight());
484: }
485: }
486:
487: /**
488: * @return the required tab height for this folder.
489: */
490: protected int computeTabHeight() {
491: GC gc = new GC(getControl());
492:
493: // Compute the tab height
494: int tabHeight = Math.max(viewToolBar.computeSize(SWT.DEFAULT,
495: SWT.DEFAULT).y, gc.getFontMetrics().getHeight());
496:
497: gc.dispose();
498:
499: return tabHeight;
500: }
501:
502: /**
503: * @param b
504: * @since 3.1
505: */
506: public void setSingleTab(boolean b) {
507: paneFolder.setSingleTab(b);
508: AbstractTabItem[] items = getItems();
509:
510: for (int i = 0; i < items.length; i++) {
511: DefaultTabItem item = (DefaultTabItem) items[i];
512:
513: item.updateTabText();
514: }
515:
516: layout(true);
517: }
518:
519: /* (non-Javadoc)
520: * @see org.eclipse.ui.internal.presentations.util.AbstractTabFolder#setVisible(boolean)
521: */
522: public void setVisible(boolean visible) {
523: super .setVisible(visible);
524: getFolder().setVisible(visible);
525: }
526:
527: /* (non-Javadoc)
528: * @see org.eclipse.ui.internal.presentations.util.AbstractTabFolder#showMinMax(boolean)
529: */
530: public void showMinMax(boolean show) {
531: paneFolder.showMinMax(show);
532: }
533: }
|