view org.eclipse.swt.gtk.linux.x86/src/org/eclipse/swt/custom/PopupList.d @ 120:536e43f63c81

Comprehensive update for Win32/Linux32 dmd-2.053/dmd-1.068+Tango-r5661 ===D2=== * added [Try]Immutable/Const/Shared templates to work with differenses in D1/D2 instead of version statements used these templates to work with strict type storage rules of dmd-2.053 * com.ibm.icu now also compilable with D2, but not tested yet * small fixes Snippet288 - shared data is in TLS ===Phobos=== * fixed critical bugs in Phobos implemention completely incorrect segfault prone fromStringz (Linux's port ruthless killer) terrible, incorrect StringBuffer realization (StyledText killer) * fixed small bugs as well Snippet72 - misprint in the snippet * implemented missed functionality for Phobos ByteArrayOutputStream implemented (image loading available) formatting correctly works for all DWT's cases As a result, folowing snippets now works with Phobos (Snippet### - what is fixed): Snippet24, 42, 111, 115, 130, 235, 276 - bad string formatting Snippet48, 282 - crash on image loading Snippet163, 189, 211, 213, 217, 218, 222 - crash on copy/cut in StyledText Snippet244 - hang-up ===Tango=== * few changes for the latest Tango trunc-r5661 * few small performance improvments ===General=== * implMissing-s for only one version changed to implMissingInTango/InPhobos * incorrect calls to Format in toString-s fixed * fixed loading \uXXXX characters in ResourceBundle * added good UTF-8 support for StyledText, TextLayout (Win32) and friends UTF functions revised and tested. It is now in java.nonstandard.*Utf modules StyledText and TextLayout (Win32) modules revised for UTF-8 support * removed small diferences in most identical files in *.swt.* folders *.swt.internal.image, *.swt.events and *.swt.custom are identical in Win32/Linux32 now 179 of 576 (~31%) files in *.swt.* folders are fully identical * Win32: snippets now have right subsystem, pretty icons and native system style controls * small fixes in snippets Snippet44 - it's not Snippet44 Snippet212 - functions work with different images and offsets arrays Win32: Snippet282 - crash on close if the button has an image Snippet293 - setGrayed is commented and others Win32: As a result, folowing snippets now works Snippet68 - color doesn't change Snippet163, 189, 211, 213, 217, 218, 222 - UTF-8 issues (see above) Snippet193 - no tabel headers
author Denis Shelomovskij <verylonglogin.reg@gmail.com>
date Sat, 09 Jul 2011 15:50:20 +0300
parents c01d033c633a
children
line wrap: on
line source

/*******************************************************************************
 * Copyright (c) 2000, 2008 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
 * Port to the D programming language:
 *     Frank Benoit <benoit@tionex.de>
 *******************************************************************************/
module org.eclipse.swt.custom.PopupList;

import java.lang.all;


import org.eclipse.swt.SWT;
import org.eclipse.swt.SWTException;
import org.eclipse.swt.events.ControlEvent;
import org.eclipse.swt.events.ControlListener;
import org.eclipse.swt.events.KeyEvent;
import org.eclipse.swt.events.KeyListener;
import org.eclipse.swt.events.MouseEvent;
import org.eclipse.swt.events.MouseListener;
import org.eclipse.swt.graphics.Font;
import org.eclipse.swt.graphics.Point;
import org.eclipse.swt.graphics.Rectangle;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Event;
import org.eclipse.swt.widgets.List;
import org.eclipse.swt.widgets.Listener;
import org.eclipse.swt.widgets.Shell;

/**
* 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.
*
* @see <a href="http://www.eclipse.org/swt/">Sample code and further information</a>
*/
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 this(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 this(Shell parent, int style) {
    shell = new Shell(parent, checkStyle(style));

    list = new List(shell, SWT.SINGLE | SWT.V_SCROLL);

    // close dialog if user selects outside of the shell
    shell.addListener(SWT.Deactivate, new class() Listener {
        public void handleEvent(Event e){
            shell.setVisible (false);
        }
    });

    // resize shell when list resizes
    shell.addControlListener(new class() 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 class() MouseListener {
        public void mouseDoubleClick(MouseEvent e){}
        public void mouseDown(MouseEvent e){}
        public void mouseUp(MouseEvent e){
            shell.setVisible (false);
        }
    });
    list.addKeyListener(new class() 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 = SWT.LEFT_TO_RIGHT | SWT.RIGHT_TO_LEFT;
    return style & mask;
}
/**
* Gets the widget font.
* <p>
* @return the widget font
*
* @exception SWTException <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 SWTException <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, SWT.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 SWTException <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 SWTException <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_INVALID_ARGUMENT - if an item in the items array is null</li>
* </ul>
* @exception SWTException <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)
        SWT.error(SWT.ERROR_INVALID_ARGUMENT);

    minimumWidth = width;
}
}