Mercurial > projects > dwt2
comparison org.eclipse.jface.databinding/src/org/eclipse/jface/internal/databinding/provisional/swt/TableUpdater.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) 2005, 2008 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.TableUpdater; | |
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.core.databinding.observable.list.IListChangeListener; | |
20 import org.eclipse.core.databinding.observable.list.IObservableList; | |
21 import org.eclipse.core.databinding.observable.list.ListChangeEvent; | |
22 import org.eclipse.core.databinding.observable.list.ListDiffEntry; | |
23 import org.eclipse.core.runtime.Assert; | |
24 import org.eclipse.swt.SWT; | |
25 import org.eclipse.swt.events.DisposeEvent; | |
26 import org.eclipse.swt.events.DisposeListener; | |
27 import org.eclipse.swt.widgets.Event; | |
28 import org.eclipse.swt.widgets.Listener; | |
29 import org.eclipse.swt.widgets.Table; | |
30 import org.eclipse.swt.widgets.TableItem; | |
31 | |
32 /** | |
33 * NON-API - This class can be used to update a table with automatic dependency | |
34 * tracking. | |
35 * | |
36 * @since 1.1 | |
37 * | |
38 * @noextend This class is not intended to be subclassed by clients. (We do | |
39 * encourage experimentation for non-production code and are | |
40 * interested in feedback though.) | |
41 * | |
42 */ | |
43 public abstract class TableUpdater { | |
44 | |
45 private class UpdateRunnable : Runnable, IChangeListener, | |
46 DisposeListener { | |
47 private TableItem item; | |
48 | |
49 private bool dirty = false; | |
50 | |
51 private IObservable[] dependencies = new IObservable[0]; | |
52 | |
53 private final Object element; | |
54 | |
55 this(TableItem item, Object element) { | |
56 this.item = item; | |
57 this.element = element; | |
58 item.addDisposeListener(this); | |
59 } | |
60 | |
61 // Runnable implementation. This method runs at most once per repaint | |
62 // whenever the | |
63 // value gets marked as dirty. | |
64 public void run() { | |
65 if (table !is null && !table.isDisposed() && item !is null | |
66 && !item.isDisposed()) { | |
67 if (table.isVisible()) { | |
68 int tableHeight = table.getClientArea().height; | |
69 int numVisibleItems = tableHeight / table.getItemHeight(); | |
70 int indexOfItem = table.indexOf(item); | |
71 int topIndex = table.getTopIndex(); | |
72 if (indexOfItem >= topIndex | |
73 && indexOfItem <= topIndex + numVisibleItems) { | |
74 updateIfNecessary(indexOfItem); | |
75 return; | |
76 } | |
77 } | |
78 table.clear(table.indexOf(item)); | |
79 } | |
80 } | |
81 | |
82 private void updateIfNecessary(int indexOfItem) { | |
83 if (dirty) { | |
84 dependencies = ObservableTracker.runAndMonitor(dgRunnable( (int indexOfItem_) { | |
85 updateItem(indexOfItem_, item, element); | |
86 }, indexOfItem), this, null); | |
87 dirty = false; | |
88 } | |
89 } | |
90 | |
91 // IChangeListener implementation (listening to the ComputedValue) | |
92 public void handleChange(ChangeEvent event) { | |
93 // Whenever this updator becomes dirty, schedule the run() method | |
94 makeDirty(); | |
95 } | |
96 | |
97 protected final void makeDirty() { | |
98 if (!dirty) { | |
99 dirty = true; | |
100 stopListening(); | |
101 SWTUtil.runOnce(table.getDisplay(), this); | |
102 } | |
103 } | |
104 | |
105 private void stopListening() { | |
106 // Stop listening for dependency changes | |
107 for (int i = 0; i < dependencies.length; i++) { | |
108 IObservable observable = dependencies[i]; | |
109 | |
110 observable.removeChangeListener(this); | |
111 } | |
112 } | |
113 | |
114 // DisposeListener implementation | |
115 public void widgetDisposed(DisposeEvent e) { | |
116 stopListening(); | |
117 dependencies = null; | |
118 item = null; | |
119 } | |
120 } | |
121 | |
122 private class PrivateInterface : Listener, DisposeListener { | |
123 | |
124 // Listener implementation | |
125 public void handleEvent(Event e) { | |
126 if (e.type is SWT.SetData) { | |
127 UpdateRunnable runnable = cast(UpdateRunnable) e.item.getData(); | |
128 if (runnable is null) { | |
129 runnable = new UpdateRunnable(cast(TableItem) e.item, list.get(e.index)); | |
130 e.item.setData(runnable); | |
131 runnable.makeDirty(); | |
132 } else { | |
133 runnable.updateIfNecessary(e.index); | |
134 } | |
135 } | |
136 } | |
137 | |
138 // DisposeListener implementation | |
139 public void widgetDisposed(DisposeEvent e) { | |
140 this.outer.dispose(); | |
141 } | |
142 | |
143 } | |
144 | |
145 private PrivateInterface privateInterface = new PrivateInterface(); | |
146 | |
147 private Table table; | |
148 | |
149 private IListChangeListener listChangeListener = new class() IListChangeListener { | |
150 public void handleListChange(ListChangeEvent event) { | |
151 ListDiffEntry[] differences = event.diff.getDifferences(); | |
152 for (int i = 0; i < differences.length; i++) { | |
153 ListDiffEntry entry = differences[i]; | |
154 if (entry.isAddition()) { | |
155 TableItem item = new TableItem(table, SWT.NONE, entry | |
156 .getPosition()); | |
157 UpdateRunnable updateRunnable = new UpdateRunnable(item, entry.getElement()); | |
158 item.setData(updateRunnable); | |
159 updateRunnable.makeDirty(); | |
160 } else { | |
161 table.getItem(entry.getPosition()).dispose(); | |
162 } | |
163 } | |
164 } | |
165 }; | |
166 | |
167 private IObservableList list; | |
168 | |
169 /** | |
170 * Creates an updator for the given control. | |
171 * | |
172 * @param table | |
173 * table to update | |
174 * @param list | |
175 * @since 1.2 | |
176 */ | |
177 public this(Table table, IObservableList list) { | |
178 this.table = table; | |
179 this.list = list; | |
180 Assert.isLegal((table.getStyle() & SWT.VIRTUAL) !is 0, | |
181 "TableUpdater requires virtual table"); //$NON-NLS-1$ | |
182 | |
183 table.setItemCount(list.size()); | |
184 list.addListChangeListener(listChangeListener); | |
185 | |
186 table.addDisposeListener(privateInterface); | |
187 table.addListener(SWT.SetData, privateInterface); | |
188 } | |
189 | |
190 /** | |
191 * This is called automatically when the control is disposed. It may also be | |
192 * called explicitly to remove this updator from the control. Subclasses | |
193 * will normally extend this method to detach any listeners they attached in | |
194 * their constructor. | |
195 */ | |
196 public void dispose() { | |
197 table.removeDisposeListener(privateInterface); | |
198 table.removeListener(SWT.SetData, privateInterface); | |
199 list.removeListChangeListener(listChangeListener); | |
200 table = null; | |
201 list = null; | |
202 } | |
203 | |
204 /** | |
205 * Updates the control. This method will be invoked once after the updator | |
206 * is created, and once before any repaint during which the control is | |
207 * visible and dirty. | |
208 * | |
209 * <p> | |
210 * Subclasses should overload this method to provide any code that changes | |
211 * the appearance of the widget. | |
212 * </p> | |
213 * | |
214 * @param index | |
215 * @param item | |
216 * the item to update | |
217 * @param element | |
218 * @since 1.2 | |
219 */ | |
220 protected abstract void updateItem(int index, TableItem item, Object element); | |
221 | |
222 } |