android: support 'animator' resource type

This commit is contained in:
Eugene Kudelevsky
2012-03-01 21:32:24 +04:00
parent 3a051136e8
commit 839b8587bb
23 changed files with 214 additions and 3 deletions
+1
View File
@@ -96,6 +96,7 @@
<dom.fileDescription implementation="org.jetbrains.android.dom.manifest.ManifestDomFileDescription"/>
<dom.fileDescription implementation="org.jetbrains.android.dom.layout.LayoutDomFileDescription"/>
<dom.fileDescription implementation="org.jetbrains.android.dom.animation.AnimationDomFileDescription"/>
<dom.fileDescription implementation="org.jetbrains.android.dom.animator.AnimatorDomFileDescription"/>
<dom.fileDescription implementation="org.jetbrains.android.dom.menu.MenuDomFileDescription"/>
<dom.fileDescription implementation="org.jetbrains.android.dom.resources.ResourcesDomFileDescription"/>
<dom.fileDescription implementation="org.jetbrains.android.dom.xml.XmlResourceDomFileDescription"/>
@@ -27,6 +27,8 @@ import com.intellij.psi.xml.XmlTag;
import org.jetbrains.android.dom.AndroidDomExtender;
import org.jetbrains.android.dom.animation.AndroidAnimationUtils;
import org.jetbrains.android.dom.animation.AnimationDomFileDescription;
import org.jetbrains.android.dom.animator.AndroidAnimatorUtil;
import org.jetbrains.android.dom.animator.AnimatorDomFileDescription;
import org.jetbrains.android.dom.color.ColorDomFileDescription;
import org.jetbrains.android.dom.drawable.AndroidDrawableDomUtil;
import org.jetbrains.android.dom.drawable.DrawableStateListDomFileDescription;
@@ -81,6 +83,10 @@ public class AndroidCompletionContributor extends CompletionContributor {
addAll(AndroidAnimationUtils.getPossibleChildren(facet), resultSet);
return false;
}
else if (AnimatorDomFileDescription.isAnimatorFile(xmlFile)) {
addAll(AndroidAnimatorUtil.getPossibleChildren(), resultSet);
return false;
}
else if (XmlResourceDomFileDescription.isXmlResourceFile(xmlFile)) {
addAll(AndroidXmlResourcesUtil.getPossibleRoots(facet), resultSet);
return false;
@@ -33,7 +33,9 @@ import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.Arrays;
import java.util.Collection;
import java.util.Comparator;
import java.util.Map;
/**
@@ -63,6 +65,14 @@ public abstract class CreateResourceDialog extends DialogWrapper {
myResourceTypeCombo.registerUpDownHint(myFileNameField);
myUpDownHint.setIcon(PlatformIcons.UP_DOWN_ARROWS);
CreateTypedResourceFileAction[] actionArray = actions.toArray(new CreateTypedResourceFileAction[actions.size()]);
Arrays.sort(actionArray, new Comparator<CreateTypedResourceFileAction>() {
@Override
public int compare(CreateTypedResourceFileAction a1, CreateTypedResourceFileAction a2) {
return a1.toString().compareTo(a2.toString());
}
});
for (CreateTypedResourceFileAction action : actionArray) {
String resType = action.getResourceType();
assert !myResType2ActionMap.containsKey(resType);
@@ -38,6 +38,7 @@ public class CreateResourceFileActionGroup extends DefaultActionGroup {
a.add(new CreateTypedResourceFileAction("Values", "values", "resources", true, false));
a.add(new CreateTypedResourceFileAction("Menu", "menu", "menu", false, false));
a.add(new CreateTypedResourceFileAction("Animation", "anim", "set"));
a.add(new CreateTypedResourceFileAction("Animator", "animator", "set"));
myMajorAction = a;
add(a);
for (CreateTypedResourceFileAction subaction : a.getSubactions()) {
@@ -33,6 +33,8 @@ import com.intellij.util.xml.reflect.DomExtension;
import com.intellij.util.xml.reflect.DomExtensionsRegistrar;
import org.jetbrains.android.dom.animation.AndroidAnimationUtils;
import org.jetbrains.android.dom.animation.AnimationElement;
import org.jetbrains.android.dom.animator.AndroidAnimatorUtil;
import org.jetbrains.android.dom.animator.AnimatorElement;
import org.jetbrains.android.dom.attrs.AttributeDefinition;
import org.jetbrains.android.dom.attrs.AttributeDefinitions;
import org.jetbrains.android.dom.attrs.AttributeFormat;
@@ -359,6 +361,24 @@ public class AndroidDomExtender extends DomExtender<AndroidDomElement> {
}
}
public static void registerExtensionsForAnimator(final AndroidFacet facet,
String tagName,
AnimatorElement element,
DomExtensionsRegistrar registrar,
Set<String> registeredSubtags) {
if (tagName.equals("set")) {
for (String subtagName : AndroidAnimatorUtil.getPossibleChildren()) {
registerSubtags(subtagName, AnimatorElement.class, registrar, registeredSubtags);
}
}
registerAttributes(facet, element, "Animator", SYSTEM_RESOURCE_PACKAGE, registrar);
final String styleableName = AndroidAnimatorUtil.getStyleableNameByTagName(tagName);
if (styleableName != null) {
registerAttributes(facet, element, styleableName, SYSTEM_RESOURCE_PACKAGE, registrar);
}
}
public static Map<String, PsiClass> getViewClassMap(@NotNull AndroidFacet facet) {
return facet.getClassMap(AndroidUtils.VIEW_CLASS_NAME, SimpleClassMapConstructor.getInstance());
}
@@ -531,6 +551,9 @@ public class AndroidDomExtender extends DomExtender<AndroidDomElement> {
else if (element instanceof AnimationElement) {
registerExtensionsForAnimation(facet, tagName, (AnimationElement)element, registrar, registeredSubtags);
}
else if (element instanceof AnimatorElement) {
registerExtensionsForAnimator(facet, tagName, (AnimatorElement)element, registrar, registeredSubtags);
}
else if (element instanceof MenuElement) {
String styleableName = StringUtil.capitalize(tagName);
if (!styleableName.equals("Menu")) {
@@ -0,0 +1,29 @@
package org.jetbrains.android.dom.animator;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.util.Arrays;
import java.util.List;
/**
* @author Eugene.Kudelevsky
*/
public class AndroidAnimatorUtil {
private static final String[] TAG_NAMES = {"set", "objectAnimator", "animator"};
public static List<String> getPossibleChildren() {
return Arrays.asList(TAG_NAMES);
}
@Nullable
public static String getStyleableNameByTagName(@NotNull String tagName) {
if (tagName.equals("set")) {
return "AnimatorSet";
}
else if (tagName.equals("objectAnimator")) {
return "PropertyAnimator";
}
return null;
}
}
@@ -0,0 +1,30 @@
package org.jetbrains.android.dom.animator;
import com.android.resources.ResourceFolderType;
import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.util.Computable;
import com.intellij.psi.xml.XmlFile;
import org.jetbrains.android.dom.AndroidResourceDomFileDescription;
import org.jetbrains.annotations.NotNull;
/**
* @author Eugene.Kudelevsky
*/
public class AnimatorDomFileDescription extends AndroidResourceDomFileDescription<AnimatorElement> {
public AnimatorDomFileDescription() {
super(AnimatorElement.class, "set", ResourceFolderType.ANIMATOR.getName());
}
@Override
public boolean acceptsOtherRootTagNames() {
return true;
}
public static boolean isAnimatorFile(@NotNull final XmlFile file) {
return ApplicationManager.getApplication().runReadAction(new Computable<Boolean>() {
public Boolean compute() {
return new AnimatorDomFileDescription().isMyFile(file, null);
}
});
}
}
@@ -0,0 +1,11 @@
package org.jetbrains.android.dom.animator;
import com.intellij.util.xml.DefinesXml;
import org.jetbrains.android.dom.AndroidDomElement;
/**
* @author Eugene.Kudelevsky
*/
@DefinesXml
public interface AnimatorElement extends AndroidDomElement {
}
@@ -55,8 +55,10 @@ import static org.jetbrains.android.util.AndroidUtils.SYSTEM_RESOURCE_PACKAGE;
* @author yole
*/
public class ResourceReferenceConverter extends ResolvingConverter<ResourceValue> implements CustomReferenceConverter<ResourceValue> {
private static final Set<ResourceType> XML_FILE_RESOURCE_TYPES =
EnumSet.of(ResourceType.ANIM, ResourceType.LAYOUT, ResourceType.MENU, ResourceType.XML, ResourceType.COLOR, ResourceType.DRAWABLE);
private static final Set<ResourceType> XML_FILE_RESOURCE_TYPES = EnumSet.of(ResourceType.ANIM, ResourceType.ANIMATOR,
ResourceType.INTERPOLATOR, ResourceType.LAYOUT,
ResourceType.MENU, ResourceType.XML, ResourceType.COLOR,
ResourceType.DRAWABLE);
private final List<String> myResourceTypes;
private ResolvingConverter<String> myAdditionalConverter;
@@ -464,7 +464,8 @@ public class AndroidResourceUtil {
public static boolean isResourceSubdirectory(@NotNull PsiDirectory directory, @Nullable String resourceType) {
PsiDirectory dir = directory;
if (resourceType != null && !dir.getName().startsWith(resourceType)) {
final String dirName = dir.getName();
if (resourceType != null && !dirName.equals(resourceType) && !dirName.startsWith(resourceType + '-')) {
return false;
}
dir = dir.getParent();
@@ -0,0 +1,3 @@
<set xmlns:android="http://schemas.android.com/apk/res/android">
<objectAnimator android:interp<caret>
</set>
@@ -0,0 +1,3 @@
<set xmlns:android="http://schemas.android.com/apk/res/android">
<objectAnimator android:interpolator="<caret>"
</set>
@@ -0,0 +1,2 @@
<set xmlns:android="http://schemas.android.com/apk/res/android" android:order<caret>>
</set>
@@ -0,0 +1,2 @@
<set xmlns:android="http://schemas.android.com/apk/res/android" android:ordering="">
</set>
@@ -0,0 +1,2 @@
<set xmlns:android="http://schemas.android.com/apk/res/android" android:ordering="toge<caret>">
</set>
@@ -0,0 +1,2 @@
<set xmlns:android="http://schemas.android.com/apk/res/android" android:ordering="together">
</set>
@@ -0,0 +1,14 @@
<set xmlns:android="http://schemas.android.com/apk/res/android">
<objectAnimator
android:interpolator="@android:interpolator/platformInterpolator"
android:valueFrom="100dp" android:valueTo="0dp"
android:valueType="floatType"
android:propertyName="translationX"
android:duration="@android:integer/config_mediumAnimTime" />
<animator
android:interpolator="@android:interpolator/platformInterpolator"
android:valueFrom="0.0" android:valueTo="1.0"
android:valueType="floatType"
android:propertyName="alpha"
android:duration="@android:integer/config_mediumAnimTime" />
</set>
@@ -0,0 +1 @@
<objectAnim<caret>
@@ -0,0 +1 @@
<objectAnimator
@@ -0,0 +1,3 @@
<set xmlns:android="http://schemas.android.com/apk/res/android">
<anima<caret>
</set>
@@ -0,0 +1,3 @@
<set xmlns:android="http://schemas.android.com/apk/res/android">
<animator
</set>
@@ -0,0 +1 @@
<accelerateInterpolator xmlns:android="http://schemas.android.com/apk/res/android" android:factor="1.5" />
@@ -0,0 +1,60 @@
/*
* Copyright 2000-2009 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;
import com.android.sdklib.SdkConstants;
/**
* @author Eugene.Kudelevsky
*/
public class AndroidAnimatorDomTest extends AndroidDomTest {
public AndroidAnimatorDomTest() {
super(false, "dom/animator");
}
@Override
protected String getPathToCopy(String testFileName) {
return "res/animator/" + testFileName;
}
@Override
public void setUp() throws Exception {
super.setUp();
myFixture.copyFileToProject(SdkConstants.FN_ANDROID_MANIFEST_XML, SdkConstants.FN_ANDROID_MANIFEST_XML);
}
public void testRootCompletion() throws Throwable {
toTestCompletion("root.xml", "root_after.xml");
}
public void testHighlighting() throws Throwable {
doTestHighlighting("hl.xml");
}
public void testTagNames() throws Throwable {
toTestCompletion("tn.xml", "tn_after.xml");
}
public void testAttributeNames() throws Throwable {
toTestCompletion("an1.xml", "an1_after.xml");
toTestCompletion("an2.xml", "an2_after.xml");
}
public void testAttributeValues() throws Throwable {
toTestCompletion("av.xml", "av_after.xml");
}
}