comparison dwt/custom/PopupList.d @ 0:380af2bdd8e5

Upload of whole dwt tree
author Jacob Carlborg <doob@me.com> <jacob.carlborg@gmail.com>
date Sat, 09 Aug 2008 17:00:02 +0200
parents
children 1a8b3cb347e0
comparison
equal deleted inserted replaced
-1:000000000000 0:380af2bdd8e5
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 *******************************************************************************/
11 module dwt.custom;
12
13 import dwt.*;
14 import dwt.events.*;
15 import dwt.graphics.*;
16 import dwt.widgets.*;
17 /**
18 * A PopupList is a list of selectable items that appears in its own shell positioned above
19 * its parent shell. It is used for selecting items when editing a Table cell (similar to the
20 * list that appears when you open a Combo box).
21 *
22 * The list will be positioned so that it does not run off the screen and the largest number of items
23 * are visible. It may appear above the current cursor location or below it depending how close you
24 * are to the edge of the screen.
25 */
26 public class PopupList {
27 Shell shell;
28 List list;
29 int minimumWidth;
30 /**
31 * Creates a PopupList above the specified shell.
32 *
33 * @param parent a Shell control which will be the parent of the new instance (cannot be null)
34 */
35 public PopupList(Shell parent) {
36 this (parent, 0);
37 }
38 /**
39 * Creates a PopupList above the specified shell.
40 *
41 * @param parent a widget which will be the parent of the new instance (cannot be null)
42 * @param style the style of widget to construct
43 *
44 * @since 3.0
45 */
46 public PopupList(Shell parent, int style) {
47 shell = new Shell(parent, checkStyle(style));
48
49 list = new List(shell, DWT.SINGLE | DWT.V_SCROLL);
50
51 // close dialog if user selects outside of the shell
52 shell.addListener(DWT.Deactivate, new Listener() {
53 public void handleEvent(Event e){
54 shell.setVisible (false);
55 }
56 });
57
58 // resize shell when list resizes
59 shell.addControlListener(new ControlListener() {
60 public void controlMoved(ControlEvent e){}
61 public void controlResized(ControlEvent e){
62 Rectangle shellSize = shell.getClientArea();
63 list.setSize(shellSize.width, shellSize.height);
64 }
65 });
66
67 // return list selection on Mouse Up or Carriage Return
68 list.addMouseListener(new MouseListener() {
69 public void mouseDoubleClick(MouseEvent e){}
70 public void mouseDown(MouseEvent e){}
71 public void mouseUp(MouseEvent e){
72 shell.setVisible (false);
73 }
74 });
75 list.addKeyListener(new KeyListener() {
76 public void keyReleased(KeyEvent e){}
77 public void keyPressed(KeyEvent e){
78 if (e.character is '\r'){
79 shell.setVisible (false);
80 }
81 }
82 });
83
84 }
85 private static int checkStyle (int style) {
86 int mask = DWT.LEFT_TO_RIGHT | DWT.RIGHT_TO_LEFT;
87 return style & mask;
88 }
89 /**
90 * Gets the widget font.
91 * <p>
92 * @return the widget font
93 *
94 * @exception DWTException <ul>
95 * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
96 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
97 * </ul>
98 */
99 public Font getFont () {
100 return list.getFont();
101 }
102 /**
103 * Gets the items.
104 * <p>
105 * This operation will fail if the items cannot
106 * be queried from the OS.
107 *
108 * @return the items in the widget
109 *
110 * @exception DWTException <ul>
111 * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
112 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
113 * </ul>
114 */
115 public String[] getItems () {
116 return list.getItems();
117 }
118 /**
119 * Gets the minimum width of the list.
120 *
121 * @return the minimum width of the list
122 */
123 public int getMinimumWidth () {
124 return minimumWidth;
125 }
126 /**
127 * Launches the Popup List, waits for an item to be selected and then closes the PopupList.
128 *
129 * @param rect the initial size and location of the PopupList; the dialog will be
130 * positioned so that it does not run off the screen and the largest number of items are visible
131 *
132 * @return the text of the selected item or null if no item is selected
133 */
134 public String open (Rectangle rect) {
135
136 Point listSize = list.computeSize (rect.width, DWT.DEFAULT, false);
137 Rectangle screenSize = shell.getDisplay().getBounds();
138
139 // Position the dialog so that it does not run off the screen and the largest number of items are visible
140 int spaceBelow = screenSize.height - (rect.y + rect.height) - 30;
141 int spaceAbove = rect.y - 30;
142
143 int y = 0;
144 if (spaceAbove > spaceBelow && listSize.y > spaceBelow) {
145 // place popup list above table cell
146 if (listSize.y > spaceAbove){
147 listSize.y = spaceAbove;
148 } else {
149 listSize.y += 2;
150 }
151 y = rect.y - listSize.y;
152
153 } else {
154 // place popup list below table cell
155 if (listSize.y > spaceBelow){
156 listSize.y = spaceBelow;
157 } else {
158 listSize.y += 2;
159 }
160 y = rect.y + rect.height;
161 }
162
163 // Make dialog as wide as the cell
164 listSize.x = rect.width;
165 // dialog width should not be less than minimumWidth
166 if (listSize.x < minimumWidth)
167 listSize.x = minimumWidth;
168
169 // Align right side of dialog with right side of cell
170 int x = rect.x + rect.width - listSize.x;
171
172 shell.setBounds(x, y, listSize.x, listSize.y);
173
174 shell.open();
175 list.setFocus();
176
177 Display display = shell.getDisplay();
178 while (!shell.isDisposed () && shell.isVisible ()) {
179 if (!display.readAndDispatch()) display.sleep();
180 }
181
182 String result = null;
183 if (!shell.isDisposed ()) {
184 String [] Strings = list.getSelection ();
185 shell.dispose();
186 if (Strings.length !is 0) result = Strings [0];
187 }
188 return result;
189 }
190 /**
191 * Selects an item with text that starts with specified String.
192 * <p>
193 * If the item is not currently selected, it is selected.
194 * If the item at an index is selected, it remains selected.
195 * If the String is not matched, it is ignored.
196 *
197 * @param String the text of the item
198 *
199 * @exception DWTException <ul>
200 * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
201 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
202 * </ul>
203 */
204 public void select(String String) {
205 String[] items = list.getItems();
206
207 // find the first entry in the list that starts with the
208 // specified String
209 if (String !is null){
210 for (int i = 0; i < items.length; i++) {
211 if (items[i].startsWith(String)){
212 int index = list.indexOf(items[i]);
213 list.select(index);
214 break;
215 }
216 }
217 }
218 }
219 /**
220 * Sets the widget font.
221 * <p>
222 * When new font is null, the font reverts
223 * to the default system font for the widget.
224 *
225 * @param font the new font (or null)
226 *
227 * @exception DWTException <ul>
228 * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
229 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
230 * </ul>
231 */
232 public void setFont (Font font) {
233 list.setFont(font);
234 }
235 /**
236 * Sets all items.
237 * <p>
238 * The previous selection is cleared.
239 * The previous items are deleted.
240 * The new items are added.
241 * The top index is set to 0.
242 *
243 * @param Strings the array of items
244 *
245 * This operation will fail when an item is null
246 * or could not be added in the OS.
247 *
248 * @exception IllegalArgumentException <ul>
249 * <li>ERROR_NULL_ARGUMENT - if the items array is null</li>
250 * <li>ERROR_INVALID_ARGUMENT - if an item in the items array is null</li>
251 * </ul>
252 * @exception DWTException <ul>
253 * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
254 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
255 * </ul>
256 */
257 public void setItems (String[] Strings) {
258 list.setItems(Strings);
259 }
260 /**
261 * Sets the minimum width of the list.
262 *
263 * @param width the minimum width of the list
264 */
265 public void setMinimumWidth (int width) {
266 if (width < 0)
267 DWT.error(DWT.ERROR_INVALID_ARGUMENT);
268
269 minimumWidth = width;
270 }
271 }