Mercurial > projects > dwt-addons
annotate dwtx/jface/action/ToolBarManager.d @ 104:04b47443bb01
Reworked the collection uses to make use of a wrapper collection that is compatible to the Java Collections.
These new wrappers now use the tango.util.containers instead of the tango.util.collections.
author | Frank Benoit <benoit@tionex.de> |
---|---|
date | Thu, 07 Aug 2008 15:01:33 +0200 |
parents | 5df4896124c7 |
children |
rev | line source |
---|---|
25 | 1 /******************************************************************************* |
2 * Copyright (c) 2000, 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 * Port to the D programming language: | |
11 * Frank Benoit <benoit@tionex.de> | |
12 *******************************************************************************/ | |
13 module dwtx.jface.action.ToolBarManager; | |
14 | |
15 import dwtx.jface.action.ContributionManager; | |
16 import dwtx.jface.action.IToolBarManager; | |
17 import dwtx.jface.action.MenuManager; | |
18 import dwtx.jface.action.IContributionItem; | |
19 | |
20 // import java.util.Iterator; | |
21 | |
22 import dwt.DWT; | |
23 import dwt.accessibility.ACC; | |
24 import dwt.accessibility.AccessibleAdapter; | |
25 import dwt.accessibility.AccessibleEvent; | |
26 import dwt.accessibility.AccessibleListener; | |
70
46a6e0e6ccd4
Merge with d-fied sources of 3.4M7
Frank Benoit <benoit@tionex.de>
parents:
25
diff
changeset
|
27 import dwt.graphics.Point; |
25 | 28 import dwt.widgets.Composite; |
29 import dwt.widgets.Control; | |
70
46a6e0e6ccd4
Merge with d-fied sources of 3.4M7
Frank Benoit <benoit@tionex.de>
parents:
25
diff
changeset
|
30 import dwt.widgets.CoolBar; |
46a6e0e6ccd4
Merge with d-fied sources of 3.4M7
Frank Benoit <benoit@tionex.de>
parents:
25
diff
changeset
|
31 import dwt.widgets.CoolItem; |
25 | 32 import dwt.widgets.Menu; |
33 import dwt.widgets.ToolBar; | |
34 import dwt.widgets.ToolItem; | |
35 | |
36 import dwt.dwthelper.utils; | |
104
04b47443bb01
Reworked the collection uses to make use of a wrapper collection that is compatible to the Java Collections.
Frank Benoit <benoit@tionex.de>
parents:
72
diff
changeset
|
37 import dwtx.dwtxhelper.Collection; |
25 | 38 |
39 /** | |
40 * A tool bar manager is a contribution manager which realizes itself and its | |
41 * items in a tool bar control. | |
42 * <p> | |
43 * This class may be instantiated; it may also be subclassed if a more | |
44 * sophisticated layout is required. | |
45 * </p> | |
46 */ | |
47 public class ToolBarManager : ContributionManager, | |
48 IToolBarManager { | |
49 | |
50 /** | |
51 * The tool bar items style; <code>DWT.NONE</code> by default. | |
52 */ | |
53 private int itemStyle = DWT.NONE; | |
54 | |
55 /** | |
56 * The tool bat control; <code>null</code> before creation and after | |
57 * disposal. | |
58 */ | |
59 private ToolBar toolBar = null; | |
60 | |
61 /** | |
62 * The menu manager to the context menu associated with the toolbar. | |
63 * | |
64 * @since 3.0 | |
65 */ | |
66 private MenuManager contextMenuManager = null; | |
67 | |
68 /** | |
69 * Creates a new tool bar manager with the default DWT button style. Use the | |
70 * {@link #createControl(Composite)} method to create the tool bar control. | |
71 * | |
72 */ | |
73 public this() { | |
74 //Do nothing if there are no parameters | |
75 } | |
76 | |
77 /** | |
78 * Creates a tool bar manager with the given DWT button style. Use the | |
79 * <code>createControl</code> method to create the tool bar control. | |
80 * | |
81 * @param style | |
82 * the tool bar item style | |
83 * @see dwt.widgets.ToolBar for valid style bits | |
84 */ | |
85 public this(int style) { | |
86 itemStyle = style; | |
87 } | |
88 | |
89 /** | |
90 * Creates a tool bar manager for an existing tool bar control. This manager | |
91 * becomes responsible for the control, and will dispose of it when the | |
92 * manager is disposed. | |
93 * <strong>NOTE</strong> When creating a ToolBarManager from an existing | |
94 * {@link ToolBar} you will not get the accessible listener provided by | |
95 * JFace. | |
96 * @see #ToolBarManager() | |
97 * @see #ToolBarManager(int) | |
98 * | |
99 * @param toolbar | |
100 * the tool bar control | |
101 */ | |
102 public this(ToolBar toolbar) { | |
103 this(); | |
104 this.toolBar = toolbar; | |
105 } | |
106 | |
107 /** | |
108 * Creates and returns this manager's tool bar control. Does not create a | |
109 * new control if one already exists. Also create an {@link AccessibleListener} | |
110 * for the {@link ToolBar}. | |
111 * | |
112 * @param parent | |
113 * the parent control | |
114 * @return the tool bar control | |
115 */ | |
116 public ToolBar createControl(Composite parent) { | |
117 if (!toolBarExist() && parent !is null) { | |
118 toolBar = new ToolBar(parent, itemStyle); | |
119 toolBar.setMenu(getContextMenuControl()); | |
120 update(true); | |
121 | |
122 toolBar.getAccessible().addAccessibleListener(getAccessibleListener()); | |
123 } | |
124 | |
125 return toolBar; | |
126 } | |
127 | |
128 /** | |
129 * Get the accessible listener for the tool bar. | |
130 * | |
131 * @return AccessibleListener | |
132 * | |
133 * @since 3.1 | |
134 */ | |
135 private AccessibleListener getAccessibleListener() { | |
136 return new class AccessibleAdapter { | |
137 public void getName(AccessibleEvent e) { | |
138 if (e.childID !is ACC.CHILDID_SELF) { | |
139 ToolItem item = toolBar.getItem(e.childID); | |
140 if (item !is null) { | |
141 String toolTip = item.getToolTipText(); | |
142 if (toolTip !is null) { | |
143 e.result = toolTip; | |
144 } | |
145 } | |
146 } | |
147 } | |
148 }; | |
149 } | |
150 | |
151 /** | |
152 * Disposes of this tool bar manager and frees all allocated DWT resources. | |
153 * Notifies all contribution items of the dispose. Note that this method | |
154 * does not clean up references between this tool bar manager and its | |
155 * associated contribution items. Use <code>removeAll</code> for that | |
156 * purpose. | |
157 */ | |
158 public void dispose() { | |
159 | |
160 if (toolBarExist()) { | |
161 toolBar.dispose(); | |
162 } | |
163 toolBar = null; | |
164 | |
165 IContributionItem[] items = getItems(); | |
166 for (int i = 0; i < items.length; i++) { | |
167 items[i].dispose(); | |
168 } | |
169 | |
170 if (getContextMenuManager() !is null) { | |
171 getContextMenuManager().dispose(); | |
172 setContextMenuManager(null); | |
173 } | |
174 } | |
175 | |
176 /** | |
177 * Returns the tool bar control for this manager. | |
178 * | |
179 * @return the tool bar control, or <code>null</code> if none (before | |
180 * creating or after disposal) | |
181 */ | |
182 public ToolBar getControl() { | |
183 return toolBar; | |
184 } | |
185 | |
186 /** | |
187 * Re-lays out the tool bar. | |
188 * <p> | |
189 * The default implementation of this framework method re-lays out the | |
70
46a6e0e6ccd4
Merge with d-fied sources of 3.4M7
Frank Benoit <benoit@tionex.de>
parents:
25
diff
changeset
|
190 * parent when the number of items are different and the new count !is 0 |
25 | 191 * |
192 * @param layoutBar | |
193 * the tool bar control | |
194 * @param oldCount | |
195 * the old number of items | |
196 * @param newCount | |
197 * the new number of items | |
198 */ | |
199 protected void relayout(ToolBar layoutBar, int oldCount, int newCount) { | |
71 | 200 if ((oldCount !is newCount) && (newCount!is 0)) { |
70
46a6e0e6ccd4
Merge with d-fied sources of 3.4M7
Frank Benoit <benoit@tionex.de>
parents:
25
diff
changeset
|
201 Point beforePack = layoutBar.getSize(); |
46a6e0e6ccd4
Merge with d-fied sources of 3.4M7
Frank Benoit <benoit@tionex.de>
parents:
25
diff
changeset
|
202 layoutBar.pack(true); |
46a6e0e6ccd4
Merge with d-fied sources of 3.4M7
Frank Benoit <benoit@tionex.de>
parents:
25
diff
changeset
|
203 Point afterPack = layoutBar.getSize(); |
71 | 204 |
70
46a6e0e6ccd4
Merge with d-fied sources of 3.4M7
Frank Benoit <benoit@tionex.de>
parents:
25
diff
changeset
|
205 // If the TB didn't change size then we're done |
72
5df4896124c7
JFace and its examples do compile
Frank Benoit <benoit@tionex.de>
parents:
71
diff
changeset
|
206 if (beforePack.opEquals(afterPack)) |
70
46a6e0e6ccd4
Merge with d-fied sources of 3.4M7
Frank Benoit <benoit@tionex.de>
parents:
25
diff
changeset
|
207 return; |
71 | 208 |
70
46a6e0e6ccd4
Merge with d-fied sources of 3.4M7
Frank Benoit <benoit@tionex.de>
parents:
25
diff
changeset
|
209 // OK, we need to re-layout the TB |
25 | 210 layoutBar.getParent().layout(); |
71 | 211 |
70
46a6e0e6ccd4
Merge with d-fied sources of 3.4M7
Frank Benoit <benoit@tionex.de>
parents:
25
diff
changeset
|
212 // Now, if we're in a CoolBar then change the CoolItem size as well |
71 | 213 if (null !is cast(CoolBar)layoutBar.getParent() ) { |
214 CoolBar cb = cast(CoolBar) layoutBar.getParent(); | |
70
46a6e0e6ccd4
Merge with d-fied sources of 3.4M7
Frank Benoit <benoit@tionex.de>
parents:
25
diff
changeset
|
215 CoolItem[] items = cb.getItems(); |
46a6e0e6ccd4
Merge with d-fied sources of 3.4M7
Frank Benoit <benoit@tionex.de>
parents:
25
diff
changeset
|
216 for (int i = 0; i < items.length; i++) { |
46a6e0e6ccd4
Merge with d-fied sources of 3.4M7
Frank Benoit <benoit@tionex.de>
parents:
25
diff
changeset
|
217 if (items[i].getControl() is layoutBar) { |
46a6e0e6ccd4
Merge with d-fied sources of 3.4M7
Frank Benoit <benoit@tionex.de>
parents:
25
diff
changeset
|
218 Point curSize = items[i].getSize(); |
46a6e0e6ccd4
Merge with d-fied sources of 3.4M7
Frank Benoit <benoit@tionex.de>
parents:
25
diff
changeset
|
219 items[i].setSize(curSize.x+ (afterPack.x - beforePack.x), |
46a6e0e6ccd4
Merge with d-fied sources of 3.4M7
Frank Benoit <benoit@tionex.de>
parents:
25
diff
changeset
|
220 curSize.y+ (afterPack.y - beforePack.y)); |
46a6e0e6ccd4
Merge with d-fied sources of 3.4M7
Frank Benoit <benoit@tionex.de>
parents:
25
diff
changeset
|
221 return; |
46a6e0e6ccd4
Merge with d-fied sources of 3.4M7
Frank Benoit <benoit@tionex.de>
parents:
25
diff
changeset
|
222 } |
46a6e0e6ccd4
Merge with d-fied sources of 3.4M7
Frank Benoit <benoit@tionex.de>
parents:
25
diff
changeset
|
223 } |
46a6e0e6ccd4
Merge with d-fied sources of 3.4M7
Frank Benoit <benoit@tionex.de>
parents:
25
diff
changeset
|
224 } |
25 | 225 } |
226 } | |
227 | |
228 /** | |
229 * Returns whether the tool bar control is created and not disposed. | |
230 * | |
231 * @return <code>true</code> if the control is created and not disposed, | |
232 * <code>false</code> otherwise | |
233 */ | |
234 private bool toolBarExist() { | |
235 return toolBar !is null && !toolBar.isDisposed(); | |
236 } | |
237 | |
238 /* | |
239 * (non-Javadoc) Method declared on IContributionManager. | |
240 */ | |
241 public void update(bool force) { | |
242 | |
243 // long startTime= 0; | |
244 // if (DEBUG) { | |
245 // dumpStatistics(); | |
246 // startTime= (new Date()).getTime(); | |
247 // } | |
248 | |
249 if (isDirty() || force) { | |
250 | |
251 if (toolBarExist()) { | |
252 | |
253 int oldCount = toolBar.getItemCount(); | |
254 | |
255 // clean contains all active items without double separators | |
256 IContributionItem[] items = getItems(); | |
104
04b47443bb01
Reworked the collection uses to make use of a wrapper collection that is compatible to the Java Collections.
Frank Benoit <benoit@tionex.de>
parents:
72
diff
changeset
|
257 ArrayList clean = new ArrayList(items.length); |
25 | 258 IContributionItem separator = null; |
259 // long cleanStartTime= 0; | |
260 // if (DEBUG) { | |
261 // cleanStartTime= (new Date()).getTime(); | |
262 // } | |
263 for (int i = 0; i < items.length; ++i) { | |
264 IContributionItem ci = items[i]; | |
265 if (!ci.isVisible()) { | |
266 continue; | |
267 } | |
268 if (ci.isSeparator()) { | |
269 // delay creation until necessary | |
270 // (handles both adjacent separators, and separator at | |
271 // end) | |
272 separator = ci; | |
273 } else { | |
274 if (separator !is null) { | |
275 if (clean.size() > 0) { | |
104
04b47443bb01
Reworked the collection uses to make use of a wrapper collection that is compatible to the Java Collections.
Frank Benoit <benoit@tionex.de>
parents:
72
diff
changeset
|
276 clean.add(cast(Object)separator); |
25 | 277 } |
278 separator = null; | |
279 } | |
104
04b47443bb01
Reworked the collection uses to make use of a wrapper collection that is compatible to the Java Collections.
Frank Benoit <benoit@tionex.de>
parents:
72
diff
changeset
|
280 clean.add(cast(Object)ci); |
25 | 281 } |
282 } | |
283 // if (DEBUG) { | |
284 // System.out.println(" Time needed to build clean vector: " + | |
285 // ((new Date()).getTime() - cleanStartTime)); | |
286 // } | |
287 | |
288 // determine obsolete items (removed or non active) | |
289 ToolItem[] mi = toolBar.getItems(); | |
104
04b47443bb01
Reworked the collection uses to make use of a wrapper collection that is compatible to the Java Collections.
Frank Benoit <benoit@tionex.de>
parents:
72
diff
changeset
|
290 ArrayList toRemove = new ArrayList(mi.length); |
25 | 291 for (int i = 0; i < mi.length; i++) { |
292 Object data = mi[i].getData(); | |
293 if (data is null | |
294 || !clean.contains(data) | |
295 || (cast(IContributionItem) data && (cast(IContributionItem) data) | |
296 .isDynamic())) { | |
104
04b47443bb01
Reworked the collection uses to make use of a wrapper collection that is compatible to the Java Collections.
Frank Benoit <benoit@tionex.de>
parents:
72
diff
changeset
|
297 toRemove.add(mi[i]); |
25 | 298 } |
299 } | |
300 | |
301 // Turn redraw off if the number of items to be added | |
302 // is above a certain threshold, to minimize flicker, | |
303 // otherwise the toolbar can be seen to redraw after each item. | |
304 // Do this before any modifications are made. | |
305 // We assume each contribution item will contribute at least one | |
306 // toolbar item. | |
307 bool useRedraw = (clean.size() - (mi.length - toRemove | |
308 .size())) >= 3; | |
309 try { | |
310 if (useRedraw) { | |
311 toolBar.setRedraw(false); | |
312 } | |
313 | |
314 // remove obsolete items | |
315 for (int i = toRemove.size(); --i >= 0;) { | |
316 ToolItem item = cast(ToolItem) toRemove.get(i); | |
317 if (!item.isDisposed()) { | |
318 Control ctrl = item.getControl(); | |
319 if (ctrl !is null) { | |
320 item.setControl(null); | |
321 ctrl.dispose(); | |
322 } | |
323 item.dispose(); | |
324 } | |
325 } | |
326 | |
327 // add new items | |
328 IContributionItem src, dest; | |
329 mi = toolBar.getItems(); | |
330 int srcIx = 0; | |
331 int destIx = 0; | |
104
04b47443bb01
Reworked the collection uses to make use of a wrapper collection that is compatible to the Java Collections.
Frank Benoit <benoit@tionex.de>
parents:
72
diff
changeset
|
332 for (Iterator e = clean.iterator(); e.hasNext();) { |
04b47443bb01
Reworked the collection uses to make use of a wrapper collection that is compatible to the Java Collections.
Frank Benoit <benoit@tionex.de>
parents:
72
diff
changeset
|
333 src = cast(IContributionItem) e.next(); |
04b47443bb01
Reworked the collection uses to make use of a wrapper collection that is compatible to the Java Collections.
Frank Benoit <benoit@tionex.de>
parents:
72
diff
changeset
|
334 |
25 | 335 |
336 // get corresponding item in DWT widget | |
337 if (srcIx < mi.length) { | |
338 dest = cast(IContributionItem) mi[srcIx].getData(); | |
339 } else { | |
340 dest = null; | |
341 } | |
342 | |
343 if (dest !is null && (cast(Object)src).opEquals(cast(Object)dest)) { | |
344 srcIx++; | |
345 destIx++; | |
346 continue; | |
347 } | |
348 | |
349 if (dest !is null && dest.isSeparator() | |
350 && src.isSeparator()) { | |
351 mi[srcIx].setData(cast(Object)src); | |
352 srcIx++; | |
353 destIx++; | |
354 continue; | |
355 } | |
356 | |
357 int start = toolBar.getItemCount(); | |
358 src.fill(toolBar, destIx); | |
359 int newItems = toolBar.getItemCount() - start; | |
360 for (int i = 0; i < newItems; i++) { | |
361 ToolItem item = toolBar.getItem(destIx++); | |
362 item.setData(cast(Object)src); | |
363 } | |
364 } | |
365 | |
366 // remove any old tool items not accounted for | |
367 for (int i = mi.length; --i >= srcIx;) { | |
368 ToolItem item = mi[i]; | |
369 if (!item.isDisposed()) { | |
370 Control ctrl = item.getControl(); | |
371 if (ctrl !is null) { | |
372 item.setControl(null); | |
373 ctrl.dispose(); | |
374 } | |
375 item.dispose(); | |
376 } | |
377 } | |
378 | |
379 setDirty(false); | |
380 | |
381 // turn redraw back on if we turned it off above | |
382 } finally { | |
383 if (useRedraw) { | |
384 toolBar.setRedraw(true); | |
385 } | |
386 } | |
387 | |
388 int newCount = toolBar.getItemCount(); | |
71 | 389 |
70
46a6e0e6ccd4
Merge with d-fied sources of 3.4M7
Frank Benoit <benoit@tionex.de>
parents:
25
diff
changeset
|
390 // If we're forcing a change then ensure that we re-layout everything |
46a6e0e6ccd4
Merge with d-fied sources of 3.4M7
Frank Benoit <benoit@tionex.de>
parents:
25
diff
changeset
|
391 if (force) |
46a6e0e6ccd4
Merge with d-fied sources of 3.4M7
Frank Benoit <benoit@tionex.de>
parents:
25
diff
changeset
|
392 oldCount = newCount+1; |
71 | 393 |
25 | 394 relayout(toolBar, oldCount, newCount); |
395 } | |
396 | |
397 } | |
398 | |
399 // if (DEBUG) { | |
400 // System.out.println(" Time needed for update: " + ((new | |
401 // Date()).getTime() - startTime)); | |
402 // System.out.println(); | |
403 // } | |
404 } | |
405 | |
406 /** | |
407 * Returns the control of the Menu Manager. If the menu manager does not | |
408 * have a control then one is created. | |
409 * | |
410 * @return menu widget associated with manager | |
411 */ | |
412 private Menu getContextMenuControl() { | |
413 if ((contextMenuManager !is null) && (toolBar !is null)) { | |
414 Menu menuWidget = contextMenuManager.getMenu(); | |
415 if ((menuWidget is null) || (menuWidget.isDisposed())) { | |
416 menuWidget = contextMenuManager.createContextMenu(toolBar); | |
417 } | |
418 return menuWidget; | |
419 } | |
420 return null; | |
421 } | |
422 | |
423 /** | |
424 * Returns the context menu manager for this tool bar manager. | |
425 * | |
426 * @return the context menu manager, or <code>null</code> if none | |
427 * @since 3.0 | |
428 */ | |
429 public MenuManager getContextMenuManager() { | |
430 return contextMenuManager; | |
431 } | |
432 | |
433 /** | |
434 * Sets the context menu manager for this tool bar manager to the given menu | |
435 * manager. If the tool bar control exists, it also adds the menu control to | |
436 * the tool bar. | |
437 * | |
438 * @param contextMenuManager | |
439 * the context menu manager, or <code>null</code> if none | |
440 * @since 3.0 | |
441 */ | |
442 public void setContextMenuManager(MenuManager contextMenuManager) { | |
443 this.contextMenuManager = contextMenuManager; | |
444 if (toolBar !is null) { | |
445 toolBar.setMenu(getContextMenuControl()); | |
446 } | |
447 } | |
448 | |
449 } |