/**
* This class may be freely distributed as part of any application or plugin.
* <p>
* Copyright (c) 2003 - 2005, Instantiations, Inc. <br>
* All Rights Reserved
*/
package com.swtdesigner;
import java.util.HashMap;
import java.util.Iterator;
import org.eclipse.swt.SWT;
import org.eclipse.swt.graphics.Color;
import org.eclipse.swt.graphics.Cursor;
import org.eclipse.swt.graphics.Font;
import org.eclipse.swt.graphics.FontData;
import org.eclipse.swt.graphics.Image;
import org.eclipse.swt.graphics.Point;
import org.eclipse.swt.graphics.RGB;
import org.eclipse.swt.widgets.Canvas;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.CoolBar;
import org.eclipse.swt.widgets.CoolItem;
import org.eclipse.swt.widgets.Display;
/**
* Utility class for managing OS resources associated with SWT controls such as
* colors, fonts, images, etc.
*
* !!! IMPORTANT !!! Application code must explicitly invoke the
* <code>dispose()</code> method to release the operating system resources
* managed by cached objects when those objects and OS resources are no longer
* needed (e.g. on application shutdown)
*
* This class may be freely distributed as part of any application or plugin.
* <p>
* Copyright (c) 2003 - 2005, Instantiations, Inc. <br>
* All Rights Reserved
*
* @author scheglov_ke
* @author Dan Rubel
*/
public class SWTResourceManager {
/**
* Dispose of cached objects and their underlying OS resources. This should
* only be called when the cached objects are no longer needed (e.g. on
* application shutdown)
*/
public static void dispose() {
disposeColors();
disposeFonts();
disposeImages();
disposeCursors();
}
//////////////////////////////
// Color support
//////////////////////////////
/**
* Maps RGB values to colors
*/
private static HashMap<RGB, Color> m_ColorMap = new HashMap<RGB, Color>();
/**
* Returns the system color matching the specific ID
*
* @param systemColorID
* int The ID value for the color
* @return Color The system color matching the specific ID
*/
public static Color getColor(final int systemColorID) {
final Display display = Display.getCurrent();
return display.getSystemColor(systemColorID);
}
/**
* Returns a color given its red, green and blue component values
*
* @param r
* int The red component of the color
* @param g
* int The green component of the color
* @param b
* int The blue component of the color
* @return Color The color matching the given red, green and blue componet
* values
*/
public static Color getColor(final int r, final int g, final int b) {
return getColor(new RGB(r, g, b));
}
/**
* Returns a color given its RGB value
*
* @param rgb
* RGB The RGB value of the color
* @return Color The color matching the RGB value
*/
public static Color getColor(final RGB rgb) {
Color color = m_ColorMap.get(rgb);
if (color == null) {
final Display display = Display.getCurrent();
color = new Color(display, rgb);
m_ColorMap.put(rgb, color);
}
return color;
}
/**
* Dispose of all the cached colors
*/
public static void disposeColors() {
for (final Color color : m_ColorMap.values()) {
color.dispose();
}
m_ColorMap.clear();
}
//////////////////////////////
// Image support
//////////////////////////////
/**
* Maps image names to images
*/
private static HashMap<String, Image> m_ClassImageMap = new HashMap<String, Image>();
/**
* Maps images to image decorators
*/
private static HashMap<Image, HashMap<Image, Image>> m_ImageToDecoratorMap = new HashMap<Image, HashMap<Image, Image>>();
/**
* Style constant for placing decorator image in top left corner of base
* image.
*/
public static final int TOP_LEFT = 1;
/**
* Style constant for placing decorator image in top right corner of base
* image.
*/
public static final int TOP_RIGHT = 2;
/**
* Style constant for placing decorator image in bottom left corner of base
* image.
*/
public static final int BOTTOM_LEFT = 3;
/**
* Style constant for placing decorator image in bottom right corner of base
* image.
*/
public static final int BOTTOM_RIGHT = 4;
/**
* Dispose all of the cached images
*/
public static void disposeImages() {
for (final Image image : m_ClassImageMap.values()) {
image.dispose();
}
m_ClassImageMap.clear();
//
for (final HashMap<Image, Image> decoratedMap : m_ImageToDecoratorMap.values()) {
for (final Image image : decoratedMap.values()) {
image.dispose();
}
}
}
/**
* Dispose cached images in specified section
*
* @param section
* the section do dispose
*/
public static void disposeImages(final String section) {
for (final Iterator<String> I = m_ClassImageMap.keySet().iterator(); I.hasNext();) {
final String key = I.next();
if (!key.startsWith(section + '|')) {
continue;
}
final Image image = m_ClassImageMap.get(key);
image.dispose();
I.remove();
}
}
//////////////////////////////
// Font support
//////////////////////////////
/**
* Maps font names to fonts
*/
private static HashMap<String, Font> m_FontMap = new HashMap<String, Font>();
/**
* Maps fonts to their bold versions
*/
private static HashMap<Font, Font> m_FontToBoldFontMap = new HashMap<Font, Font>();
/**
* Returns a font based on its name, height and style
*
* @param name
* String The name of the font
* @param height
* int The height of the font
* @param style
* int The style of the font
* @return Font The font matching the name, height and style
*/
public static Font getFont(final String name, final int height, final int style) {
return getFont(name, height, style, false, false);
}
/**
* Returns a font based on its name, height and style. Windows-specific
* strikeout and underline flags are also supported.
*
* @param name
* String The name of the font
* @param size
* int The size of the font
* @param style
* int The style of the font
* @param strikeout
* boolean The strikeout flag (warning: Windows only)
* @param underline
* boolean The underline flag (warning: Windows only)
* @return Font The font matching the name, height, style, strikeout and
* underline
*/
public static Font getFont(final String name, final int size, final int style, final boolean strikeout,
final boolean underline) {
final String fontName = name + '|' + size + '|' + style + '|' + strikeout + '|' + underline;
Font font = m_FontMap.get(fontName);
if (font == null) {
final FontData fontData = new FontData(name, size, style);
if (strikeout || underline) {
try {
final Class<?> logFontClass = Class.forName("org.eclipse.swt.internal.win32.LOGFONT"); //$NON-NLS-1$
final Object logFont = FontData.class.getField("data").get(fontData); //$NON-NLS-1$
if (logFont != null && logFontClass != null) {
if (strikeout) {
logFontClass.getField("lfStrikeOut").set(logFont, new Byte((byte) 1)); //$NON-NLS-1$
}
if (underline) {
logFontClass.getField("lfUnderline").set(logFont, new Byte((byte) 1)); //$NON-NLS-1$
}
}
} catch (final Throwable e) {
System.err
.println("Unable to set underline or strikeout" + " (probably on a non-Windows platform). " + e); //$NON-NLS-1$ //$NON-NLS-2$
}
}
font = new Font(Display.getCurrent(), fontData);
m_FontMap.put(fontName, font);
}
return font;
}
/**
* Return a bold version of the give font
*
* @param baseFont
* Font The font for whoch a bold version is desired
* @return Font The bold version of the give font
*/
public static Font getBoldFont(final Font baseFont) {
Font font = m_FontToBoldFontMap.get(baseFont);
if (font == null) {
final FontData fontDatas[] = baseFont.getFontData();
final FontData data = fontDatas[0];
font = new Font(Display.getCurrent(), data.getName(), data.getHeight(), SWT.BOLD);
m_FontToBoldFontMap.put(baseFont, font);
}
return font;
}
/**
* Dispose all of the cached fonts
*/
public static void disposeFonts() {
// clear fonts
for (final Font font : m_FontMap.values()) {
font.dispose();
}
m_FontMap.clear();
// clear bold fonts
for (final Font font : m_FontToBoldFontMap.values()) {
font.dispose();
}
m_FontToBoldFontMap.clear();
}
//////////////////////////////
// CoolBar support
//////////////////////////////
/**
* Fix the layout of the specified CoolBar
*
* @param bar
* CoolBar The CoolBar that shgoud be fixed
*/
public static void fixCoolBarSize(final CoolBar bar) {
final CoolItem[] items = bar.getItems();
// ensure that each item has control (at least empty one)
for (final CoolItem item : items) {
if (item.getControl() == null) {
item.setControl(new Canvas(bar, SWT.NONE) {
@Override
public Point computeSize(final int wHint, final int hHint, final boolean changed) {
return new Point(20, 20);
}
});
}
}
// compute size for each item
for (final CoolItem item : items) {
final Control control = item.getControl();
control.pack();
final Point size = control.getSize();
item.setSize(item.computeSize(size.x, size.y));
}
}
//////////////////////////////
// Cursor support
//////////////////////////////
/**
* Maps IDs to cursors
*/
private static HashMap<Integer, Cursor> m_IdToCursorMap = new HashMap<Integer, Cursor>();
/**
* Returns the system cursor matching the specific ID
*
* @param id
* int The ID value for the cursor
* @return Cursor The system cursor matching the specific ID
*/
public static Cursor getCursor(final int id) {
final Integer key = new Integer(id);
Cursor cursor = m_IdToCursorMap.get(key);
if (cursor == null) {
cursor = new Cursor(Display.getDefault(), id);
m_IdToCursorMap.put(key, cursor);
}
return cursor;
}
/**
* Dispose all of the cached cursors
*/
public static void disposeCursors() {
for (final Cursor cursor : m_IdToCursorMap.values()) {
cursor.dispose();
}
m_IdToCursorMap.clear();
}
}