/*
* 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);
}