Mercurial > projects > dwt-addons
annotate dwtx/jface/viewers/DialogCellEditor.d @ 43:ea8ff534f622
Fix override and super aliases
author | Frank Benoit <benoit@tionex.de> |
---|---|
date | Fri, 11 Apr 2008 01:24:25 +0200 |
parents | 4567a6f54939 |
children |
rev | line source |
---|---|
10 | 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.viewers.DialogCellEditor; | |
14 | |
15 import dwtx.jface.viewers.CellEditor; | |
16 | |
17 import dwt.DWT; | |
18 import dwt.events.FocusEvent; | |
19 import dwt.events.FocusListener; | |
20 import dwt.events.KeyAdapter; | |
21 import dwt.events.KeyEvent; | |
22 import dwt.events.SelectionAdapter; | |
23 import dwt.events.SelectionEvent; | |
24 import dwt.graphics.Color; | |
25 import dwt.graphics.Font; | |
26 import dwt.graphics.Point; | |
27 import dwt.graphics.Rectangle; | |
28 import dwt.widgets.Button; | |
29 import dwt.widgets.Composite; | |
30 import dwt.widgets.Control; | |
31 import dwt.widgets.Label; | |
32 import dwt.widgets.Layout; | |
33 import dwtx.jface.resource.ImageDescriptor; | |
34 import dwtx.jface.resource.ImageRegistry; | |
35 import dwtx.jface.resource.JFaceResources; | |
36 | |
37 import dwt.dwthelper.utils; | |
38 import tango.text.convert.Format; | |
39 | |
40 /** | |
41 * An abstract cell editor that uses a dialog. | |
42 * Dialog cell editors usually have a label control on the left and a button on | |
43 * the right. Pressing the button opens a dialog window (for example, a color dialog | |
44 * or a file dialog) to change the cell editor's value. | |
45 * The cell editor's value is the value of the dialog. | |
46 * <p> | |
47 * Subclasses may override the following methods: | |
48 * <ul> | |
49 * <li><code>createButton</code>: creates the cell editor's button control</li> | |
50 * <li><code>createContents</code>: creates the cell editor's 'display value' control</li> | |
51 * <li><code>updateContents</code>: updates the cell editor's 'display value' control | |
52 * after its value has changed</li> | |
53 * <li><code>openDialogBox</code>: opens the dialog box when the end user presses | |
54 * the button</li> | |
55 * </ul> | |
56 * </p> | |
57 */ | |
58 public abstract class DialogCellEditor : CellEditor { | |
59 | |
60 /** | |
61 * Image registry key for three dot image (value <code>"cell_editor_dots_button_image"</code>). | |
62 */ | |
63 public static const String CELL_EDITOR_IMG_DOTS_BUTTON = "cell_editor_dots_button_image";//$NON-NLS-1$ | |
64 | |
65 /** | |
66 * The editor control. | |
67 */ | |
68 private Composite editor; | |
69 | |
70 /** | |
71 * The current contents. | |
72 */ | |
73 private Control contents; | |
74 | |
75 /** | |
76 * The label that gets reused by <code>updateLabel</code>. | |
77 */ | |
78 private Label defaultLabel; | |
79 | |
80 /** | |
81 * The button. | |
82 */ | |
83 private Button button; | |
84 | |
85 /** | |
86 * Listens for 'focusLost' events and fires the 'apply' event as long | |
87 * as the focus wasn't lost because the dialog was opened. | |
88 */ | |
89 private FocusListener buttonFocusListener; | |
90 | |
91 /** | |
92 * The value of this cell editor; initially <code>null</code>. | |
93 */ | |
94 private Object value = null; | |
95 | |
96 static this() { | |
97 ImageRegistry reg = JFaceResources.getImageRegistry(); | |
98 reg.put(CELL_EDITOR_IMG_DOTS_BUTTON, ImageDescriptor.createFromFile( | |
42 | 99 getImportData!("dwtx.jface.images.dots_button.gif")));//$NON-NLS-1$ |
10 | 100 } |
101 | |
102 /** | |
103 * Internal class for laying out the dialog. | |
104 */ | |
105 private class DialogCellLayout : Layout { | |
43
ea8ff534f622
Fix override and super aliases
Frank Benoit <benoit@tionex.de>
parents:
42
diff
changeset
|
106 public override void layout(Composite editor, bool force) { |
10 | 107 Rectangle bounds = editor.getClientArea(); |
108 Point size = button.computeSize(DWT.DEFAULT, DWT.DEFAULT, force); | |
109 if (contents !is null) { | |
110 contents.setBounds(0, 0, bounds.width - size.x, bounds.height); | |
111 } | |
112 button.setBounds(bounds.width - size.x, 0, size.x, bounds.height); | |
113 } | |
114 | |
43
ea8ff534f622
Fix override and super aliases
Frank Benoit <benoit@tionex.de>
parents:
42
diff
changeset
|
115 public override Point computeSize(Composite editor, int wHint, int hHint, |
10 | 116 bool force) { |
117 if (wHint !is DWT.DEFAULT && hHint !is DWT.DEFAULT) { | |
118 return new Point(wHint, hHint); | |
119 } | |
120 Point contentsSize = contents.computeSize(DWT.DEFAULT, DWT.DEFAULT, | |
121 force); | |
122 Point buttonSize = button.computeSize(DWT.DEFAULT, DWT.DEFAULT, | |
123 force); | |
124 // Just return the button width to ensure the button is not clipped | |
125 // if the label is long. | |
126 // The label will just use whatever extra width there is | |
127 Point result = new Point(buttonSize.x, Math.max(contentsSize.y, | |
128 buttonSize.y)); | |
129 return result; | |
130 } | |
131 } | |
132 | |
133 /** | |
134 * Default DialogCellEditor style | |
135 */ | |
136 private static const int defaultStyle = DWT.NONE; | |
137 | |
138 /** | |
139 * Creates a new dialog cell editor with no control | |
140 * @since 2.1 | |
141 */ | |
142 public this() { | |
143 setStyle(defaultStyle); | |
144 } | |
145 | |
146 /** | |
147 * Creates a new dialog cell editor parented under the given control. | |
148 * The cell editor value is <code>null</code> initially, and has no | |
149 * validator. | |
150 * | |
151 * @param parent the parent control | |
152 */ | |
153 protected this(Composite parent) { | |
154 this(parent, defaultStyle); | |
155 } | |
156 | |
157 /** | |
158 * Creates a new dialog cell editor parented under the given control. | |
159 * The cell editor value is <code>null</code> initially, and has no | |
160 * validator. | |
161 * | |
162 * @param parent the parent control | |
163 * @param style the style bits | |
164 * @since 2.1 | |
165 */ | |
166 protected this(Composite parent, int style) { | |
167 super(parent, style); | |
168 } | |
169 | |
170 /** | |
171 * Creates the button for this cell editor under the given parent control. | |
172 * <p> | |
173 * The default implementation of this framework method creates the button | |
174 * display on the right hand side of the dialog cell editor. Subclasses | |
175 * may extend or reimplement. | |
176 * </p> | |
177 * | |
178 * @param parent the parent control | |
179 * @return the new button control | |
180 */ | |
181 protected Button createButton(Composite parent) { | |
182 Button result = new Button(parent, DWT.DOWN); | |
183 result.setText("..."); //$NON-NLS-1$ | |
184 return result; | |
185 } | |
186 | |
187 /** | |
188 * Creates the controls used to show the value of this cell editor. | |
189 * <p> | |
190 * The default implementation of this framework method creates | |
191 * a label widget, using the same font and background color as the parent control. | |
192 * </p> | |
193 * <p> | |
194 * Subclasses may reimplement. If you reimplement this method, you | |
195 * should also reimplement <code>updateContents</code>. | |
196 * </p> | |
197 * | |
198 * @param cell the control for this cell editor | |
199 * @return the underlying control | |
200 */ | |
201 protected Control createContents(Composite cell) { | |
202 defaultLabel = new Label(cell, DWT.LEFT); | |
203 defaultLabel.setFont(cell.getFont()); | |
204 defaultLabel.setBackground(cell.getBackground()); | |
205 return defaultLabel; | |
206 } | |
207 | |
208 /* (non-Javadoc) | |
209 * Method declared on CellEditor. | |
210 */ | |
43
ea8ff534f622
Fix override and super aliases
Frank Benoit <benoit@tionex.de>
parents:
42
diff
changeset
|
211 protected override Control createControl(Composite parent) { |
10 | 212 |
213 Font font = parent.getFont(); | |
214 Color bg = parent.getBackground(); | |
215 | |
216 editor = new Composite(parent, getStyle()); | |
217 editor.setFont(font); | |
218 editor.setBackground(bg); | |
219 editor.setLayout(new DialogCellLayout()); | |
220 | |
221 contents = createContents(editor); | |
222 updateContents(value); | |
223 | |
224 button = createButton(editor); | |
225 button.setFont(font); | |
226 | |
227 button.addKeyListener(new class KeyAdapter { | |
228 /* (non-Javadoc) | |
229 * @see dwt.events.KeyListener#keyReleased(dwt.events.KeyEvent) | |
230 */ | |
231 public void keyReleased(KeyEvent e) { | |
232 if (e.character is '\u001b') { // Escape | |
233 fireCancelEditor(); | |
234 } | |
235 } | |
236 }); | |
237 | |
238 button.addFocusListener(getButtonFocusListener()); | |
239 | |
240 button.addSelectionListener(new class SelectionAdapter { | |
241 /* (non-Javadoc) | |
242 * @see dwt.events.SelectionListener#widgetSelected(dwt.events.SelectionEvent) | |
243 */ | |
244 public void widgetSelected(SelectionEvent event) { | |
245 // Remove the button's focus listener since it's guaranteed | |
246 // to lose focus when the dialog opens | |
247 button.removeFocusListener(getButtonFocusListener()); | |
248 | |
249 Object newValue = openDialogBox(editor); | |
250 | |
251 // Re-add the listener once the dialog closes | |
252 button.addFocusListener(getButtonFocusListener()); | |
253 | |
254 if (newValue !is null) { | |
255 bool newValidState = isCorrect(newValue); | |
256 if (newValidState) { | |
257 markDirty(); | |
258 doSetValue(newValue); | |
259 } else { | |
260 // try to insert the current value into the error message. | |
261 setErrorMessage(Format(getErrorMessage(), | |
262 newValue.toString() )); | |
263 } | |
264 fireApplyEditorValue(); | |
265 } | |
266 } | |
267 }); | |
268 | |
269 setValueValid(true); | |
270 | |
271 return editor; | |
272 } | |
273 | |
274 /* (non-Javadoc) | |
275 * | |
276 * Override in order to remove the button's focus listener if the celleditor | |
277 * is deactivating. | |
278 * | |
279 * @see dwtx.jface.viewers.CellEditor#deactivate() | |
280 */ | |
43
ea8ff534f622
Fix override and super aliases
Frank Benoit <benoit@tionex.de>
parents:
42
diff
changeset
|
281 public override void deactivate() { |
10 | 282 if (button !is null && !button.isDisposed()) { |
283 button.removeFocusListener(getButtonFocusListener()); | |
284 } | |
285 | |
286 super.deactivate(); | |
287 } | |
288 | |
289 /* (non-Javadoc) | |
290 * Method declared on CellEditor. | |
291 */ | |
43
ea8ff534f622
Fix override and super aliases
Frank Benoit <benoit@tionex.de>
parents:
42
diff
changeset
|
292 protected override Object doGetValue() { |
10 | 293 return value; |
294 } | |
295 | |
296 /* (non-Javadoc) | |
297 * Method declared on CellEditor. | |
298 * The focus is set to the cell editor's button. | |
299 */ | |
43
ea8ff534f622
Fix override and super aliases
Frank Benoit <benoit@tionex.de>
parents:
42
diff
changeset
|
300 protected override void doSetFocus() { |
10 | 301 button.setFocus(); |
302 | |
303 // add a FocusListener to the button | |
304 button.addFocusListener(getButtonFocusListener()); | |
305 } | |
306 | |
307 /** | |
308 * Return a listener for button focus. | |
309 * @return FocusListener | |
310 */ | |
311 private FocusListener getButtonFocusListener() { | |
312 if (buttonFocusListener is null) { | |
313 buttonFocusListener = new class FocusListener { | |
314 | |
315 /* (non-Javadoc) | |
316 * @see dwt.events.FocusListener#focusGained(dwt.events.FocusEvent) | |
317 */ | |
318 public void focusGained(FocusEvent e) { | |
319 // Do nothing | |
320 } | |
321 | |
322 /* (non-Javadoc) | |
323 * @see dwt.events.FocusListener#focusLost(dwt.events.FocusEvent) | |
324 */ | |
325 public void focusLost(FocusEvent e) { | |
326 this.outer.focusLost(); | |
327 } | |
328 }; | |
329 } | |
330 | |
331 return buttonFocusListener; | |
332 } | |
333 | |
334 /* (non-Javadoc) | |
335 * Method declared on CellEditor. | |
336 */ | |
43
ea8ff534f622
Fix override and super aliases
Frank Benoit <benoit@tionex.de>
parents:
42
diff
changeset
|
337 protected override void doSetValue(Object value) { |
10 | 338 this.value = value; |
339 updateContents(value); | |
340 } | |
341 | |
342 /** | |
343 * Returns the default label widget created by <code>createContents</code>. | |
344 * | |
345 * @return the default label widget | |
346 */ | |
347 protected Label getDefaultLabel() { | |
348 return defaultLabel; | |
349 } | |
350 | |
351 /** | |
352 * Opens a dialog box under the given parent control and returns the | |
353 * dialog's value when it closes, or <code>null</code> if the dialog | |
354 * was canceled or no selection was made in the dialog. | |
355 * <p> | |
356 * This framework method must be implemented by concrete subclasses. | |
357 * It is called when the user has pressed the button and the dialog | |
358 * box must pop up. | |
359 * </p> | |
360 * | |
361 * @param cellEditorWindow the parent control cell editor's window | |
362 * so that a subclass can adjust the dialog box accordingly | |
363 * @return the selected value, or <code>null</code> if the dialog was | |
364 * canceled or no selection was made in the dialog | |
365 */ | |
366 protected abstract Object openDialogBox(Control cellEditorWindow); | |
367 | |
368 /** | |
369 * Updates the controls showing the value of this cell editor. | |
370 * <p> | |
371 * The default implementation of this framework method just converts | |
372 * the passed object to a string using <code>toString</code> and | |
373 * sets this as the text of the label widget. | |
374 * </p> | |
375 * <p> | |
376 * Subclasses may reimplement. If you reimplement this method, you | |
377 * should also reimplement <code>createContents</code>. | |
378 * </p> | |
379 * | |
380 * @param value the new value of this cell editor | |
381 */ | |
382 protected void updateContents(Object value) { | |
383 if (defaultLabel is null) { | |
384 return; | |
385 } | |
386 | |
387 String text = "";//$NON-NLS-1$ | |
388 if (value !is null) { | |
389 text = value.toString(); | |
390 } | |
391 defaultLabel.setText(text); | |
392 } | |
393 } |