diff options
-rw-r--r-- | assetstudio/.classpath | 7 | ||||
-rw-r--r-- | assetstudio/.gitignore | 2 | ||||
-rw-r--r-- | assetstudio/.project | 17 | ||||
-rw-r--r-- | assetstudio/.settings/org.eclipse.jdt.core.prefs | 71 | ||||
-rw-r--r-- | assetstudio/Android.mk | 30 | ||||
-rw-r--r-- | assetstudio/src/com/android/assetstudiolib/GraphicGenerator.java (renamed from assetstudio/libs/assetstudiolib/src/com/android/assetstudiolib/GraphicGenerator.java) | 38 | ||||
-rw-r--r-- | assetstudio/src/com/android/assetstudiolib/GraphicGeneratorContext.java (renamed from assetstudio/libs/assetstudiolib/src/com/android/assetstudiolib/GraphicGeneratorContext.java) | 0 | ||||
-rw-r--r-- | assetstudio/src/com/android/assetstudiolib/LauncherIconGenerator.java (renamed from assetstudio/libs/assetstudiolib/src/com/android/assetstudiolib/LauncherIconGenerator.java) | 19 | ||||
-rw-r--r-- | assetstudio/src/com/android/assetstudiolib/MenuIconGenerator.java (renamed from assetstudio/libs/assetstudiolib/src/com/android/assetstudiolib/MenuIconGenerator.java) | 6 | ||||
-rw-r--r-- | assetstudio/src/com/android/assetstudiolib/Util.java (renamed from assetstudio/libs/assetstudiolib/src/com/android/assetstudiolib/Util.java) | 0 | ||||
-rw-r--r-- | assetstudio/src/images/launcher_stencil/circle/hdpi/back.png (renamed from assetstudio/res/launcher-stencil/circle/hdpi/back.png) | bin | 1885 -> 1885 bytes | |||
-rw-r--r-- | assetstudio/src/images/launcher_stencil/circle/hdpi/fore1.png (renamed from assetstudio/res/launcher-stencil/circle/hdpi/fore1.png) | bin | 666 -> 666 bytes | |||
-rw-r--r-- | assetstudio/src/images/launcher_stencil/circle/hdpi/fore2.png (renamed from assetstudio/res/launcher-stencil/circle/hdpi/fore2.png) | bin | 2922 -> 2922 bytes | |||
-rw-r--r-- | assetstudio/src/images/launcher_stencil/circle/hdpi/fore3.png (renamed from assetstudio/res/launcher-stencil/circle/hdpi/fore3.png) | bin | 4690 -> 4690 bytes | |||
-rw-r--r-- | assetstudio/src/images/launcher_stencil/circle/hdpi/mask.png (renamed from assetstudio/res/launcher-stencil/circle/hdpi/mask.png) | bin | 992 -> 992 bytes | |||
-rw-r--r-- | assetstudio/src/images/launcher_stencil/circle/ldpi/back.png (renamed from assetstudio/res/launcher-stencil/circle/ldpi/back.png) | bin | 745 -> 745 bytes | |||
-rw-r--r-- | assetstudio/src/images/launcher_stencil/circle/ldpi/fore1.png (renamed from assetstudio/res/launcher-stencil/circle/ldpi/fore1.png) | bin | 376 -> 376 bytes | |||
-rw-r--r-- | assetstudio/src/images/launcher_stencil/circle/ldpi/fore2.png (renamed from assetstudio/res/launcher-stencil/circle/ldpi/fore2.png) | bin | 1370 -> 1370 bytes | |||
-rw-r--r-- | assetstudio/src/images/launcher_stencil/circle/ldpi/fore3.png (renamed from assetstudio/res/launcher-stencil/circle/ldpi/fore3.png) | bin | 2432 -> 2432 bytes | |||
-rw-r--r-- | assetstudio/src/images/launcher_stencil/circle/ldpi/mask.png (renamed from assetstudio/res/launcher-stencil/circle/ldpi/mask.png) | bin | 435 -> 435 bytes | |||
-rw-r--r-- | assetstudio/src/images/launcher_stencil/circle/mdpi/back.png (renamed from assetstudio/res/launcher-stencil/circle/mdpi/back.png) | bin | 1162 -> 1162 bytes | |||
-rw-r--r-- | assetstudio/src/images/launcher_stencil/circle/mdpi/fore1.png (renamed from assetstudio/res/launcher-stencil/circle/mdpi/fore1.png) | bin | 457 -> 457 bytes | |||
-rw-r--r-- | assetstudio/src/images/launcher_stencil/circle/mdpi/fore2.png (renamed from assetstudio/res/launcher-stencil/circle/mdpi/fore2.png) | bin | 1720 -> 1720 bytes | |||
-rw-r--r-- | assetstudio/src/images/launcher_stencil/circle/mdpi/fore3.png (renamed from assetstudio/res/launcher-stencil/circle/mdpi/fore3.png) | bin | 2926 -> 2926 bytes | |||
-rw-r--r-- | assetstudio/src/images/launcher_stencil/circle/mdpi/mask.png (renamed from assetstudio/res/launcher-stencil/circle/mdpi/mask.png) | bin | 610 -> 610 bytes | |||
-rw-r--r-- | assetstudio/src/images/launcher_stencil/circle/web/back.png (renamed from assetstudio/res/launcher-stencil/circle/web/back.png) | bin | 29806 -> 29806 bytes | |||
-rw-r--r-- | assetstudio/src/images/launcher_stencil/circle/web/fore1.png (renamed from assetstudio/res/launcher-stencil/circle/web/fore1.png) | bin | 30292 -> 30292 bytes | |||
-rw-r--r-- | assetstudio/src/images/launcher_stencil/circle/web/fore2.png (renamed from assetstudio/res/launcher-stencil/circle/web/fore2.png) | bin | 59463 -> 59463 bytes | |||
-rw-r--r-- | assetstudio/src/images/launcher_stencil/circle/web/fore3.png (renamed from assetstudio/res/launcher-stencil/circle/web/fore3.png) | bin | 61713 -> 61713 bytes | |||
-rw-r--r-- | assetstudio/src/images/launcher_stencil/circle/web/mask.png (renamed from assetstudio/res/launcher-stencil/circle/web/mask.png) | bin | 8447 -> 8447 bytes | |||
-rw-r--r-- | assetstudio/src/images/launcher_stencil/circle/xhdpi/back.png (renamed from assetstudio/res/launcher-stencil/circle/xhdpi/back.png) | bin | 3451 -> 3451 bytes | |||
-rw-r--r-- | assetstudio/src/images/launcher_stencil/circle/xhdpi/fore1.png (renamed from assetstudio/res/launcher-stencil/circle/xhdpi/fore1.png) | bin | 1746 -> 1746 bytes | |||
-rw-r--r-- | assetstudio/src/images/launcher_stencil/circle/xhdpi/fore2.png (renamed from assetstudio/res/launcher-stencil/circle/xhdpi/fore2.png) | bin | 5054 -> 5054 bytes | |||
-rw-r--r-- | assetstudio/src/images/launcher_stencil/circle/xhdpi/fore3.png (renamed from assetstudio/res/launcher-stencil/circle/xhdpi/fore3.png) | bin | 6239 -> 6239 bytes | |||
-rw-r--r-- | assetstudio/src/images/launcher_stencil/circle/xhdpi/mask.png (renamed from assetstudio/res/launcher-stencil/circle/xhdpi/mask.png) | bin | 2142 -> 2142 bytes | |||
-rw-r--r-- | assetstudio/src/images/launcher_stencil/square/hdpi/back.png (renamed from assetstudio/res/launcher-stencil/square/hdpi/back.png) | bin | 713 -> 713 bytes | |||
-rw-r--r-- | assetstudio/src/images/launcher_stencil/square/hdpi/fore1.png (renamed from assetstudio/res/launcher-stencil/square/hdpi/fore1.png) | bin | 331 -> 331 bytes | |||
-rw-r--r-- | assetstudio/src/images/launcher_stencil/square/hdpi/fore2.png (renamed from assetstudio/res/launcher-stencil/square/hdpi/fore2.png) | bin | 1477 -> 1477 bytes | |||
-rw-r--r-- | assetstudio/src/images/launcher_stencil/square/hdpi/fore3.png (renamed from assetstudio/res/launcher-stencil/square/hdpi/fore3.png) | bin | 3592 -> 3592 bytes | |||
-rw-r--r-- | assetstudio/src/images/launcher_stencil/square/hdpi/mask.png (renamed from assetstudio/res/launcher-stencil/square/hdpi/mask.png) | bin | 370 -> 370 bytes | |||
-rw-r--r-- | assetstudio/src/images/launcher_stencil/square/ldpi/back.png (renamed from assetstudio/res/launcher-stencil/square/ldpi/back.png) | bin | 295 -> 295 bytes | |||
-rw-r--r-- | assetstudio/src/images/launcher_stencil/square/ldpi/fore1.png (renamed from assetstudio/res/launcher-stencil/square/ldpi/fore1.png) | bin | 212 -> 212 bytes | |||
-rw-r--r-- | assetstudio/src/images/launcher_stencil/square/ldpi/fore2.png (renamed from assetstudio/res/launcher-stencil/square/ldpi/fore2.png) | bin | 693 -> 693 bytes | |||
-rw-r--r-- | assetstudio/src/images/launcher_stencil/square/ldpi/fore3.png (renamed from assetstudio/res/launcher-stencil/square/ldpi/fore3.png) | bin | 2061 -> 2061 bytes | |||
-rw-r--r-- | assetstudio/src/images/launcher_stencil/square/ldpi/mask.png (renamed from assetstudio/res/launcher-stencil/square/ldpi/mask.png) | bin | 205 -> 205 bytes | |||
-rw-r--r-- | assetstudio/src/images/launcher_stencil/square/mdpi/back.png (renamed from assetstudio/res/launcher-stencil/square/mdpi/back.png) | bin | 455 -> 455 bytes | |||
-rw-r--r-- | assetstudio/src/images/launcher_stencil/square/mdpi/fore1.png (renamed from assetstudio/res/launcher-stencil/square/mdpi/fore1.png) | bin | 239 -> 239 bytes | |||
-rw-r--r-- | assetstudio/src/images/launcher_stencil/square/mdpi/fore2.png (renamed from assetstudio/res/launcher-stencil/square/mdpi/fore2.png) | bin | 1010 -> 1010 bytes | |||
-rw-r--r-- | assetstudio/src/images/launcher_stencil/square/mdpi/fore3.png (renamed from assetstudio/res/launcher-stencil/square/mdpi/fore3.png) | bin | 2510 -> 2510 bytes | |||
-rw-r--r-- | assetstudio/src/images/launcher_stencil/square/mdpi/mask.png (renamed from assetstudio/res/launcher-stencil/square/mdpi/mask.png) | bin | 250 -> 250 bytes | |||
-rw-r--r-- | assetstudio/src/images/launcher_stencil/square/web/back.png (renamed from assetstudio/res/launcher-stencil/square/web/back.png) | bin | 10984 -> 10984 bytes | |||
-rw-r--r-- | assetstudio/src/images/launcher_stencil/square/web/fore1.png (renamed from assetstudio/res/launcher-stencil/square/web/fore1.png) | bin | 8562 -> 8562 bytes | |||
-rw-r--r-- | assetstudio/src/images/launcher_stencil/square/web/fore2.png (renamed from assetstudio/res/launcher-stencil/square/web/fore2.png) | bin | 26230 -> 26230 bytes | |||
-rw-r--r-- | assetstudio/src/images/launcher_stencil/square/web/fore3.png (renamed from assetstudio/res/launcher-stencil/square/web/fore3.png) | bin | 42175 -> 42175 bytes | |||
-rw-r--r-- | assetstudio/src/images/launcher_stencil/square/web/mask.png (renamed from assetstudio/res/launcher-stencil/square/web/mask.png) | bin | 3786 -> 3786 bytes | |||
-rw-r--r-- | assetstudio/src/images/launcher_stencil/square/xhdpi/back.png (renamed from assetstudio/res/launcher-stencil/square/xhdpi/back.png) | bin | 1956 -> 1956 bytes | |||
-rw-r--r-- | assetstudio/src/images/launcher_stencil/square/xhdpi/fore1.png (renamed from assetstudio/res/launcher-stencil/square/xhdpi/fore1.png) | bin | 1289 -> 1289 bytes | |||
-rw-r--r-- | assetstudio/src/images/launcher_stencil/square/xhdpi/fore2.png (renamed from assetstudio/res/launcher-stencil/square/xhdpi/fore2.png) | bin | 2932 -> 2932 bytes | |||
-rw-r--r-- | assetstudio/src/images/launcher_stencil/square/xhdpi/fore3.png (renamed from assetstudio/res/launcher-stencil/square/xhdpi/fore3.png) | bin | 4649 -> 4649 bytes | |||
-rw-r--r-- | assetstudio/src/images/launcher_stencil/square/xhdpi/mask.png (renamed from assetstudio/res/launcher-stencil/square/xhdpi/mask.png) | bin | 1396 -> 1396 bytes | |||
-rw-r--r-- | eclipse/plugins/com.android.ide.eclipse.adt/.classpath | 1 | ||||
-rw-r--r-- | eclipse/plugins/com.android.ide.eclipse.adt/META-INF/MANIFEST.MF | 3 | ||||
-rw-r--r-- | eclipse/plugins/com.android.ide.eclipse.adt/icons/new_asset_set.png | bin | 0 -> 907 bytes | |||
-rw-r--r-- | eclipse/plugins/com.android.ide.eclipse.adt/plugin.xml | 11 | ||||
-rw-r--r-- | eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/AdtConstants.java | 2 | ||||
-rw-r--r-- | eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/assetstudio/ChooseAssetTypePage.java | 217 | ||||
-rw-r--r-- | eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/assetstudio/ConfigureAssetSetPage.java | 782 | ||||
-rw-r--r-- | eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/assetstudio/ConfigureLauncherAssetsPanel.java | 37 | ||||
-rw-r--r-- | eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/assetstudio/CreateAssetSetWizard.java | 249 | ||||
-rw-r--r-- | eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/resources/ResourceNameValidator.java | 32 | ||||
-rw-r--r-- | eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/wizards/newxmlfile/NewXmlFileWizard.java | 2 | ||||
-rwxr-xr-x | eclipse/scripts/create_adt_symlinks.sh | 2 |
72 files changed, 1492 insertions, 36 deletions
diff --git a/assetstudio/.classpath b/assetstudio/.classpath new file mode 100644 index 0000000..ee79d96 --- /dev/null +++ b/assetstudio/.classpath @@ -0,0 +1,7 @@ +<?xml version="1.0" encoding="UTF-8"?> +<classpath> + <classpathentry kind="src" path="src"/> + <classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER"/> + <classpathentry kind="output" path="bin"/> + <classpathentry combineaccessrules="false" kind="src" path="/common"/> +</classpath> diff --git a/assetstudio/.gitignore b/assetstudio/.gitignore new file mode 100644 index 0000000..fe99505 --- /dev/null +++ b/assetstudio/.gitignore @@ -0,0 +1,2 @@ +bin + diff --git a/assetstudio/.project b/assetstudio/.project new file mode 100644 index 0000000..f9aa2ce --- /dev/null +++ b/assetstudio/.project @@ -0,0 +1,17 @@ +<?xml version="1.0" encoding="UTF-8"?> +<projectDescription> + <name>assetstudio</name> + <comment></comment> + <projects> + </projects> + <buildSpec> + <buildCommand> + <name>org.eclipse.jdt.core.javabuilder</name> + <arguments> + </arguments> + </buildCommand> + </buildSpec> + <natures> + <nature>org.eclipse.jdt.core.javanature</nature> + </natures> +</projectDescription> diff --git a/assetstudio/.settings/org.eclipse.jdt.core.prefs b/assetstudio/.settings/org.eclipse.jdt.core.prefs new file mode 100644 index 0000000..e755df2 --- /dev/null +++ b/assetstudio/.settings/org.eclipse.jdt.core.prefs @@ -0,0 +1,71 @@ +#Thu Jun 09 12:26:44 PDT 2011 +eclipse.preferences.version=1 +org.eclipse.jdt.core.compiler.problem.annotationSuperInterface=warning +org.eclipse.jdt.core.compiler.problem.autoboxing=ignore +org.eclipse.jdt.core.compiler.problem.comparingIdentical=warning +org.eclipse.jdt.core.compiler.problem.deadCode=warning +org.eclipse.jdt.core.compiler.problem.deprecation=warning +org.eclipse.jdt.core.compiler.problem.deprecationInDeprecatedCode=disabled +org.eclipse.jdt.core.compiler.problem.deprecationWhenOverridingDeprecatedMethod=disabled +org.eclipse.jdt.core.compiler.problem.discouragedReference=warning +org.eclipse.jdt.core.compiler.problem.emptyStatement=ignore +org.eclipse.jdt.core.compiler.problem.fallthroughCase=warning +org.eclipse.jdt.core.compiler.problem.fatalOptionalError=enabled +org.eclipse.jdt.core.compiler.problem.fieldHiding=warning +org.eclipse.jdt.core.compiler.problem.finalParameterBound=warning +org.eclipse.jdt.core.compiler.problem.finallyBlockNotCompletingNormally=warning +org.eclipse.jdt.core.compiler.problem.forbiddenReference=error +org.eclipse.jdt.core.compiler.problem.hiddenCatchBlock=warning +org.eclipse.jdt.core.compiler.problem.includeNullInfoFromAsserts=enabled +org.eclipse.jdt.core.compiler.problem.incompatibleNonInheritedInterfaceMethod=warning +org.eclipse.jdt.core.compiler.problem.incompleteEnumSwitch=ignore +org.eclipse.jdt.core.compiler.problem.indirectStaticAccess=ignore +org.eclipse.jdt.core.compiler.problem.localVariableHiding=warning +org.eclipse.jdt.core.compiler.problem.methodWithConstructorName=warning +org.eclipse.jdt.core.compiler.problem.missingDeprecatedAnnotation=warning +org.eclipse.jdt.core.compiler.problem.missingHashCodeMethod=warning +org.eclipse.jdt.core.compiler.problem.missingOverrideAnnotation=error +org.eclipse.jdt.core.compiler.problem.missingOverrideAnnotationForInterfaceMethodImplementation=enabled +org.eclipse.jdt.core.compiler.problem.missingSerialVersion=warning +org.eclipse.jdt.core.compiler.problem.missingSynchronizedOnInheritedMethod=ignore +org.eclipse.jdt.core.compiler.problem.noEffectAssignment=warning +org.eclipse.jdt.core.compiler.problem.noImplicitStringConversion=warning +org.eclipse.jdt.core.compiler.problem.nonExternalizedStringLiteral=ignore +org.eclipse.jdt.core.compiler.problem.nullReference=error +org.eclipse.jdt.core.compiler.problem.overridingPackageDefaultMethod=warning +org.eclipse.jdt.core.compiler.problem.parameterAssignment=ignore +org.eclipse.jdt.core.compiler.problem.possibleAccidentalBooleanAssignment=warning +org.eclipse.jdt.core.compiler.problem.potentialNullReference=warning +org.eclipse.jdt.core.compiler.problem.rawTypeReference=warning +org.eclipse.jdt.core.compiler.problem.redundantNullCheck=ignore +org.eclipse.jdt.core.compiler.problem.redundantSuperinterface=warning +org.eclipse.jdt.core.compiler.problem.reportMethodCanBePotentiallyStatic=ignore +org.eclipse.jdt.core.compiler.problem.reportMethodCanBeStatic=ignore +org.eclipse.jdt.core.compiler.problem.specialParameterHidingField=disabled +org.eclipse.jdt.core.compiler.problem.staticAccessReceiver=warning +org.eclipse.jdt.core.compiler.problem.suppressOptionalErrors=disabled +org.eclipse.jdt.core.compiler.problem.suppressWarnings=enabled +org.eclipse.jdt.core.compiler.problem.syntheticAccessEmulation=ignore +org.eclipse.jdt.core.compiler.problem.typeParameterHiding=warning +org.eclipse.jdt.core.compiler.problem.unavoidableGenericTypeProblems=disabled +org.eclipse.jdt.core.compiler.problem.uncheckedTypeOperation=warning +org.eclipse.jdt.core.compiler.problem.undocumentedEmptyBlock=ignore +org.eclipse.jdt.core.compiler.problem.unhandledWarningToken=warning +org.eclipse.jdt.core.compiler.problem.unnecessaryElse=ignore +org.eclipse.jdt.core.compiler.problem.unnecessaryTypeCheck=warning +org.eclipse.jdt.core.compiler.problem.unqualifiedFieldAccess=ignore +org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownException=warning +org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownExceptionExemptExceptionAndThrowable=enabled +org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownExceptionIncludeDocCommentReference=enabled +org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownExceptionWhenOverriding=disabled +org.eclipse.jdt.core.compiler.problem.unusedImport=warning +org.eclipse.jdt.core.compiler.problem.unusedLabel=warning +org.eclipse.jdt.core.compiler.problem.unusedLocal=warning +org.eclipse.jdt.core.compiler.problem.unusedObjectAllocation=warning +org.eclipse.jdt.core.compiler.problem.unusedParameter=ignore +org.eclipse.jdt.core.compiler.problem.unusedParameterIncludeDocCommentReference=enabled +org.eclipse.jdt.core.compiler.problem.unusedParameterWhenImplementingAbstract=disabled +org.eclipse.jdt.core.compiler.problem.unusedParameterWhenOverridingConcrete=disabled +org.eclipse.jdt.core.compiler.problem.unusedPrivateMember=warning +org.eclipse.jdt.core.compiler.problem.unusedWarningToken=warning +org.eclipse.jdt.core.compiler.problem.varargsArgumentNeedCast=warning diff --git a/assetstudio/Android.mk b/assetstudio/Android.mk new file mode 100644 index 0000000..a48c3a0 --- /dev/null +++ b/assetstudio/Android.mk @@ -0,0 +1,30 @@ +# +# Copyright (C) 2011 The Android Open Source Project +# +# 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. +# +LOCAL_PATH := $(call my-dir) +include $(CLEAR_VARS) + +LOCAL_SRC_FILES := $(call all-java-files-under,src) +LOCAL_JAVA_RESOURCE_DIRS := src + +# TODO: Replace common with the batik stuff +LOCAL_JAVA_LIBRARIES := \ + common + +LOCAL_MODULE := assetstudio + +LOCAL_MODULE_TAGS := optional + +include $(BUILD_HOST_JAVA_LIBRARY) diff --git a/assetstudio/libs/assetstudiolib/src/com/android/assetstudiolib/GraphicGenerator.java b/assetstudio/src/com/android/assetstudiolib/GraphicGenerator.java index 25f7039..e53f0ab 100644 --- a/assetstudio/libs/assetstudiolib/src/com/android/assetstudiolib/GraphicGenerator.java +++ b/assetstudio/src/com/android/assetstudiolib/GraphicGenerator.java @@ -16,6 +16,14 @@ package com.android.assetstudiolib; +import com.android.resources.Density; + +import java.awt.image.BufferedImage; +import java.io.IOException; +import java.io.InputStream; + +import javax.imageio.ImageIO; + /** * The base Generator class. */ @@ -24,23 +32,21 @@ public class GraphicGenerator { * Options used for all generators. */ public static class Options { - /** - * The screen density of the icon. - */ - public static enum Density { - LDPI("ldpi", 120), MDPI("mdpi", 160), HDPI("hdpi", 240), XHDPI("xhdpi", 320); - - public String id; - public int dpi; + } - Density(String id, int dpi) { - this.id = id; - this.dpi = dpi; - } + public static float getScaleFactor(Density density) { + return density.getDpiValue() / (float) Density.DEFAULT_DENSITY; + } - public float scaleFactor() { - return (float) this.dpi / 160; - } - } + /** + * Returns one of the built in stencil images, or null + * + * @param relativePath stencil path such as "launcher-stencil/square/web/back.png" + * @return the image, or null + * @throws IOException if an unexpected I/O error occurs + */ + public static BufferedImage getStencilImage(String relativePath) throws IOException { + InputStream is = GraphicGenerator.class.getResourceAsStream(relativePath); + return ImageIO.read(is); } } diff --git a/assetstudio/libs/assetstudiolib/src/com/android/assetstudiolib/GraphicGeneratorContext.java b/assetstudio/src/com/android/assetstudiolib/GraphicGeneratorContext.java index e0b00a6..e0b00a6 100644 --- a/assetstudio/libs/assetstudiolib/src/com/android/assetstudiolib/GraphicGeneratorContext.java +++ b/assetstudio/src/com/android/assetstudiolib/GraphicGeneratorContext.java diff --git a/assetstudio/libs/assetstudiolib/src/com/android/assetstudiolib/LauncherIconGenerator.java b/assetstudio/src/com/android/assetstudiolib/LauncherIconGenerator.java index e9cc65b..b6715a4 100644 --- a/assetstudio/libs/assetstudiolib/src/com/android/assetstudiolib/LauncherIconGenerator.java +++ b/assetstudio/src/com/android/assetstudiolib/LauncherIconGenerator.java @@ -16,6 +16,8 @@ package com.android.assetstudiolib; +import com.android.resources.Density; + import java.awt.AlphaComposite; import java.awt.Color; import java.awt.Graphics2D; @@ -36,16 +38,17 @@ public class LauncherIconGenerator extends GraphicGenerator { public LauncherIconGenerator(GraphicGeneratorContext context, Options options) { mOptions = options; - mBackImage = context.loadImageResource("launcher-stencil/" - + options.shape.id + "/" + options.density.id + "/back.png"); - mForeImage = context.loadImageResource("launcher-stencil/" - + options.shape.id + "/" + options.density.id + "/" + options.style.id + ".png"); - mMaskImage = context.loadImageResource("launcher-stencil/" - + options.shape.id + "/" + options.density.id + "/mask.png"); + mBackImage = context.loadImageResource("/images/launcher_stencil/" + + options.shape.id + "/" + options.density.getResourceValue() + "/back.png"); + mForeImage = context.loadImageResource("/images/launcher_stencil/" + + options.shape.id + "/" + options.density.getResourceValue() + "/" + + options.style.id + ".png"); + mMaskImage = context.loadImageResource("/images/launcher_stencil/" + + options.shape.id + "/" + options.density.getResourceValue() + "/mask.png"); } public BufferedImage generate() { - final float scaleFactor = mOptions.density.scaleFactor(); + final float scaleFactor = GraphicGenerator.getScaleFactor(mOptions.density); Rectangle imageRect = Util.scaleRectangle(BASE_IMAGE_RECT, scaleFactor); Rectangle targetRect = Util.scaleRectangle(BASE_TARGET_RECT, scaleFactor); @@ -80,7 +83,7 @@ public class LauncherIconGenerator extends GraphicGenerator { public boolean crop = true; public Shape shape = Shape.SQUARE; public Style style = Style.SIMPLE; - public GraphicGenerator.Options.Density density = GraphicGenerator.Options.Density.XHDPI; + public Density density = Density.XHIGH; public static enum Shape { CIRCLE("circle"), SQUARE("square"); diff --git a/assetstudio/libs/assetstudiolib/src/com/android/assetstudiolib/MenuIconGenerator.java b/assetstudio/src/com/android/assetstudiolib/MenuIconGenerator.java index bff6e42..07b7a6b 100644 --- a/assetstudio/libs/assetstudiolib/src/com/android/assetstudiolib/MenuIconGenerator.java +++ b/assetstudio/src/com/android/assetstudiolib/MenuIconGenerator.java @@ -16,6 +16,8 @@ package com.android.assetstudiolib; +import com.android.resources.Density; + import java.awt.Color; import java.awt.GradientPaint; import java.awt.Graphics2D; @@ -36,7 +38,7 @@ public class MenuIconGenerator extends GraphicGenerator { } public BufferedImage generate() { - final float scaleFactor = mOptions.density.scaleFactor(); + final float scaleFactor = GraphicGenerator.getScaleFactor(mOptions.density); Rectangle imageRect = Util.scaleRectangle(BASE_IMAGE_RECT, scaleFactor); Rectangle targetRect = Util.scaleRectangle(BASE_TARGET_RECT, scaleFactor); @@ -85,6 +87,6 @@ public class MenuIconGenerator extends GraphicGenerator { public static class Options { public BufferedImage sourceImage; - public GraphicGenerator.Options.Density density = GraphicGenerator.Options.Density.XHDPI; + public Density density = Density.XHIGH; } } diff --git a/assetstudio/libs/assetstudiolib/src/com/android/assetstudiolib/Util.java b/assetstudio/src/com/android/assetstudiolib/Util.java index 82299a4..82299a4 100644 --- a/assetstudio/libs/assetstudiolib/src/com/android/assetstudiolib/Util.java +++ b/assetstudio/src/com/android/assetstudiolib/Util.java diff --git a/assetstudio/res/launcher-stencil/circle/hdpi/back.png b/assetstudio/src/images/launcher_stencil/circle/hdpi/back.png Binary files differindex 8e3dbc1..8e3dbc1 100644 --- a/assetstudio/res/launcher-stencil/circle/hdpi/back.png +++ b/assetstudio/src/images/launcher_stencil/circle/hdpi/back.png diff --git a/assetstudio/res/launcher-stencil/circle/hdpi/fore1.png b/assetstudio/src/images/launcher_stencil/circle/hdpi/fore1.png Binary files differindex 79d75c0..79d75c0 100644 --- a/assetstudio/res/launcher-stencil/circle/hdpi/fore1.png +++ b/assetstudio/src/images/launcher_stencil/circle/hdpi/fore1.png diff --git a/assetstudio/res/launcher-stencil/circle/hdpi/fore2.png b/assetstudio/src/images/launcher_stencil/circle/hdpi/fore2.png Binary files differindex 594257a..594257a 100644 --- a/assetstudio/res/launcher-stencil/circle/hdpi/fore2.png +++ b/assetstudio/src/images/launcher_stencil/circle/hdpi/fore2.png diff --git a/assetstudio/res/launcher-stencil/circle/hdpi/fore3.png b/assetstudio/src/images/launcher_stencil/circle/hdpi/fore3.png Binary files differindex 65fb48b..65fb48b 100644 --- a/assetstudio/res/launcher-stencil/circle/hdpi/fore3.png +++ b/assetstudio/src/images/launcher_stencil/circle/hdpi/fore3.png diff --git a/assetstudio/res/launcher-stencil/circle/hdpi/mask.png b/assetstudio/src/images/launcher_stencil/circle/hdpi/mask.png Binary files differindex 99e787a..99e787a 100644 --- a/assetstudio/res/launcher-stencil/circle/hdpi/mask.png +++ b/assetstudio/src/images/launcher_stencil/circle/hdpi/mask.png diff --git a/assetstudio/res/launcher-stencil/circle/ldpi/back.png b/assetstudio/src/images/launcher_stencil/circle/ldpi/back.png Binary files differindex d9a9fcc..d9a9fcc 100644 --- a/assetstudio/res/launcher-stencil/circle/ldpi/back.png +++ b/assetstudio/src/images/launcher_stencil/circle/ldpi/back.png diff --git a/assetstudio/res/launcher-stencil/circle/ldpi/fore1.png b/assetstudio/src/images/launcher_stencil/circle/ldpi/fore1.png Binary files differindex ecc3bc5..ecc3bc5 100644 --- a/assetstudio/res/launcher-stencil/circle/ldpi/fore1.png +++ b/assetstudio/src/images/launcher_stencil/circle/ldpi/fore1.png diff --git a/assetstudio/res/launcher-stencil/circle/ldpi/fore2.png b/assetstudio/src/images/launcher_stencil/circle/ldpi/fore2.png Binary files differindex c86b59c..c86b59c 100644 --- a/assetstudio/res/launcher-stencil/circle/ldpi/fore2.png +++ b/assetstudio/src/images/launcher_stencil/circle/ldpi/fore2.png diff --git a/assetstudio/res/launcher-stencil/circle/ldpi/fore3.png b/assetstudio/src/images/launcher_stencil/circle/ldpi/fore3.png Binary files differindex 1ae4d31..1ae4d31 100644 --- a/assetstudio/res/launcher-stencil/circle/ldpi/fore3.png +++ b/assetstudio/src/images/launcher_stencil/circle/ldpi/fore3.png diff --git a/assetstudio/res/launcher-stencil/circle/ldpi/mask.png b/assetstudio/src/images/launcher_stencil/circle/ldpi/mask.png Binary files differindex e537ad0..e537ad0 100644 --- a/assetstudio/res/launcher-stencil/circle/ldpi/mask.png +++ b/assetstudio/src/images/launcher_stencil/circle/ldpi/mask.png diff --git a/assetstudio/res/launcher-stencil/circle/mdpi/back.png b/assetstudio/src/images/launcher_stencil/circle/mdpi/back.png Binary files differindex e165038..e165038 100644 --- a/assetstudio/res/launcher-stencil/circle/mdpi/back.png +++ b/assetstudio/src/images/launcher_stencil/circle/mdpi/back.png diff --git a/assetstudio/res/launcher-stencil/circle/mdpi/fore1.png b/assetstudio/src/images/launcher_stencil/circle/mdpi/fore1.png Binary files differindex c42af13..c42af13 100644 --- a/assetstudio/res/launcher-stencil/circle/mdpi/fore1.png +++ b/assetstudio/src/images/launcher_stencil/circle/mdpi/fore1.png diff --git a/assetstudio/res/launcher-stencil/circle/mdpi/fore2.png b/assetstudio/src/images/launcher_stencil/circle/mdpi/fore2.png Binary files differindex 0c06821..0c06821 100644 --- a/assetstudio/res/launcher-stencil/circle/mdpi/fore2.png +++ b/assetstudio/src/images/launcher_stencil/circle/mdpi/fore2.png diff --git a/assetstudio/res/launcher-stencil/circle/mdpi/fore3.png b/assetstudio/src/images/launcher_stencil/circle/mdpi/fore3.png Binary files differindex 01fe418..01fe418 100644 --- a/assetstudio/res/launcher-stencil/circle/mdpi/fore3.png +++ b/assetstudio/src/images/launcher_stencil/circle/mdpi/fore3.png diff --git a/assetstudio/res/launcher-stencil/circle/mdpi/mask.png b/assetstudio/src/images/launcher_stencil/circle/mdpi/mask.png Binary files differindex 19f18bf..19f18bf 100644 --- a/assetstudio/res/launcher-stencil/circle/mdpi/mask.png +++ b/assetstudio/src/images/launcher_stencil/circle/mdpi/mask.png diff --git a/assetstudio/res/launcher-stencil/circle/web/back.png b/assetstudio/src/images/launcher_stencil/circle/web/back.png Binary files differindex 191c677..191c677 100644 --- a/assetstudio/res/launcher-stencil/circle/web/back.png +++ b/assetstudio/src/images/launcher_stencil/circle/web/back.png diff --git a/assetstudio/res/launcher-stencil/circle/web/fore1.png b/assetstudio/src/images/launcher_stencil/circle/web/fore1.png Binary files differindex 7ea8096..7ea8096 100644 --- a/assetstudio/res/launcher-stencil/circle/web/fore1.png +++ b/assetstudio/src/images/launcher_stencil/circle/web/fore1.png diff --git a/assetstudio/res/launcher-stencil/circle/web/fore2.png b/assetstudio/src/images/launcher_stencil/circle/web/fore2.png Binary files differindex 5a76240..5a76240 100644 --- a/assetstudio/res/launcher-stencil/circle/web/fore2.png +++ b/assetstudio/src/images/launcher_stencil/circle/web/fore2.png diff --git a/assetstudio/res/launcher-stencil/circle/web/fore3.png b/assetstudio/src/images/launcher_stencil/circle/web/fore3.png Binary files differindex 1794bff..1794bff 100644 --- a/assetstudio/res/launcher-stencil/circle/web/fore3.png +++ b/assetstudio/src/images/launcher_stencil/circle/web/fore3.png diff --git a/assetstudio/res/launcher-stencil/circle/web/mask.png b/assetstudio/src/images/launcher_stencil/circle/web/mask.png Binary files differindex 8316d80..8316d80 100644 --- a/assetstudio/res/launcher-stencil/circle/web/mask.png +++ b/assetstudio/src/images/launcher_stencil/circle/web/mask.png diff --git a/assetstudio/res/launcher-stencil/circle/xhdpi/back.png b/assetstudio/src/images/launcher_stencil/circle/xhdpi/back.png Binary files differindex e655af6..e655af6 100644 --- a/assetstudio/res/launcher-stencil/circle/xhdpi/back.png +++ b/assetstudio/src/images/launcher_stencil/circle/xhdpi/back.png diff --git a/assetstudio/res/launcher-stencil/circle/xhdpi/fore1.png b/assetstudio/src/images/launcher_stencil/circle/xhdpi/fore1.png Binary files differindex 639ccba..639ccba 100644 --- a/assetstudio/res/launcher-stencil/circle/xhdpi/fore1.png +++ b/assetstudio/src/images/launcher_stencil/circle/xhdpi/fore1.png diff --git a/assetstudio/res/launcher-stencil/circle/xhdpi/fore2.png b/assetstudio/src/images/launcher_stencil/circle/xhdpi/fore2.png Binary files differindex b922452..b922452 100644 --- a/assetstudio/res/launcher-stencil/circle/xhdpi/fore2.png +++ b/assetstudio/src/images/launcher_stencil/circle/xhdpi/fore2.png diff --git a/assetstudio/res/launcher-stencil/circle/xhdpi/fore3.png b/assetstudio/src/images/launcher_stencil/circle/xhdpi/fore3.png Binary files differindex 5f1c15e..5f1c15e 100644 --- a/assetstudio/res/launcher-stencil/circle/xhdpi/fore3.png +++ b/assetstudio/src/images/launcher_stencil/circle/xhdpi/fore3.png diff --git a/assetstudio/res/launcher-stencil/circle/xhdpi/mask.png b/assetstudio/src/images/launcher_stencil/circle/xhdpi/mask.png Binary files differindex 6dc3bc7..6dc3bc7 100644 --- a/assetstudio/res/launcher-stencil/circle/xhdpi/mask.png +++ b/assetstudio/src/images/launcher_stencil/circle/xhdpi/mask.png diff --git a/assetstudio/res/launcher-stencil/square/hdpi/back.png b/assetstudio/src/images/launcher_stencil/square/hdpi/back.png Binary files differindex 3e58211..3e58211 100644 --- a/assetstudio/res/launcher-stencil/square/hdpi/back.png +++ b/assetstudio/src/images/launcher_stencil/square/hdpi/back.png diff --git a/assetstudio/res/launcher-stencil/square/hdpi/fore1.png b/assetstudio/src/images/launcher_stencil/square/hdpi/fore1.png Binary files differindex e76d493..e76d493 100644 --- a/assetstudio/res/launcher-stencil/square/hdpi/fore1.png +++ b/assetstudio/src/images/launcher_stencil/square/hdpi/fore1.png diff --git a/assetstudio/res/launcher-stencil/square/hdpi/fore2.png b/assetstudio/src/images/launcher_stencil/square/hdpi/fore2.png Binary files differindex ab28d8d..ab28d8d 100644 --- a/assetstudio/res/launcher-stencil/square/hdpi/fore2.png +++ b/assetstudio/src/images/launcher_stencil/square/hdpi/fore2.png diff --git a/assetstudio/res/launcher-stencil/square/hdpi/fore3.png b/assetstudio/src/images/launcher_stencil/square/hdpi/fore3.png Binary files differindex 59f5e8f..59f5e8f 100644 --- a/assetstudio/res/launcher-stencil/square/hdpi/fore3.png +++ b/assetstudio/src/images/launcher_stencil/square/hdpi/fore3.png diff --git a/assetstudio/res/launcher-stencil/square/hdpi/mask.png b/assetstudio/src/images/launcher_stencil/square/hdpi/mask.png Binary files differindex 9c56fe6..9c56fe6 100644 --- a/assetstudio/res/launcher-stencil/square/hdpi/mask.png +++ b/assetstudio/src/images/launcher_stencil/square/hdpi/mask.png diff --git a/assetstudio/res/launcher-stencil/square/ldpi/back.png b/assetstudio/src/images/launcher_stencil/square/ldpi/back.png Binary files differindex 1a68be3..1a68be3 100644 --- a/assetstudio/res/launcher-stencil/square/ldpi/back.png +++ b/assetstudio/src/images/launcher_stencil/square/ldpi/back.png diff --git a/assetstudio/res/launcher-stencil/square/ldpi/fore1.png b/assetstudio/src/images/launcher_stencil/square/ldpi/fore1.png Binary files differindex c46e1c2..c46e1c2 100644 --- a/assetstudio/res/launcher-stencil/square/ldpi/fore1.png +++ b/assetstudio/src/images/launcher_stencil/square/ldpi/fore1.png diff --git a/assetstudio/res/launcher-stencil/square/ldpi/fore2.png b/assetstudio/src/images/launcher_stencil/square/ldpi/fore2.png Binary files differindex 3bc8315..3bc8315 100644 --- a/assetstudio/res/launcher-stencil/square/ldpi/fore2.png +++ b/assetstudio/src/images/launcher_stencil/square/ldpi/fore2.png diff --git a/assetstudio/res/launcher-stencil/square/ldpi/fore3.png b/assetstudio/src/images/launcher_stencil/square/ldpi/fore3.png Binary files differindex 0bfa4f7..0bfa4f7 100644 --- a/assetstudio/res/launcher-stencil/square/ldpi/fore3.png +++ b/assetstudio/src/images/launcher_stencil/square/ldpi/fore3.png diff --git a/assetstudio/res/launcher-stencil/square/ldpi/mask.png b/assetstudio/src/images/launcher_stencil/square/ldpi/mask.png Binary files differindex 04d6d1a..04d6d1a 100644 --- a/assetstudio/res/launcher-stencil/square/ldpi/mask.png +++ b/assetstudio/src/images/launcher_stencil/square/ldpi/mask.png diff --git a/assetstudio/res/launcher-stencil/square/mdpi/back.png b/assetstudio/src/images/launcher_stencil/square/mdpi/back.png Binary files differindex f49e513..f49e513 100644 --- a/assetstudio/res/launcher-stencil/square/mdpi/back.png +++ b/assetstudio/src/images/launcher_stencil/square/mdpi/back.png diff --git a/assetstudio/res/launcher-stencil/square/mdpi/fore1.png b/assetstudio/src/images/launcher_stencil/square/mdpi/fore1.png Binary files differindex 2837d41..2837d41 100644 --- a/assetstudio/res/launcher-stencil/square/mdpi/fore1.png +++ b/assetstudio/src/images/launcher_stencil/square/mdpi/fore1.png diff --git a/assetstudio/res/launcher-stencil/square/mdpi/fore2.png b/assetstudio/src/images/launcher_stencil/square/mdpi/fore2.png Binary files differindex 566941f..566941f 100644 --- a/assetstudio/res/launcher-stencil/square/mdpi/fore2.png +++ b/assetstudio/src/images/launcher_stencil/square/mdpi/fore2.png diff --git a/assetstudio/res/launcher-stencil/square/mdpi/fore3.png b/assetstudio/src/images/launcher_stencil/square/mdpi/fore3.png Binary files differindex 9bcfc5e..9bcfc5e 100644 --- a/assetstudio/res/launcher-stencil/square/mdpi/fore3.png +++ b/assetstudio/src/images/launcher_stencil/square/mdpi/fore3.png diff --git a/assetstudio/res/launcher-stencil/square/mdpi/mask.png b/assetstudio/src/images/launcher_stencil/square/mdpi/mask.png Binary files differindex 90e5cd0..90e5cd0 100644 --- a/assetstudio/res/launcher-stencil/square/mdpi/mask.png +++ b/assetstudio/src/images/launcher_stencil/square/mdpi/mask.png diff --git a/assetstudio/res/launcher-stencil/square/web/back.png b/assetstudio/src/images/launcher_stencil/square/web/back.png Binary files differindex 2f008b7..2f008b7 100644 --- a/assetstudio/res/launcher-stencil/square/web/back.png +++ b/assetstudio/src/images/launcher_stencil/square/web/back.png diff --git a/assetstudio/res/launcher-stencil/square/web/fore1.png b/assetstudio/src/images/launcher_stencil/square/web/fore1.png Binary files differindex 527ac47..527ac47 100644 --- a/assetstudio/res/launcher-stencil/square/web/fore1.png +++ b/assetstudio/src/images/launcher_stencil/square/web/fore1.png diff --git a/assetstudio/res/launcher-stencil/square/web/fore2.png b/assetstudio/src/images/launcher_stencil/square/web/fore2.png Binary files differindex 5e557f8..5e557f8 100644 --- a/assetstudio/res/launcher-stencil/square/web/fore2.png +++ b/assetstudio/src/images/launcher_stencil/square/web/fore2.png diff --git a/assetstudio/res/launcher-stencil/square/web/fore3.png b/assetstudio/src/images/launcher_stencil/square/web/fore3.png Binary files differindex 58d85af..58d85af 100644 --- a/assetstudio/res/launcher-stencil/square/web/fore3.png +++ b/assetstudio/src/images/launcher_stencil/square/web/fore3.png diff --git a/assetstudio/res/launcher-stencil/square/web/mask.png b/assetstudio/src/images/launcher_stencil/square/web/mask.png Binary files differindex 2c80196..2c80196 100644 --- a/assetstudio/res/launcher-stencil/square/web/mask.png +++ b/assetstudio/src/images/launcher_stencil/square/web/mask.png diff --git a/assetstudio/res/launcher-stencil/square/xhdpi/back.png b/assetstudio/src/images/launcher_stencil/square/xhdpi/back.png Binary files differindex 84caac0..84caac0 100644 --- a/assetstudio/res/launcher-stencil/square/xhdpi/back.png +++ b/assetstudio/src/images/launcher_stencil/square/xhdpi/back.png diff --git a/assetstudio/res/launcher-stencil/square/xhdpi/fore1.png b/assetstudio/src/images/launcher_stencil/square/xhdpi/fore1.png Binary files differindex 2d237e1..2d237e1 100644 --- a/assetstudio/res/launcher-stencil/square/xhdpi/fore1.png +++ b/assetstudio/src/images/launcher_stencil/square/xhdpi/fore1.png diff --git a/assetstudio/res/launcher-stencil/square/xhdpi/fore2.png b/assetstudio/src/images/launcher_stencil/square/xhdpi/fore2.png Binary files differindex cce5e0e..cce5e0e 100644 --- a/assetstudio/res/launcher-stencil/square/xhdpi/fore2.png +++ b/assetstudio/src/images/launcher_stencil/square/xhdpi/fore2.png diff --git a/assetstudio/res/launcher-stencil/square/xhdpi/fore3.png b/assetstudio/src/images/launcher_stencil/square/xhdpi/fore3.png Binary files differindex 3b91aa4..3b91aa4 100644 --- a/assetstudio/res/launcher-stencil/square/xhdpi/fore3.png +++ b/assetstudio/src/images/launcher_stencil/square/xhdpi/fore3.png diff --git a/assetstudio/res/launcher-stencil/square/xhdpi/mask.png b/assetstudio/src/images/launcher_stencil/square/xhdpi/mask.png Binary files differindex 9e0bbdc..9e0bbdc 100644 --- a/assetstudio/res/launcher-stencil/square/xhdpi/mask.png +++ b/assetstudio/src/images/launcher_stencil/square/xhdpi/mask.png diff --git a/eclipse/plugins/com.android.ide.eclipse.adt/.classpath b/eclipse/plugins/com.android.ide.eclipse.adt/.classpath index 7a693db..a77b6b6 100644 --- a/eclipse/plugins/com.android.ide.eclipse.adt/.classpath +++ b/eclipse/plugins/com.android.ide.eclipse.adt/.classpath @@ -13,6 +13,7 @@ <classpathentry kind="lib" path="libs/sdkstats.jar" sourcepath="/SdkStatsService"/> <classpathentry kind="lib" path="libs/sdkuilib.jar" sourcepath="/SdkUiLib"/> <classpathentry kind="lib" path="libs/common.jar" sourcepath="/common"/> + <classpathentry kind="lib" path="libs/assetstudio.jar" sourcepath="/assetstudio"/> <classpathentry combineaccessrules="false" kind="src" path="/ddmlib"/> <classpathentry combineaccessrules="false" kind="src" path="/ddmuilib"/> <classpathentry kind="output" path="bin"/> diff --git a/eclipse/plugins/com.android.ide.eclipse.adt/META-INF/MANIFEST.MF b/eclipse/plugins/com.android.ide.eclipse.adt/META-INF/MANIFEST.MF index aa4d55e..9218d6d 100644 --- a/eclipse/plugins/com.android.ide.eclipse.adt/META-INF/MANIFEST.MF +++ b/eclipse/plugins/com.android.ide.eclipse.adt/META-INF/MANIFEST.MF @@ -13,7 +13,8 @@ Bundle-ClassPath: ., libs/kxml2-2.3.0.jar, libs/layoutlib_api.jar, libs/ide_common.jar, - libs/common.jar + libs/common.jar, + libs/assetstudio.jar Bundle-Activator: com.android.ide.eclipse.adt.AdtPlugin Bundle-Vendor: The Android Open Source Project Require-Bundle: com.android.ide.eclipse.ddms, diff --git a/eclipse/plugins/com.android.ide.eclipse.adt/icons/new_asset_set.png b/eclipse/plugins/com.android.ide.eclipse.adt/icons/new_asset_set.png Binary files differnew file mode 100644 index 0000000..108dcb1 --- /dev/null +++ b/eclipse/plugins/com.android.ide.eclipse.adt/icons/new_asset_set.png diff --git a/eclipse/plugins/com.android.ide.eclipse.adt/plugin.xml b/eclipse/plugins/com.android.ide.eclipse.adt/plugin.xml index 9a956d3..32442b6 100644 --- a/eclipse/plugins/com.android.ide.eclipse.adt/plugin.xml +++ b/eclipse/plugins/com.android.ide.eclipse.adt/plugin.xml @@ -140,6 +140,17 @@ preferredPerspectives="org.eclipse.jdt.ui.JavaPerspective" project="false"> </wizard> + <wizard + canFinishEarly="false" + category="com.android.ide.eclipse.wizards.category" + class="com.android.ide.eclipse.adt.internal.assetstudio.CreateAssetSetWizard" + finalPerspective="org.eclipse.jdt.ui.JavaPerspective" + hasPages="true" + icon="icons/new_asset_set.png" + id="com.android.ide.eclipse.adt.internal.assetstudio.CreateAssetSetWizard" + name="Asset Set" + preferredPerspectives="org.eclipse.jdt.ui.JavaPerspective" + project="false"/> </extension> <extension point="org.eclipse.debug.core.launchConfigurationTypes"> diff --git a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/AdtConstants.java b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/AdtConstants.java index 1eaa4b9..ac2e4dd 100644 --- a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/AdtConstants.java +++ b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/AdtConstants.java @@ -118,6 +118,8 @@ public class AdtConstants { public static final String DOT_JPG = ".jpg"; //$NON-NLS-1$ /** Dot-Extension for BMP files, i.e. ".bmp" */ public static final String DOT_BMP = ".bmp"; //$NON-NLS-1$ + /** Dot-Extension for SVG files, i.e. ".svg" */ + public static final String DOT_SVG = ".svg"; //$NON-NLS-1$ /** Name of the android sources directory */ public static final String FD_ANDROID_SOURCES = "sources"; //$NON-NLS-1$ diff --git a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/assetstudio/ChooseAssetTypePage.java b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/assetstudio/ChooseAssetTypePage.java new file mode 100644 index 0000000..a5b0480 --- /dev/null +++ b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/assetstudio/ChooseAssetTypePage.java @@ -0,0 +1,217 @@ +/* + * Copyright (C) 2011 The Android Open Source Project + * + * Licensed under the Eclipse Public License, Version 1.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.eclipse.org/org/documents/epl-v10.php + * + * 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 com.android.ide.eclipse.adt.internal.assetstudio; + +import com.android.ide.eclipse.adt.internal.project.ProjectChooserHelper; +import com.android.ide.eclipse.adt.internal.resources.ResourceNameValidator; +import com.android.resources.ResourceFolderType; + +import org.eclipse.core.resources.IProject; +import org.eclipse.jdt.core.IJavaProject; +import org.eclipse.jface.dialogs.IMessageProvider; +import org.eclipse.jface.wizard.WizardPage; +import org.eclipse.swt.SWT; +import org.eclipse.swt.events.ModifyEvent; +import org.eclipse.swt.events.ModifyListener; +import org.eclipse.swt.events.SelectionEvent; +import org.eclipse.swt.events.SelectionListener; +import org.eclipse.swt.layout.GridData; +import org.eclipse.swt.layout.GridLayout; +import org.eclipse.swt.widgets.Button; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Label; +import org.eclipse.swt.widgets.Text; + +public class ChooseAssetTypePage extends WizardPage implements SelectionListener, ModifyListener { + private Text mProjectText; + private Button mBrowseButton; + private ProjectChooserHelper mProjectChooserHelper; + private IProject mProject; + private Text mNameText; + + /** + * Create the wizard. + */ + public ChooseAssetTypePage() { + super("chooseAssetTypePage"); + setTitle("Choose Asset Set Type"); + setDescription("Select the type of asset set to create:"); + } + + /** + * Create contents of the wizard. + * + * @param parent the parent composite + */ + @SuppressWarnings("unused") + public void createControl(Composite parent) { + Composite container = new Composite(parent, SWT.NULL); + + setControl(container); + container.setLayout(new GridLayout(3, false)); + + Button launcherIcons = new Button(container, SWT.RADIO); + launcherIcons.setLayoutData(new GridData(SWT.LEFT, SWT.CENTER, false, false, 3, 1)); + launcherIcons.setSelection(true); + launcherIcons.setText("Launcher Icons"); + + Button menuIcons = new Button(container, SWT.RADIO); + menuIcons.setLayoutData(new GridData(SWT.LEFT, SWT.CENTER, false, false, 3, 1)); + menuIcons.setEnabled(false); + menuIcons.setText("Menu Icons"); + + Button actionBarIcons = new Button(container, SWT.RADIO); + actionBarIcons.setLayoutData(new GridData(SWT.LEFT, SWT.CENTER, false, false, 3, 1)); + actionBarIcons.setEnabled(false); + actionBarIcons.setText("Action Bar Icons (Android 3.0+)"); + + Button tabIcons = new Button(container, SWT.RADIO); + tabIcons.setLayoutData(new GridData(SWT.LEFT, SWT.CENTER, false, false, 3, 1)); + tabIcons.setEnabled(false); + tabIcons.setText("Tab Icons"); + + Button notificationIcons = new Button(container, SWT.RADIO); + notificationIcons.setLayoutData(new GridData(SWT.LEFT, SWT.CENTER, false, false, 3, 1)); + notificationIcons.setEnabled(false); + notificationIcons.setText("Notification Icons"); + + mProjectChooserHelper = new ProjectChooserHelper(parent.getShell(), null /*filter*/); + + Label separator = new Label(container, SWT.SEPARATOR | SWT.HORIZONTAL); + GridData gdSeparator = new GridData(SWT.FILL, SWT.CENTER, false, false, 3, 1); + gdSeparator.heightHint = 20; + separator.setLayoutData(gdSeparator); + + Label projectLabel = new Label(container, SWT.NONE); + projectLabel.setLayoutData(new GridData(SWT.RIGHT, SWT.CENTER, false, false, 1, 1)); + projectLabel.setText("Project:"); + + mProjectText = new Text(container, SWT.BORDER); + mProjectText.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false, 1, 1)); + if (mProject != null) { + mProjectText.setText(mProject.getName()); + } + mProjectText.addModifyListener(this); + + mBrowseButton = new Button(container, SWT.FLAT); + mBrowseButton.setText("Browse..."); + mBrowseButton.setToolTipText("Allows you to select the Android project to modify."); + + Label assetLabel = new Label(container, SWT.NONE); + assetLabel.setLayoutData(new GridData(SWT.RIGHT, SWT.CENTER, false, false, 1, 1)); + assetLabel.setText("Asset Name:"); + + mNameText = new Text(container, SWT.BORDER); + mNameText.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false, 1, 1)); + mNameText.setText("ic_launcher"); + mNameText.addModifyListener(this); + new Label(container, SWT.NONE); + mBrowseButton.addSelectionListener(this); + + validatePage(); + parent.getDisplay().asyncExec(new Runnable() { + public void run() { + mNameText.setFocus(); + } + }); + } + + void setProject(IProject project) { + mProject = project; + } + + IProject getProject() { + return mProject; + } + + @Override + public boolean canFlipToNextPage() { + return mProject != null; + } + + public void widgetSelected(SelectionEvent e) { + if (e.getSource() == mBrowseButton) { + IJavaProject p = mProjectChooserHelper.chooseJavaProject(mProjectText.getText(), + "Please select the target project"); + if (p != null) { + changeProject(p.getProject()); + mProjectText.setText(mProject.getName()); + } + + } + } + + public void widgetDefaultSelected(SelectionEvent e) { + } + + public void modifyText(ModifyEvent e) { + String project = mProjectText.getText(); + + // Is this a valid project? + IJavaProject[] projects = mProjectChooserHelper.getAndroidProjects(null /*javaModel*/); + IProject found = null; + for (IJavaProject p : projects) { + if (p.getProject().getName().equals(project)) { + found = p.getProject(); + break; + } + } + + if (found != mProject) { + changeProject(found); + } + + validatePage(); + } + + private void changeProject(IProject newProject) { + mProject = newProject; + validatePage(); + } + + String getOutputName() { + return mNameText.getText().trim(); + } + + private void validatePage() { + String error = null; + //String warning = null; + + if (getProject() == null) { + error = "Please select an Android project."; + } + + String outputName = getOutputName(); + if (outputName == null || outputName.length() == 0) { + error = "Please enter a name"; + } else { + ResourceNameValidator validator = + ResourceNameValidator.create(true, ResourceFolderType.DRAWABLE); + error = validator.isValid(outputName); + } + + setPageComplete(error == null); + if (error != null) { + setMessage(error, IMessageProvider.ERROR); + //} else if (warning != null) { + // setMessage(warning, IMessageProvider.WARNING); + } else { + setErrorMessage(null); + setMessage(null); + } + } +} diff --git a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/assetstudio/ConfigureAssetSetPage.java b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/assetstudio/ConfigureAssetSetPage.java new file mode 100644 index 0000000..b871d1e --- /dev/null +++ b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/assetstudio/ConfigureAssetSetPage.java @@ -0,0 +1,782 @@ +/* + * Copyright (C) 2011 The Android Open Source Project + * + * Licensed under the Eclipse Public License, Version 1.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.eclipse.org/org/documents/epl-v10.php + * + * 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 com.android.ide.eclipse.adt.internal.assetstudio; + +import static com.android.assetstudiolib.LauncherIconGenerator.Options.Shape.CIRCLE; +import static com.android.assetstudiolib.LauncherIconGenerator.Options.Shape.SQUARE; + +import com.android.assetstudiolib.GraphicGenerator; +import com.android.assetstudiolib.GraphicGeneratorContext; +import com.android.assetstudiolib.LauncherIconGenerator; +import com.android.assetstudiolib.LauncherIconGenerator.Options.Style; +import com.android.ide.eclipse.adt.internal.editors.layout.gle2.ImageControl; +import com.android.ide.eclipse.adt.internal.editors.layout.gle2.ImageUtils; +import com.android.ide.eclipse.adt.internal.editors.layout.gle2.SwtUtils; +import com.android.resources.Density; + +import org.eclipse.core.resources.IProject; +import org.eclipse.core.resources.IResource; +import org.eclipse.core.resources.IWorkspaceRoot; +import org.eclipse.core.resources.ResourcesPlugin; +import org.eclipse.core.runtime.IPath; +import org.eclipse.jface.dialogs.IMessageProvider; +import org.eclipse.jface.wizard.WizardPage; +import org.eclipse.swt.SWT; +import org.eclipse.swt.custom.ScrolledComposite; +import org.eclipse.swt.custom.StackLayout; +import org.eclipse.swt.events.ModifyEvent; +import org.eclipse.swt.events.ModifyListener; +import org.eclipse.swt.events.SelectionEvent; +import org.eclipse.swt.events.SelectionListener; +import org.eclipse.swt.graphics.Font; +import org.eclipse.swt.graphics.FontData; +import org.eclipse.swt.graphics.Image; +import org.eclipse.swt.graphics.RGB; +import org.eclipse.swt.layout.FillLayout; +import org.eclipse.swt.layout.GridData; +import org.eclipse.swt.layout.GridLayout; +import org.eclipse.swt.layout.RowLayout; +import org.eclipse.swt.widgets.Button; +import org.eclipse.swt.widgets.ColorDialog; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Control; +import org.eclipse.swt.widgets.Display; +import org.eclipse.swt.widgets.FileDialog; +import org.eclipse.swt.widgets.FontDialog; +import org.eclipse.swt.widgets.Label; +import org.eclipse.swt.widgets.Slider; +import org.eclipse.swt.widgets.Text; + +import java.awt.image.BufferedImage; +import java.io.File; +import java.io.IOException; +import java.util.Arrays; +import java.util.Collections; +import java.util.Comparator; +import java.util.HashMap; +import java.util.LinkedHashMap; +import java.util.Map; + +import javax.imageio.ImageIO; + +/** + * This is normally page 2 of a Create New Asset Set wizard, unless we can offer actions + * to create a specific asset type, in which case we skip page 1. On this page the user + * gets to configure the parameters of the asset, and see a preview. + */ +public class ConfigureAssetSetPage extends WizardPage implements SelectionListener, + GraphicGeneratorContext, ModifyListener { + + private Composite configurationArea; + private Button mImageRadio; + private Button mClipartRadio; + private Button mTextRadio; + private Button mPickImageButton; + private Button mTrimCheckBox; + private Slider mPaddingSlider; + private Label mPercentLabel; + private Button mCropRadio; + private Button mCenterRadio; + private Button mSquareRadio; + private Button mCircleButton; + private Button mBgButton; + private Button mFgButton; + private Button mSimpleRadio; + private Button mFancyRadio; + private Button mGlossyRadio; + private Composite mPreviewArea; + private Button mFontButton; + private Composite mForegroundArea; + private Composite mImageForm; + private Composite mClipartForm; + private Composite mTextForm; + private Text mImagePathText; + + private boolean mTimerPending; + private Map<String, BufferedImage> mImageCache = new HashMap<String, BufferedImage>(); + private RGB mBgColor; + private RGB mFgColor; + private Text mText; + + /** Most recently set image path: preserved across wizard sessions */ + private static String sImagePath; + + /** + * Create the wizard. + * + * @param wizard the surrounding wizard + */ + public ConfigureAssetSetPage() { + super("configureAssetPage"); + setTitle("Configure Asset Set"); + setDescription("Configure the attributes of the asset set"); + } + + /** + * Create contents of the wizard. + * + * @param parent the parent widget + */ + @SuppressWarnings("unused") // Don't warn about unassigned "new Label(.)": has side-effect + public void createControl(Composite parent) { + Composite container = new Composite(parent, SWT.NULL); + + setControl(container); + GridLayout glContainer = new GridLayout(2, false); + glContainer.marginWidth = 0; + glContainer.horizontalSpacing = 0; + glContainer.marginHeight = 0; + glContainer.verticalSpacing = 0; + container.setLayout(glContainer); + + ScrolledComposite configurationScrollArea = new ScrolledComposite(container, SWT.V_SCROLL); + configurationScrollArea.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true, 1, 2)); + configurationScrollArea.setExpandHorizontal(true); + configurationScrollArea.setExpandVertical(true); + + configurationArea = new Composite(configurationScrollArea, SWT.NONE); + GridLayout glConfigurationArea = new GridLayout(3, false); + glConfigurationArea.marginRight = 15; + glConfigurationArea.marginWidth = 0; + glConfigurationArea.marginHeight = 0; + configurationArea.setLayout(glConfigurationArea); + + Label foregroundLabel = new Label(configurationArea, SWT.NONE); + foregroundLabel.setLayoutData(new GridData(SWT.RIGHT, SWT.CENTER, false, false, 1, 1)); + foregroundLabel.setText("Foreground:"); + + Composite foregroundComposite = new Composite(configurationArea, SWT.NONE); + foregroundComposite.setLayoutData(new GridData(SWT.FILL, SWT.FILL, false, false, 2, 1)); + GridLayout glForegroundComposite = new GridLayout(5, false); + glForegroundComposite.horizontalSpacing = 0; + foregroundComposite.setLayout(glForegroundComposite); + + mImageRadio = new Button(foregroundComposite, SWT.FLAT | SWT.TOGGLE); + mImageRadio.setSelection(true); + mImageRadio.addSelectionListener(this); + mImageRadio.setText("Image"); + + mClipartRadio = new Button(foregroundComposite, SWT.FLAT | SWT.TOGGLE); + mClipartRadio.setEnabled(false); + mClipartRadio.setText("Clipart"); + mClipartRadio.addSelectionListener(this); + + mTextRadio = new Button(foregroundComposite, SWT.FLAT | SWT.TOGGLE); + mTextRadio.setLayoutData(new GridData(SWT.LEFT, SWT.CENTER, false, false, 3, 1)); + mTextRadio.setText("Text"); + mTextRadio.addSelectionListener(this); + new Label(configurationArea, SWT.NONE); + + mForegroundArea = new Composite(configurationArea, SWT.NONE); + mForegroundArea.setLayout(new StackLayout()); + mForegroundArea.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false, 2, 1)); + + mImageForm = new Composite(mForegroundArea, SWT.NONE); + mImageForm.setLayout(new GridLayout(3, false)); + + Label fileLabel = new Label(mImageForm, SWT.NONE); + fileLabel.setLayoutData(new GridData(SWT.RIGHT, SWT.CENTER, false, false, 1, 1)); + fileLabel.setText("Image File:"); + + mImagePathText = new Text(mImageForm, SWT.BORDER); + GridData pathLayoutData = new GridData(SWT.FILL, SWT.CENTER, true, false, 1, 1); + pathLayoutData.widthHint = 200; + mImagePathText.setLayoutData(pathLayoutData); + mImagePathText.addSelectionListener(this); + mImagePathText.addModifyListener(this); + + mPickImageButton = new Button(mImageForm, SWT.FLAT); + mPickImageButton.setText("Browse..."); + mPickImageButton.addSelectionListener(this); + + mClipartForm = new Composite(mForegroundArea, SWT.V_SCROLL); + mClipartForm.setLayout(new FillLayout(SWT.HORIZONTAL)); + + mTextForm = new Composite(mForegroundArea, SWT.NONE); + mTextForm.setLayout(new GridLayout(2, false)); + + Label textLabel = new Label(mTextForm, SWT.NONE); + textLabel.setLayoutData(new GridData(SWT.RIGHT, SWT.CENTER, false, false, 1, 1)); + textLabel.setText("Text:"); + + mText = new Text(mTextForm, SWT.BORDER); + mText.setText("Label"); + mText.setLayoutData(pathLayoutData); + + Label fontLabel = new Label(mTextForm, SWT.NONE); + fontLabel.setLayoutData(new GridData(SWT.RIGHT, SWT.CENTER, false, false, 1, 1)); + fontLabel.setText("Font:"); + + mFontButton = new Button(mTextForm, SWT.FLAT); + mFontButton.setLayoutData(new GridData(SWT.LEFT, SWT.CENTER, true, false, 1, 1)); + mFontButton.addSelectionListener(this); + mFontButton.setText("Choose Font..."); + new Label(configurationArea, SWT.NONE); + + mTrimCheckBox = new Button(configurationArea, SWT.CHECK); + mTrimCheckBox.setEnabled(false); + mTrimCheckBox.setLayoutData(new GridData(SWT.LEFT, SWT.CENTER, false, false, 2, 1)); + mTrimCheckBox.setSelection(true); + mTrimCheckBox.setText("Trim Surrounding Blank Space"); + new Label(configurationArea, SWT.NONE); + + Label paddingLabel = new Label(configurationArea, SWT.NONE); + paddingLabel.setLayoutData(new GridData(SWT.LEFT, SWT.CENTER, false, false, 2, 1)); + paddingLabel.setText("Additional Padding:"); + new Label(configurationArea, SWT.NONE); + + mPaddingSlider = new Slider(configurationArea, SWT.NONE); + mPaddingSlider.setEnabled(false); + mPaddingSlider.setLayoutData(pathLayoutData); + // This doesn't work right -- not sure why. For now just use a plain slider + // and subtract from it to get the real range. + //mPaddingSlider.setValues(0, -10, 50, 0, 1, 10); + mPaddingSlider.setSelection(10); + mPaddingSlider.addSelectionListener(this); + + mPercentLabel = new Label(configurationArea, SWT.NONE); + mPercentLabel.setText(" 0%"); // Enough available space for -10% + + Label scalingLabel = new Label(configurationArea, SWT.NONE); + scalingLabel.setLayoutData(new GridData(SWT.RIGHT, SWT.CENTER, false, false, 1, 1)); + scalingLabel.setText("Foreground Scaling:"); + + Composite scalingComposite = new Composite(configurationArea, SWT.NONE); + scalingComposite.setLayoutData(new GridData(SWT.FILL, SWT.FILL, false, false, 2, 1)); + GridLayout glScalingComposite = new GridLayout(5, false); + glScalingComposite.horizontalSpacing = 0; + scalingComposite.setLayout(glScalingComposite); + + mCropRadio = new Button(scalingComposite, SWT.FLAT | SWT.TOGGLE); + mCropRadio.setSelection(true); + mCropRadio.setText("Crop"); + mCropRadio.addSelectionListener(this); + + mCenterRadio = new Button(scalingComposite, SWT.FLAT | SWT.TOGGLE); + mCenterRadio.setLayoutData(new GridData(SWT.LEFT, SWT.CENTER, false, false, 4, 1)); + mCenterRadio.setText("Center"); + mCenterRadio.addSelectionListener(this); + + Label shapeLabel = new Label(configurationArea, SWT.NONE); + shapeLabel.setLayoutData(new GridData(SWT.RIGHT, SWT.CENTER, false, false, 1, 1)); + shapeLabel.setText("Shape"); + + Composite shapeComposite = new Composite(configurationArea, SWT.NONE); + shapeComposite.setLayoutData(new GridData(SWT.FILL, SWT.FILL, false, false, 2, 1)); + GridLayout glShapeComposite = new GridLayout(5, false); + glShapeComposite.horizontalSpacing = 0; + shapeComposite.setLayout(glShapeComposite); + + mSquareRadio = new Button(shapeComposite, SWT.FLAT | SWT.TOGGLE); + mSquareRadio.setSelection(true); + mSquareRadio.setText("Square"); + mSquareRadio.addSelectionListener(this); + + mCircleButton = new Button(shapeComposite, SWT.FLAT | SWT.TOGGLE); + mCircleButton.setLayoutData(new GridData(SWT.LEFT, SWT.CENTER, false, false, 4, 1)); + mCircleButton.setText("Circle"); + mCircleButton.addSelectionListener(this); + + Label bgColorLabel = new Label(configurationArea, SWT.NONE); + bgColorLabel.setLayoutData(new GridData(SWT.RIGHT, SWT.CENTER, false, false, 1, 1)); + bgColorLabel.setText("Background Color:"); + + mBgButton = new Button(configurationArea, SWT.FLAT); + mBgButton.addSelectionListener(this); + mBgButton.setAlignment(SWT.CENTER); + new Label(configurationArea, SWT.NONE); + + Label fgColorLabel = new Label(configurationArea, SWT.NONE); + fgColorLabel.setLayoutData(new GridData(SWT.RIGHT, SWT.CENTER, false, false, 1, 1)); + fgColorLabel.setText("Foreground Color:"); + + mFgButton = new Button(configurationArea, SWT.FLAT); + mFgButton.setAlignment(SWT.CENTER); + mFgButton.addSelectionListener(this); + new Label(configurationArea, SWT.NONE); + + Label effectsLabel = new Label(configurationArea, SWT.NONE); + effectsLabel.setLayoutData(new GridData(SWT.RIGHT, SWT.CENTER, false, false, 1, 1)); + effectsLabel.setText("Foreground Effects:"); + + Composite effectsComposite = new Composite(configurationArea, SWT.NONE); + effectsComposite.setLayoutData(new GridData(SWT.FILL, SWT.FILL, false, false, 1, 1)); + GridLayout glEffectsComposite = new GridLayout(5, false); + glEffectsComposite.horizontalSpacing = 0; + effectsComposite.setLayout(glEffectsComposite); + + mSimpleRadio = new Button(effectsComposite, SWT.FLAT | SWT.TOGGLE); + mSimpleRadio.setEnabled(false); + mSimpleRadio.setSelection(true); + mSimpleRadio.setText("Simple"); + mSimpleRadio.addSelectionListener(this); + + mFancyRadio = new Button(effectsComposite, SWT.FLAT | SWT.TOGGLE); + mFancyRadio.setEnabled(false); + mFancyRadio.setText("Fancy"); + mFancyRadio.addSelectionListener(this); + + mGlossyRadio = new Button(effectsComposite, SWT.FLAT | SWT.TOGGLE); + mGlossyRadio.setEnabled(false); + mGlossyRadio.setLayoutData(new GridData(SWT.LEFT, SWT.CENTER, false, false, 3, 1)); + mGlossyRadio.setText("Glossy"); + mGlossyRadio.addSelectionListener(this); + + new Label(configurationArea, SWT.NONE); + configurationScrollArea.setContent(configurationArea); + configurationScrollArea.setMinSize(configurationArea.computeSize(SWT.DEFAULT, + SWT.DEFAULT)); + + Label previewLabel = new Label(container, SWT.NONE); + previewLabel.setLayoutData(new GridData(SWT.CENTER, SWT.CENTER, false, false, 1, 1)); + previewLabel.setText("Preview:"); + + mPreviewArea = new Composite(container, SWT.BORDER); + + RowLayout rlPreviewAreaPreviewArea = new RowLayout(SWT.VERTICAL); + rlPreviewAreaPreviewArea.wrap = false; + rlPreviewAreaPreviewArea.pack = true; + rlPreviewAreaPreviewArea.center = true; + rlPreviewAreaPreviewArea.spacing = 0; + rlPreviewAreaPreviewArea.marginBottom = 0; + rlPreviewAreaPreviewArea.marginTop = 0; + rlPreviewAreaPreviewArea.marginRight = 0; + rlPreviewAreaPreviewArea.marginLeft = 0; + mPreviewArea.setLayout(rlPreviewAreaPreviewArea); + GridData gdMPreviewArea = new GridData(SWT.FILL, SWT.FILL, false, false, 1, 1); + gdMPreviewArea.widthHint = 120; + mPreviewArea.setLayoutData(gdMPreviewArea); + + // Initial color + Display display = parent.getDisplay(); + updateColor(display, new RGB(0xa4, 0xc6, 0x39), true /*background*/); + updateColor(display, new RGB(0x00, 0x00, 0x00), false /*background*/); + + // Start out showing the image form + mImageRadio.setSelection(true); + chooseForegroundTab(mImageRadio, mImageForm); + validatePage(); + } + + @Override + public void setVisible(boolean visible) { + super.setVisible(visible); + + // We update the image selection here rather than in {@link #createControl} because + // that method is called when the wizard is created, and we want to wait until the + // user has chosen a project before attempting to look up the right default image to use + if (visible) { + // Initial image - use the most recently used image, or the default launcher + // icon created in our default projects, if there + if (sImagePath == null) { + IProject project = ((CreateAssetSetWizard) getWizard()).getProject(); + if (project != null) { + IResource icon = project.findMember("res/drawable-hdpi/icon.png"); //$NON-NLS-1$ + if (icon != null) { + IWorkspaceRoot workspace = ResourcesPlugin.getWorkspace().getRoot(); + IPath workspacePath = workspace.getLocation(); + sImagePath = workspacePath.append(icon.getFullPath()).toOSString(); + } + } + } + if (sImagePath != null) { + mImagePathText.setText(sImagePath); + } + validatePage(); + } + } + + private boolean validatePage() { + String error = null; + //String warning = null; + + if (mImageRadio.getSelection()) { + String path = mImagePathText.getText().trim(); + if (path.length() == 0) { + error = "Select an image"; + } else if (!(new File(path).exists())) { + error = String.format("%1$s does not exist", path); + } else { + // Preserve across wizard sessions + sImagePath = path; + } + } else { + error = "Clipart and Text not yet implemented"; + } + + setPageComplete(error == null); + if (error != null) { + setMessage(error, IMessageProvider.ERROR); + //} else if (warning != null) { + // setMessage(warning, IMessageProvider.WARNING); + } else { + setErrorMessage(null); + setMessage(null); + } + + return error == null; + } + + // ---- Implements ModifyListener ---- + + public void modifyText(ModifyEvent e) { + if (e.getSource() == mImagePathText) { + requestUpdatePreview(false); + } + + validatePage(); + } + + // ---- Implements SelectionListener ---- + + public void widgetDefaultSelected(SelectionEvent e) { + // Nothing to do + } + + public void widgetSelected(SelectionEvent e) { + Object source = e.getSource(); + boolean updateQuickly = true; + + // Tabs + if (source == mImageRadio) { + chooseForegroundTab((Button) source, mImageForm); + } else if (source == mClipartRadio) { + chooseForegroundTab((Button) source, mClipartForm); + } else if (source == mTextRadio) { + updateFontLabel(mFontButton.getFont()); + chooseForegroundTab((Button) source, mTextForm); + mText.setFocus(); + } + + // Choose image file + if (source == mPickImageButton) { + FileDialog dialog = new FileDialog(mPickImageButton.getShell(), SWT.OPEN); + String file = dialog.open(); + if (file != null) { + mImagePathText.setText(file); + } + } + + // Enforce Radio Groups + if (source == mCropRadio) { + mCenterRadio.setSelection(false); + } else if (source == mCenterRadio) { + mCropRadio.setSelection(false); + } + if (source == mSquareRadio) { + mCircleButton.setSelection(false); + } else if (source == mCircleButton) { + mSquareRadio.setSelection(false); + } + if (source == mSimpleRadio) { + mGlossyRadio.setSelection(false); + mFancyRadio.setSelection(false); + } else if (source == mFancyRadio) { + mSimpleRadio.setSelection(false); + mGlossyRadio.setSelection(false); + } else if (source == mGlossyRadio) { + mSimpleRadio.setSelection(false); + mFancyRadio.setSelection(false); + } + + if (source == mBgButton) { + ColorDialog dlg = new ColorDialog(mBgButton.getShell()); + dlg.setRGB(mBgColor); + dlg.setText("Choose a new Background Color"); + RGB rgb = dlg.open(); + if (rgb != null) { + // Dispose the old color, create the + // new one, and set into the label + updateColor(mBgButton.getDisplay(), rgb, true /*background*/); + } + } else if (source == mFgButton) { + ColorDialog dlg = new ColorDialog(mFgButton.getShell()); + dlg.setRGB(mFgColor); + dlg.setText("Choose a new Foreground Color"); + RGB rgb = dlg.open(); + if (rgb != null) { + // Dispose the old color, create the + // new one, and set into the label + updateColor(mFgButton.getDisplay(), rgb, false /*background*/); + } + } + + if (source == mFontButton) { + FontDialog dialog = new FontDialog(mFontButton.getShell()); + FontData data = dialog.open(); + if (data != null) { + Font font = new Font(mFontButton.getDisplay(), dialog.getFontList()); + mFontButton.setFont(font); + updateFontLabel(font); + mFontButton.getParent().pack(); + } + } + + if (source == mPaddingSlider) { + mPercentLabel.setText(Integer.toString(getPadding()) + '%'); + + // When dragging the slider, only do periodic updates + updateQuickly = false; + } + + requestUpdatePreview(updateQuickly); + } + + private void updateFontLabel(Font f) { + FontData[] fd = f.getFontData(); + FontData primary = fd[0]; + String description = String.format("%1$s %2$s", primary.name, + Integer.toString((int) primary.height)); + mFontButton.setText(description); + } + + private java.awt.Font getSelectedFont() { + Font font = mFontButton.getFont(); + FontData fontData = font.getFontData()[0]; + + int awtStyle = java.awt.Font.PLAIN; + int swtStyle = fontData.getStyle(); + + if ((swtStyle & SWT.ITALIC) != 0) { + awtStyle |= java.awt.Font.ITALIC; + } + if ((swtStyle & SWT.BOLD) != 0) { + awtStyle = java.awt.Font.BOLD; + } + + int dpi = mFontButton.getDisplay().getDPI().y; + int height = (int) Math.round(fontData.getHeight() * dpi / 72.0); + + return new java.awt.Font(fontData.getName(), awtStyle, height); + } + + private int getPadding() { + // Shifted - see comment for mPaddingSlider construction for an explanation + return mPaddingSlider.getSelection() - 10; + } + + public void chooseForegroundTab(Button newButton, Composite newArea) { + if (newButton.getSelection()) { + mImageRadio.setSelection(false); + mClipartRadio.setSelection(false); + mTextRadio.setSelection(false); + newButton.setSelection(true); + StackLayout stackLayout = (StackLayout) mForegroundArea.getLayout(); + stackLayout.topControl = newArea; + mForegroundArea.layout(); + } + } + + /** + * Delay updates of the preview, to ensure that the SWT UI acts immediately (to handle + * radio group selections etc). + * + * @param quickly if true, update the previews soon, otherwise schedule one a bit later + */ + private void requestUpdatePreview(boolean quickly) { + if (mTimerPending) { + return; + } + mTimerPending = true; + + final Runnable timer = new Runnable() { + public void run() { + mTimerPending = false; + updatePreview(); + } + }; + + mPreviewArea.getDisplay().timerExec(quickly ? 10 : 250, timer); + } + + private void updatePreview() { + Display display = mPreviewArea.getDisplay(); + + for (Control c : mPreviewArea.getChildren()) { + c.dispose(); + } + + if (!validatePage()) { + return; + } + + Map<String, BufferedImage> map = generatePreviews(); + for (Map.Entry<String, BufferedImage> entry : map.entrySet()) { + String id = entry.getKey(); + BufferedImage image = entry.getValue(); + Label nameLabel = new Label(mPreviewArea, SWT.NONE); + nameLabel.setText(id); + + Image swtImage = SwtUtils.convertToSwt(display, image, true, -1); + if (swtImage != null) { + @SuppressWarnings("unused") // Has side effect + ImageControl imageControl = new ImageControl(mPreviewArea, SWT.NONE, swtImage); + } + } + + mPreviewArea.layout(true); + } + + Map<String, BufferedImage> generatePreviews() { + // Map of ids to images: Preserve insertion order (the densities) + Map<String, BufferedImage> imageMap = new LinkedHashMap<String, BufferedImage>(); + + // Load the image + // TODO: Only do this when the source image type is image + String path = mImagePathText.getText().trim(); + if (path.length() == 0) { + setErrorMessage("Enter a filename"); + return Collections.emptyMap(); + } + File file = new File(path); + if (!file.exists()) { + setErrorMessage(String.format("%1$s does not exist", file.getPath())); + return Collections.emptyMap(); + } + + setErrorMessage(null); + BufferedImage sourceImage = getImage(path, false); + + LauncherIconGenerator.Options options = new LauncherIconGenerator.Options(); + options.shape = mCircleButton.getSelection() ? CIRCLE : SQUARE; + options.crop = mCropRadio.getSelection(); + + int color = (mBgColor.red << 16) | (mBgColor.green << 8) | mBgColor.blue; + options.backgroundColor = color; + options.sourceImage = sourceImage; + + Density[] densityValues = Density.values(); + // Sort density values into ascending order + Arrays.sort(densityValues, new Comparator<Density>() { + public int compare(Density d1, Density d2) { + return d1.getDpiValue() - d2.getDpiValue(); + } + + }); + Style[] styleValues = LauncherIconGenerator.Options.Style.values(); + + for (Density density : densityValues) { + if (!density.isValidValueForDevice()) { + continue; + } + if (density == Density.TV) { + // Not yet supported -- missing stencil image + continue; + } + options.density = density; + for (LauncherIconGenerator.Options.Style style : styleValues) { + options.style = style; + LauncherIconGenerator generator = new LauncherIconGenerator(this, options); + BufferedImage image = generator.generate(); + if (image != null) { + imageMap.put(density.getResourceValue(), image); + } + } + } + + return imageMap; + } + + private void updateColor(Display display, RGB color, boolean isBackground) { + // Button.setBackgroundColor does not work (at least not on OSX) so + // we instead have to use Button.setImage with an image of the given + // color + BufferedImage coloredImage = ImageUtils.createColoredImage(60, 20, color); + Image image = SwtUtils.convertToSwt(display, coloredImage, false, -1); + + if (isBackground) { + mBgColor = color; + mBgButton.setImage(image); + } else { + mFgColor = color; + mFgButton.setImage(image); + } + } + + public BufferedImage loadImageResource(String relativeName) { + return getImage(relativeName, true); + } + + private BufferedImage getImage(String path, boolean isPluginRelative) { + BufferedImage image = mImageCache.get(path); + if (image == null) { + try { + if (isPluginRelative) { + image = GraphicGenerator.getStencilImage(path); + } else { + File file = new File(path); + + // Requires Batik + //if (file.getName().endsWith(DOT_SVG)) { + // image = loadSvgImage(file); + //} + + if (image == null) { + image = ImageIO.read(file); + } + } + } catch (IOException e) { + setErrorMessage(e.getLocalizedMessage()); + } + + if (image == null) { + image = new BufferedImage(1,1, BufferedImage.TYPE_INT_ARGB); + } + + mImageCache.put(path, image); + } + + return image; + } + + // This requires Batik for SVG rendering + // + //public static BufferedImage loadSvgImage(File file) { + // BufferedImageTranscoder transcoder = new BufferedImageTranscoder(); + // + // String svgURI = file.toURI().toString(); + // TranscoderInput input = new TranscoderInput(svgURI); + // + // try { + // transcoder.transcode(input, null); + // } catch (TranscoderException e) { + // e.printStackTrace(); + // return null; + // } + // + // return transcoder.decodedImage; + //} + // + ///** + // * A dummy implementation of an {@link ImageTranscoder} that simply stores the {@link + // * BufferedImage} generated by the SVG library. + // */ + //private static class BufferedImageTranscoder extends ImageTranscoder { + // public BufferedImage decodedImage; + // + // @Override + // public BufferedImage createImage(int w, int h) { + // return new BufferedImage(w, h, BufferedImage.TYPE_INT_ARGB); + // } + // + // @Override + // public void writeImage(BufferedImage image, TranscoderOutput output) + // throws TranscoderException { + // this.decodedImage = image; + // } + //} +} diff --git a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/assetstudio/ConfigureLauncherAssetsPanel.java b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/assetstudio/ConfigureLauncherAssetsPanel.java new file mode 100644 index 0000000..930e93c --- /dev/null +++ b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/assetstudio/ConfigureLauncherAssetsPanel.java @@ -0,0 +1,37 @@ +/* + * Copyright (C) 2011 The Android Open Source Project + * + * Licensed under the Eclipse Public License, Version 1.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.eclipse.org/org/documents/epl-v10.php + * + * 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 com.android.ide.eclipse.adt.internal.assetstudio; + +import org.eclipse.swt.widgets.Composite; + +public class ConfigureLauncherAssetsPanel extends Composite { + + /** + * Create the composite. + * @param parent + * @param style + */ + public ConfigureLauncherAssetsPanel(Composite parent, int style) { + super(parent, style); + + } + + @Override + protected void checkSubclass() { + // Disable the check that prevents subclassing of SWT components + } + +} diff --git a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/assetstudio/CreateAssetSetWizard.java b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/assetstudio/CreateAssetSetWizard.java new file mode 100644 index 0000000..4aa67fa --- /dev/null +++ b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/assetstudio/CreateAssetSetWizard.java @@ -0,0 +1,249 @@ +/* + * Copyright (C) 2011 The Android Open Source Project + * + * Licensed under the Eclipse Public License, Version 1.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.eclipse.org/org/documents/epl-v10.php + * + * 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 com.android.ide.eclipse.adt.internal.assetstudio; + +import static com.android.ide.eclipse.adt.AdtConstants.DOT_PNG; +import static com.android.ide.eclipse.adt.AdtConstants.WS_RESOURCES; +import static com.android.ide.eclipse.adt.AdtConstants.WS_SEP; + +import com.android.ide.eclipse.adt.AdtConstants; +import com.android.ide.eclipse.adt.AdtPlugin; +import com.android.ide.eclipse.adt.internal.editors.AndroidXmlEditor; +import com.android.ide.eclipse.adt.internal.project.BaseProjectHelper; +import com.android.ide.eclipse.adt.internal.project.BaseProjectHelper.IProjectFilter; +import com.android.ide.eclipse.adt.internal.wizards.newxmlfile.NewXmlFileWizard; +import com.android.util.Pair; + +import org.eclipse.core.resources.IContainer; +import org.eclipse.core.resources.IFile; +import org.eclipse.core.resources.IProject; +import org.eclipse.core.resources.IResource; +import org.eclipse.core.runtime.CoreException; +import org.eclipse.core.runtime.IAdaptable; +import org.eclipse.core.runtime.IPath; +import org.eclipse.core.runtime.NullProgressMonitor; +import org.eclipse.core.runtime.Path; +import org.eclipse.jdt.core.IJavaProject; +import org.eclipse.jdt.ui.JavaUI; +import org.eclipse.jface.viewers.ISelectionProvider; +import org.eclipse.jface.viewers.IStructuredSelection; +import org.eclipse.jface.viewers.TreePath; +import org.eclipse.jface.viewers.TreeSelection; +import org.eclipse.jface.wizard.Wizard; +import org.eclipse.ui.IEditorPart; +import org.eclipse.ui.INewWizard; +import org.eclipse.ui.IViewPart; +import org.eclipse.ui.IWorkbench; +import org.eclipse.ui.IWorkbenchPage; +import org.eclipse.ui.IWorkbenchPartSite; +import org.eclipse.ui.IWorkbenchWindow; +import org.eclipse.ui.PlatformUI; +import org.eclipse.ui.part.FileEditorInput; + +import java.awt.image.BufferedImage; +import java.io.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.io.InputStream; +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; +import java.util.Map; + +import javax.imageio.ImageIO; + +public class CreateAssetSetWizard extends Wizard implements INewWizard { + private ChooseAssetTypePage chooseAssetPage; + private ConfigureAssetSetPage configureAssetPage; + private IProject mInitialProject; + + public CreateAssetSetWizard() { + setWindowTitle("Create Asset Set"); + } + + @Override + public void addPages() { + chooseAssetPage = new ChooseAssetTypePage(); + chooseAssetPage.setProject(mInitialProject); + configureAssetPage = new ConfigureAssetSetPage(); + + addPage(chooseAssetPage); + addPage(configureAssetPage); + } + + @Override + public boolean performFinish() { + String name = chooseAssetPage.getOutputName(); + Map<String, BufferedImage> previews = configureAssetPage.generatePreviews(); + IProject project = getProject(); + + // Write out the images into the project + List<IFile> createdFiles = new ArrayList<IFile>(); + for (Map.Entry<String, BufferedImage> entry : previews.entrySet()) { + String id = entry.getKey(); + + IPath dest = new Path(WS_RESOURCES + WS_SEP + "drawable-" //$NON-NLS-1$ + + id + WS_SEP + name + DOT_PNG); + IFile file = project.getFile(dest); + if (file.exists()) { + // TODO: Warn that the file already exists and ask the user what to do? + try { + file.delete(true, new NullProgressMonitor()); + } catch (CoreException e) { + AdtPlugin.log(e, null); + } + } + + NewXmlFileWizard.createWsParentDirectory(file.getParent()); + BufferedImage image = entry.getValue(); + + ByteArrayOutputStream stream = new ByteArrayOutputStream(); + try { + ImageIO.write(image, "PNG", stream); //$NON-NLS-1$ + byte[] bytes = stream.toByteArray(); + InputStream is = new ByteArrayInputStream(bytes); + file.create(is, true /*force*/, null /*progress*/); + createdFiles.add(file); + } catch (IOException e) { + AdtPlugin.log(e, null); + } catch (CoreException e) { + AdtPlugin.log(e, null); + } + + try { + file.getParent().refreshLocal(1, new NullProgressMonitor()); + } catch (CoreException e) { + AdtPlugin.log(e, null); + } + } + + // Attempt to select the newly created files in the Package Explorer + IWorkbench workbench = AdtPlugin.getDefault().getWorkbench(); + IWorkbenchPage page = workbench.getActiveWorkbenchWindow().getActivePage(); + IViewPart viewPart = page.findView(JavaUI.ID_PACKAGES); + if (viewPart != null) { + IWorkbenchPartSite site = viewPart.getSite(); + IJavaProject javaProject = null; + try { + javaProject = BaseProjectHelper.getJavaProject(project); + } catch (CoreException e) { + AdtPlugin.log(e, null); + } + ISelectionProvider provider = site.getSelectionProvider(); + if (provider != null) { + List<TreePath> pathList = new ArrayList<TreePath>(); + for (IFile file : createdFiles) { + // Create a TreePath for the given file, + // which should be the JavaProject, followed by the folders down to + // the final file. + List<Object> segments = new ArrayList<Object>(); + segments.add(file); + IContainer folder = file.getParent(); + segments.add(folder); + // res folder + folder = folder.getParent(); + segments.add(folder); + // project + segments.add(javaProject); + + Collections.reverse(segments); + TreePath path = new TreePath(segments.toArray()); + pathList.add(path); + } + + TreePath[] paths = pathList.toArray(new TreePath[pathList.size()]); + provider.setSelection(new TreeSelection(paths)); + } + } + + return true; + } + + IProject getProject() { + if (chooseAssetPage != null) { + return chooseAssetPage.getProject(); + } else { + return mInitialProject; + } + } + + public void init(IWorkbench workbench, IStructuredSelection selection) { + setHelpAvailable(false); + + mInitialProject = guessProject(selection); + if (chooseAssetPage != null) { + chooseAssetPage.setProject(mInitialProject); + } + } + + private IProject guessProject(IStructuredSelection selection) { + if (selection == null) { + return null; + } + + for (Object element : selection.toList()) { + if (element instanceof IAdaptable) { + IResource res = (IResource) ((IAdaptable) element).getAdapter(IResource.class); + IProject project = res != null ? res.getProject() : null; + + // Is this an Android project? + try { + if (project == null || !project.hasNature(AdtConstants.NATURE_DEFAULT)) { + continue; + } + } catch (CoreException e) { + // checking the nature failed, ignore this resource + continue; + } + + return project; + } else if (element instanceof Pair<?, ?>) { + // Pair of Project/String + @SuppressWarnings("unchecked") + Pair<IProject, String> pair = (Pair<IProject, String>) element; + return pair.getFirst(); + } + } + + // Try to figure out the project from the active editor + IWorkbenchWindow window = PlatformUI.getWorkbench().getActiveWorkbenchWindow(); + if (window != null) { + IWorkbenchPage page = window.getActivePage(); + if (page != null) { + IEditorPart activeEditor = page.getActiveEditor(); + if (activeEditor instanceof AndroidXmlEditor) { + Object input = ((AndroidXmlEditor) activeEditor).getEditorInput(); + if (input instanceof FileEditorInput) { + FileEditorInput fileInput = (FileEditorInput) input; + return fileInput.getFile().getProject(); + } + } + } + } + + IJavaProject[] projects = BaseProjectHelper.getAndroidProjects(new IProjectFilter() { + public boolean accept(IProject project) { + return project.isAccessible(); + } + }); + + if (projects != null && projects.length == 1) { + return projects[0].getProject(); + } + + return null; + } +} diff --git a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/resources/ResourceNameValidator.java b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/resources/ResourceNameValidator.java index 4c1127a..1838d14 100644 --- a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/resources/ResourceNameValidator.java +++ b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/resources/ResourceNameValidator.java @@ -19,8 +19,8 @@ package com.android.ide.eclipse.adt.internal.resources; import static com.android.ide.eclipse.adt.AdtConstants.DOT_XML; import com.android.ide.common.resources.ResourceItem; -import com.android.ide.eclipse.adt.AdtConstants; import com.android.ide.eclipse.adt.AdtPlugin; +import com.android.ide.eclipse.adt.internal.editors.layout.gle2.ImageUtils; import com.android.ide.eclipse.adt.internal.resources.manager.ProjectResources; import com.android.ide.eclipse.adt.internal.resources.manager.ResourceManager; import com.android.resources.ResourceFolderType; @@ -49,14 +49,20 @@ public class ResourceNameValidator implements IInputValidator { */ private boolean mIsFileType; + /** + * True if the resource type can point to image resources + */ + private boolean mIsImageType; + /** If true, allow .xml as a name suffix */ private boolean mAllowXmlExtension; private ResourceNameValidator(boolean allowXmlExtension, Set<String> existing, - boolean isFileType) { + boolean isFileType, boolean isImageType) { mAllowXmlExtension = allowXmlExtension; mExisting = existing; mIsFileType = isFileType; + mIsImageType = isImageType; } public String isValid(String newText) { @@ -70,8 +76,17 @@ public class ResourceNameValidator implements IInputValidator { newText = newText.substring(0, newText.length() - DOT_XML.length()); } - if (newText.indexOf('.') != -1 && !newText.endsWith(AdtConstants.DOT_XML)) { - return String.format("The filename must end with %1$s.", DOT_XML); + if (mAllowXmlExtension && mIsImageType + && ImageUtils.hasImageExtension(newText)) { + newText = newText.substring(0, newText.lastIndexOf('.')); + } + + if (newText.indexOf('.') != -1 && !newText.endsWith(DOT_XML)) { + if (mIsImageType) { + return "The filename must end with .xml or .png"; + } else { + return "The filename must end with .xml"; + } } // Resource names must be valid Java identifiers, since they will @@ -126,7 +141,8 @@ public class ResourceNameValidator implements IInputValidator { public static ResourceNameValidator create(boolean allowXmlExtension, ResourceFolderType type) { boolean isFileType = type != ResourceFolderType.VALUES; - return new ResourceNameValidator(allowXmlExtension, null, isFileType); + return new ResourceNameValidator(allowXmlExtension, null, isFileType, + type == ResourceFolderType.DRAWABLE); } /** @@ -142,7 +158,8 @@ public class ResourceNameValidator implements IInputValidator { public static ResourceNameValidator create(boolean allowXmlExtension, Set<String> existing, ResourceType type) { boolean isFileType = ResourceHelper.isFileBasedResourceType(type); - return new ResourceNameValidator(allowXmlExtension, existing, isFileType); + return new ResourceNameValidator(allowXmlExtension, existing, isFileType, + type == ResourceType.DRAWABLE); } /** @@ -165,6 +182,7 @@ public class ResourceNameValidator implements IInputValidator { } boolean isFileType = ResourceHelper.isFileBasedResourceType(type); - return new ResourceNameValidator(allowXmlExtension, existing, isFileType); + return new ResourceNameValidator(allowXmlExtension, existing, isFileType, + type == ResourceType.DRAWABLE); } } diff --git a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/wizards/newxmlfile/NewXmlFileWizard.java b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/wizards/newxmlfile/NewXmlFileWizard.java index 87afa11..a375987 100644 --- a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/wizards/newxmlfile/NewXmlFileWizard.java +++ b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/wizards/newxmlfile/NewXmlFileWizard.java @@ -247,7 +247,7 @@ public class NewXmlFileWizard extends Wizard implements INewWizard { return createXmlFile(file, xmlns, root, attrs, null); } - private static boolean createWsParentDirectory(IContainer wsPath) { + public static boolean createWsParentDirectory(IContainer wsPath) { if (wsPath.getType() == IResource.FOLDER) { if (wsPath.exists()) { return true; diff --git a/eclipse/scripts/create_adt_symlinks.sh b/eclipse/scripts/create_adt_symlinks.sh index 949362e..5966454 100755 --- a/eclipse/scripts/create_adt_symlinks.sh +++ b/eclipse/scripts/create_adt_symlinks.sh @@ -16,7 +16,7 @@ BACK=`echo $DEST | sed 's@[^/]*@..@g'` mkdir -p $DEST -LIBS="sdkstats androidprefs common layoutlib_api ide_common ninepatch sdklib sdkuilib" +LIBS="sdkstats androidprefs common layoutlib_api ide_common ninepatch sdklib sdkuilib assetstudio" echo "make java libs ..." make -j3 showcommands $LIBS || die "ADT: Fail to build one of $LIBS." |