001: /*******************************************************************************
002: * Copyright (c) 2004, 2006 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.internal.themes;
011:
012: import java.util.ArrayList;
013: import java.util.Arrays;
014: import java.util.Collections;
015: import java.util.HashMap;
016: import java.util.HashSet;
017: import java.util.Iterator;
018: import java.util.List;
019: import java.util.Map;
020: import java.util.Set;
021:
022: import org.eclipse.ui.themes.IThemeManager;
023:
024: /**
025: * The central manager for Theme descriptors.
026: *
027: * @since 3.0
028: */
029: public class ThemeRegistry implements IThemeRegistry {
030:
031: private List themes;
032:
033: private List colors;
034:
035: private List fonts;
036:
037: private List categories;
038:
039: private Map dataMap;
040:
041: /**
042: * Map from String (categoryId) -> Set (presentationIds)
043: */
044: private Map categoryBindingMap;
045:
046: /**
047: * Create a new ThemeRegistry.
048: */
049: public ThemeRegistry() {
050: themes = new ArrayList();
051: colors = new ArrayList();
052: fonts = new ArrayList();
053: categories = new ArrayList();
054: dataMap = new HashMap();
055: categoryBindingMap = new HashMap();
056: }
057:
058: /**
059: * Add a descriptor to the registry.
060: */
061: void add(IThemeDescriptor desc) {
062: if (findTheme(desc.getId()) != null) {
063: return;
064: }
065: themes.add(desc);
066: }
067:
068: /**
069: * Add a descriptor to the registry.
070: */
071: void add(ColorDefinition desc) {
072: if (findColor(desc.getId()) != null) {
073: return;
074: }
075: colors.add(desc);
076: }
077:
078: /* (non-Javadoc)
079: * @see org.eclipse.ui.internal.themes.IThemeRegistry#findCategory(java.lang.String)
080: */
081: public ThemeElementCategory findCategory(String id) {
082: return (ThemeElementCategory) findDescriptor(getCategories(),
083: id);
084: }
085:
086: /* (non-Javadoc)
087: * @see org.eclipse.ui.internal.themes.IThemeRegistry#findColor(java.lang.String)
088: */
089: public ColorDefinition findColor(String id) {
090: return (ColorDefinition) findDescriptor(getColors(), id);
091: }
092:
093: /* (non-Javadoc)
094: * @see org.eclipse.ui.internal.registry.IThemeRegistry#find(java.lang.String)
095: */
096: public IThemeDescriptor findTheme(String id) {
097: return (IThemeDescriptor) findDescriptor(getThemes(), id);
098: }
099:
100: /**
101: * @param descriptors
102: * @param id
103: * @return
104: */
105: private IThemeElementDefinition findDescriptor(
106: IThemeElementDefinition[] descriptors, String id) {
107: int idx = Arrays.binarySearch(descriptors, id, ID_COMPARATOR);
108: if (idx < 0) {
109: return null;
110: }
111: return descriptors[idx];
112: }
113:
114: /* (non-Javadoc)
115: * @see org.eclipse.ui.internal.registry.IThemeRegistry#getLookNFeels()
116: */
117: public IThemeDescriptor[] getThemes() {
118: int nSize = themes.size();
119: IThemeDescriptor[] retArray = new IThemeDescriptor[nSize];
120: themes.toArray(retArray);
121: Arrays.sort(retArray, ID_COMPARATOR);
122: return retArray;
123: }
124:
125: /* (non-Javadoc)
126: * @see org.eclipse.ui.internal.registry.IThemeRegistry#getLookNFeels()
127: */
128: public ColorDefinition[] getColors() {
129: int nSize = colors.size();
130: ColorDefinition[] retArray = new ColorDefinition[nSize];
131: colors.toArray(retArray);
132: Arrays.sort(retArray, ID_COMPARATOR);
133: return retArray;
134: }
135:
136: /* (non-Javadoc)
137: * @see org.eclipse.ui.internal.themes.IThemeRegistry#getColorsFor(java.lang.String)
138: */
139: public ColorDefinition[] getColorsFor(String themeId) {
140: ColorDefinition[] defs = getColors();
141: if (themeId.equals(IThemeManager.DEFAULT_THEME)) {
142: return defs;
143: }
144:
145: IThemeDescriptor desc = findTheme(themeId);
146: ColorDefinition[] overrides = desc.getColors();
147: return (ColorDefinition[]) overlay(defs, overrides);
148: }
149:
150: /* (non-Javadoc)
151: * @see org.eclipse.ui.internal.themes.IThemeRegistry#getFontsFor(java.lang.String)
152: */
153: public FontDefinition[] getFontsFor(String themeId) {
154: FontDefinition[] defs = getFonts();
155: if (themeId.equals(IThemeManager.DEFAULT_THEME)) {
156: return defs;
157: }
158:
159: IThemeDescriptor desc = findTheme(themeId);
160: FontDefinition[] overrides = desc.getFonts();
161: return (FontDefinition[]) overlay(defs, overrides);
162: }
163:
164: /**
165: * Overlay the overrides onto the base definitions.
166: *
167: * @param defs the base definitions
168: * @param overrides the overrides
169: * @return the overlayed elements
170: */
171: private IThemeElementDefinition[] overlay(
172: IThemeElementDefinition[] defs,
173: IThemeElementDefinition[] overrides) {
174: for (int i = 0; i < overrides.length; i++) {
175: int idx = Arrays.binarySearch(defs, overrides[i],
176: IThemeRegistry.ID_COMPARATOR);
177: if (idx >= 0) {
178: defs[idx] = overlay(defs[idx], overrides[i]);
179: }
180: }
181: return defs;
182: }
183:
184: /**
185: * Overlay the override onto the base definition.
186: *
187: * @param defs the base definition
188: * @param overrides the override
189: * @return the overlayed element
190: */
191: private IThemeElementDefinition overlay(
192: IThemeElementDefinition original,
193: IThemeElementDefinition overlay) {
194: if (original instanceof ColorDefinition) {
195: ColorDefinition originalColor = (ColorDefinition) original;
196: ColorDefinition overlayColor = (ColorDefinition) overlay;
197: return new ColorDefinition(originalColor, overlayColor
198: .getValue());
199: } else if (original instanceof FontDefinition) {
200: FontDefinition originalFont = (FontDefinition) original;
201: FontDefinition overlayFont = (FontDefinition) overlay;
202: return new FontDefinition(originalFont, overlayFont
203: .getValue());
204: }
205: return null;
206: }
207:
208: /**
209: * @param definition
210: */
211: void add(FontDefinition definition) {
212: if (findFont(definition.getId()) != null) {
213: return;
214: }
215: fonts.add(definition);
216: }
217:
218: /* (non-Javadoc)
219: * @see org.eclipse.ui.internal.themes.IThemeRegistry#getGradients()
220: */
221: public FontDefinition[] getFonts() {
222: int nSize = fonts.size();
223: FontDefinition[] retArray = new FontDefinition[nSize];
224: fonts.toArray(retArray);
225: Arrays.sort(retArray, ID_COMPARATOR);
226: return retArray;
227: }
228:
229: /* (non-Javadoc)
230: * @see org.eclipse.ui.internal.themes.IThemeRegistry#findFont(java.lang.String)
231: */
232: public FontDefinition findFont(String id) {
233: return (FontDefinition) findDescriptor(getFonts(), id);
234: }
235:
236: /**
237: * @param definition
238: */
239: void add(ThemeElementCategory definition) {
240: if (findCategory(definition.getId()) != null) {
241: return;
242: }
243: categories.add(definition);
244: }
245:
246: /* (non-Javadoc)
247: * @see org.eclipse.ui.internal.themes.IThemeRegistry#getCategories()
248: */
249: public ThemeElementCategory[] getCategories() {
250: int nSize = categories.size();
251: ThemeElementCategory[] retArray = new ThemeElementCategory[nSize];
252: categories.toArray(retArray);
253: Arrays.sort(retArray, ID_COMPARATOR);
254: return retArray;
255: }
256:
257: /**
258: * @param name
259: * @param value
260: */
261: void setData(String name, String value) {
262: if (dataMap.containsKey(name)) {
263: return;
264: }
265:
266: dataMap.put(name, value);
267: }
268:
269: /* (non-Javadoc)
270: * @see org.eclipse.ui.internal.themes.IThemeRegistry#getData()
271: */
272: public Map getData() {
273: return Collections.unmodifiableMap(dataMap);
274: }
275:
276: /**
277: * Add the data from another map to this data
278: *
279: * @param otherData the other data to add
280: */
281: public void addData(Map otherData) {
282: for (Iterator i = otherData.keySet().iterator(); i.hasNext();) {
283: Object key = i.next();
284: if (dataMap.containsKey(key)) {
285: continue;
286: }
287: dataMap.put(key, otherData.get(key));
288: }
289: }
290:
291: /**
292: * Add a category presentation binding. The given category will only be
293: * availible if the given presentation is active.
294: *
295: * @param categoryId the category id
296: * @param presentationId the presentation id
297: */
298: public void addCategoryPresentationBinding(String categoryId,
299: String presentationId) {
300: Set presentations = (Set) categoryBindingMap.get(categoryId);
301: if (presentations == null) {
302: presentations = new HashSet();
303: categoryBindingMap.put(categoryId, presentations);
304: }
305: presentations.add(presentationId);
306: }
307:
308: /* (non-Javadoc)
309: * @see org.eclipse.ui.internal.themes.IThemeRegistry#getPresentationsBindingsFor(org.eclipse.ui.internal.themes.ThemeElementCategory)
310: */
311: public Set getPresentationsBindingsFor(ThemeElementCategory category) {
312: return (Set) categoryBindingMap.get(category.getId());
313: }
314: }
|