Search in sources :

Example 11 with Density

use of com.android.resources.Density 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)

Example 12 with Density

use of com.android.resources.Density in project android by JetBrains.

the class VaryingConfiguration method getDevice.

@Override
@Nullable
public Device getDevice() {
    if (isOverridingDevice()) {
        return super.getDevice();
    }
    Device device = myParent.getDevice();
    if (isAlternatingDevice() && device != null) {
        if (device == myPrevParentDevice) {
            return myPrevDevice;
        }
        myPrevParentDevice = device;
        // Pick a different device
        List<Device> devices = getConfigurationManager().getDevices();
        // Divide up the available devices into {@link #myVariationCount} + 1 buckets
        // (the + 1 is for the bucket now taken up by the inherited value).
        // Then assign buckets to each {@link #myVariation} version, and pick one
        // from the bucket assigned to this current configuration's variation version.
        // I could just divide up the device list count, but that would treat a lot of
        // very similar phones as having the same kind of variety as the 7" and 10"
        // tablets which are sitting right next to each other in the device list.
        // Instead, do this by screen size.
        boolean isTv = isTv(device);
        boolean isWear = isWear(device);
        double smallest = 100;
        double biggest = 1;
        for (Device d : devices) {
            double size = getScreenSize(d);
            if (size < 0) {
                // no data
                continue;
            } else if (isTv != isTv(d) || isWear != isWear(d)) {
                continue;
            }
            if (size >= biggest) {
                biggest = size;
            }
            if (size <= smallest) {
                smallest = size;
            }
        }
        int bucketCount = myVariationCount + 1;
        double inchesPerBucket = (biggest - smallest) / bucketCount;
        double overriddenSize = getScreenSize(device);
        int overriddenBucket = (int) ((overriddenSize - smallest) / inchesPerBucket);
        int bucket = (myVariation < overriddenBucket) ? myVariation : myVariation + 1;
        double from = inchesPerBucket * bucket + smallest;
        double to = from + inchesPerBucket;
        if (biggest - to < 0.1) {
            to = biggest + 0.1;
        }
        boolean canScaleNinePatch = supports(Features.FIXED_SCALABLE_NINE_PATCH);
        for (Device d : devices) {
            if (isTv != isTv(d) || isWear != isWear(d)) {
                continue;
            }
            double size = getScreenSize(d);
            if (size >= from && size < to) {
                if (!canScaleNinePatch) {
                    Density density = getDensity(d);
                    if (density == null || !density.isRecommended() || density == Density.LOW) {
                        continue;
                    }
                }
                device = d;
                break;
            }
        }
        myPrevDevice = device;
    }
    return device;
}
Also used : Device(com.android.sdklib.devices.Device) Density(com.android.resources.Density) Nullable(org.jetbrains.annotations.Nullable)

Example 13 with Density

use of com.android.resources.Density in project android by JetBrains.

the class ConfirmGenerateIconsStep method onEntering.

@Override
protected void onEntering() {
    // Just in case we're entering this step a second time
    myListeners.release(mySelectedSourceSet);
    myListeners.receiveAndFire(mySelectedSourceSet, sourceSet -> {
        AndroidIconGenerator iconGenerator = getModel().getIconGenerator();
        File resDir = sourceSet.getPaths().getResDirectory();
        if (iconGenerator == null || resDir == null || resDir.getParentFile() == null) {
            return;
        }
        final Map<File, BufferedImage> pathIconMap = iconGenerator.generateIntoFileMap(sourceSet.getPaths());
        myFilesAlreadyExist.set(false);
        int minHeight = Integer.MAX_VALUE;
        int maxHeight = Integer.MIN_VALUE;
        for (BufferedImage image : pathIconMap.values()) {
            minHeight = Math.min(minHeight, image.getHeight());
            maxHeight = Math.max(maxHeight, image.getHeight());
        }
        ImmutableSortedSet.Builder<File> sortedPaths = ImmutableSortedSet.orderedBy(new Comparator<File>() {

            @Override
            public int compare(File file1, File file2) {
                String path1 = file1.getAbsolutePath();
                String path2 = file2.getAbsolutePath();
                Density density1 = CategoryIconMap.pathToDensity(path1);
                Density density2 = CategoryIconMap.pathToDensity(path2);
                if (density1 != null && density2 != null && density1 != density2) {
                    return Ints.compare(density2.ordinal(), density1.ordinal());
                } else {
                    BufferedImage image1 = pathIconMap.get(file1);
                    BufferedImage image2 = pathIconMap.get(file2);
                    int compareValue = Ints.compare(image2.getHeight(), image1.getHeight());
                    return (compareValue != 0) ? compareValue : path2.compareTo(path1);
                }
            }
        });
        sortedPaths.addAll(pathIconMap.keySet());
        FileTreeModel treeModel = new FileTreeModel(resDir.getParentFile(), true);
        for (File path : sortedPaths.build()) {
            Image image = pathIconMap.get(path);
            if (path.exists()) {
                myFilesAlreadyExist.set(true);
            }
            if (maxHeight > MAX_TREE_ROW_HEIGHT) {
                int hCurr = image.getHeight(null);
                int wCurr = image.getWidth(null);
                double hScale;
                if (maxHeight != minHeight) {
                    double hCurrPercent = (double) (hCurr - minHeight) / (double) (maxHeight - minHeight);
                    double scaledDeltaH = hCurrPercent * (MAX_TREE_ROW_HEIGHT - minHeight);
                    double hCurrScaled = minHeight + scaledDeltaH;
                    hScale = hCurrScaled / hCurr;
                } else {
                    hScale = MAX_TREE_ROW_HEIGHT / (double) hCurr;
                }
                int hFinal = (int) (hCurr * hScale);
                int wFinal = (int) (wCurr * hScale);
                image = image.getScaledInstance(wFinal, hFinal, Image.SCALE_SMOOTH);
            }
            treeModel.forceAddFile(path, new ImageIcon(image));
        }
        myOutputPreviewTree.setModel(treeModel);
        for (int i = 0; i < myOutputPreviewTree.getRowCount(); ++i) {
            myOutputPreviewTree.expandRow(i);
        }
    });
}
Also used : AndroidIconGenerator(com.android.tools.idea.npw.assetstudio.icon.AndroidIconGenerator) BufferedImage(java.awt.image.BufferedImage) Density(com.android.resources.Density) BufferedImage(java.awt.image.BufferedImage) FileTreeModel(com.android.tools.idea.ui.FileTreeModel) ImmutableSortedSet(com.google.common.collect.ImmutableSortedSet) File(java.io.File)

Example 14 with Density

use of com.android.resources.Density in project android by JetBrains.

the class CategoryIconMap method pathToDensity.

/**
   * Convert the path to a density, if possible. Output paths don't always map cleanly to density
   * values, such as the path for the "web" icon, so in those cases, {@code null} is returned.
   */
@Nullable
public static Density pathToDensity(@NotNull String iconPath) {
    iconPath = FileUtil.toSystemIndependentName(iconPath);
    // Strip off the filename, in case the user names their icon "xxxhdpi" etc.
    // but leave the trailing slash, as it's used in the regex pattern
    iconPath = iconPath.substring(0, iconPath.lastIndexOf('/') + 1);
    for (Density density : Density.values()) {
        if (DENSITY_PATTERNS.get(density).matcher(iconPath).matches()) {
            return density;
        }
    }
    return null;
}
Also used : Density(com.android.resources.Density) Nullable(org.jetbrains.annotations.Nullable)

Example 15 with Density

use of com.android.resources.Density in project android by JetBrains.

the class PreviewIconsPanel method initializeIconComponents.

private void initializeIconComponents(@NotNull Collection<Density> densities) {
    // Sort the densities, so that we always line up icons from highest to lowest densities.
    Ordering<Density> densityOrdering = new Ordering<Density>() {

        @Override
        public int compare(Density left, Density right) {
            // The lower the enum index, the higher the density
            return Ints.compare(left.ordinal(), right.ordinal());
        }
    };
    densities = densityOrdering.immutableSortedCopy(densities);
    for (Density density : densities) {
        JPanel iconPanel = new JPanel(new VerticalFlowLayout(false, false));
        iconPanel.setBackground(myTheme.getMainColor());
        iconPanel.setOpaque(myTheme != Theme.TRANSPARENT);
        JBLabel title = new JBLabel(density.getResourceValue());
        title.setForeground(myTheme.getAltColor());
        iconPanel.add(title);
        ImageComponent iconImage = new ImageComponent(null);
        iconImage.setBorder(new LineBorder(myTheme.getAltColor()));
        iconImage.setOpaque(false);
        iconPanel.add(iconImage);
        GridBagConstraints c = new GridBagConstraints();
        c.anchor = GridBagConstraints.PAGE_START;
        myIconsPanel.add(iconPanel, c);
        myIconImages.put(density, iconImage);
    }
}
Also used : ImageComponent(com.android.tools.idea.ui.ImageComponent) JBLabel(com.intellij.ui.components.JBLabel) LineBorder(javax.swing.border.LineBorder) Ordering(com.google.common.collect.Ordering) Density(com.android.resources.Density) VerticalFlowLayout(com.intellij.openapi.ui.VerticalFlowLayout)

Aggregations

Density (com.android.resources.Density)34 IOException (java.io.IOException)12 File (java.io.File)10 ScreenSize (com.android.resources.ScreenSize)8 Bitmap (android.graphics.Bitmap)7 BitmapDrawable (android.graphics.drawable.BitmapDrawable)7 Configuration (android.content.res.Configuration)6 ColorDrawable (android.graphics.drawable.ColorDrawable)6 DensityBasedResourceValue (com.android.ide.common.rendering.api.DensityBasedResourceValue)6 HardwareConfig (com.android.ide.common.rendering.api.HardwareConfig)6 BridgeXmlBlockParser (com.android.layoutlib.bridge.android.BridgeXmlBlockParser)6 ScreenOrientation (com.android.resources.ScreenOrientation)6 FileInputStream (java.io.FileInputStream)6 MalformedURLException (java.net.MalformedURLException)6 XmlPullParser (org.xmlpull.v1.XmlPullParser)6 XmlPullParserException (org.xmlpull.v1.XmlPullParserException)6 NinePatchChunk (com.android.ninepatch.NinePatchChunk)5 ScreenRound (com.android.resources.ScreenRound)5 LayoutlibDelegate (com.android.tools.layoutlib.annotations.LayoutlibDelegate)5 FileNotFoundException (java.io.FileNotFoundException)5