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 "";
}
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);
}
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;
}
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;
}
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());
}
}
}
}
}
Aggregations