Mercurial > projects > dwt2
comparison org.eclipse.jface.databinding/src/org/eclipse/jface/internal/databinding/provisional/swt/MenuUpdater.d @ 78:0a55d2d5a946
Added file for databinding
author | Frank Benoit <benoit@tionex.de> |
---|---|
date | Tue, 14 Apr 2009 11:35:29 +0200 |
parents | |
children | 6be48cf9f95c |
comparison
equal
deleted
inserted
replaced
76:f05e6e8b2f2d | 78:0a55d2d5a946 |
---|---|
1 /******************************************************************************* | |
2 * Copyright (c) 2006, 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 module org.eclipse.jface.internal.databinding.provisional.swt.MenuUpdater; | |
12 | |
13 import java.lang.all; | |
14 | |
15 import org.eclipse.core.databinding.observable.ChangeEvent; | |
16 import org.eclipse.core.databinding.observable.IChangeListener; | |
17 import org.eclipse.core.databinding.observable.IObservable; | |
18 import org.eclipse.core.databinding.observable.ObservableTracker; | |
19 import org.eclipse.swt.events.DisposeEvent; | |
20 import org.eclipse.swt.events.DisposeListener; | |
21 import org.eclipse.swt.events.MenuEvent; | |
22 import org.eclipse.swt.events.MenuListener; | |
23 import org.eclipse.swt.widgets.Menu; | |
24 | |
25 /** | |
26 * NON-API - A MenuUpdater updates an SWT menu in response to changes in the model. By | |
27 * wrapping a block of code in a MenuUpdater, clients can rely on the fact that | |
28 * the block of code will be re-executed whenever anything changes in the model | |
29 * that might affect its behavior. | |
30 * | |
31 * <p> | |
32 * MenuUpdaters only execute once their menus are shown. If something changes in | |
33 * the model, the updater is flagged as dirty and it stops listening to the | |
34 * model until the next time the menu is shown. If the menu is visible while the | |
35 * model changes, it will be updated right away. | |
36 * </p> | |
37 * | |
38 * <p> | |
39 * Clients should subclass this when copying information from the model to a | |
40 * menu. Typical usage: | |
41 * </p> | |
42 * | |
43 * <ul> | |
44 * <li>Override updateMenu. It should do whatever is necessary to display the | |
45 * contents of the model in the menu.</li> | |
46 * <li>In the constructor, attach listeners to the model. The listeners should | |
47 * call markDirty whenever anything changes in the model that affects | |
48 * updateMenu. Note: this step can be omitted when calling any method tagged | |
49 * with "@TrackedGetter" since MenuUpdater will automatically attach a listener | |
50 * to any object if a "@TrackedGetter" method is called in updateMenu.</li> | |
51 * <li>(optional)Extend dispose() to remove any listeners attached in the | |
52 * constructor</li> | |
53 * </ul> | |
54 * | |
55 * @since 1.1 | |
56 */ | |
57 public abstract class MenuUpdater { | |
58 | |
59 private class PrivateInterface : MenuListener, | |
60 DisposeListener, Runnable, IChangeListener { | |
61 | |
62 // DisposeListener implementation | |
63 public void widgetDisposed(DisposeEvent e) { | |
64 this.outer.dispose(); | |
65 } | |
66 | |
67 // Runnable implementation. This method runs at most once per repaint whenever the | |
68 // value gets marked as dirty. | |
69 public void run() { | |
70 if (theMenu !is null && !theMenu.isDisposed() && theMenu.isVisible()) { | |
71 updateIfNecessary(); | |
72 } | |
73 } | |
74 | |
75 // IChangeListener implementation (listening to the ComputedValue) | |
76 public void handleChange(ChangeEvent event) { | |
77 // Whenever this updator becomes dirty, schedule the run() method | |
78 makeDirty(); | |
79 } | |
80 | |
81 public void menuHidden(MenuEvent e) { | |
82 // do nothing | |
83 } | |
84 | |
85 public void menuShown(MenuEvent e) { | |
86 updateIfNecessary(); | |
87 } | |
88 | |
89 } | |
90 | |
91 private Runnable updateRunnable = new class() Runnable { | |
92 public void run() { | |
93 updateMenu(); | |
94 } | |
95 }; | |
96 | |
97 private PrivateInterface privateInterface = new PrivateInterface(); | |
98 private Menu theMenu; | |
99 private IObservable[] dependencies = new IObservable[0]; | |
100 private bool dirty = false; | |
101 | |
102 /** | |
103 * Creates an updator for the given menu. | |
104 * | |
105 * @param toUpdate menu to update | |
106 */ | |
107 public this(Menu toUpdate) { | |
108 theMenu = toUpdate; | |
109 | |
110 theMenu.addDisposeListener(privateInterface); | |
111 theMenu.addMenuListener(privateInterface); | |
112 makeDirty(); | |
113 } | |
114 | |
115 private void updateIfNecessary() { | |
116 if (dirty) { | |
117 dependencies = ObservableTracker.runAndMonitor(updateRunnable, privateInterface, null); | |
118 dirty = false; | |
119 } | |
120 } | |
121 | |
122 /** | |
123 * This is called automatically when the menu is disposed. It may also | |
124 * be called explicitly to remove this updator from the menu. Subclasses | |
125 * will normally extend this method to detach any listeners they attached | |
126 * in their constructor. | |
127 */ | |
128 public void dispose() { | |
129 theMenu.removeDisposeListener(privateInterface); | |
130 theMenu.removeMenuListener(privateInterface); | |
131 | |
132 stopListening(); | |
133 } | |
134 | |
135 private void stopListening() { | |
136 // Stop listening for dependency changes | |
137 for (int i = 0; i < dependencies.length; i++) { | |
138 IObservable observable = dependencies[i]; | |
139 | |
140 observable.removeChangeListener(privateInterface); | |
141 } | |
142 } | |
143 | |
144 /** | |
145 * Updates the menu. This method will be invoked once after the | |
146 * updater is created, and once for any SWT.Show event if this | |
147 * updater is marked as dirty at that time. | |
148 * | |
149 * <p> | |
150 * Subclasses should overload this method to provide any code that | |
151 * udates the menu. | |
152 * </p> | |
153 */ | |
154 protected abstract void updateMenu(); | |
155 | |
156 /** | |
157 * Marks this updator as dirty. Causes the updateControl method to | |
158 * be invoked before the next time the control is repainted. | |
159 */ | |
160 protected final void makeDirty() { | |
161 if (!dirty) { | |
162 dirty = true; | |
163 stopListening(); | |
164 SWTUtil.runOnce(theMenu.getDisplay(), privateInterface); | |
165 } | |
166 } | |
167 | |
168 } |