package at.bestsolution.efxclipse.runtime.theme.internal; import java.net.URL; import java.util.ArrayList; import java.util.List; import javafx.scene.Scene; import org.eclipse.core.runtime.IConfigurationElement; import org.eclipse.core.runtime.IExtensionRegistry; import org.eclipse.core.runtime.Platform; import org.eclipse.core.runtime.RegistryFactory; import org.osgi.framework.Bundle; import com.sun.javafx.css.StyleManager; import at.bestsolution.efxclipse.runtime.services.theme.Theme; import at.bestsolution.efxclipse.runtime.services.theme.ThemeManager; public class DefaultThemeManager implements ThemeManager { static final String ATT_ID = "id"; static final String ATT_NAME = "name"; static final String ATT_THEME_ID = "themeId"; static final String ATT_BASETYLESHEET = "basestylesheet"; static final String ATT_RESOURCE = "resource"; static class ThemeImpl implements Theme { private final IConfigurationElement element; private final List<IConfigurationElement> stylesheetElements = new ArrayList<IConfigurationElement>(); private final List<URL> resolvedUrls = new ArrayList<URL>(); public ThemeImpl(IConfigurationElement element) { this.element = element; } void addStylesheet(IConfigurationElement stylesheet) { this.resolvedUrls.clear(); this.stylesheetElements.add(stylesheet); } @Override public String getId() { return this.element.getAttribute(ATT_ID); } @Override public String getName() { return this.element.getAttribute(ATT_NAME); } @Override public List<URL> getStylesheetURL() { if (resolvedUrls.isEmpty()) { URL url = getUrl(element, ATT_BASETYLESHEET); if (url != null) { resolvedUrls.add(url); } else { // TODO Log an error } for (IConfigurationElement e : stylesheetElements) { url = getUrl(e, ATT_RESOURCE); if (url != null) { resolvedUrls.add(url); } else { // TODO Log an error } } } return resolvedUrls; } private URL getUrl(IConfigurationElement e, String attributeName) { String resource = e.getAttribute(attributeName); String contributer = e.getDeclaringExtension().getContributor().getName(); Bundle b = Platform.getBundle(contributer); return b.getResource(resource); } } private final List<Theme> themes = new ArrayList<Theme>(); private String currentThemeId; private List<Scene> managedScenes = new ArrayList<Scene>(); public DefaultThemeManager() { IExtensionRegistry registry = RegistryFactory.getRegistry(); for (IConfigurationElement e : registry.getConfigurationElementsFor("at.bestsolution.efxclipse.runtime.theme")) { if (e.getName().equals("theme")) { themes.add(new ThemeImpl(e)); } } for (IConfigurationElement e : registry.getConfigurationElementsFor("at.bestsolution.efxclipse.runtime.theme")) { if (e.getName().equals("stylesheet")) { String themeId = e.getAttribute(ATT_THEME_ID); for (Theme t : themes) { if (t.getId().equals(themeId)) { } } } } } @Override public Theme getCurrentTheme() { if (themes.size() == 1) { return themes.get(0); } else { String id = getCurrentThemeId(); if (id != null) { for (Theme t : themes) { if (t.getId().equals(id)) { return t; } } } themes.get(0); } return null; } @Override public List<Theme> getAvailableThemes() { return themes; } @SuppressWarnings("restriction") @Override public void setCurrentThemeId(String id) { for (Theme t : themes) { if (t.getId().equals(id)) { currentThemeId = id; for( Scene scene : managedScenes ) { List<Theme> availableThemes = getAvailableThemes(); for (Theme theme : availableThemes) { for (URL url : theme.getStylesheetURL()) { scene.getStylesheets().remove(url.toExternalForm()); } } for (Theme theme : availableThemes) { for (URL url : theme.getStylesheetURL()) { if (theme.getId().equals(currentThemeId)) { scene.getStylesheets().add(url.toExternalForm()); } } } StyleManager.getInstance().reloadStylesheets(scene); } return; } } throw new IllegalArgumentException("Theme with id '" + id + "' is not known."); } private String getCurrentThemeId() { return currentThemeId; } @Override public Registration registerScene(final Scene scene) { managedScenes.add(scene); return new Registration() { @Override public void dispose() { managedScenes.remove(scene); } }; } }