javafx: color completion/navigation/gutter (IDEA-101338)

This commit is contained in:
anna
2013-03-07 15:48:22 +01:00
parent be67ee2664
commit e68f79a45b
10 changed files with 169 additions and 28 deletions
@@ -136,6 +136,10 @@ public class JavaFXHighlightingTest extends DaemonAnalyzerTestCase {
doTestNavigation("MyController", "label", "injected/" + getTestName(true) + ".fxml", "injected/FooVBox.java", "injected/MyController.java");
}
public void testNamedColor() throws Exception {
doTestNavigation(JavaFxCommonClassNames.JAVAFX_SCENE_COLOR, "ORANGE");
}
private void doTestNavigation(String resultClassName, String resultFieldName) throws Exception {
doTestNavigation(resultClassName, resultFieldName, ArrayUtil.EMPTY_STRING_ARRAY);
}
@@ -109,6 +109,10 @@ public class JavaFxCompletionTest extends CompletionTestCase {
doTest("stylesheets");
}
public void testNamedColors() throws Exception {
doTest("blue");
}
public void testReadOnly() throws Exception {
configureByFile(getTestName(true) + ".fxml");
assertTrue(myItems.length > 0);
@@ -35,6 +35,7 @@ public class JavaFxCommonClassNames {
@NonNls public static final String JAVAFX_EVENT_EVENT_HANDLER = "javafx.event.EventHandler";
@NonNls public static final String JAVAFX_SCENE_NODE = "javafx.scene.Node";
@NonNls public static final String JAVAFX_SCENE_PAINT = "javafx.scene.paint.Paint";
@NonNls public static final String JAVAFX_SCENE_COLOR = "javafx.scene.paint.Color";
@NonNls public static final String JAVAFX_FXML_BUILDER = "javafx.util.Builder";
@NonNls public static final String JAVAFX_BEANS_OBSERVABLE = "javafx.beans.Observable";
@NonNls public static final String VALUE_OF = "valueOf";
@@ -100,6 +100,9 @@ public class FxmlReferencesContributor extends PsiReferenceContributor {
registrar.registerReferenceProvider(XmlPatterns.xmlAttributeValue().and(attributeValueInFxml),
new EnumeratedAttributeReferenceProvider());
registrar.registerReferenceProvider(XmlPatterns.xmlAttributeValue().and(attributeValueInFxml),
new JavaFxColorReferenceProvider());
registrar.registerReferenceProvider(XmlPatterns.xmlAttributeValue()
.withParent(XmlPatterns.xmlAttribute().withName(FxmlConstants.FX_VALUE)
.withParent(XmlPatterns.xmlTag().withParent(XmlPatterns.xmlTag().withName(FxmlConstants.STYLESHEETS))))
@@ -28,19 +28,17 @@ import com.intellij.openapi.editor.markup.GutterIconRenderer;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.psi.*;
import com.intellij.psi.presentation.java.SymbolPresentationUtil;
import com.intellij.psi.util.InheritanceUtil;
import com.intellij.psi.xml.XmlAttribute;
import com.intellij.psi.xml.XmlAttributeValue;
import com.intellij.ui.ColorUtil;
import com.intellij.util.ArrayUtil;
import com.intellij.util.ui.ColorIcon;
import com.intellij.xml.XmlAttributeDescriptor;
import com.intellij.xml.util.ColorSampleLookupValue;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.plugins.javaFX.fxml.FxmlConstants;
import org.jetbrains.plugins.javaFX.fxml.JavaFxCommonClassNames;
import org.jetbrains.plugins.javaFX.fxml.JavaFxFileTypeFactory;
import org.jetbrains.plugins.javaFX.fxml.JavaFxPsiUtil;
import org.jetbrains.plugins.javaFX.fxml.descriptors.JavaFxPropertyAttributeDescriptor;
import javax.swing.*;
import java.awt.*;
@@ -70,11 +68,8 @@ public class JavaFxAnnotator implements Annotator {
}
}
}
if (references.length == 0) {
final String attributeValueText = StringUtil.stripQuotesAroundValue(element.getText());
if (attributeValueText.startsWith("#")) {
attachColorIcon(element, holder, attributeValueText);
}
if (references.length == 1 && references[0] instanceof JavaFxColorReference) {
attachColorIcon(element, holder, StringUtil.stripQuotesAroundValue(element.getText()));
}
} else if (element instanceof XmlAttribute) {
final String attributeName = ((XmlAttribute)element).getName();
@@ -87,28 +82,23 @@ public class JavaFxAnnotator implements Annotator {
}
private static void attachColorIcon(final PsiElement element, AnnotationHolder holder, String attributeValueText) {
final PsiElement parent = element.getParent();
if (parent instanceof XmlAttribute) {
final XmlAttributeDescriptor descriptor = ((XmlAttribute)parent).getDescriptor();
if (descriptor instanceof JavaFxPropertyAttributeDescriptor) {
final PsiElement declaration = descriptor.getDeclaration();
if (declaration instanceof PsiField) {
final PsiField field = (PsiField)declaration;
final PsiClassType propertyClassType = JavaFxPsiUtil.getPropertyClassType(field);
if (propertyClassType != null && InheritanceUtil.isInheritor(propertyClassType, JavaFxCommonClassNames.JAVAFX_SCENE_PAINT)) {
try {
final Color color = ColorUtil.fromHex(attributeValueText.substring(1));
if (color != null) {
final ColorIcon icon = new ColorIcon(8, color);
final Annotation annotation = holder.createInfoAnnotation(element, null);
annotation.setGutterIconRenderer(new ColorIconRenderer(icon, element));
}
}
catch (Exception ignored) {
}
}
try {
Color color = null;
if (attributeValueText.startsWith("#")) {
color = ColorUtil.fromHex(attributeValueText.substring(1));
} else {
final String hexCode = ColorSampleLookupValue.getHexCodeForColorName(StringUtil.toLowerCase(attributeValueText));
if (hexCode != null) {
color = ColorUtil.fromHex(hexCode);
}
}
if (color != null) {
final ColorIcon icon = new ColorIcon(8, color);
final Annotation annotation = holder.createInfoAnnotation(element, null);
annotation.setGutterIconRenderer(new ColorIconRenderer(icon, element));
}
}
catch (Exception ignored) {
}
}
@@ -0,0 +1,69 @@
/*
* Copyright 2000-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 org.jetbrains.plugins.javaFX.fxml.refs;
import com.intellij.openapi.project.Project;
import com.intellij.psi.JavaPsiFacade;
import com.intellij.psi.PsiClass;
import com.intellij.psi.PsiElement;
import com.intellij.psi.PsiReferenceBase;
import com.intellij.psi.search.GlobalSearchScope;
import com.intellij.psi.xml.XmlAttributeValue;
import com.intellij.xml.util.ColorSampleLookupValue;
import com.intellij.xml.util.UserColorLookup;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.plugins.javaFX.fxml.JavaFxCommonClassNames;
/**
* User: anna
* Date: 3/7/13
*/
public class JavaFxColorReference extends PsiReferenceBase<XmlAttributeValue> {
public JavaFxColorReference(XmlAttributeValue value) {
super(value);
}
@Nullable
@Override
public PsiElement resolve() {
final Project project = getElement().getProject();
final PsiClass psiClass =
JavaPsiFacade.getInstance(project).findClass(JavaFxCommonClassNames.JAVAFX_SCENE_COLOR, GlobalSearchScope.allScope(project));
if (psiClass != null) {
return psiClass.findFieldByName(getCanonicalText().toUpperCase(), false);
}
return null;
}
@NotNull
@Override
public Object[] getVariants() {
final ColorSampleLookupValue[] lookupValues = ColorSampleLookupValue.getColors();
final Object[] vars = new Object[lookupValues.length + 1];
for (int i = 0; i < lookupValues.length; i++) {
final ColorSampleLookupValue value = lookupValues[i];
vars[i] = new ColorSampleLookupValue(value.getName(), value.getValue(), true);
}
vars[lookupValues.length] = new UserColorLookup();
return vars;
}
@Override
public boolean isSoft() {
return true;
}
}
@@ -0,0 +1,55 @@
/*
* Copyright 2000-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 org.jetbrains.plugins.javaFX.fxml.refs;
import com.intellij.psi.*;
import com.intellij.psi.util.InheritanceUtil;
import com.intellij.psi.xml.XmlAttribute;
import com.intellij.psi.xml.XmlAttributeValue;
import com.intellij.util.ProcessingContext;
import com.intellij.xml.XmlAttributeDescriptor;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.plugins.javaFX.fxml.JavaFxCommonClassNames;
import org.jetbrains.plugins.javaFX.fxml.JavaFxPsiUtil;
import org.jetbrains.plugins.javaFX.fxml.descriptors.JavaFxPropertyAttributeDescriptor;
/**
* User: anna
* Date: 3/7/13
*/
class JavaFxColorReferenceProvider extends PsiReferenceProvider {
@NotNull
@Override
public PsiReference[] getReferencesByElement(@NotNull PsiElement element,
@NotNull ProcessingContext context) {
final XmlAttributeValue attributeValue = (XmlAttributeValue)element;
final PsiElement parent = attributeValue.getParent();
if (parent instanceof XmlAttribute) {
final XmlAttributeDescriptor descriptor = ((XmlAttribute)parent).getDescriptor();
if (descriptor instanceof JavaFxPropertyAttributeDescriptor) {
final PsiElement declaration = descriptor.getDeclaration();
if (declaration instanceof PsiField) {
final PsiField field = (PsiField)declaration;
final PsiClassType propertyClassType = JavaFxPsiUtil.getPropertyClassType(field);
if (propertyClassType != null && InheritanceUtil.isInheritor(propertyClassType, JavaFxCommonClassNames.JAVAFX_SCENE_PAINT)) {
return new PsiReference[] {new JavaFxColorReference(attributeValue)};
}
}
}
}
return PsiReference.EMPTY_ARRAY;
}
}
@@ -0,0 +1,5 @@
<?import javafx.scene.control.Label?>
<?import javafx.scene.layout.GridPane?>
<GridPane xmlns:fx="http://javafx.com/fxml">
<Label text="foo" textFill="<caret>"/>
</GridPane>
@@ -0,0 +1,5 @@
<?import javafx.scene.control.Label?>
<?import javafx.scene.layout.GridPane?>
<GridPane xmlns:fx="http://javafx.com/fxml">
<Label text="foo" textFill="blue"/>
</GridPane>
@@ -0,0 +1,5 @@
<?import javafx.scene.control.Label?>
<?import javafx.scene.layout.GridPane?>
<GridPane xmlns:fx="http://javafx.com/fxml">
<Label text="foo" textFill="oran<caret>ge"/>
</GridPane>