/* * Copyright 2003-2013 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package jetbrains.mps.editor.runtime.style; import jetbrains.mps.logging.Logger; import jetbrains.mps.openapi.editor.descriptor.EditorAspectDescriptor; import jetbrains.mps.openapi.editor.descriptor.StyleAttributeProvider; import jetbrains.mps.openapi.editor.style.StyleAttribute; import jetbrains.mps.openapi.editor.style.StyleRegistry; import jetbrains.mps.smodel.language.LanguageRegistry; import jetbrains.mps.smodel.language.LanguageRegistryListener; import jetbrains.mps.smodel.language.LanguageRuntime; import org.apache.log4j.LogManager; import org.jetbrains.mps.openapi.model.SNode; import java.awt.Color; import java.awt.Font; import java.util.ArrayList; import java.util.HashMap; import java.util.LinkedHashSet; import java.util.List; import java.util.Map; import java.util.Set; /** * User: shatalin * Date: 1/14/13 */ public class StyleAttributes { private static StyleAttributes ourInstance; private static final Logger LOG = Logger.wrap(LogManager.getLogger(StyleAttributes.class)); private StyleAttributes() { if (LanguageRegistry.getInstance() == null) { // For testing purposes // TODO: modify this code. Introduce ILanguageAspect.dispose() method, unregister // TODO: StyleAttributes from EditorAspectDescriptor.dispose() // TODO: similar code present in ValidEditorDescriptorsCache return; } LanguageRegistry.getInstance().addRegistryListener(new LanguageRegistryListener() { @Override public void afterLanguagesLoaded(Iterable<LanguageRuntime> languages) { } @Override public void beforeLanguagesUnloaded(Iterable<LanguageRuntime> languages) { for (LanguageRuntime language : languages) { Map<String, StyleAttribute> attributeMap = ourLanguageAttributes.get(language); if (attributeMap != null) { for (StyleAttribute attribute : attributeMap.values()) { attribute.unregister(); } ourLanguageAttributes.remove(language); } } } }); } public static StyleAttributes getInstance() { if (ourInstance == null) { ourInstance = new StyleAttributes(); } return ourInstance; } private List<StyleAttribute> ourAttributes = new ArrayList<StyleAttribute>(); private Set<Integer> ourFreeIndices = new LinkedHashSet<Integer>(); private Map<LanguageRuntime, Map<String, StyleAttribute>> ourLanguageAttributes = new HashMap<LanguageRuntime, Map<String, StyleAttribute>>(); int getAttributesCount() { return ourAttributes.size(); } StyleAttribute getAttributeByIndex(int index) { return ourAttributes.get(index); } int register(StyleAttribute a) { int index; if (ourFreeIndices.isEmpty()) { index = ourAttributes.size(); ourAttributes.add(a); } else { index = ourFreeIndices.iterator().next(); ourFreeIndices.remove(index); ourAttributes.set(index, a); } return index; } void unregister(StyleAttribute a) { int index = ourAttributes.indexOf(a); ourAttributes.set(index, null); ourFreeIndices.add(index); } static boolean isSimple(StyleAttribute a) { return a instanceof SimpleStyleAttribute; } public <T> StyleAttribute<T> getAttribute(String languageName, String attributeName) { LanguageRuntime language = LanguageRegistry.getInstance().getLanguage(languageName); if (language == null) { throw new IllegalArgumentException("language not found: " + languageName); } if (!ourLanguageAttributes.containsKey(language)) { ourLanguageAttributes.put(language, new HashMap<String, StyleAttribute>()); } if (ourLanguageAttributes.get(language).containsKey(attributeName)) { return ourLanguageAttributes.get(language).get(attributeName); } else { EditorAspectDescriptor editorAspectDescriptor = language.getAspect(EditorAspectDescriptor.class); if (!(editorAspectDescriptor instanceof StyleAttributeProvider)) { throw new IllegalArgumentException("language does not contain editor descriptor: " + languageName); } StyleAttribute attribute = ((StyleAttributeProvider) editorAspectDescriptor).getStyleAttribute(attributeName); if (attribute == null) { throw new IllegalArgumentException("language " + languageName + "does not contain style attribute" + attributeName); } ourLanguageAttributes.get(language).put(attributeName, attribute); attribute.register(); return attribute; } } public static final StyleAttribute<Color> BACKGROUND_COLOR = new InheritableStyleAttribute<Color>("background-color", null, true); public static final StyleAttribute<Color> BRACKETS_COLOR = new InheritableStyleAttribute<Color>("bracket-color", Color.BLACK, true); public static final StyleAttribute<Color> TEXT_COLOR = new InheritableStyleAttribute<Color>("text-color", StyleRegistry.getInstance() != null ? StyleRegistry.getInstance().getEditorForeground() : Color.BLACK, true); public static final StyleAttribute<Color> NULL_TEXT_COLOR = new InheritableStyleAttribute<Color>("null-text-color", StyleRegistry.getInstance() != null ? StyleRegistry.getInstance().getColor("DEFAULT_NULL_TEXT_COLOR") : Color.GRAY, true); public static final StyleAttribute<Color> TEXT_BACKGROUND_COLOR = new InheritableStyleAttribute<Color>("text-background-color", null, true); public static final StyleAttribute<Color> NULL_TEXT_BACKGROUND_COLOR = new InheritableStyleAttribute<Color>("null-text-color", null, true); public static final StyleAttribute<Color> SELECTED_TEXT_BACKGROUND_COLOR = new InheritableStyleAttribute<Color>("selected-text-background-color", null, true); public static final StyleAttribute<Color> NULL_SELECTED_TEXT_BACKGROUND_COLOR = new InheritableStyleAttribute<Color>("null-selected-text-color", null, true); public static final StyleAttribute<Boolean> DRAW_BRACKETS = new SimpleStyleAttribute<Boolean>("draw-brackets", false, true); public static final StyleAttribute<Boolean> DRAW_BORDER = new SimpleStyleAttribute<Boolean>("draw-border", false, true); public static final StyleAttribute<Boolean> SELECTABLE = new SimpleStyleAttribute<Boolean>("selectable", true, true); public static final StyleAttribute<Boolean> EDITABLE = new SimpleStyleAttribute<Boolean>("editable", true, true); public static final StyleAttribute<Boolean> READ_ONLY = new InheritableStyleAttribute<Boolean>("read-only", false, true); public static final StyleAttribute<Boolean> UNDERLINED = new SimpleStyleAttribute<Boolean>("underlined", false, true); public static final StyleAttribute<Boolean> STRIKE_OUT = new SimpleStyleAttribute<Boolean>("deprecated", false, true); public static final StyleAttribute<Boolean> BASE_LINE_CELL = new SimpleStyleAttribute<Boolean>("baseLineCell", false, true); public static final StyleAttribute<DefaultBaseLine> DEFAULT_BASE_LINE = new SimpleStyleAttribute<DefaultBaseLine>("default-baseline", DefaultBaseLine.FIRST, true); public static final StyleAttribute<Boolean> CONTROL_OVERED_REFERENCE = new SimpleStyleAttribute<Boolean>("control-overed-reference", false, true); public static final StyleAttribute<String> RT_ANCHOR_TAG = new SimpleStyleAttribute<String>("rt-anchor-tag", SideTransformTagUtils.getDefaultSideTransformTag(), true); public static final StyleAttribute<String> LAYOUT_CONSTRAINT = new SimpleStyleAttribute<String>("layout-constraint", null, true); public static final StyleAttribute<FocusPolicy> FOCUS_POLICY = new SimpleStyleAttribute<FocusPolicy>("focus-policy", FocusPolicy.NONE, true); public static final StyleAttribute<CaretPosition> DEFAULT_CARET_POSITION = new SimpleStyleAttribute<CaretPosition>("default-caret-position", null, true); public static final StyleAttribute<Boolean> AUTO_DELETABLE = new SimpleStyleAttribute<Boolean>("auto-deletable", false, true); public static final StyleAttribute<Integer> FONT_STYLE = new InheritableStyleAttribute<Integer>("font-style", Font.PLAIN, true); public static final StyleAttribute<Integer> FONT_SIZE = new InheritableStyleAttribute<Integer>("font-size", null, true); public static final StyleAttribute<Padding> PADDING_LEFT = new SimpleStyleAttribute<Padding>("padding-left", new Padding(0.0), true); public static final StyleAttribute<Padding> PADDING_RIGHT = new SimpleStyleAttribute<Padding>("padding-right", new Padding(0.0), true); public static final StyleAttribute<Padding> PADDING_TOP = new SimpleStyleAttribute<Padding>("padding-top", new Padding(0.0), true); public static final StyleAttribute<Padding> PADDING_BOTTOM = new SimpleStyleAttribute<Padding>("padding-bottom", new Padding(0.0), true); public static final StyleAttribute<Boolean> FIRST_POSITION_ALLOWED = new SimpleStyleAttribute<Boolean>("first-position-allowed", true, true); public static final StyleAttribute<Boolean> LAST_POSITION_ALLOWED = new SimpleStyleAttribute<Boolean>("last-position-allowed", true, true); public static final StyleAttribute<Boolean> PUNCTUATION_LEFT = new SimpleStyleAttribute<Boolean>("punctuation-left", false, true); public static final StyleAttribute<Boolean> PUNCTUATION_RIGHT = new SimpleStyleAttribute<Boolean>("punctuation-right", false, true); public static final StyleAttribute<Padding> HORIZONTAL_GAP = new SimpleStyleAttribute<Padding>("horizontal-gap", new Padding(1.0), true); public static final StyleAttribute<String> POSITION = new SimpleStyleAttribute<String>("position", null, true); public static final StyleAttribute<String> POSITION_CHILDREN = new SimpleStyleAttribute<String>("position-children", null, true); public static final StyleAttribute<String> NAVIGATABLE_REFERENCE = new SimpleStyleAttribute<String>("navigatableReference", null, true); public static final StyleAttribute<CellAlign> HORIZONTAL_ALIGN = new SimpleStyleAttribute<CellAlign>("horizontal-align", CellAlign.LEFT, true); public static final StyleAttribute<String> MATCHING_LABEL = new SimpleStyleAttribute<String>("matching-label", null, true); public static final StyleAttribute<ShowBoundariesArea> SHOW_BOUNDARIES_IN = new SimpleStyleAttribute<>("show-boundaries-in", null, true); public static final StyleAttribute<Boolean> INDENT_LAYOUT_INDENT = new SimpleStyleAttribute<Boolean>("indent-layout-indented", false, true); public static final StyleAttribute<Boolean> INDENT_LAYOUT_INDENT_ANCHOR = new SimpleStyleAttribute<Boolean>("indent-layout-indent-anchor", false, true); public static final StyleAttribute<Boolean> INDENT_LAYOUT_WRAP_ANCHOR = new SimpleStyleAttribute<Boolean>("indent-layout-wrap-anchor", false, true); public static final StyleAttribute<Boolean> INDENT_LAYOUT_NEW_LINE = new SimpleStyleAttribute<Boolean>("indent-layout-new-line", false, true); public static final StyleAttribute<Boolean> INDENT_LAYOUT_ON_NEW_LINE = new SimpleStyleAttribute<Boolean>("indent-layout-on-new-line", false, true); public static final StyleAttribute<Boolean> INDENT_LAYOUT_CHILDREN_NEWLINE = new SimpleStyleAttribute<Boolean>("indent-layout-children-new-line", false, true); public static final StyleAttribute<Boolean> INDENT_LAYOUT_NO_WRAP = new SimpleStyleAttribute<Boolean>("indent-layout-no-wrap", false, true); public static final StyleAttribute<ParametersInformation> PARAMETERS_INFORMATION = new SimpleStyleAttribute<ParametersInformation>("parameters-information", null, true); public static final StyleAttribute<ScriptKind> SCRIPT_KIND = new SimpleStyleAttribute<ScriptKind>("script-kind", ScriptKind.NORMAL, true); public static final StyleAttribute<Integer> ORIGINAL_FONT_SIZE = new SimpleStyleAttribute<Integer>("original-font-size", null, true); public static final StyleAttribute<TableComponent> TABLE_COMPONENT = new SimpleStyleAttribute<TableComponent>("table-component", TableComponent.HORIZONTAL_COLLECTION, true); public static final StyleAttribute<SNode> NAVIGATABLE_NODE = new SimpleStyleAttribute<SNode>("navigatable-node", null, true); public static final StyleAttribute<Integer> MAX_WIDTH = new SimpleStyleAttribute<Integer>("max.width", null, true); }