Initial commit from SVN.

This commit is contained in:
wcrisman
2014-05-30 10:31:51 -07:00
commit b45e56b890
1968 changed files with 370949 additions and 0 deletions

View File

@@ -0,0 +1,531 @@
/*
* Copyright (c) 2005,2009 Declarative Engineering LLC.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Declarative Engineering LLC
* verson 1 which accompanies this distribution, and is available at
* http://declarativeengineering.com/legal/DE_Developer_License_v1.txt
*/
package com.foundation.view.swt.util;
import java.io.ByteArrayInputStream;
import org.eclipse.swt.SWT;
import org.eclipse.swt.graphics.Color;
import org.eclipse.swt.graphics.Device;
import org.eclipse.swt.graphics.Font;
import org.eclipse.swt.graphics.FontData;
import org.eclipse.swt.graphics.GC;
import org.eclipse.swt.graphics.Image;
import org.eclipse.swt.graphics.ImageData;
import org.eclipse.swt.graphics.Point;
import org.eclipse.swt.graphics.RGB;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.Display;
import com.common.util.IList;
import com.common.util.LiteList;
import com.common.util.optimized.IntIntHashMap;
import com.foundation.view.IKeyBinding;
import com.foundation.view.JefColor;
import com.foundation.view.JefFont;
import com.foundation.view.JefImage;
/**
* TODO: Move these methods to a better location where finding them is more natural.
*/
public class SwtUtilities {
/** Simplify the translation of JEF color constants to SWT color constants. */
private static final IntIntHashMap jefToSwtColorConstantMap = new IntIntHashMap(40);
static {
//Setup the JEF to SWT Color Constant mappings.//
jefToSwtColorConstantMap.put(JefColor.COLOR_WHITE, SWT.COLOR_WHITE);
jefToSwtColorConstantMap.put(JefColor.COLOR_BLACK, SWT.COLOR_BLACK);
jefToSwtColorConstantMap.put(JefColor.COLOR_RED, SWT.COLOR_RED);
jefToSwtColorConstantMap.put(JefColor.COLOR_DARK_RED, SWT.COLOR_DARK_RED);
jefToSwtColorConstantMap.put(JefColor.COLOR_GREEN, SWT.COLOR_GREEN);
jefToSwtColorConstantMap.put(JefColor.COLOR_DARK_GREEN, SWT.COLOR_DARK_GREEN);
jefToSwtColorConstantMap.put(JefColor.COLOR_YELLOW, SWT.COLOR_YELLOW);
jefToSwtColorConstantMap.put(JefColor.COLOR_DARK_YELLOW, SWT.COLOR_DARK_YELLOW);
jefToSwtColorConstantMap.put(JefColor.COLOR_BLUE, SWT.COLOR_BLUE);
jefToSwtColorConstantMap.put(JefColor.COLOR_DARK_BLUE, SWT.COLOR_DARK_BLUE);
jefToSwtColorConstantMap.put(JefColor.COLOR_MAGENTA, SWT.COLOR_MAGENTA);
jefToSwtColorConstantMap.put(JefColor.COLOR_DARK_MAGENTA, SWT.COLOR_DARK_MAGENTA);
jefToSwtColorConstantMap.put(JefColor.COLOR_CYAN, SWT.COLOR_CYAN);
jefToSwtColorConstantMap.put(JefColor.COLOR_DARK_CYAN, SWT.COLOR_DARK_CYAN);
jefToSwtColorConstantMap.put(JefColor.COLOR_GRAY, SWT.COLOR_GRAY);
jefToSwtColorConstantMap.put(JefColor.COLOR_DARK_GRAY, SWT.COLOR_DARK_GRAY);
jefToSwtColorConstantMap.put(JefColor.COLOR_WIDGET_DARK_SHADOW, SWT.COLOR_WIDGET_DARK_SHADOW);
jefToSwtColorConstantMap.put(JefColor.COLOR_WIDGET_NORMAL_SHADOW, SWT.COLOR_WIDGET_NORMAL_SHADOW);
jefToSwtColorConstantMap.put(JefColor.COLOR_WIDGET_LIGHT_SHADOW, SWT.COLOR_WIDGET_LIGHT_SHADOW);
jefToSwtColorConstantMap.put(JefColor.COLOR_WIDGET_HIGHLIGHT_SHADOW, SWT.COLOR_WIDGET_HIGHLIGHT_SHADOW);
jefToSwtColorConstantMap.put(JefColor.COLOR_WIDGET_FOREGROUND, SWT.COLOR_WIDGET_FOREGROUND);
jefToSwtColorConstantMap.put(JefColor.COLOR_WIDGET_BACKGROUND, SWT.COLOR_WIDGET_BACKGROUND);
jefToSwtColorConstantMap.put(JefColor.COLOR_WIDGET_BORDER, SWT.COLOR_WIDGET_BORDER);
jefToSwtColorConstantMap.put(JefColor.COLOR_LIST_FOREGROUND, SWT.COLOR_LIST_FOREGROUND);
jefToSwtColorConstantMap.put(JefColor.COLOR_LIST_BACKGROUND, SWT.COLOR_LIST_BACKGROUND);
jefToSwtColorConstantMap.put(JefColor.COLOR_LIST_SELECTION, SWT.COLOR_LIST_SELECTION);
jefToSwtColorConstantMap.put(JefColor.COLOR_LIST_SELECTION_TEXT, SWT.COLOR_LIST_SELECTION_TEXT);
jefToSwtColorConstantMap.put(JefColor.COLOR_INFO_FOREGROUND, SWT.COLOR_INFO_FOREGROUND);
jefToSwtColorConstantMap.put(JefColor.COLOR_INFO_BACKGROUND, SWT.COLOR_INFO_BACKGROUND);
jefToSwtColorConstantMap.put(JefColor.COLOR_TITLE_FOREGROUND, SWT.COLOR_TITLE_FOREGROUND);
jefToSwtColorConstantMap.put(JefColor.COLOR_TITLE_BACKGROUND, SWT.COLOR_TITLE_BACKGROUND);
jefToSwtColorConstantMap.put(JefColor.COLOR_TITLE_BACKGROUND_GRADIENT, SWT.COLOR_TITLE_BACKGROUND_GRADIENT);
jefToSwtColorConstantMap.put(JefColor.COLOR_TITLE_INACTIVE_FOREGROUND, SWT.COLOR_TITLE_INACTIVE_FOREGROUND);
jefToSwtColorConstantMap.put(JefColor.COLOR_TITLE_INACTIVE_BACKGROUND, SWT.COLOR_TITLE_INACTIVE_BACKGROUND);
jefToSwtColorConstantMap.put(JefColor.COLOR_TITLE_INACTIVE_BACKGROUND_GRADIENT, SWT.COLOR_TITLE_INACTIVE_BACKGROUND_GRADIENT);
}//static//
/**
* SwtUtilities constructor.
*/
private SwtUtilities() {
super();
}//SwtUtilities()//
/**
* Sets the redraw for a control.
* <p>Using this method allows for simpler debugging. If a single call is made to turn off redrawing without another call to turn it on, then the app gets all buggered up.</p>
* @param control The control whose redraw is being toggled.
* @param redraw Whether the redraw should be turned on.
*/
public static void setRedraw(Control control, boolean redraw) {
//Warning: Calling this method causes flashing in the UI (on windows at least).//
control.setRedraw(redraw);
}//setRedraw()//
/**
* Converts the key modifiers from SWT to JEF.
* @param modifiers The swt modifiers.
* @return The jef modifiers.
*/
public static int convertKeyModifiers(int modifiers) {
int result = 0;
if((SWT.SHIFT & modifiers) > 0) {
result |= IKeyBinding.MODIFIER_SHIFT;
}//if//
if((SWT.ALT & modifiers) > 0) {
result |= IKeyBinding.MODIFIER_ALT;
}//if//
if((SWT.COMMAND & modifiers) > 0) {
result |= IKeyBinding.MODIFIER_COMMAND;
}//if//
if((SWT.CONTROL & modifiers) > 0) {
result |= IKeyBinding.MODIFIER_CONTROL;
}//if//
return result;
}//convertKeyModifiers()//
/**
* Gets the SWT Color object given a device.
* <p>Warning: The caller is responsible for disposing of the Color instance when it is no longer needed.</p>
* @param device The device that the color will be displayed on.
* @param color The foundation color instance from which the color data will be translated.
* @return The new color object.
*/
public static Color getColor(Device device, JefColor color) {
return color != null ? color.isColorConstant() ? device.getSystemColor(translateColorConstant(color.getColorConstant())) : new Color(device, color.getRed() & 0xFF, color.getGreen() & 0xFF, color.getBlue() & 0xFF) : null;
}//getColor()//
/**
* Gets the SWT RGB object given a device. An RGB does not use platform system resources unlike a Color instance and therefore is very light weight and does not require disposal.
* @param device The device that the color will be displayed on.
* @param color The foundation color instance from which the color data will be translated.
* @return
*/
public static RGB getRgb(Device device, JefColor color) {
RGB result = null;
if(color != null) {
int red = color.getRed() & 0xFF;
int green = color.getGreen() & 0xFF;
int blue = color.getBlue() & 0xFF;
int colorConstant = translateColorConstant(color.getColorConstant());
if(colorConstant != 0) {
Color constant = device.getSystemColor(colorConstant);
if(constant != null) {
red = constant.getRed();
green = constant.getGreen();
blue = constant.getBlue();
constant.dispose();
}//if//
else {
//Do nothing? Or simulate the constant?//
}//else//
}//if//
result = new RGB(red, green, blue);
}//if//
return result;
}//getRgb()//
/**
* Translates the JEF color constant into a SWT color constant.
* @param jefColorConstant The JEF color constant to be translated.
* @return The SWT color constant, or zero if it could not be translated.
*/
private static int translateColorConstant(int jefColorConstant) {
return jefToSwtColorConstantMap.containsKey(jefColorConstant) ? jefToSwtColorConstantMap.get(jefColorConstant) : 0;
}//translateColorConstant()//
/**
* Gets an image for the given JEF image.
* <p>Warning: The caller is responsible for disposing of the resulting image.</p>
* @param device The SWT device on which the image will be used.
* @param image The JEF image containing the image data and metadata.
* @return The SWT image usable on the given device.
*/
public static Image getImage(Device device, JefImage image) {
return image != null ? new Image(device, new ImageData(new ByteArrayInputStream(image.getImageData()))) : null;
}//getImage()//
/**
* Gets the JEF font data for the given device.
* <p>Warning: The caller is responsible for disposing of the resulting font.</p>
* @param fontData The collection of font objects describing in order what font is desired.
* @return The best matching font for the device.
*/
public static JefFont[] getJefFont(FontData[] fontData) {
JefFont[] result = null;
if(fontData != null) {
result = new JefFont[fontData.length];
//Iterate over the passed font data and create jef font data structures.//
for(int index = 0; index < fontData.length; index++) {
result[index] = new JefFont(fontData[index].getName(), fontData[index].getHeight(), convertFromSwtStyle(fontData[index].getStyle()), null);
}//for//
}//if//
return result;
}//getFontData()//
/**
* Gets the SWT font data for the given device.
* <p>Warning: The caller is responsible for disposing of the resulting font.</p>
* @param device The SWT device whose font is required.
* @param fontData The collection of font objects describing in order what font is desired.
* @return The best matching font for the device.
*/
public static FontData[] getFontData(Device device, JefFont[] fontData) {
FontData[] result = null;
if(fontData != null) {
result = new FontData[fontData.length];
//Iterate over the passed font data and create SWT font data structures.//
for(int index = 0; index < fontData.length; index++) {
String name = fontData[index].getName();
int height = fontData[index].getHeight();
if((name == null) || (height == 0)) {
FontData[] systemFont = device.getSystemFont().getFontData();
if((systemFont != null) && (systemFont.length > 0)) {
if(name == null) {
name = systemFont[0].getName();
}//if//
if(height == 0) {
height = systemFont[0].getHeight();
}//if//
}//if//
}//if//
result[index] = new FontData(name, height, convertToSwtStyle(fontData[index].getStyle()));
}//for//
}//if//
return result;
}//getFontData()//
/**
* Gets the SWT font for the given device.
* <p>Warning: The caller is responsible for disposing of the resulting font.</p>
* @param device The SWT device whose font is required.
* @param fontData The collection of font objects describing in order what font is desired.
* @return The best matching font for the device.
*/
public static Font getFont(Device device, JefFont[] fontData) {
Font result = null;
if(fontData != null) {
FontData[] swtFontData = new FontData[fontData.length];
//Iterate over the passed font data and create SWT font data structures.//
for(int index = 0; index < fontData.length; index++) {
if(fontData[index] != null) {
String name = fontData[index].getName();
int height = fontData[index].getHeight();
if((name == null) || (height == 0)) {
FontData[] systemFont = device.getSystemFont().getFontData();
if((systemFont != null) && (systemFont.length > 0)) {
if(name == null) {
name = systemFont[0].getName();
}//if//
if(height == 0) {
height = systemFont[0].getHeight();
}//if//
}//if//
}//if//
swtFontData[index] = new FontData(name, height, convertToSwtStyle(fontData[index].getStyle()));
}//if//
}//for//
result = new Font(device, swtFontData);
}//if//
return result;
}//getFont()//
/**
* Gets the SWT font for the given device.
* <p>Warning: The caller is responsible for disposing of the resulting font.</p>
* @param device The SWT device whose font is required.
* @param fontData The collection of font objects describing in order what font is desired.
* @return The best matching font for the device.
*/
public static Font getFont(Device device, IList fontData) {
Font result = null;
if(fontData != null) {
if(fontData.getSize() == 1) {
//Small optimization.//
result = getFont(device, (JefFont) fontData.get(0));
}//if//
else {
FontData[] fontDataArray = null;
LiteList swtFontData = new LiteList(fontData.getSize(), 10);
for(int fontDataIndex = 0; fontDataIndex < fontData.getSize(); fontDataIndex++) {
JefFont font = (JefFont) fontData.get(fontDataIndex);
if(font.getName() != null) {
swtFontData.add(new FontData(font.getName(), font.getHeight(), convertToSwtStyle(font.getStyle())));
}//if//
else {
FontData[] systemFontData = device.getSystemFont().getFontData();
for(int systemFontDataIndex = 0; systemFontDataIndex < systemFontData.length; systemFontDataIndex++) {
swtFontData.add(systemFontData[systemFontDataIndex]);
}//for//
}//else//
}//for//
fontDataArray = new FontData[swtFontData.getSize()];
swtFontData.toArray(fontDataArray);
result = new Font(device, fontDataArray);
}//else//
}//if//
return result;
}//getFont()//
/**
* Gets the SWT font for the given device.
* <p>Warning: The caller is responsible for disposing of the resulting font.</p>
* @param device The SWT device whose font is required.
* @param fontData The font object describing what font is desired.
* @return The best matching font for the device.
*/
public static Font getFont(Device device, JefFont fontData) {
return fontData != null ? new Font(device, fontData.getName(), fontData.getHeight(), convertToSwtStyle(fontData.getStyle())) : null;
}//getFont()//
/**
* Converts the style from an SWT style to a JEF style.
* @param swtStyle The SWT style.
* @return The JEF style.
*/
private static int convertFromSwtStyle(int swtStyle) {
int style = JefFont.STYLE_NORMAL;
if((swtStyle & SWT.BOLD) > 0) {
style |= JefFont.STYLE_BOLD;
}//if//
if((swtStyle & SWT.ITALIC) > 0) {
style |= JefFont.STYLE_ITALIC;
}//if//
return style;
}//convertFromSwtStyle()//
/**
* Converts the style from a JEF style to an SWT style.
* @param style The JEF style.
* @return The SWT style.
*/
private static int convertToSwtStyle(int style) {
int swtStyle = SWT.NORMAL;
if((style & JefFont.STYLE_BOLD) > 0) {
swtStyle |= SWT.BOLD;
}//if//
if((style & JefFont.STYLE_ITALIC) > 0) {
swtStyle |= SWT.ITALIC;
}//if//
return swtStyle;
}//convertToSwtStyle()//
/**
* Converts the given font to a bold font.
* @param font The font to convert.
* @return The new bolded font.
*/
public static Font createBoldFont(Font font) {
FontData[] data = font.getFontData();
for(int index = 0; index < data.length; index++) {
data[index].setStyle(SWT.BOLD);
}//for//
return new Font(Display.getCurrent(), data);
}//createBoldFont()//
/**
* Creates a new color that is a blend of two existing colors.
* @param color1 The first color to use.
* @param color2 The second color to user.
* @param ratio The percentage of the first to be used.
* @return The new color.
*/
public static RGB mixColor(RGB color1, RGB color2, int ratio) {
return new RGB((ratio * color1.red + (100 - ratio) * color2.red) / 100, (ratio * color1.green + (100 - ratio) * color2.green) / 100, (ratio * color1.blue + (100 - ratio) * color2.blue) / 100);
}//mixColor()//
/**
* Creates a new color that is a blend of two existing colors.
* @param color1 The first color to use.
* @param color2 The second color to user.
* @param ratio The percentage of the first to be used.
* @return The new color.
*/
public static Color mixColor(Color color1, Color color2, int ratio) {
return new Color(Display.getCurrent(), (ratio * color1.getRed() + (100 - ratio) * color2.getRed()) / 100, (ratio * color1.getGreen() + (100 - ratio) * color2.getGreen()) / 100, (ratio * color1.getBlue() + (100 - ratio) * color2.getBlue()) / 100);
}//mixColor()//
/**
* Truncates the text, and optionally appends a string at the end or middle (usually '...'), such that the resulting text fits the requested width.
* @param gc The graphics context.
* @param text The text to be truncated.
* @param postPend The string to append when truncating the text.
* @param width The maximum width of the text.
* @param processFormattingCharacters Whether the size calculation should take tab, carriage returns, and other formatting characters into account.
* @param centerTruncate Whether any removed text should come from the middle of the string instead of the end.
* @return The modified text.
*/
public static String truncateText(GC gc, String text, String postPend, int width, boolean processFormattingCharacters, boolean centerTruncate) {
if(text != null && text.length() > 0) {
Point textExtent = processFormattingCharacters ? gc.textExtent(text) : gc.stringExtent(text);
Point dotExtent = postPend == null ? new Point(0, 0) : processFormattingCharacters ? gc.textExtent(postPend) : gc.stringExtent(postPend);
if(width < textExtent.x) {
LiteList lines = new LiteList(10, 100);
//If we are processing formatting characters then break up the text into lines (minus the terminator) followed by the line terminator.//
if(processFormattingCharacters) {
int nextLineBreak = 0;
int index = text.indexOf("\r\n", nextLineBreak);
int breakCharacterCount = 2;
if(index == -1) {
index = text.indexOf('\n', nextLineBreak);
breakCharacterCount = 1;
}//if//
while(index != -1) {
//Add the line to the list, then add the terminator to the list.//
lines.add(text.substring(nextLineBreak, index));
lines.add(text.substring(index, index + breakCharacterCount));
nextLineBreak = index + breakCharacterCount;
index = text.indexOf("\r\n", nextLineBreak);
breakCharacterCount = 2;
if(index == -1) {
index = text.indexOf('\n', nextLineBreak);
breakCharacterCount = 1;
}//if//
}//while//
lines.add(text.substring(nextLineBreak));
}//if//
else {
lines.add(text);
}//else//
text = "";
//Modify each line separately.//
for(int lineIndex = 0; lineIndex < lines.getSize(); lineIndex++) {
String line = (String) lines.get(lineIndex);
int lineLength = line.length();
Point lineExtent = processFormattingCharacters ? gc.textExtent(line) : gc.stringExtent(line);
//Check the line prior to hacking it up.//
if(width < lineExtent.x) {
boolean done = false;
//We can either remove characters from the center, or from the end.//
if(centerTruncate) {
int midpoint = lineLength >> 1;
int start = midpoint;
int end = midpoint + 1;
boolean removeFromEnd = false;
//TODO: This would be a lot faster if we used a more complex search pattern.
//Search for the largest string that fits the width.//
while(!done && start >= 0 && end < lineLength) {
String beginningSection = line.substring(0, start);
String endingSection = line.substring(end);
int beginningWidth = (processFormattingCharacters ? gc.textExtent(beginningSection) : gc.stringExtent(beginningSection)).x;
int endingWidth = (processFormattingCharacters ? gc.textExtent(endingSection) : gc.stringExtent(endingSection)).x;
//If the line fits then wear it.//
if(beginningWidth + dotExtent.x + endingWidth < width) {
line = beginningSection + postPend + endingSection;
done = true;
}//if//
//Switch between removing characters from the end or beginning of the line.//
if(removeFromEnd) {
end--;
removeFromEnd = false;
}//if//
else {
start--;
removeFromEnd = true;
}//else//
}//for//
}//if//
else {
for(int index = lineLength - 1; index > 0; index--) {
String section = line.substring(0, index);
int lineWidth = (processFormattingCharacters ? gc.textExtent(section) : gc.stringExtent(section)).x;
//If the line fits then wear it.//
if(lineWidth + dotExtent.x < width) {
line = section + postPend;
done = true;
}//if//
}//for//
}//else//
//If we can't get any characters in the given width then just use the postPend text and hope something shows up.//
if(!done) {
line = postPend;
}//if//
}//if//
//Add the modified line to the text.//
text += line;
//Add the line terminator (which has no width).//
if(lineIndex + 1 != lines.getSize()) {
text += lines.get(++lineIndex);
}//if//
}//for//
}//if//
}//if//
return text;
}//truncateText()//
}//SwtUtilities//