KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > eclipse > ui > internal > layout > TrimToolBarBase


1 /*******************************************************************************
2  * Copyright (c) 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  *******************************************************************************/

11 package org.eclipse.ui.internal.layout;
12
13 import org.eclipse.jface.action.ContributionItem;
14 import org.eclipse.jface.action.MenuManager;
15 import org.eclipse.jface.action.ToolBarManager;
16 import org.eclipse.swt.SWT;
17 import org.eclipse.swt.events.SelectionEvent;
18 import org.eclipse.swt.events.SelectionListener;
19 import org.eclipse.swt.graphics.Cursor;
20 import org.eclipse.swt.graphics.Point;
21 import org.eclipse.swt.graphics.Rectangle;
22 import org.eclipse.swt.widgets.Control;
23 import org.eclipse.swt.widgets.CoolBar;
24 import org.eclipse.swt.widgets.CoolItem;
25 import org.eclipse.swt.widgets.Event;
26 import org.eclipse.swt.widgets.Listener;
27 import org.eclipse.swt.widgets.Menu;
28 import org.eclipse.swt.widgets.MenuItem;
29 import org.eclipse.swt.widgets.ToolBar;
30 import org.eclipse.swt.widgets.ToolItem;
31 import org.eclipse.ui.internal.IChangeListener;
32 import org.eclipse.ui.internal.IntModel;
33 import org.eclipse.ui.internal.RadioMenu;
34 import org.eclipse.ui.internal.TrimFrame;
35 import org.eclipse.ui.internal.WorkbenchMessages;
36 import org.eclipse.ui.internal.WorkbenchWindow;
37 import org.eclipse.ui.internal.dnd.DragUtil;
38 import org.eclipse.ui.presentations.PresentationUtil;
39
40 /**
41  * This control provides common UI functionality for trim elements
42  * that wish to use a ToolBarManager-based implementation.
43  * <p>
44  * It provides the following features:
45  * <p>
46  * Drag affordance and handling:
47  * <ol>
48  * <li>The ToolBar is contained within a CoolBar/Item to provide the same
49  * drag handle affordance as the rest of the trim
50  * <li>Drag handling is provided to allow rearrangement within a trim side or
51  * to other sides, depending on the values returned by <code>IWindowTrim.getValidSides</code></li>
52  * </ol>
53  * </p>
54  * <p>
55  * Context Menu:
56  * <ol>
57  * <li>A "Dock on" menu item is provided to allow changing the side, depending on the values returned by
58  * <code>IWindowTrim.getValidSides</code></li>
59  * <li>A "Close" menu item is provided to allow the User to close (hide) the trim element,
60  * based on the value returned by <code>IWindowTrim.isCloseable</code>
61  * </ol>
62  * </p>
63  * <p>
64  * @since 3.3
65  * </p>
66  */

67 public abstract class TrimToolBarBase implements IWindowTrim {
68     // Fields
69
protected String JavaDoc id;
70     protected int orientation;
71     protected WorkbenchWindow wbw;
72     protected TrimLayout layout;
73     protected ToolBarManager tbMgr = null;
74     protected ToolItem contextToolItem = null;
75
76     // CoolBar handling
77
private TrimFrame frame = null;
78     private CoolBar cb = null;
79     private CoolItem ci = null;
80     
81     // Context Menu
82
private MenuManager dockMenuManager;
83     private ContributionItem dockContributionItem = null;
84     private Menu sidesMenu;
85     private MenuItem dockCascade;
86     private RadioMenu radioButtons;
87     private IntModel radioVal = new IntModel(0);
88 // private Menu showMenu;
89
// private MenuItem showCascade;
90

91     /*
92      * Listeners...
93      */

94
95     private Listener tbListener = new Listener() {
96         public void handleEvent(Event event) {
97             Point loc = new Point(event.x, event.y);
98             if (event.type == SWT.MenuDetect) {
99                 showToolBarPopup(loc);
100             }
101         }
102     };
103
104     /**
105      * This listener brings up the context menu
106      */

107     private Listener cbListener = new Listener() {
108         public void handleEvent(Event event) {
109             Point loc = new Point(event.x, event.y);
110             if (event.type == SWT.MenuDetect) {
111                 showDockTrimPopup(loc);
112             }
113         }
114     };
115     
116     /**
117      * This listener starts a drag operation when
118      * the Drag and Drop manager tells it to
119      */

120     private Listener dragListener = new Listener() {
121         public void handleEvent(Event event) {
122             // Only allow 'left mouse' drags...
123
if (event.button != 3) {
124                 Point position = DragUtil.getEventLoc(event);
125                 startDraggingTrim(position);
126             }
127         }
128     };
129
130     /**
131      * Create a new trim UI handle for a particular IWindowTrim item
132      *
133      * @param layout the TrimLayout we're being used in
134      * @param trim the IWindowTrim we're acting on behalf of
135      * @param curSide the SWT side that the trim is currently on
136      */

137     protected TrimToolBarBase(String JavaDoc id, int curSide, WorkbenchWindow wbw) {
138         this.id = id;
139         this.wbw = wbw;
140         this.layout = (TrimLayout) wbw.getTrimManager();
141     }
142
143     /**
144      * @param loc
145      */

146     private void showToolBarPopup(Point loc) {
147         Point tbLoc = tbMgr.getControl().toControl(loc);
148         contextToolItem = tbMgr.getControl().getItem(tbLoc);
149         MenuManager mm = tbMgr.getContextMenuManager();
150         if (mm != null) {
151             Menu menu = mm.createContextMenu(wbw.getShell());
152             menu.setLocation(loc.x, loc.y);
153             menu.setVisible(true);
154         }
155     }
156
157     /**
158      * Initialize the ToolBarManger for this instance. We create a
159      * new ToolBarManager whenever we need to and this gives the
160      * derived class a chance to define the ICI's and context
161      * menu...
162      *
163      * @param mgr The manager to initialize
164      */

165     public abstract void initToolBarManager(ToolBarManager mgr);
166     
167     /**
168      * Hook any necessary listeners to the new ToolBar instance.
169      * <p>
170      * NOTE: Clients should add a dispose listener if necessary to
171      * unhook listeners added through this call.
172      * </p>
173      * @param mgr The ToolBarManager whose control is to be hooked
174      */

175     public abstract void hookControl(ToolBarManager mgr);
176     
177     /**
178      * Set up the trim with its cursor, drag listener, context menu and menu listener.
179      * This method can also be used to 'recycle' a trim handle as long as the new handle
180      * is for trim under the same parent as it was originally used for.
181      */

182     private void createControl(int curSide) {
183         // out with the old
184
dispose();
185         
186         this.radioVal.set(curSide);
187         
188         // remember the orientation to use
189
orientation = (curSide == SWT.LEFT || curSide == SWT.RIGHT) ? SWT.VERTICAL : SWT.HORIZONTAL;
190
191         frame = new TrimFrame(wbw.getShell());
192         
193         // Create the necessary parts...
194
cb = new CoolBar(frame.getComposite(), orientation | SWT.FLAT);
195         ci = new CoolItem(cb, SWT.FLAT);
196
197         // Create (and 'fill') the toolbar
198
tbMgr = new ToolBarManager(orientation | SWT.FLAT);
199         
200         // Have the subclass define any manager content
201
initToolBarManager(tbMgr);
202         
203         // Create the new ToolBar
204
ToolBar tb = tbMgr.createControl(cb);
205         ci.setControl(tb);
206         
207         // Have the subclass hook any listeners
208
hookControl(tbMgr);
209         
210         // set up the frame's layout
211
update(true);
212         
213         // Set the cursor affordance
214
Cursor dragCursor = getControl().getDisplay().getSystemCursor(SWT.CURSOR_SIZEALL);
215         cb.setCursor(dragCursor);
216         
217         // Now, we have to explicity set the arrow for the TB
218
Cursor tbCursor = getControl().getDisplay().getSystemCursor(SWT.CURSOR_ARROW);
219         tb.setCursor(tbCursor);
220         
221         //cb.setBackground(cb.getDisplay().getSystemColor(SWT.COLOR_RED));
222

223         // Set up the dragging behaviour
224
PresentationUtil.addDragListener(cb, dragListener);
225         
226         // Create the docking context menu
227
dockMenuManager = new MenuManager();
228         dockContributionItem = getDockingContribution();
229         dockMenuManager.add(dockContributionItem);
230
231         tb.addListener(SWT.MenuDetect, tbListener);
232         cb.addListener(SWT.MenuDetect, cbListener);
233         
234         //tbMgr.getControl().setBackground(cb.getDisplay().getSystemColor(SWT.COLOR_GREEN));
235
//tbMgr.getControl().pack(true);
236
cb.pack(true);
237         cb.setVisible(true);
238         
239         tbMgr.getControl().setVisible(true);
240         cb.setVisible(true);
241         frame.getComposite().setVisible(true);
242     }
243
244     /**
245      * Handle the event generated when a User selects a new side to
246      * dock this trim on using the context menu
247      */

248     private void handleShowOnChange() {
249         if (getControl() == null)
250             return;
251         
252         layout.removeTrim(this);
253         dock(radioVal.get());
254         layout.addTrim(radioVal.get(), this, null);
255         
256         // perform an optimized layout to show the trim in its new location
257
LayoutUtil.resize(getControl());
258     }
259
260     /**
261      * Force the toobar to re-synch to the model
262      * @param changed true if changes have occurred in the structure
263      */

264     public void update(boolean changed) {
265         tbMgr.update(changed);
266         
267         // Force a resize
268
tbMgr.getControl().pack();
269         Point size = tbMgr.getControl().getSize();
270         //tbMgr.getControl().setBounds(0, 0, size.x, size.y);
271
Point ps = ci.computeSize (size.x, size.y);
272         ci.setPreferredSize (ps);
273         ci.setSize(ps);
274         cb.pack();
275         cb.update();
276         LayoutUtil.resize(getControl());
277     }
278     
279     /**
280      * Construct (if necessary) a context menu contribution item and return it. This
281      * is explicitly <code>public</code> so that trim elements can retrieve the item
282      * and add it into their own context menus if desired.
283      *
284      * @return The contribution item for the handle's context menu.
285      */

286     private ContributionItem getDockingContribution() {
287         if (dockContributionItem == null) {
288             dockContributionItem = new ContributionItem() {
289                 public void fill(Menu menu, int index) {
290                     // populate from superclass
291
super.fill(menu, index);
292                     
293                     // Add a 'Close' menu entry if the trim supports the operation
294
if (isCloseable()) {
295                         MenuItem closeItem = new MenuItem(menu, SWT.PUSH, index++);
296                         closeItem.setText(WorkbenchMessages.TrimCommon_Close);
297                         
298                         closeItem.addSelectionListener(new SelectionListener() {
299                             public void widgetSelected(SelectionEvent e) {
300                                 handleCloseTrim();
301                             }
302
303                             public void widgetDefaultSelected(SelectionEvent e) {
304                             }
305                         });
306
307                         new MenuItem(menu, SWT.SEPARATOR, index++);
308                     }
309                     
310                     // Test Hook: add a menu entry that brings up a dialog to allow
311
// testing with various GUI prefs.
312
// MenuItem closeItem = new MenuItem(menu, SWT.PUSH, index++);
313
// closeItem.setText("Change Preferences"); //$NON-NLS-1$
314
//
315
// closeItem.addSelectionListener(new SelectionListener() {
316
// public void widgetSelected(SelectionEvent e) {
317
// handleChangePreferences();
318
// }
319
//
320
// public void widgetDefaultSelected(SelectionEvent e) {
321
// }
322
// });
323
//
324
// new MenuItem(menu, SWT.SEPARATOR, index++);
325

326                     // Create a cascading menu to allow the user to dock the trim
327
dockCascade = new MenuItem(menu, SWT.CASCADE, index++);
328                     {
329                         dockCascade.setText(WorkbenchMessages.TrimCommon_DockOn);
330                         
331                         sidesMenu = new Menu(dockCascade);
332                         radioButtons = new RadioMenu(sidesMenu, radioVal);
333                         
334                         radioButtons.addMenuItem(WorkbenchMessages.TrimCommon_Top, new Integer JavaDoc(SWT.TOP));
335                         radioButtons.addMenuItem(WorkbenchMessages.TrimCommon_Bottom, new Integer JavaDoc(SWT.BOTTOM));
336                         radioButtons.addMenuItem(WorkbenchMessages.TrimCommon_Left, new Integer JavaDoc(SWT.LEFT));
337                         radioButtons.addMenuItem(WorkbenchMessages.TrimCommon_Right, new Integer JavaDoc(SWT.RIGHT));
338                         
339                         dockCascade.setMenu(sidesMenu);
340                     }
341
342                     // if the radioVal changes it means that the User wants to change the docking location
343
radioVal.addChangeListener(new IChangeListener() {
344                         public void update(boolean changed) {
345                             if (changed) {
346                                 handleShowOnChange();
347                             }
348                         }
349                     });
350                     
351                     // Provide Show / Hide trim capabilities
352
// showCascade = new MenuItem(menu, SWT.CASCADE, index++);
353
// {
354
// showCascade.setText(WorkbenchMessages.TrimCommon_ShowTrim);
355
//
356
// showMenu = new Menu(dockCascade);
357
//
358
// // Construct a 'hide/show' cascade from -all- the existing trim...
359
// List trimItems = layout.getAllTrim();
360
// Iterator d = trimItems.iterator();
361
// while (d.hasNext()) {
362
// IWindowTrim trimItem = (IWindowTrim) d.next();
363
// MenuItem item = new MenuItem(showMenu, SWT.CHECK);
364
// item.setText(trimItem.getDisplayName());
365
// item.setSelection(trimItem.getControl().getVisible());
366
// item.setData(trimItem);
367
//
368
// // TODO: Make this work...wire it off for now
369
// item.setEnabled(false);
370
//
371
// item.addSelectionListener(new SelectionListener() {
372
//
373
// public void widgetSelected(SelectionEvent e) {
374
// IWindowTrim trim = (IWindowTrim) e.widget.getData();
375
// layout.setTrimVisible(trim, !trim.getControl().getVisible());
376
// }
377
//
378
// public void widgetDefaultSelected(SelectionEvent e) {
379
// }
380
//
381
// });
382
// }
383
//
384
// showCascade.setMenu(showMenu);
385
// }
386
}
387             };
388         }
389         return dockContributionItem;
390     }
391
392     /**
393      * @return The side the trm is currently on
394      */

395     public int getCurrentSide() {
396         return radioVal.get();
397     }
398     
399     /**
400      * Test Hook: Bring up a dialog that allows the user to
401      * modify the trimdragging GUI preferences.
402      */

403 // private void handleChangePreferences() {
404
// TrimDragPreferenceDialog dlg = new TrimDragPreferenceDialog(getShell());
405
// dlg.open();
406
// }
407

408     /**
409      * Handle the event generated when the "Close" item is
410      * selected on the context menu. This removes the associated
411      * trim and calls back to the IWidnowTrim to inform it that
412      * the User has closed the trim.
413      */

414     private void handleCloseTrim() {
415         handleClose();
416     }
417     
418     /* (non-Javadoc)
419      * @see org.eclipse.swt.widgets.Widget#dispose()
420      */

421     public void dispose() {
422         if (getControl() == null || getControl().isDisposed())
423             return;
424         
425         if (radioButtons != null) {
426             radioButtons.dispose();
427         }
428
429         // tidy up...
430
getControl().removeListener(SWT.MenuDetect, cbListener);
431         
432         tbMgr.dispose();
433         tbMgr = null;
434         
435         getControl().dispose();
436         frame = null;
437     }
438
439     /**
440      * Begins dragging the trim
441      *
442      * @param position initial mouse position
443      */

444     private void startDraggingTrim(Point position) {
445         Rectangle fakeBounds = new Rectangle(100000, 0,0,0);
446         DragUtil.performDrag(this, fakeBounds, position, true);
447     }
448
449     /**
450      * Shows the popup menu for an item in the fast view bar.
451      */

452     private void showDockTrimPopup(Point pt) {
453         Menu menu = dockMenuManager.createContextMenu(this.getControl());
454         menu.setLocation(pt.x, pt.y);
455         menu.setVisible(true);
456     }
457
458     /* (non-Javadoc)
459      * @see org.eclipse.ui.internal.layout.IWindowTrim#dock(int)
460      */

461     public void dock(int dropSide) {
462         createControl(dropSide);
463     }
464
465     /* (non-Javadoc)
466      * @see org.eclipse.ui.internal.layout.IWindowTrim#getControl()
467      */

468     public Control getControl() {
469         if (frame == null)
470             return null;
471         
472         return frame.getComposite();
473     }
474
475     /* (non-Javadoc)
476      * @see org.eclipse.ui.internal.layout.IWindowTrim#getDisplayName()
477      */

478     public String JavaDoc getDisplayName() {
479         return id;
480     }
481
482     /* (non-Javadoc)
483      * @see org.eclipse.ui.internal.layout.IWindowTrim#getHeightHint()
484      */

485     public int getHeightHint() {
486         return getControl().computeSize(SWT.DEFAULT, SWT.DEFAULT, true).y;
487     }
488
489     /* (non-Javadoc)
490      * @see org.eclipse.ui.internal.layout.IWindowTrim#getId()
491      */

492     public String JavaDoc getId() {
493         return id;
494     }
495
496     /* (non-Javadoc)
497      * @see org.eclipse.ui.internal.layout.IWindowTrim#getValidSides()
498      */

499     public int getValidSides() {
500         return SWT.BOTTOM | SWT.TOP | SWT.LEFT | SWT.RIGHT;
501     }
502
503     /* (non-Javadoc)
504      * @see org.eclipse.ui.internal.layout.IWindowTrim#getWidthHint()
505      */

506     public int getWidthHint() {
507         return getControl().computeSize(SWT.DEFAULT, SWT.DEFAULT, true).x;
508     }
509
510     /* (non-Javadoc)
511      * @see org.eclipse.ui.internal.layout.IWindowTrim#handleClose()
512      */

513     public void handleClose() {
514     }
515
516     /* (non-Javadoc)
517      * @see org.eclipse.ui.internal.layout.IWindowTrim#isCloseable()
518      */

519     public boolean isCloseable() {
520         return false;
521     }
522
523     /* (non-Javadoc)
524      * @see org.eclipse.ui.internal.layout.IWindowTrim#isResizeable()
525      */

526     public boolean isResizeable() {
527         return false;
528     }
529 }
530
Popular Tags