aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTor Norbye <tnorbye@google.com>2012-09-24 09:23:49 -0700
committerGerrit Code Review <noreply-gerritcodereview@google.com>2012-09-24 09:23:50 -0700
commit779041f18578734729c41d172eee38e45dec4627 (patch)
treec0916ae9ed5525872df4ab7985f37db7b6eb0608
parent6538a60efdc6edf66929e8e07c69ee5fa33c32f9 (diff)
parent0ac28eed3f5d796198e8b510ed82374ce99090d1 (diff)
downloadsdk-779041f18578734729c41d172eee38e45dec4627.zip
sdk-779041f18578734729c41d172eee38e45dec4627.tar.gz
sdk-779041f18578734729c41d172eee38e45dec4627.tar.bz2
Merge "Improve the Device menu"
-rw-r--r--eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/layout/configuration/DeviceMenuListener.java210
1 files changed, 180 insertions, 30 deletions
diff --git a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/layout/configuration/DeviceMenuListener.java b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/layout/configuration/DeviceMenuListener.java
index 8707c0e..32f8e9d 100644
--- a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/layout/configuration/DeviceMenuListener.java
+++ b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/editors/layout/configuration/DeviceMenuListener.java
@@ -20,6 +20,7 @@ import com.android.annotations.NonNull;
import com.android.annotations.Nullable;
import com.android.ide.eclipse.adt.internal.sdk.Sdk;
import com.android.sdklib.devices.Device;
+import com.android.sdklib.devices.Screen;
import com.android.sdklib.internal.avd.AvdInfo;
import com.android.sdklib.internal.avd.AvdManager;
@@ -33,15 +34,24 @@ import org.eclipse.swt.widgets.MenuItem;
import org.eclipse.swt.widgets.ToolItem;
import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Comparator;
import java.util.List;
import java.util.Map;
import java.util.TreeMap;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
/**
* The {@linkplain DeviceMenuListener} class is responsible for generating the device
* menu in the {@link ConfigurationChooser}.
*/
class DeviceMenuListener extends SelectionAdapter {
+ private static final String NEXUS = "Nexus"; //$NON-NLS-1$
+ private static final String GENERIC = "Generic"; //$NON-NLS-1$
+ private static Pattern PATTERN = Pattern.compile(
+ "(\\d+\\.?\\d*)in (.+?)( \\(.*Nexus.*\\))?"); //$NON-NLS-1$
+
private final ConfigurationChooser mConfigChooser;
private final Device mDevice;
@@ -63,34 +73,48 @@ class DeviceMenuListener extends SelectionAdapter {
Device current = configuration.getDevice();
Menu menu = new Menu(chooser.getShell(), SWT.POP_UP);
- AvdManager avdManager = Sdk.getCurrent().getAvdManager();
- AvdInfo[] avds = avdManager.getValidAvds();
List<Device> deviceList = chooser.getDeviceList();
- boolean separatorNeeded = false;
- for (AvdInfo avd : avds) {
- for (Device device : deviceList) {
- if (device.getManufacturer().equals(avd.getDeviceManufacturer())
- && device.getName().equals(avd.getDeviceName())) {
- separatorNeeded = true;
- MenuItem item = new MenuItem(menu, SWT.CHECK);
- item.setText(avd.getName());
- item.setSelection(current == device);
+ Sdk sdk = Sdk.getCurrent();
+ if (sdk != null) {
+ AvdManager avdManager = sdk.getAvdManager();
+ if (avdManager != null) {
+ boolean separatorNeeded = false;
+ AvdInfo[] avds = avdManager.getValidAvds();
+ for (AvdInfo avd : avds) {
+ for (Device device : deviceList) {
+ if (device.getManufacturer().equals(avd.getDeviceManufacturer())
+ && device.getName().equals(avd.getDeviceName())) {
+ separatorNeeded = true;
+ MenuItem item = new MenuItem(menu, SWT.CHECK);
+ item.setText(avd.getName());
+ item.setSelection(current == device);
- item.addSelectionListener(new DeviceMenuListener(chooser, device));
+ item.addSelectionListener(new DeviceMenuListener(chooser, device));
+ }
+ }
}
- }
- }
- if (separatorNeeded) {
- @SuppressWarnings("unused")
- MenuItem separator = new MenuItem(menu, SWT.SEPARATOR);
+ if (separatorNeeded) {
+ @SuppressWarnings("unused")
+ MenuItem separator = new MenuItem(menu, SWT.SEPARATOR);
+ }
+ }
}
- // Group the devices by manufacturer, then put them in the menu
+ // Group the devices by manufacturer, then put them in the menu.
+ // If we don't have anything but Nexus devices, group them together rather than
+ // make many manufacturer submenus.
+ boolean haveNexus = false;
+ boolean haveNonNexus = false;
if (!deviceList.isEmpty()) {
Map<String, List<Device>> manufacturers = new TreeMap<String, List<Device>>();
for (Device device : deviceList) {
List<Device> devices;
+ if (isNexus(device)) {
+ haveNexus = true;
+ } else if (!isGeneric(device)) {
+ haveNonNexus = true;
+ }
if (manufacturers.containsKey(device.getManufacturer())) {
devices = manufacturers.get(device.getManufacturer());
} else {
@@ -99,20 +123,62 @@ class DeviceMenuListener extends SelectionAdapter {
}
devices.add(device);
}
- for (List<Device> devices : manufacturers.values()) {
- Menu manufacturerMenu = menu;
- if (manufacturers.size() > 1) {
- MenuItem item = new MenuItem(menu, SWT.CASCADE);
- item.setText(devices.get(0).getManufacturer());
- manufacturerMenu = new Menu(menu);
- item.setMenu(manufacturerMenu);
+ if (haveNonNexus) {
+ for (List<Device> devices : manufacturers.values()) {
+ Menu manufacturerMenu = menu;
+ if (manufacturers.size() > 1) {
+ MenuItem item = new MenuItem(menu, SWT.CASCADE);
+ item.setText(devices.get(0).getManufacturer());
+ manufacturerMenu = new Menu(menu);
+ item.setMenu(manufacturerMenu);
+ }
+ for (final Device device : devices) {
+ MenuItem deviceItem = new MenuItem(manufacturerMenu, SWT.CHECK);
+ deviceItem.setText(getGenericLabel(device));
+ deviceItem.setSelection(current == device);
+ deviceItem.addSelectionListener(new DeviceMenuListener(chooser, device));
+ }
+ }
+ } else {
+ List<Device> nexus = new ArrayList<Device>();
+ List<Device> generic = new ArrayList<Device>();
+ if (haveNexus) {
+ // Nexus
+ for (List<Device> devices : manufacturers.values()) {
+ for (Device device : devices) {
+ if (isNexus(device)) {
+ if (device.getManufacturer().equals(GENERIC)) {
+ generic.add(device);
+ } else {
+ nexus.add(device);
+ }
+ } else {
+ generic.add(device);
+ }
+ }
+ }
}
- for (final Device d : devices) {
- MenuItem deviceItem = new MenuItem(manufacturerMenu, SWT.CHECK);
- deviceItem.setText(d.getName());
- deviceItem.setSelection(current == d);
- deviceItem.addSelectionListener(new DeviceMenuListener(chooser, d));
+ if (!nexus.isEmpty()) {
+ sortNexusList(nexus);
+ for (final Device device : nexus) {
+ MenuItem item = new MenuItem(menu, SWT.CHECK);
+ item.setText(getNexusLabel(device));
+ item.setSelection(current == device);
+ item.addSelectionListener(new DeviceMenuListener(chooser, device));
+ }
+
+ @SuppressWarnings("unused")
+ MenuItem separator = new MenuItem(menu, SWT.SEPARATOR);
+ }
+
+ // Generate the generic menu.
+ Collections.reverse(generic);
+ for (final Device device : generic) {
+ MenuItem item = new MenuItem(menu, SWT.CHECK);
+ item.setText(getGenericLabel(device));
+ item.setSelection(current == device);
+ item.addSelectionListener(new DeviceMenuListener(chooser, device));
}
}
}
@@ -123,4 +189,88 @@ class DeviceMenuListener extends SelectionAdapter {
menu.setLocation(location.x, location.y);
menu.setVisible(true);
}
+
+ private static String getNexusLabel(Device d) {
+ String name = d.getName();
+ Screen screen = d.getDefaultHardware().getScreen();
+ float length = (float) screen.getDiagonalLength();
+ return String.format(java.util.Locale.US, "%1$s (%3$s\", %2$s)",
+ name, getResolutionString(d), Float.toString(length));
+ }
+
+ private static String getGenericLabel(Device d) {
+ // * Replace "'in'" with '"' (e.g. 2.7" QVGA instead of 2.7in QVGA)
+ // * Use the same precision for all devices (all but one specify decimals)
+ // * Add some leading space such that the dot ends up roughly in the
+ // same space
+ // * Add in screen resolution and density
+ String name = d.getName();
+ if (name.equals("3.7 FWVGA slider")) {
+ // Fix metadata: this one entry doesn't have "in" like the rest of them
+ name = "3.7in FWVGA slider";
+ }
+
+ Matcher matcher = PATTERN.matcher(name);
+ if (matcher.matches()) {
+ String size = matcher.group(1);
+ String n = matcher.group(2);
+ int dot = size.indexOf('.');
+ if (dot == -1) {
+ size = size + ".0";
+ dot = size.length() - 2;
+ }
+ for (int i = 0; i < 2 - dot; i++) {
+ size = ' ' + size;
+ }
+ name = size + "\" " + n;
+ }
+
+ return String.format(java.util.Locale.US, "%1$s (%2$s)", name,
+ getResolutionString(d));
+ }
+
+ @Nullable
+ private static String getResolutionString(Device device) {
+ Screen screen = device.getDefaultHardware().getScreen();
+ return String.format(java.util.Locale.US,
+ "%1$d \u00D7 %2$d: %3$s", // U+00D7: Unicode multiplication sign
+ screen.getXDimension(),
+ screen.getYDimension(),
+ screen.getPixelDensity().getResourceValue());
+ }
+
+ private static boolean isGeneric(Device device) {
+ return device.getManufacturer().equals(GENERIC);
+ }
+
+ private static boolean isNexus(Device device) {
+ return device.getName().contains(NEXUS);
+ }
+
+ private static void sortNexusList(List<Device> list) {
+ Collections.sort(list, new Comparator<Device>() {
+ @Override
+ public int compare(Device device1, Device device2) {
+ // Descending order of age
+ return nexusRank(device2) - nexusRank(device1);
+ }
+ private int nexusRank(Device device) {
+ String name = device.getName();
+ if (name.endsWith(" One")) { //$NON-NLS-1$
+ return 1;
+ }
+ if (name.endsWith(" S")) { //$NON-NLS-1$
+ return 2;
+ }
+ if (name.startsWith("Galaxy")) { //$NON-NLS-1$
+ return 3;
+ }
+ if (name.endsWith(" 7")) { //$NON-NLS-1$
+ return 4;
+ }
+
+ return 5;
+ }
+ });
+ }
}