/*
* (c) Copyright 2004 by Heng Yuan
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included
* in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* ITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
* DEALINGS IN THE SOFTWARE.
*/
package cookxml.cookswt.util;
import java.util.HashMap;
import org.eclipse.swt.SWT;
import org.eclipse.swt.graphics.*;
import org.eclipse.swt.widgets.*;
/**
* SWT useful utilities.
*
* @since CookSwt 1.0
* @author Heng Yuan
*/
public class SwtUtils
{
/**
* automatically dispose Color resource
*/
public static boolean autoDisposeColor = true;
/**
* automatically dispose Font resource
*/
public static boolean autoDisposeFont = true;
/**
* automatically dispose Image resource
*/
public static boolean autoDisposeImage = true;
/**
* automatically dispose Image resource
*/
public static boolean autoDisposeCursor = true;
/**
* This is a table of system colors that cannot be disposed.
*/
private static HashMap s_systemColorTable;
/**
* This is a table of system cursors that cannot be disposed.
*/
private static HashMap s_systemCursorTable;
/**
* This is a table of system images that cannot be disposed.
*/
private static HashMap s_systemImageTable;
/**
* Setup the system color table for the given device.
*
* @param device the display device.
*/
private static void setupSystemColorTable (Device device)
{
HashMap colorTable = new HashMap ();
for (int i = 0; i <= 35; ++i)
{
Color c = device.getSystemColor (i);
colorTable.put (c, c);
}
s_systemColorTable = colorTable;
}
/**
* Setup the system cursor table for the given device.
*
* @param display the display device.
*/
private static void setupSystemCursorTable (Display display)
{
HashMap cursorTable = new HashMap ();
for (int i = 0; i <= 21; ++i)
{
Cursor c = display.getSystemCursor (i);
cursorTable.put (c, c);
}
s_systemCursorTable = cursorTable;
}
/**
* Setup the system cursor table for the given device.
*
* @param display the display device.
*/
private static void setupSystemImageTable (Display display)
{
HashMap imageTable = new HashMap ();
Image image;
image = display.getSystemImage (SWT.ICON_ERROR);
imageTable.put (image, image);
image = display.getSystemImage (SWT.ICON_INFORMATION);
imageTable.put (image, image);
image = display.getSystemImage (SWT.ICON_QUESTION);
imageTable.put (image, image);
image = display.getSystemImage (SWT.ICON_WARNING);
imageTable.put (image, image);
image = display.getSystemImage (SWT.ICON_WORKING);
imageTable.put (image, image);
s_systemImageTable = imageTable;
}
/**
* Check if a color is a system color. A system color cannot be disposed.
*
* @param color The color to be disposed.
* @param device The device that contains the color.
*/
public static boolean isSystemColor (Color color, Device device)
{
if (s_systemColorTable == null)
setupSystemColorTable (device);
return s_systemColorTable.get (color) == color;
}
/**
* Check if a color is a system color. A system color cannot be disposed.
*
* @param cursor The cursor to be disposed.
* @param display The display device.
*/
public static boolean isSystemCursor (Cursor cursor, Display display)
{
if (s_systemCursorTable == null)
setupSystemCursorTable (display);
return s_systemCursorTable.get (cursor) == cursor;
}
/**
* Check if a color is a system color. A system color cannot be disposed.
*
* @param image The image to be disposed.
* @param display The display device.
*/
public static boolean isSystemImage (Image image, Display display)
{
if (s_systemImageTable == null)
setupSystemImageTable (display);
return s_systemImageTable.get (image) == image;
}
/**
* Check if a color is a system color. A system color cannot be disposed.
*
* @param font The font to be disposed.
* @param device The display device.
*/
public static boolean isSystemFont (Font font, Device device)
{
return device.getSystemFont () == font;
}
/**
* Dispose a color if it is not a system color.
*
* @param color The color to be disposed.
* @param device The device that contains the color.
*/
public static void disposeColor (Color color, Device device)
{
if (color.isDisposed ())
return;
if (!isSystemColor (color, device))
{
assert disposeDebug ("Dispose color: " + color);
color.dispose ();
}
}
/**
* Dispose a color if it is not a system color.
*
* @param image The image to be disposed.
* @param device The device that contains the color.
*/
public static void disposeImage (Image image, Display device)
{
if (image.isDisposed ())
return;
if (!isSystemImage (image, device))
{
assert disposeDebug ("Dispose image: " + image);
image.dispose ();
}
}
/**
* Attach a DisposeListener that dispose the resource when the widget
* object is disposed.
*
* @param widget the widget to listen to.
* @param color the resource to be disposed.
*/
public static void attachColorDisposeListener (Widget widget, Color color)
{
if (autoDisposeColor &&
!isSystemColor (color, widget.getDisplay ()))
widget.addDisposeListener (new ColorDisposeListener (color));
}
/**
* Attach a DisposeListener that dispose the resource when the widget
* object is disposed.
*
* @param widget the widget to listen to.
* @param cursor the resource to be disposed.
*/
public static void attachCursorDisposeListener (Widget widget, Cursor cursor)
{
if (autoDisposeCursor &&
!isSystemCursor (cursor, widget.getDisplay ()))
widget.addDisposeListener (new CursorDisposeListener (cursor));
}
/**
* Attach a DisposeListener that dispose the resource when the widget
* object is disposed.
*
* @param widget the widget to listen to.
* @param font the resource to be disposed.
*/
public static void attachFontDisposeListener (Widget widget, Font font)
{
if (autoDisposeFont &&
!isSystemFont (font, widget.getDisplay ()))
widget.addDisposeListener (new FontDisposeListener (font));
}
/**
* Attach a DisposeListener that dispose the resource when the widget
* object is disposed.
*
* @param widget the widget to listen to.
* @param image the resource to be disposed.
*/
public static void attachImageDisposeListener (Widget widget, Image image)
{
if (autoDisposeImage &&
!isSystemImage (image, widget.getDisplay ()))
widget.addDisposeListener (new ImageDisposeListener (image));
}
/**
* Attach a dropdown menu to a drop down ToolItem. The drop down menu will be
* automatically positioned and displayed at under the ToolItem.
*
* @param item the drop down tool item
* @param menu the drop down menu
*/
public static void attachToolItemDropDownMenu (ToolItem item, Menu menu)
{
item.addSelectionListener (new DropDownListener (menu));
}
/**
* Open all the shells inside the Display object and dispose the Display
* after all shells are disposed.
*
* @param display the Display object.
*/
public static void showDisplay (Display display)
{
// open shells for display
Shell[] shells = display.getShells ();
for (int i = 0; i < shells.length; ++i)
{
if (!shells[i].isDisposed () && !shells[i].isVisible ())
shells[i].open ();
}
// exit after all shells are disposed
while (!display.isDisposed ())
{
shells = display.getShells ();
boolean canExit = true;
for (int i = 0; i < shells.length; ++i)
{
if (!shells[i].isDisposed ())
{
canExit = false;
break;
}
}
if (canExit)
break;
if (!display.readAndDispatch ())
display.sleep ();
}
if (!display.isDisposed ())
display.dispose ();
}
/**
* This function is supposed to work in conjunction with assert to generate
* a debug message but does not really throw an Exception
*
* @param msg the message to be printed.
* @return true
*/
public static boolean disposeDebug (String msg)
{
System.out.println (msg);
return true;
}
}