1 /* 2 * Copyright (C) 2007 The Android Open Source Project 3 * 4 * Licensed under the Eclipse Public License, Version 1.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.eclipse.org/org/documents/epl-v10.php 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package com.android.ide.eclipse.adt.internal.resources.configurations; 18 19 import com.android.ide.eclipse.adt.internal.editors.IconFactory; 20 import com.android.layoutlib.api.IDensityBasedResourceValue; 21 import com.android.sdklib.AndroidVersion; 22 import com.android.sdklib.IAndroidTarget; 23 24 import org.eclipse.swt.graphics.Image; 25 26 import java.util.regex.Matcher; 27 import java.util.regex.Pattern; 28 29 /** 30 * Resource Qualifier for Screen Pixel Density. 31 */ 32 public final class PixelDensityQualifier extends ResourceQualifier { 33 private final static Pattern sDensityLegacyPattern = Pattern.compile("^(\\d+)dpi$");//$NON-NLS-1$ 34 35 public static final String NAME = "Pixel Density"; 36 37 private Density mValue = Density.MEDIUM; 38 39 /** 40 * Screen Orientation enum. 41 */ 42 public static enum Density { 43 HIGH("hdpi", "High Density", IDensityBasedResourceValue.Density.HIGH), //$NON-NLS-1$ 44 MEDIUM("mdpi", "Medium Density", IDensityBasedResourceValue.Density.MEDIUM), //$NON-NLS-1$ 45 LOW("ldpi", "Low Density", IDensityBasedResourceValue.Density.LOW), //$NON-NLS-1$ 46 NODPI("nodpi", "No Density", IDensityBasedResourceValue.Density.NODPI); //$NON-NLS-1$ 47 48 private final String mValue; 49 private final String mDisplayValue; 50 private final IDensityBasedResourceValue.Density mDensity; 51 Density(String value, String displayValue, IDensityBasedResourceValue.Density density)52 private Density(String value, String displayValue, 53 IDensityBasedResourceValue.Density density) { 54 mValue = value; 55 mDisplayValue = displayValue; 56 mDensity = density; 57 } 58 59 /** 60 * Returns the enum for matching the provided qualifier value. 61 * @param value The qualifier value. 62 * @return the enum for the qualifier value or null if no matching was found. 63 */ getEnum(String value)64 public static Density getEnum(String value) { 65 for (Density orient : values()) { 66 if (orient.mValue.equals(value)) { 67 return orient; 68 } 69 } 70 71 return null; 72 } 73 getLegacyEnum(String value)74 static Density getLegacyEnum(String value) { 75 Matcher m = sDensityLegacyPattern.matcher(value); 76 if (m.matches()) { 77 String v = m.group(1); 78 79 try { 80 int density = Integer.parseInt(v); 81 for (Density orient : values()) { 82 if (orient.mDensity.getValue() == density) { 83 return orient; 84 } 85 } 86 } catch (NumberFormatException e) { 87 // looks like the string we extracted wasn't a valid number 88 // which really shouldn't happen since the regexp would have failed. 89 } 90 } 91 return null; 92 } 93 getValue()94 public String getValue() { 95 return mValue; 96 } 97 getDpiValue()98 public int getDpiValue() { 99 return mDensity.getValue(); 100 } 101 getLegacyValue()102 public String getLegacyValue() { 103 if (this != NODPI) { 104 return String.format("%1$ddpi", getDpiValue()); 105 } 106 107 return ""; 108 } 109 getDisplayValue()110 public String getDisplayValue() { 111 return mDisplayValue; 112 } 113 114 /** 115 * Returns the {@link com.android.layoutlib.api.IDensityBasedResourceValue.Density} value 116 * associated to this {@link Density}. 117 */ getDensity()118 public IDensityBasedResourceValue.Density getDensity() { 119 return mDensity; 120 } 121 getIndex(Density value)122 public static int getIndex(Density value) { 123 int i = 0; 124 for (Density input : values()) { 125 if (value == input) { 126 return i; 127 } 128 129 i++; 130 } 131 132 return -1; 133 } 134 getByIndex(int index)135 public static Density getByIndex(int index) { 136 int i = 0; 137 for (Density value : values()) { 138 if (i == index) { 139 return value; 140 } 141 i++; 142 } 143 return null; 144 } 145 } 146 PixelDensityQualifier()147 public PixelDensityQualifier() { 148 // pass 149 } 150 PixelDensityQualifier(Density value)151 public PixelDensityQualifier(Density value) { 152 mValue = value; 153 } 154 getValue()155 public Density getValue() { 156 return mValue; 157 } 158 159 @Override getName()160 public String getName() { 161 return NAME; 162 } 163 164 @Override getShortName()165 public String getShortName() { 166 return NAME; 167 } 168 169 @Override getIcon()170 public Image getIcon() { 171 return IconFactory.getInstance().getIcon("dpi"); //$NON-NLS-1$ 172 } 173 174 @Override isValid()175 public boolean isValid() { 176 return mValue != null; 177 } 178 179 @Override checkAndSet(String value, FolderConfiguration config)180 public boolean checkAndSet(String value, FolderConfiguration config) { 181 Density density = Density.getEnum(value); 182 if (density == null) { 183 density = Density.getLegacyEnum(value); 184 } 185 186 if (density != null) { 187 PixelDensityQualifier qualifier = new PixelDensityQualifier(); 188 qualifier.mValue = density; 189 config.setPixelDensityQualifier(qualifier); 190 return true; 191 } 192 193 return false; 194 } 195 196 @Override isMatchFor(ResourceQualifier qualifier)197 public boolean isMatchFor(ResourceQualifier qualifier) { 198 if (qualifier instanceof PixelDensityQualifier) { 199 // as long as there's a density qualifier, it's always a match. 200 // The best match will be found later. 201 return true; 202 } 203 204 return false; 205 } 206 207 @Override isBetterMatchThan(ResourceQualifier compareTo, ResourceQualifier reference)208 public boolean isBetterMatchThan(ResourceQualifier compareTo, ResourceQualifier reference) { 209 if (compareTo == null) { 210 return true; 211 } 212 213 PixelDensityQualifier compareQ = (PixelDensityQualifier)compareTo; 214 PixelDensityQualifier referenceQ = (PixelDensityQualifier)reference; 215 216 if (mValue == referenceQ.mValue && compareQ.mValue != referenceQ.mValue) { 217 // got exact value, this is the best! 218 return true; 219 } else { 220 // in all case we're going to prefer the higher dpi. 221 // if reference is high, we want highest dpi. 222 // if reference is medium, we'll prefer to scale down high dpi, than scale up low dpi 223 // if reference if low, we'll prefer to scale down high than medium (2:1 over 4:3) 224 return mValue.mDensity.getValue() > compareQ.mValue.mDensity.getValue(); 225 } 226 } 227 228 @Override equals(Object qualifier)229 public boolean equals(Object qualifier) { 230 if (qualifier instanceof PixelDensityQualifier) { 231 return mValue == ((PixelDensityQualifier)qualifier).mValue; 232 } 233 234 return false; 235 } 236 237 @Override hashCode()238 public int hashCode() { 239 if (mValue != null) { 240 return mValue.hashCode(); 241 } 242 243 return 0; 244 } 245 246 /** 247 * Returns the string used to represent this qualifier in the folder name. 248 */ 249 @Override getFolderSegment(IAndroidTarget target)250 public String getFolderSegment(IAndroidTarget target) { 251 if (mValue != null) { 252 if (target != null) { 253 AndroidVersion version = target.getVersion(); 254 if (version.getApiLevel() <= 3 && version.getCodename() == null) { 255 return mValue.getLegacyValue(); 256 } 257 } 258 return mValue.getValue(); 259 } 260 261 return ""; //$NON-NLS-1$ 262 } 263 264 @Override getStringValue()265 public String getStringValue() { 266 if (mValue != null) { 267 return mValue.getDisplayValue(); 268 } 269 270 return ""; //$NON-NLS-1$ 271 } 272 } 273