KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > eclipse > ui > internal > FastViewPane


1 /*******************************************************************************
2  * Copyright (c) 2004, 2007 IBM Corporation and others.
3  * All rights reserved. This program and the accompanying materials
4  * are made available under the terms of the Eclipse Public License v1.0
5  * which accompanies this distribution, and is available at
6  * http://www.eclipse.org/legal/epl-v10.html
7  *
8  * Contributors:
9  * IBM Corporation - initial API and implementation
10  * Chris Gross chris.gross@us.ibm.com Bug 107443
11  *******************************************************************************/

12 package org.eclipse.ui.internal;
13
14 import org.eclipse.jface.action.ContributionItem;
15 import org.eclipse.jface.action.IMenuManager;
16 import org.eclipse.jface.util.Geometry;
17 import org.eclipse.swt.SWT;
18 import org.eclipse.swt.events.FocusAdapter;
19 import org.eclipse.swt.events.FocusEvent;
20 import org.eclipse.swt.events.KeyAdapter;
21 import org.eclipse.swt.events.KeyEvent;
22 import org.eclipse.swt.events.KeyListener;
23 import org.eclipse.swt.events.SelectionAdapter;
24 import org.eclipse.swt.events.SelectionEvent;
25 import org.eclipse.swt.graphics.Point;
26 import org.eclipse.swt.graphics.Rectangle;
27 import org.eclipse.swt.widgets.Composite;
28 import org.eclipse.swt.widgets.Control;
29 import org.eclipse.swt.widgets.Display;
30 import org.eclipse.swt.widgets.Event;
31 import org.eclipse.swt.widgets.Listener;
32 import org.eclipse.swt.widgets.Sash;
33 import org.eclipse.swt.widgets.ToolBar;
34 import org.eclipse.ui.ISizeProvider;
35 import org.eclipse.ui.IViewReference;
36 import org.eclipse.ui.IWorkbenchPartReference;
37 import org.eclipse.ui.internal.dnd.DragUtil;
38 import org.eclipse.ui.internal.presentations.PresentablePart;
39 import org.eclipse.ui.internal.presentations.SystemMenuFastView;
40 import org.eclipse.ui.internal.presentations.SystemMenuFastViewOrientation;
41 import org.eclipse.ui.internal.presentations.SystemMenuSizeFastView;
42 import org.eclipse.ui.internal.presentations.UpdatingActionContributionItem;
43 import org.eclipse.ui.presentations.AbstractPresentationFactory;
44 import org.eclipse.ui.presentations.IPresentablePart;
45 import org.eclipse.ui.presentations.IStackPresentationSite;
46 import org.eclipse.ui.presentations.StackPresentation;
47
48 /**
49  * Handles the presentation of an active fastview. A fast view pane docks to one side of a
50  * parent composite, and is capable of displaying a single view. The view may be resized.
51  * Displaying a new view will hide any view currently being displayed in the pane.
52  *
53  * Currently, the fast view pane does not own or contain the view. It only controls the view's
54  * position and visibility.
55  *
56  * @see org.eclipse.ui.internal.FastViewBar
57  */

58 public class FastViewPane {
59     private int side = SWT.LEFT;
60
61     private PresentablePart currentPane;
62
63     private Composite clientComposite;
64     
65     private static final int SASH_SIZE = 3;
66
67     private int minSize = 10;
68
69     private int size;
70
71     private Sash sash;
72
73     // Traverse listener -- listens to ESC and closes the active fastview
74
private Listener escapeListener = new Listener() {
75         public void handleEvent(Event event) {
76             if (event.character == SWT.ESC) {
77                 if (currentPane != null) {
78                     currentPane.getPane().getPage().hideFastView();
79                 }
80             }
81         }
82     };
83
84     private DefaultStackPresentationSite site = new DefaultStackPresentationSite() {
85         /* (non-Javadoc)
86          * @see org.eclipse.ui.internal.skins.IPresentationSite#setState(int)
87          */

88         public void setState(int newState) {
89             super.setState(newState);
90             PartPane pane = currentPane.getPane();
91             switch (newState) {
92             case IStackPresentationSite.STATE_MINIMIZED:
93                 
94                 pane.getPage().hideFastView();
95                 break;
96             case IStackPresentationSite.STATE_MAXIMIZED:
97                 pane.setZoomed(true);
98                 sash.setVisible(false);
99                 this.getPresentation().setBounds(getBounds());
100                 break;
101             case IStackPresentationSite.STATE_RESTORED:
102                 pane.setZoomed(false);
103                 sash.setVisible(true);
104                 this.getPresentation().setBounds(getBounds());
105                 break;
106             default:
107             }
108         }
109
110         public void flushLayout() {
111             
112         }
113         
114         public void close(IPresentablePart part) {
115             if (!isCloseable(part)) {
116                 return;
117             }
118             IWorkbenchPartReference ref = currentPane.getPane().getPartReference();
119             if (ref instanceof IViewReference) {
120                 currentPane.getPane().getPage().hideView((IViewReference)ref);
121             }
122         }
123
124         public void close(IPresentablePart[] parts) {
125             for (int idx = 0; idx < parts.length; idx++) {
126                 close(parts[idx]);
127             }
128         }
129
130         /* (non-Javadoc)
131          * @see org.eclipse.ui.internal.skins.IPresentationSite#dragStart(org.eclipse.ui.internal.skins.IPresentablePart, boolean)
132          */

133         public void dragStart(IPresentablePart beingDragged,
134                 Point initialPosition, boolean keyboard) {
135             dragStart(initialPosition, keyboard);
136         }
137
138         /* (non-Javadoc)
139          * @see org.eclipse.ui.internal.skins.IPresentationSite#dragStart(boolean)
140          */

141         public void dragStart(Point initialPosition, boolean keyboard) {
142             if (!isPartMoveable()) {
143                 return;
144             }
145
146             PartPane pane = currentPane.getPane();
147
148             Control control = this.getPresentation().getControl();
149
150             Rectangle bounds = Geometry.toDisplay(clientComposite, control
151                     .getBounds());
152
153             WorkbenchPage page = pane.getPage();
154
155             page.hideFastView();
156             if (page.isZoomed()) {
157                 page.zoomOut();
158             }
159
160             DragUtil.performDrag(pane, bounds, initialPosition, !keyboard);
161         }
162
163         public IPresentablePart getSelectedPart() {
164             return currentPane;
165         }
166
167         public void addSystemActions(IMenuManager menuManager) {
168             ViewStackTrimToolBar vstt = getTrim();
169             
170             appendToGroupIfPossible(menuManager,
171                     "misc", new SystemMenuFastViewOrientation(currentPane.getPane(), vstt)); //$NON-NLS-1$
172

173             // Only add the 'Fast View' menu entry if the
174
// pane is showing a 'legacy' fast view
175
if (vstt == null) {
176                 appendToGroupIfPossible(menuManager,
177                         "misc", new UpdatingActionContributionItem(fastViewAction)); //$NON-NLS-1$
178
}
179             
180             appendToGroupIfPossible(menuManager,
181                     "size", new SystemMenuSizeFastView(FastViewPane.this)); //$NON-NLS-1$
182
}
183
184         /**
185          * Returns the ViewStackTrimToolBar which has caused the FV to be shown. If
186          * <code>null</code> then we can assume it was the legacy FastViewBar.
187          */

188         private ViewStackTrimToolBar getTrim() {
189             if (currentPane == null || currentPane.getPane() == null)
190                 return null;
191
192             ViewStackTrimToolBar trim = null;
193
194             PartPane pane = currentPane.getPane();
195             if (pane instanceof ViewPane) {
196                 ViewPane vp = (ViewPane) pane;
197                 Perspective persp = vp.getPage().getActivePerspective();
198                 IViewReference viewRef = vp.getViewReference();
199                 FastViewManager fvm = persp.getFastViewManager();
200                 
201                 String JavaDoc trimId = null;
202                 if (fvm != null)
203                     trimId = fvm.getIdForRef(viewRef);
204
205                 if (trimId != null && !trimId.equals(FastViewBar.FASTVIEWBAR_ID))
206                     trim = fvm.getViewStackTrimToolbar(trimId);
207             }
208             
209             return trim;
210         }
211         
212         public boolean isPartMoveable(IPresentablePart toMove) {
213             return isPartMoveable();
214         }
215
216         public boolean isStackMoveable() {
217             // a fast view stack is moveable iff its part is moveable
218
return isPartMoveable();
219         }
220
221         private boolean isPartMoveable() {
222             if (currentPane == null) {
223                 return false;
224             }
225             Perspective perspective = currentPane.getPane().getPage()
226                     .getActivePerspective();
227             if (perspective == null) {
228                 // Shouldn't happen -- can't have a FastViewPane without a perspective
229
return false;
230             }
231             
232             IWorkbenchPartReference ref = currentPane.getPane().getPartReference();
233             
234             if (ref instanceof IViewReference) {
235                 return perspective.isMoveable((IViewReference)ref);
236             }
237             return true;
238         }
239
240         public boolean supportsState(int newState) {
241             if (currentPane == null) {
242                 return false;
243             }
244             if (currentPane.getPane().getPage().isFixedLayout()) {
245                 return false;
246             }
247             return true;
248         }
249
250         public IPresentablePart[] getPartList() {
251             return new IPresentablePart[] {getSelectedPart()};
252         }
253
254         /* (non-Javadoc)
255          * @see org.eclipse.ui.presentations.IStackPresentationSite#getProperty(java.lang.String)
256          */

257         public String JavaDoc getProperty(String JavaDoc id) {
258             // fast views stacks do not get arbitrary user properties.
259
return null;
260         }
261     };
262
263     private SystemMenuFastView fastViewAction = new SystemMenuFastView(site);
264
265     private static void appendToGroupIfPossible(IMenuManager m, String JavaDoc groupId,
266             ContributionItem item) {
267         try {
268             m.appendToGroup(groupId, item);
269         } catch (IllegalArgumentException JavaDoc e) {
270             m.add(item);
271         }
272     }
273
274     private Listener mouseDownListener = new Listener() {
275         public void handleEvent(Event event) {
276             if (event.widget instanceof Control) {
277                 Control control = (Control) event.widget;
278
279                 if (control.getShell() != clientComposite.getShell()) {
280                     return;
281                 }
282
283                 if (event.widget instanceof ToolBar) {
284                     // Ignore mouse down on actual tool bar buttons
285
Point pt = new Point(event.x, event.y);
286                     ToolBar toolBar = (ToolBar) event.widget;
287                     if (toolBar.getItem(pt) != null) {
288                         return;
289                     }
290                 }
291
292                 Point loc = DragUtil.getEventLoc(event);
293
294                 // 'Extrude' the rect -before- converting to Display coords
295
// to avoid Right-to-Left issues
296
Rectangle bounds = clientComposite.getBounds();
297                 if (site.getState() != IStackPresentationSite.STATE_MAXIMIZED) {
298                     bounds = Geometry.getExtrudedEdge(bounds, size + SASH_SIZE, side);
299                 }
300                 
301                 // Now map the bounds to display coords
302
bounds = clientComposite.getDisplay().map(clientComposite, null, bounds);
303
304                 if (!bounds.contains(loc)) {
305                     site.setState(IStackPresentationSite.STATE_MINIMIZED);
306                 }
307             }
308         }
309     };
310
311     public void moveSash() {
312         final KeyListener listener = new KeyAdapter() {
313             public void keyPressed(KeyEvent e) {
314                 if (e.character == SWT.ESC || e.character == '\r') {
315                     currentPane.setFocus();
316                 }
317             }
318         };
319         sash.addFocusListener(new FocusAdapter() {
320             public void focusGained(FocusEvent e) {
321                 sash.setBackground(sash.getDisplay().getSystemColor(
322                         SWT.COLOR_LIST_SELECTION));
323                 sash.addKeyListener(listener);
324             }
325
326             public void focusLost(FocusEvent e) {
327                 sash.setBackground(null);
328                 sash.removeKeyListener(listener);
329             }
330         });
331         sash.setFocus();
332     }
333
334     private Listener resizeListener = new Listener() {
335         public void handleEvent(Event event) {
336             if (event.type == SWT.Resize && currentPane != null) {
337                 setSize(size);
338             }
339         }
340     };
341
342     private SelectionAdapter selectionListener = new SelectionAdapter() {
343         public void widgetSelected(SelectionEvent e) {
344
345             if (currentPane != null) {
346                 Rectangle bounds = clientComposite.getClientArea();
347                 Point location = new Point(e.x, e.y);
348                 int distanceFromEdge = Geometry.getDistanceFromEdge(bounds,
349                         location, side);
350
351                 if (!(side == SWT.TOP || side == SWT.LEFT)) {
352                     distanceFromEdge -= SASH_SIZE;
353                 }
354
355                 setSize(distanceFromEdge);
356
357                 if (e.detail != SWT.DRAG) {
358                     updateFastViewSashBounds();
359                     // getPresentation().getControl().moveAbove(null);
360
// currentPane.moveAbove(null);
361
// sash.moveAbove(null);
362
//currentPane.getControl().redraw();
363
sash.redraw();
364                 }
365             }
366         }
367     };
368
369     private void setSize(int size) {
370
371         if (size < minSize) {
372             size = minSize;
373         }
374         this.size = size;
375
376         StackPresentation presentation = getPresentation();
377         if (presentation == null || presentation.getControl().isDisposed()) {
378             return;
379         }
380         getPresentation().setBounds(getBounds());
381         updateFastViewSashBounds();
382     }
383
384     /**
385      * Returns the current fastview size ratio. Returns 0.0 if there is no fastview visible.
386      */

387     public float getCurrentRatio() {
388         if (currentPane == null) {
389             return 0.0f;
390         }
391
392         boolean isVertical = !Geometry.isHorizontal(side);
393         Rectangle clientArea = clientComposite.getClientArea();
394
395         int clientSize = Geometry.getDimension(clientArea, isVertical);
396
397         return (float) size / (float) clientSize;
398     }
399
400     private Rectangle getClientArea() {
401         return clientComposite.getClientArea();
402     }
403
404     private Rectangle getBounds() {
405         Rectangle bounds = getClientArea();
406
407         if (site.getState() == IStackPresentationSite.STATE_MAXIMIZED) {
408             return bounds;
409         }
410
411         boolean horizontal = Geometry.isHorizontal(side);
412
413         int available = Geometry.getDimension(bounds, !horizontal);
414
415         return Geometry.getExtrudedEdge(bounds, Math.min(
416                 FastViewPane.this.size, available), side);
417     }
418
419     /**
420      * Displays the given view as a fastview. The view will be docked to the edge of the
421      * given composite until it is subsequently hidden by a call to hideFastView.
422      *
423      * @param newClientComposite
424      * @param pane
425      * @param newSide
426      */

427     public void showView(Composite newClientComposite, ViewPane pane,
428             int newSide, float sizeRatio) {
429         side = newSide;
430
431         if (currentPane != null) {
432             hideView();
433         }
434
435         currentPane = new PresentablePart(pane, newClientComposite);
436         
437         fastViewAction.setPane(currentPane);
438         clientComposite = newClientComposite;
439
440         clientComposite.addListener(SWT.Resize, resizeListener);
441
442         // Create the control first
443
Control ctrl = pane.getControl();
444         if (ctrl == null) {
445             pane.createControl(clientComposite);
446             ctrl = pane.getControl();
447         }
448
449         ctrl.addListener(SWT.Traverse, escapeListener);
450
451         // Temporarily use the same appearance as docked views .. eventually, fastviews will
452
// be independently pluggable.
453
AbstractPresentationFactory factory = ((WorkbenchWindow) pane
454                 .getWorkbenchWindow()).getWindowConfigurer()
455                 .getPresentationFactory();
456         StackPresentation presentation = factory.createViewPresentation(
457                 newClientComposite, site);
458
459         site.setPresentation(presentation);
460         site.setPresentationState(IStackPresentationSite.STATE_RESTORED);
461         presentation.addPart(currentPane, null);
462         presentation.selectPart(currentPane);
463         presentation.setActive(StackPresentation.AS_ACTIVE_FOCUS);
464         presentation.setVisible(true);
465
466         boolean horizontalResize = Geometry.isHorizontal(side);
467
468         minSize = presentation.computePreferredSize(horizontalResize,
469                 ISizeProvider.INFINITE,
470                 Geometry.getDimension(getClientArea(), horizontalResize),
471                 0);
472         
473         // Show pane fast.
474
ctrl.setEnabled(true); // Add focus support.
475
Composite parent = ctrl.getParent();
476
477         boolean horizontal = Geometry.isHorizontal(side);
478         sash = new Sash(parent, Geometry
479                 .getSwtHorizontalOrVerticalConstant(horizontal));
480
481         sash.addSelectionListener(selectionListener);
482
483         Rectangle clientArea = newClientComposite.getClientArea();
484
485         getPresentation().getControl().moveAbove(null);
486         currentPane.getPane().moveAbove(null);
487         sash.moveAbove(null);
488
489         setSize((int) (Geometry.getDimension(clientArea, !horizontal) * sizeRatio));
490
491         Display display = sash.getDisplay();
492
493         display.addFilter(SWT.MouseDown, mouseDownListener);
494
495         pane.setFocus();
496     }
497
498     /**
499      * Updates the position of the resize sash.
500      */

501     private void updateFastViewSashBounds() {
502         Rectangle bounds = getBounds();
503
504         int oppositeSide = Geometry.getOppositeSide(side);
505         Rectangle newBounds = Geometry.getExtrudedEdge(bounds, -SASH_SIZE,
506                 oppositeSide);
507
508         Rectangle oldBounds = sash.getBounds();
509
510         if (!newBounds.equals(oldBounds)) {
511             sash.setBounds(newBounds);
512         }
513     }
514
515     /**
516      * Disposes of any active widgetry being used for the fast view pane. Does not dispose
517      * of the view itself.
518      */

519     public void dispose() {
520         hideView();
521     }
522     
523     private StackPresentation getPresentation() {
524         return site.getPresentation();
525     }
526
527     /**
528      * Hides the sash for the fastview if it is currently visible. This method may not be
529      * required anymore, and might be removed from the public interface.
530      */

531     public void hideFastViewSash() {
532         if (sash != null) {
533             sash.setVisible(false);
534         }
535     }
536
537     /**
538      * Hides the currently visible fastview.
539      */

540     public void hideView() {
541
542         if (clientComposite != null) {
543             Display display = clientComposite.getDisplay();
544
545             display.removeFilter(SWT.MouseDown, mouseDownListener);
546         }
547
548         if (currentPane == null) {
549             return;
550         }
551
552         fastViewAction.setPane(null);
553         
554         //unzoom before hiding
555
currentPane.getPane().setZoomed(false);
556
557         if (sash != null) {
558             sash.dispose();
559             sash = null;
560         }
561
562         clientComposite.removeListener(SWT.Resize, resizeListener);
563
564         // Get pane.
565
// Hide the right side sash first
566
//hideFastViewSash();
567
Control ctrl = currentPane.getControl();
568
569         ctrl.removeListener(SWT.Traverse, escapeListener);
570
571         // Hide it completely.
572
getPresentation().setVisible(false);
573         site.dispose();
574         //currentPane.setFastViewSash(null);
575
ctrl.setEnabled(false); // Remove focus support.
576

577         currentPane.dispose();
578         currentPane = null;
579     }
580
581     /**
582      * @return Returns the currently visible fastview or null if none
583      */

584     public ViewPane getCurrentPane() {
585         if (currentPane != null && currentPane.getPane() instanceof ViewPane) {
586             return (ViewPane)currentPane.getPane();
587         }
588         
589         return null;
590     }
591
592     public void setState(int newState) {
593         site.setState(newState);
594     }
595     
596     public int getState() {
597         return site.getState();
598     }
599     
600     /**
601      *
602      */

603     public void showSystemMenu() {
604         getPresentation().showSystemMenu();
605     }
606     
607     /**
608      *
609      */

610     public void showPaneMenu() {
611         getPresentation().showPaneMenu();
612     }
613 }
614
Popular Tags