Search in sources :

Example 81 with ResourceValue

use of com.android.ide.common.rendering.api.ResourceValue in project android by JetBrains.

the class ThemeEditorUtils method getDefaultResourceName.

/**
   * Build a name for a new resource based on a provided name.
   * @param initialName a name that result should be based on (that might not be vacant)
   */
@NotNull
private static String getDefaultResourceName(@NotNull ThemeEditorContext context, @NotNull final String initialName) {
    if (context.getCurrentTheme() == null || !context.getCurrentTheme().isReadOnly()) {
        // behaviour of color picker would be to edit the existing resource.
        return initialName;
    }
    final ResourceResolver resolver = context.getResourceResolver();
    assert resolver != null;
    final ResourceValue value = resolver.findResValue(SdkConstants.COLOR_RESOURCE_PREFIX + initialName, false);
    // Value doesn't exist, safe to use initial guess
    if (value == null) {
        return initialName;
    }
    // Given value exist, need to add a suffix to initialName to make it unique
    for (int i = 1; i <= 50; ++i) {
        final String name = initialName + "_" + i;
        if (resolver.findResValue(SdkConstants.COLOR_RESOURCE_PREFIX + name, false) == null) {
            // Found a vacant name
            return name;
        }
    }
    // Just set a default name to empty string so user have to insert the name manually
    return "";
}
Also used : ResourceResolver(com.android.ide.common.resources.ResourceResolver) ItemResourceValue(com.android.ide.common.rendering.api.ItemResourceValue) ResourceValue(com.android.ide.common.rendering.api.ResourceValue) NotNull(org.jetbrains.annotations.NotNull)

Example 82 with ResourceValue

use of com.android.ide.common.rendering.api.ResourceValue in project android by JetBrains.

the class ThemeEditorUtils method getModuleThemeQualifiedNamesList.

/**
   * Returns the list of the qualified names of all the user-defined themes available from a given module
   */
@NotNull
public static ImmutableList<String> getModuleThemeQualifiedNamesList(@NotNull Module module) {
    AndroidFacet facet = AndroidFacet.getInstance(module);
    assert facet != null;
    ConfigurationManager manager = facet.getConfigurationManager();
    // We create a new ResourceResolverCache instead of using cache from myConfiguration to optimize memory instead of time/speed,
    // because we are about to create a lot of instances of ResourceResolver here that won't be used outside of this method
    final ResourceResolverCache resolverCache = new ResourceResolverCache(manager);
    final IAndroidTarget target = manager.getTarget();
    final Map<ResourceValue, Boolean> cache = new HashMap<ResourceValue, Boolean>();
    final Set<String> themeNamesSet = Sets.newTreeSet(String.CASE_INSENSITIVE_ORDER);
    ResourceFolderVisitor visitor = new ResourceFolderVisitor() {

        @Override
        public void visitResourceFolder(@NotNull LocalResourceRepository resources, String moduleName, @NotNull String variantName, boolean isSelected) {
            if (!isSelected) {
                return;
            }
            for (String simpleThemeName : resources.getItemsOfType(ResourceType.STYLE)) {
                String themeStyleResourceUrl = SdkConstants.STYLE_RESOURCE_PREFIX + simpleThemeName;
                List<ResourceItem> themeItems = resources.getResourceItem(ResourceType.STYLE, simpleThemeName);
                assert themeItems != null;
                for (ResourceItem themeItem : themeItems) {
                    ResourceResolver resolver = resolverCache.getResourceResolver(target, themeStyleResourceUrl, themeItem.getConfiguration());
                    ResourceValue themeItemResourceValue = themeItem.getResourceValue(false);
                    assert themeItemResourceValue != null;
                    if (resolver.isTheme(themeItemResourceValue, cache)) {
                        themeNamesSet.add(simpleThemeName);
                        break;
                    }
                }
            }
        }
    };
    acceptResourceResolverVisitor(facet, visitor);
    return ImmutableList.copyOf(themeNamesSet);
}
Also used : IAndroidTarget(com.android.sdklib.IAndroidTarget) NotNull(org.jetbrains.annotations.NotNull) AndroidFacet(org.jetbrains.android.facet.AndroidFacet) ResourceResolverCache(com.android.tools.idea.configurations.ResourceResolverCache) ItemResourceValue(com.android.ide.common.rendering.api.ItemResourceValue) ResourceValue(com.android.ide.common.rendering.api.ResourceValue) ResourceResolver(com.android.ide.common.resources.ResourceResolver) ResourceItem(com.android.ide.common.res2.ResourceItem) ConfigurationManager(com.android.tools.idea.configurations.ConfigurationManager) NotNull(org.jetbrains.annotations.NotNull)

Example 83 with ResourceValue

use of com.android.ide.common.rendering.api.ResourceValue in project android by JetBrains.

the class ThemeEditorUtils method getGoodContrastPreviewBackground.

/**
   * Returns the color that should be used for the background of the preview panel depending on the background color
   * of the theme being displayed, so as to always keep some contrast between the two.
   */
public static JBColor getGoodContrastPreviewBackground(@NotNull ConfiguredThemeEditorStyle theme, @NotNull ResourceResolver resourceResolver) {
    ItemResourceValue themeColorBackgroundItem = resolveItemFromParents(theme, "colorBackground", true);
    ResourceValue backgroundResourceValue = resourceResolver.resolveResValue(themeColorBackgroundItem);
    if (backgroundResourceValue != null) {
        String colorBackgroundValue = backgroundResourceValue.getValue();
        Color colorBackground = ResourceHelper.parseColor(colorBackgroundValue);
        if (colorBackground != null) {
            float backgroundDistance = MaterialColorUtils.colorDistance(colorBackground, ThemeEditorComponent.PREVIEW_BACKGROUND);
            if (backgroundDistance < ThemeEditorComponent.COLOR_DISTANCE_THRESHOLD && backgroundDistance < MaterialColorUtils.colorDistance(colorBackground, ThemeEditorComponent.ALT_PREVIEW_BACKGROUND)) {
                return ThemeEditorComponent.ALT_PREVIEW_BACKGROUND;
            }
        }
    }
    return ThemeEditorComponent.PREVIEW_BACKGROUND;
}
Also used : ItemResourceValue(com.android.ide.common.rendering.api.ItemResourceValue) JBColor(com.intellij.ui.JBColor) ItemResourceValue(com.android.ide.common.rendering.api.ItemResourceValue) ResourceValue(com.android.ide.common.rendering.api.ResourceValue)

Example 84 with ResourceValue

use of com.android.ide.common.rendering.api.ResourceValue in project android by JetBrains.

the class ResourceHelper method resolveMultipleColors.

/**
   * Tries to resolve colors from given resource value. When state list is encountered all
   * possibilities are explored.
   */
@NotNull
private static List<Color> resolveMultipleColors(@NotNull RenderResources resources, @Nullable ResourceValue value, @NotNull Project project, int depth) {
    if (depth >= MAX_RESOURCE_INDIRECTION) {
        LOG.warn("too deep " + value);
        return Collections.emptyList();
    }
    if (value != null) {
        value = resources.resolveResValue(value);
    }
    if (value == null) {
        return Collections.emptyList();
    }
    final List<Color> result = new ArrayList<>();
    StateList stateList = resolveStateList(resources, value, project);
    if (stateList != null) {
        for (StateListState state : stateList.getStates()) {
            List<Color> stateColors;
            ResourceValue resolvedStateResource = resources.findResValue(state.getValue(), false);
            if (resolvedStateResource != null) {
                stateColors = resolveMultipleColors(resources, resolvedStateResource, project, depth + 1);
            } else {
                Color color = parseColor(state.getValue());
                stateColors = color == null ? Collections.emptyList() : ImmutableList.of(color);
            }
            for (Color color : stateColors) {
                try {
                    result.add(makeColorWithAlpha(resources, color, state.getAlpha()));
                } catch (NumberFormatException e) {
                    // If the alpha value is not valid, Android uses 1.0 so nothing more needs to be done, we simply take color as it is
                    result.add(color);
                    LOG.warn(String.format(ALPHA_FLOATING_ERROR_FORMAT, stateList.getDirName(), stateList.getFileName()));
                }
            }
        }
    } else {
        Color color = parseColor(value.getValue());
        if (color != null) {
            result.add(color);
        }
    }
    return result;
}
Also used : ResourceValue(com.android.ide.common.rendering.api.ResourceValue) NotNull(org.jetbrains.annotations.NotNull)

Example 85 with ResourceValue

use of com.android.ide.common.rendering.api.ResourceValue in project android by JetBrains.

the class ResourceResolverCache method replaceDrawableBitmaps.

/**
   * Replaces drawable bitmaps with those from the real older target. This helps the simulated platform look more genuine,
   * since a lot of the look comes from the nine patch assets. For example, when used to simulate Froyo, the checkboxes
   * will look better than if we use the current classic theme assets, which look like gingerbread.
   */
private static void replaceDrawableBitmaps(@NotNull Map<ResourceType, ResourceValueMap> frameworkResources, @NotNull IAndroidTarget from, @NotNull IAndroidTarget realTarget) {
    // This is a bit hacky; we should be operating at the resource repository level rather than
    // for configured resources. However, we may not need this for very long.
    ResourceValueMap map = frameworkResources.get(ResourceType.DRAWABLE);
    String oldPrefix = from.getPath(IAndroidTarget.RESOURCES);
    String newPrefix = realTarget.getPath(IAndroidTarget.RESOURCES);
    if (map == null || map.isEmpty() || oldPrefix == null || newPrefix == null || oldPrefix.equals(newPrefix)) {
        return;
    }
    Collection<ResourceValue> values = map.values();
    Map<String, String> densityDirMap = Maps.newHashMap();
    // Leave XML drawable resources alone since they can reference nonexistent colors and other resources
    // not available in the real rendering platform
    final boolean ONLY_REPLACE_BITMAPS = true;
    Density[] densities = Density.values();
    for (ResourceValue value : values) {
        String v = value.getValue();
        //noinspection ConstantConditions,PointlessBooleanExpression
        if (v != null && (!ONLY_REPLACE_BITMAPS || v.endsWith(DOT_PNG))) {
            if (v.startsWith(oldPrefix)) {
                String relative = v.substring(oldPrefix.length());
                if (v.endsWith(DOT_PNG)) {
                    int index = relative.indexOf(File.separatorChar);
                    if (index == -1) {
                        index = relative.indexOf('/');
                    }
                    if (index == -1) {
                        continue;
                    }
                    String parent = relative.substring(0, index);
                    String replace = densityDirMap.get(parent);
                    if (replace == null) {
                        FolderConfiguration configuration = FolderConfiguration.getConfigForFolder(parent);
                        if (configuration != null) {
                            DensityQualifier densityQualifier = configuration.getDensityQualifier();
                            if (densityQualifier != null) {
                                Density density = densityQualifier.getValue();
                                if (!new File(newPrefix, parent).exists()) {
                                    String oldQualifier = SdkConstants.RES_QUALIFIER_SEP + density.getResourceValue();
                                    String matched = null;
                                    for (Density d : densities) {
                                        if (d.ordinal() <= density.ordinal()) {
                                            // No reason to check higher
                                            continue;
                                        }
                                        String newQualifier = SdkConstants.RES_QUALIFIER_SEP + d.getResourceValue();
                                        String newName = parent.replace(oldQualifier, newQualifier);
                                        File dir = new File(newPrefix, newName);
                                        if (dir.exists()) {
                                            matched = newName;
                                            break;
                                        }
                                    }
                                    if (matched == null) {
                                        continue;
                                    }
                                    replace = matched;
                                    // This isn't right; there may be some assets only in mdpi!
                                    densityDirMap.put(parent, replace);
                                }
                            }
                        }
                    }
                    relative = replace + relative.substring(index);
                }
                File newFile = new File(newPrefix, relative);
                if (newFile.exists()) {
                    value.setValue(newFile.getPath());
                }
            }
        }
    }
}
Also used : ResourceValue(com.android.ide.common.rendering.api.ResourceValue) FolderConfiguration(com.android.ide.common.resources.configuration.FolderConfiguration) Density(com.android.resources.Density) File(java.io.File) DensityQualifier(com.android.ide.common.resources.configuration.DensityQualifier) ResourceValueMap(com.android.ide.common.resources.ResourceValueMap)

Aggregations

ResourceValue (com.android.ide.common.rendering.api.ResourceValue)243 StyleResourceValue (com.android.ide.common.rendering.api.StyleResourceValue)82 ArrayResourceValue (com.android.ide.common.rendering.api.ArrayResourceValue)80 DensityBasedResourceValue (com.android.ide.common.rendering.api.DensityBasedResourceValue)69 LayoutlibDelegate (com.android.tools.layoutlib.annotations.LayoutlibDelegate)56 RenderResources (com.android.ide.common.rendering.api.RenderResources)48 File (java.io.File)44 BridgeContext (com.android.layoutlib.bridge.android.BridgeContext)40 ResourceType (com.android.resources.ResourceType)31 XmlPullParser (org.xmlpull.v1.XmlPullParser)28 TypedValue (android.util.TypedValue)26 FileNotFoundException (java.io.FileNotFoundException)26 XmlPullParserException (org.xmlpull.v1.XmlPullParserException)23 AttrResourceValue (com.android.ide.common.rendering.api.AttrResourceValue)22 BridgeXmlBlockParser (com.android.layoutlib.bridge.android.BridgeXmlBlockParser)22 Context (android.content.Context)16 NotNull (org.jetbrains.annotations.NotNull)14 ResourceResolver (com.android.ide.common.resources.ResourceResolver)13 BridgeTypedArray (android.content.res.BridgeTypedArray)12 NotFoundException (android.content.res.Resources.NotFoundException)12