support for bitmaps and nine-patchs

This commit is contained in:
Eugene Kudelevsky
2011-04-14 18:07:49 +04:00
parent f167b90e09
commit b05be8393c
29 changed files with 233 additions and 39 deletions
+1
View File
@@ -60,6 +60,7 @@
<extensions defaultExtensionNs="com.intellij">
<errorHandler implementation="com.intellij.diagnostic.ITNReporter"/>
<dom.fileDescription implementation="org.jetbrains.android.dom.drawable.DrawableStateListDomFileDescription"/>
<dom.fileDescription implementation="org.jetbrains.android.dom.drawable.BitmapOrNinePatchDomFileDescription"/>
<dom.fileDescription implementation="org.jetbrains.android.dom.color.ColorDomFileDescription"/>
<dom.fileDescription implementation="org.jetbrains.android.dom.manifest.ManifestDomFileDescription"/>
@@ -86,7 +86,7 @@ public class AndroidCompletionContributor extends CompletionContributor {
}
else if (AndroidDrawableDomUtil.isDrawableResourceFile(xmlFile) ||
ColorDomFileDescription.isColorResourceFile(xmlFile)) {
addAll(DrawableStateListDomFileDescription.getPossibleRoots(), resultSet);
addAll(AndroidDrawableDomUtil.getPossibleRoots(), resultSet);
}
}
}
@@ -517,13 +517,13 @@ public class AndroidDomExtender extends DomExtender<AndroidDomElement> {
registerExtensionsForXmlResources(facet, tagName, (XmlResourceElement)element, registrar, registeredSubtags);
}
else if (element instanceof DrawableDomElement || element instanceof ColorDomElement) {
registerExtensionsForDrawable(facet, tagName, element, registrar);
registerExtensionsForStateList(facet, tagName, element, registrar);
}
Collections.addAll(registeredSubtags, AndroidDomUtil.getStaticallyDefinedSubtags(element));
if (!(element instanceof LayoutElement) &&
!(element instanceof ColorDomElement) &&
(!(element instanceof DrawableDomElement) || element instanceof UnknownDrawableElement)) {
(!(element instanceof DrawableDomElement) || element instanceof UnknownDrawableDomElement)) {
Processor<String> existingSubtagsFilter = element instanceof XmlResourceElement ?
new Processor<String>() {
public boolean process(String s) {
@@ -534,11 +534,11 @@ public class AndroidDomExtender extends DomExtender<AndroidDomElement> {
}
}
private static void registerExtensionsForDrawable(AndroidFacet facet,
String tagName,
AndroidDomElement element,
DomExtensionsRegistrar registrar) {
final String specialStyleableName = DrawableStateListDomFileDescription.SPECIAL_STYLEABLE_NAMES.get(tagName);
private static void registerExtensionsForStateList(AndroidFacet facet,
String tagName,
AndroidDomElement element,
DomExtensionsRegistrar registrar) {
final String specialStyleableName = AndroidDrawableDomUtil.SPECIAL_STYLEABLE_NAMES.get(tagName);
if (specialStyleableName != null) {
registerAttributes(facet, element, specialStyleableName, SYSTEM_RESOURCE_PACKAGE, registrar);
}
@@ -16,17 +16,35 @@
package org.jetbrains.android.dom.drawable;
import com.intellij.psi.xml.XmlFile;
import com.intellij.util.containers.HashMap;
import org.jetbrains.android.dom.AndroidResourceDomFileDescription;
import org.jetbrains.annotations.NotNull;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
/**
* @author Eugene.Kudelevsky
*/
public class AndroidDrawableDomUtil {
public static final Map<String, String> SPECIAL_STYLEABLE_NAMES = new HashMap<String, String>();
private static final String[] POSSIBLE_DRAWABLE_ROOTS = new String[] {"selector", "bitmap", "nine-patch"};
static {
SPECIAL_STYLEABLE_NAMES.put("selector", "StateListDrawable");
SPECIAL_STYLEABLE_NAMES.put("bitmap", "BitmapDrawable");
SPECIAL_STYLEABLE_NAMES.put("nine-patch", "NinePatchDrawable");
}
private AndroidDrawableDomUtil() {
}
public static boolean isDrawableResourceFile(@NotNull XmlFile file) {
return AndroidResourceDomFileDescription.doIsMyFile(file, new String[] {"drawable"});
return AndroidResourceDomFileDescription.doIsMyFile(file, new String[]{"drawable"});
}
public static List<String> getPossibleRoots() {
return Arrays.asList(POSSIBLE_DRAWABLE_ROOTS);
}
}
@@ -0,0 +1,54 @@
/*
* Copyright 2000-2011 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.android.dom.drawable;
import com.intellij.openapi.module.Module;
import com.intellij.psi.xml.XmlFile;
import com.intellij.psi.xml.XmlTag;
import com.intellij.util.ArrayUtil;
import org.jetbrains.android.dom.AndroidResourceDomFileDescription;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
/**
* @author Eugene.Kudelevsky
*/
public class BitmapOrNinePatchDomFileDescription extends AndroidResourceDomFileDescription<BitmapOrNinePatchElement> {
static final String[] ROOT_TAG_NAMES = new String[] {"bitmap", "nine-patch"};
public BitmapOrNinePatchDomFileDescription() {
super(BitmapOrNinePatchElement.class, ROOT_TAG_NAMES[0], "drawable");
}
@Override
public boolean acceptsOtherRootTagNames() {
return true;
}
@Override
public boolean isMyFile(@NotNull XmlFile file, @Nullable Module module) {
if (!super.isMyFile(file, module)) {
return false;
}
final XmlTag rootTag = file.getRootTag();
if (rootTag == null) {
return false;
}
return ArrayUtil.find(ROOT_TAG_NAMES, rootTag.getName()) >= 0;
}
}
@@ -0,0 +1,34 @@
/*
* Copyright 2000-2011 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.android.dom.drawable;
import com.intellij.util.xml.Convert;
import com.intellij.util.xml.DefinesXml;
import com.intellij.util.xml.Required;
import org.jetbrains.android.dom.AndroidAttributeValue;
import org.jetbrains.android.dom.ResourceType;
import org.jetbrains.android.dom.converters.ResourceReferenceConverter;
/**
* @author Eugene.Kudelevsky
*/
@DefinesXml
public interface BitmapOrNinePatchElement extends DrawableDomElement {
@Required
@Convert(ResourceReferenceConverter.class)
@ResourceType("drawable")
AndroidAttributeValue<String> getSrc();
}
@@ -19,6 +19,7 @@ package org.jetbrains.android.dom.drawable;
import com.intellij.openapi.module.Module;
import com.intellij.psi.xml.XmlFile;
import com.intellij.psi.xml.XmlTag;
import com.intellij.util.ArrayUtil;
import org.jetbrains.android.dom.AndroidResourceDomFileDescription;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
@@ -30,10 +31,10 @@ import org.jetbrains.annotations.Nullable;
* Time: 9:42:38 PM
* To change this template use File | Settings | File Templates.
*/
public class DrawableDomFileDescription extends AndroidResourceDomFileDescription<UnknownDrawableElement> {
public class DrawableDomFileDescription extends AndroidResourceDomFileDescription<UnknownDrawableDomElement> {
public DrawableDomFileDescription() {
super(UnknownDrawableElement.class, "shape", "drawable");
super(UnknownDrawableDomElement.class, "shape", "bitmap", "nine-patch", "drawable");
}
@Override
@@ -53,6 +54,7 @@ public class DrawableDomFileDescription extends AndroidResourceDomFileDescriptio
}
final String rootTagName = rootTag.getName();
return !"selector".equals(rootTagName);
return !DrawableStateListDomFileDescription.SELECTOR_TAG_NAME.equals(rootTagName) &&
ArrayUtil.find(BitmapOrNinePatchDomFileDescription.ROOT_TAG_NAMES, rootTag) < 0;
}
}
@@ -23,6 +23,6 @@ import java.util.List;
* @author Eugene.Kudelevsky
*/
@DefinesXml
public interface DrawableSelector extends DrawableDomElement {
public interface DrawableSelector extends DrawableStateListElement {
List<DrawableStateListItem> getItems();
}
@@ -18,7 +18,6 @@ package org.jetbrains.android.dom.drawable;
import com.intellij.openapi.module.Module;
import com.intellij.psi.xml.XmlFile;
import com.intellij.psi.xml.XmlTag;
import com.intellij.util.containers.HashMap;
import org.jetbrains.android.dom.AndroidResourceDomFileDescription;
import org.jetbrains.annotations.NonNls;
import org.jetbrains.annotations.NotNull;
@@ -26,18 +25,12 @@ import org.jetbrains.annotations.Nullable;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
/**
* @author Eugene.Kudelevsky
*/
public class DrawableStateListDomFileDescription extends AndroidResourceDomFileDescription<DrawableSelector> {
@NonNls public static final String SELECTOR_TAG_NAME = "selector";
public static final Map<String, String> SPECIAL_STYLEABLE_NAMES = new HashMap<String, String>();
static {
DrawableStateListDomFileDescription.SPECIAL_STYLEABLE_NAMES.put("selector", "StateListDrawable");
}
public DrawableStateListDomFileDescription() {
super(DrawableSelector.class, SELECTOR_TAG_NAME, "drawable");
@@ -61,8 +54,4 @@ public class DrawableStateListDomFileDescription extends AndroidResourceDomFileD
return SELECTOR_TAG_NAME.equals(rootTag.getName());
}
public static List<String> getPossibleRoots() {
return Arrays.asList(SELECTOR_TAG_NAME);
}
}
@@ -0,0 +1,27 @@
/*
* Copyright 2000-2011 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.android.dom.drawable;
/**
* Created by IntelliJ IDEA.
* User: Eugene.Kudelevsky
* Date: Aug 22, 2009
* Time: 1:36:56 PM
* To change this template use File | Settings | File Templates.
*/
public interface DrawableStateListElement extends DrawableDomElement {
}
@@ -25,7 +25,7 @@ import org.jetbrains.android.dom.resources.ResourceValue;
/**
* @author Eugene.Kudelevsky
*/
public interface DrawableStateListItem extends DrawableDomElement {
public interface DrawableStateListItem extends DrawableStateListElement {
@Convert(ResourceReferenceConverter.class)
@ResourceType("drawable")
@Required
@@ -16,11 +16,10 @@
package org.jetbrains.android.dom.drawable;
import com.intellij.util.xml.DefinesXml;
import org.jetbrains.android.dom.AndroidDomElement;
/**
* @author Eugene.Kudelevksy
* @author Eugene.Kudelevsky
*/
@DefinesXml
public interface UnknownDrawableElement extends AndroidDomElement {
public interface UnknownDrawableDomElement extends DrawableDomElement {
}
@@ -0,0 +1,2 @@
<?xml version="1.0" encoding="utf-8"?>
<bitmap xmlns:android="http://schemas.android.com/apk/res/android" android:src="@drawable/myDrawable" android:tileMo<caret>/>
@@ -0,0 +1,2 @@
<?xml version="1.0" encoding="utf-8"?>
<bitmap xmlns:android="http://schemas.android.com/apk/res/android" android:src="@drawable/myDrawable" android:tileMode=""/>
@@ -0,0 +1,2 @@
<?xml version="1.0" encoding="utf-8"?>
<bitmap xmlns:android="http://schemas.android.com/apk/res/android" android:src="@<caret>"/>
@@ -0,0 +1,2 @@
<?xml version="1.0" encoding="utf-8"?>
<bitmap xmlns:android="http://schemas.android.com/apk/res/android" android:src="@drawable/myDrawable" android:tileMode="repeat" />
@@ -0,0 +1,2 @@
<?xml version="1.0" encoding="utf-8"?>
<<error>bitmap</error> xmlns:android="http://schemas.android.com/apk/res/android"/>
@@ -0,0 +1,2 @@
<?xml version="1.0" encoding="utf-8"?>
<nine-patch xmlns:android="http://schemas.android.com/apk/res/android" android:src="@drawable/myDrawable" android:dith<caret>/>
@@ -0,0 +1,2 @@
<?xml version="1.0" encoding="utf-8"?>
<nine-patch xmlns:android="http://schemas.android.com/apk/res/android" android:src="@drawable/myDrawable" android:dither=""/>
@@ -0,0 +1,2 @@
<?xml version="1.0" encoding="utf-8"?>
<nine-patch xmlns:android="http://schemas.android.com/apk/res/android" android:src="@<caret>"/>
@@ -0,0 +1,2 @@
<?xml version="1.0" encoding="utf-8"?>
<nine-patch xmlns:android="http://schemas.android.com/apk/res/android" android:src="@drawable/myDrawable" android:dither="false" />
@@ -0,0 +1,2 @@
<?xml version="1.0" encoding="utf-8"?>
<<error>nine-patch</error> xmlns:android="http://schemas.android.com/apk/res/android"/>
@@ -0,0 +1,3 @@
<resources>
<string name="myStringResource">abacaba</string>
</resources>
@@ -0,0 +1 @@
<<caret>
@@ -1,3 +1,4 @@
<?xml version="1.0" encoding="utf-8"?>
<select<caret>
<selector xmlns:android="http://schemas.android.com/apk/res/android" constantS<caret>>
</selector>
@@ -1,3 +1,4 @@
<?xml version="1.0" encoding="utf-8"?>
<selector
<selector xmlns:android="http://schemas.android.com/apk/res/android" android:constantSize="">
</selector>
@@ -1,4 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android" constantS<caret>>
</selector>
@@ -1,4 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android" android:constantSize="">
</selector>
@@ -15,6 +15,12 @@
*/
package org.jetbrains.android.dom;
import com.intellij.codeInsight.completion.CompletionType;
import com.intellij.openapi.vfs.VirtualFile;
import java.io.IOException;
import java.util.List;
/**
* @author Eugene.Kudelevsky
*/
@@ -27,6 +33,7 @@ public class AndroidDrawableResourcesDomTest extends AndroidDomTest {
public void setUp() throws Exception {
super.setUp();
copyFileToProject("myDrawable.png", "res/drawable/myDrawable.png");
copyFileToProject("otherResource.xml", "res/values/strings1.xml");
}
@Override
@@ -58,7 +65,52 @@ public class AndroidDrawableResourcesDomTest extends AndroidDomTest {
doTestCompletion();
}
public void testStateListCompletion6() throws Throwable {
public void testBitmapHighlighting1() throws Throwable {
doTestHighlighting();
}
public void testBitmapHighlighting2() throws Throwable {
doTestHighlighting();
}
public void testBitmapCompletion1() throws Throwable {
doTestCompletion();
}
public void testBitmapCompletion2() throws Throwable {
doTestOnlyDrawableReferences();
}
public void testNinePatchHighlighting1() throws Throwable {
doTestHighlighting();
}
public void testNinePatchHighlighting2() throws Throwable {
doTestHighlighting();
}
public void testNinePatchCompletion1() throws Throwable {
doTestCompletion();
}
public void testNinePatchCompletion2() throws Throwable {
doTestOnlyDrawableReferences();
}
private void doTestOnlyDrawableReferences() throws IOException {
VirtualFile file = copyFileToProject(getTestName(true) + ".xml");
myFixture.configureFromExistingVirtualFile(file);
myFixture.complete(CompletionType.BASIC);
List<String> lookupElementStrings = myFixture.getLookupElementStrings();
assertNotNull(lookupElementStrings);
for (String s : lookupElementStrings) {
if (!s.startsWith("@android") && !s.startsWith("@drawable")) {
fail("Variant " + s + " shouldn't be threre");
}
}
}
public void testRootTagCompletion() throws Throwable {
doTestCompletionVariants(getTestName(true) + ".xml", "selector", "bitmap", "nine-patch");
}
}