001: /*******************************************************************************
002: * Copyright (c) 2004, 2007 IBM Corporation and others.
003: * All rights reserved. This program and the accompanying materials
004: * are made available under the terms of the Eclipse Public License v1.0
005: * which accompanies this distribution, and is available at
006: * http://www.eclipse.org/legal/epl-v10.html
007: *
008: * Contributors:
009: * IBM Corporation - initial API and implementation
010: *******************************************************************************/package org.eclipse.ui.themes;
011:
012: import java.lang.reflect.Field;
013: import java.lang.reflect.Modifier;
014: import java.util.ArrayList;
015:
016: import org.eclipse.jface.resource.DataFormatException;
017: import org.eclipse.jface.resource.StringConverter;
018: import org.eclipse.swt.SWT;
019: import org.eclipse.swt.graphics.RGB;
020: import org.eclipse.swt.widgets.Display;
021:
022: /**
023: * Useful color utilities.
024: *
025: * @since 3.0 - initial release
026: * @since 3.2 - public API
027: */
028: public final class ColorUtil {
029:
030: private static Field[] cachedFields;
031:
032: /**
033: * Process the given string and return a corresponding RGB object.
034: *
035: * @param value
036: * the SWT constant <code>String</code>
037: * @return the value of the SWT constant, or <code>SWT.COLOR_BLACK</code>
038: * if it could not be determined
039: */
040: private static RGB process(String value) {
041: Field[] fields = getFields();
042: try {
043: for (int i = 0; i < fields.length; i++) {
044: Field field = fields[i];
045: if (field.getName().equals(value)) {
046: return getSystemColor(field.getInt(null));
047: }
048: }
049: } catch (IllegalArgumentException e) {
050: // no op - shouldnt happen. We check for static before calling
051: // getInt(null)
052: } catch (IllegalAccessException e) {
053: // no op - shouldnt happen. We check for public before calling
054: // getInt(null)
055: }
056: return getSystemColor(SWT.COLOR_BLACK);
057: }
058:
059: /**
060: * Get the SWT constant fields.
061: *
062: * @return the fields
063: * @since 3.3
064: */
065: private static Field[] getFields() {
066: if (cachedFields == null) {
067: Class clazz = SWT.class;
068: Field[] allFields = clazz.getDeclaredFields();
069: ArrayList applicableFields = new ArrayList(allFields.length);
070:
071: for (int i = 0; i < allFields.length; i++) {
072: Field field = allFields[i];
073: if (field.getType() == Integer.TYPE
074: && Modifier.isStatic(field.getModifiers())
075: && Modifier.isPublic(field.getModifiers())
076: && Modifier.isFinal(field.getModifiers())
077: && field.getName().startsWith("COLOR")) { //$NON-NLS-1$
078:
079: applicableFields.add(field);
080: }
081: }
082: cachedFields = (Field[]) applicableFields
083: .toArray(new Field[applicableFields.size()]);
084: }
085: return cachedFields;
086: }
087:
088: /**
089: * Blends the two color values according to the provided ratio.
090: *
091: * @param c1
092: * first color
093: * @param c2
094: * second color
095: * @param ratio
096: * percentage of the first color in the blend (0-100)
097: * @return the RGB value of the blended color
098: *
099: * @since 3.3
100: */
101: public static RGB blend(RGB c1, RGB c2, int ratio) {
102: int r = blend(c1.red, c2.red, ratio);
103: int g = blend(c1.green, c2.green, ratio);
104: int b = blend(c1.blue, c2.blue, ratio);
105: return new RGB(r, g, b);
106: }
107:
108: private static int blend(int v1, int v2, int ratio) {
109: int b = (ratio * v1 + (100 - ratio) * v2) / 100;
110: return Math.min(255, b);
111: }
112:
113: /**
114: * Blend the two color values returning a value that is halfway between
115: * them.
116: *
117: * @param val1
118: * the first value
119: * @param val2
120: * the second value
121: * @return the blended color
122: */
123: public static RGB blend(RGB val1, RGB val2) {
124: int red = blend(val1.red, val2.red);
125: int green = blend(val1.green, val2.green);
126: int blue = blend(val1.blue, val2.blue);
127: return new RGB(red, green, blue);
128: }
129:
130: /**
131: * Blend the two color values returning a value that is halfway between
132: * them.
133: *
134: * @param temp1
135: * the first value
136: * @param temp2
137: * the second value
138: * @return the blended int value
139: */
140: private static int blend(int temp1, int temp2) {
141: return (Math.abs(temp1 - temp2) / 2) + Math.min(temp1, temp2);
142: }
143:
144: /**
145: * Return the system color that matches the provided SWT constant value.
146: *
147: * @param colorId
148: * the system color identifier
149: * @return the RGB value of the supplied system color
150: */
151: private static RGB getSystemColor(int colorId) {
152: return Display.getCurrent().getSystemColor(colorId).getRGB();
153: }
154:
155: /**
156: * Get the RGB value for a given color.
157: *
158: * @param rawValue
159: * the raw value, either an RGB triple or an SWT constant name
160: * @return the RGB value
161: * @throws DataFormatException
162: * thrown if the value cannot be interpreted as a color
163: */
164: public static RGB getColorValue(String rawValue)
165: throws DataFormatException {
166: if (rawValue == null) {
167: return null;
168: }
169:
170: rawValue = rawValue.trim();
171:
172: if (!isDirectValue(rawValue)) {
173: return process(rawValue);
174: }
175:
176: return StringConverter.asRGB(rawValue);
177: }
178:
179: /**
180: * Get the RGB values for a given color array.
181: *
182: * @param rawValues
183: * the raw values, either RGB triple or an SWT constant
184: * @return the RGB values
185: */
186: public static RGB[] getColorValues(String[] rawValues) {
187: RGB[] values = new RGB[rawValues.length];
188: for (int i = 0; i < rawValues.length; i++) {
189: values[i] = getColorValue(rawValues[i]);
190: }
191: return values;
192: }
193:
194: /**
195: * Return whether the value returned by <code>getValue()</code> is already
196: * in RGB form.
197: *
198: * @return whether the value returned by <code>getValue()</code> is
199: * already in RGB form
200: */
201: private static boolean isDirectValue(String rawValue) {
202: return rawValue.indexOf(',') >= 0;
203: }
204:
205: /**
206: * Not intended to be instantiated.
207: */
208: private ColorUtil() {
209: // no-op
210: }
211: }
|