Mercurial > projects > dwt-mac
diff 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 |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/dwt/custom/PopupList.d Sat Aug 09 17:00:02 2008 +0200 @@ -0,0 +1,271 @@ +/******************************************************************************* + * Copyright (c) 2000, 2007 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +module dwt.custom; + +import dwt.*; +import dwt.events.*; +import dwt.graphics.*; +import dwt.widgets.*; +/** +* A PopupList is a list of selectable items that appears in its own shell positioned above +* its parent shell. It is used for selecting items when editing a Table cell (similar to the +* list that appears when you open a Combo box). +* +* The list will be positioned so that it does not run off the screen and the largest number of items +* are visible. It may appear above the current cursor location or below it depending how close you +* are to the edge of the screen. +*/ +public class PopupList { + Shell shell; + List list; + int minimumWidth; +/** +* Creates a PopupList above the specified shell. +* +* @param parent a Shell control which will be the parent of the new instance (cannot be null) +*/ +public PopupList(Shell parent) { + this (parent, 0); +} +/** +* Creates a PopupList above the specified shell. +* +* @param parent a widget which will be the parent of the new instance (cannot be null) +* @param style the style of widget to construct +* +* @since 3.0 +*/ +public PopupList(Shell parent, int style) { + shell = new Shell(parent, checkStyle(style)); + + list = new List(shell, DWT.SINGLE | DWT.V_SCROLL); + + // close dialog if user selects outside of the shell + shell.addListener(DWT.Deactivate, new Listener() { + public void handleEvent(Event e){ + shell.setVisible (false); + } + }); + + // resize shell when list resizes + shell.addControlListener(new ControlListener() { + public void controlMoved(ControlEvent e){} + public void controlResized(ControlEvent e){ + Rectangle shellSize = shell.getClientArea(); + list.setSize(shellSize.width, shellSize.height); + } + }); + + // return list selection on Mouse Up or Carriage Return + list.addMouseListener(new MouseListener() { + public void mouseDoubleClick(MouseEvent e){} + public void mouseDown(MouseEvent e){} + public void mouseUp(MouseEvent e){ + shell.setVisible (false); + } + }); + list.addKeyListener(new KeyListener() { + public void keyReleased(KeyEvent e){} + public void keyPressed(KeyEvent e){ + if (e.character is '\r'){ + shell.setVisible (false); + } + } + }); + +} +private static int checkStyle (int style) { + int mask = DWT.LEFT_TO_RIGHT | DWT.RIGHT_TO_LEFT; + return style & mask; +} +/** +* Gets the widget font. +* <p> +* @return the widget font +* +* @exception DWTException <ul> +* <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> +* <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> +* </ul> +*/ +public Font getFont () { + return list.getFont(); +} +/** +* Gets the items. +* <p> +* This operation will fail if the items cannot +* be queried from the OS. +* +* @return the items in the widget +* +* @exception DWTException <ul> +* <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> +* <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> +* </ul> +*/ +public String[] getItems () { + return list.getItems(); +} +/** +* Gets the minimum width of the list. +* +* @return the minimum width of the list +*/ +public int getMinimumWidth () { + return minimumWidth; +} +/** +* Launches the Popup List, waits for an item to be selected and then closes the PopupList. +* +* @param rect the initial size and location of the PopupList; the dialog will be +* positioned so that it does not run off the screen and the largest number of items are visible +* +* @return the text of the selected item or null if no item is selected +*/ +public String open (Rectangle rect) { + + Point listSize = list.computeSize (rect.width, DWT.DEFAULT, false); + Rectangle screenSize = shell.getDisplay().getBounds(); + + // Position the dialog so that it does not run off the screen and the largest number of items are visible + int spaceBelow = screenSize.height - (rect.y + rect.height) - 30; + int spaceAbove = rect.y - 30; + + int y = 0; + if (spaceAbove > spaceBelow && listSize.y > spaceBelow) { + // place popup list above table cell + if (listSize.y > spaceAbove){ + listSize.y = spaceAbove; + } else { + listSize.y += 2; + } + y = rect.y - listSize.y; + + } else { + // place popup list below table cell + if (listSize.y > spaceBelow){ + listSize.y = spaceBelow; + } else { + listSize.y += 2; + } + y = rect.y + rect.height; + } + + // Make dialog as wide as the cell + listSize.x = rect.width; + // dialog width should not be less than minimumWidth + if (listSize.x < minimumWidth) + listSize.x = minimumWidth; + + // Align right side of dialog with right side of cell + int x = rect.x + rect.width - listSize.x; + + shell.setBounds(x, y, listSize.x, listSize.y); + + shell.open(); + list.setFocus(); + + Display display = shell.getDisplay(); + while (!shell.isDisposed () && shell.isVisible ()) { + if (!display.readAndDispatch()) display.sleep(); + } + + String result = null; + if (!shell.isDisposed ()) { + String [] Strings = list.getSelection (); + shell.dispose(); + if (Strings.length !is 0) result = Strings [0]; + } + return result; +} +/** +* Selects an item with text that starts with specified String. +* <p> +* If the item is not currently selected, it is selected. +* If the item at an index is selected, it remains selected. +* If the String is not matched, it is ignored. +* +* @param String the text of the item +* +* @exception DWTException <ul> +* <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> +* <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> +* </ul> +*/ +public void select(String String) { + String[] items = list.getItems(); + + // find the first entry in the list that starts with the + // specified String + if (String !is null){ + for (int i = 0; i < items.length; i++) { + if (items[i].startsWith(String)){ + int index = list.indexOf(items[i]); + list.select(index); + break; + } + } + } +} +/** +* Sets the widget font. +* <p> +* When new font is null, the font reverts +* to the default system font for the widget. +* +* @param font the new font (or null) +* +* @exception DWTException <ul> +* <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> +* <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> +* </ul> +*/ +public void setFont (Font font) { + list.setFont(font); +} +/** +* Sets all items. +* <p> +* The previous selection is cleared. +* The previous items are deleted. +* The new items are added. +* The top index is set to 0. +* +* @param Strings the array of items +* +* This operation will fail when an item is null +* or could not be added in the OS. +* +* @exception IllegalArgumentException <ul> +* <li>ERROR_NULL_ARGUMENT - if the items array is null</li> +* <li>ERROR_INVALID_ARGUMENT - if an item in the items array is null</li> +* </ul> +* @exception DWTException <ul> +* <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> +* <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> +* </ul> +*/ +public void setItems (String[] Strings) { + list.setItems(Strings); +} +/** +* Sets the minimum width of the list. +* +* @param width the minimum width of the list +*/ +public void setMinimumWidth (int width) { + if (width < 0) + DWT.error(DWT.ERROR_INVALID_ARGUMENT); + + minimumWidth = width; +} +}