Home | History | Annotate | Download | only in configuration
      1 /*
      2  * Copyright (C) 2012 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.editors.layout.configuration;
     18 
     19 import static com.android.ide.common.rendering.HardwareConfigHelper.MANUFACTURER_GENERIC;
     20 import static com.android.ide.common.rendering.HardwareConfigHelper.getGenericLabel;
     21 import static com.android.ide.common.rendering.HardwareConfigHelper.getNexusLabel;
     22 import static com.android.ide.common.rendering.HardwareConfigHelper.isGeneric;
     23 import static com.android.ide.common.rendering.HardwareConfigHelper.isNexus;
     24 import static com.android.ide.common.rendering.HardwareConfigHelper.sortNexusList;
     25 
     26 import com.android.annotations.NonNull;
     27 import com.android.annotations.Nullable;
     28 import com.android.ide.eclipse.adt.internal.editors.layout.gle2.RenderPreviewMode;
     29 import com.android.ide.eclipse.adt.internal.sdk.Sdk;
     30 import com.android.sdklib.devices.Device;
     31 import com.android.sdklib.internal.avd.AvdInfo;
     32 import com.android.sdklib.internal.avd.AvdManager;
     33 
     34 import org.eclipse.swt.SWT;
     35 import org.eclipse.swt.events.SelectionAdapter;
     36 import org.eclipse.swt.events.SelectionEvent;
     37 import org.eclipse.swt.graphics.Point;
     38 import org.eclipse.swt.graphics.Rectangle;
     39 import org.eclipse.swt.widgets.Menu;
     40 import org.eclipse.swt.widgets.MenuItem;
     41 import org.eclipse.swt.widgets.ToolItem;
     42 
     43 import java.util.ArrayList;
     44 import java.util.Collection;
     45 import java.util.Collections;
     46 import java.util.List;
     47 import java.util.Map;
     48 import java.util.TreeMap;
     49 
     50 /**
     51  * The {@linkplain DeviceMenuListener} class is responsible for generating the device
     52  * menu in the {@link ConfigurationChooser}.
     53  */
     54 class DeviceMenuListener extends SelectionAdapter {
     55     private final ConfigurationChooser mConfigChooser;
     56     private final Device mDevice;
     57 
     58     DeviceMenuListener(
     59             @NonNull ConfigurationChooser configChooser,
     60             @Nullable Device device) {
     61         mConfigChooser = configChooser;
     62         mDevice = device;
     63     }
     64 
     65     @Override
     66     public void widgetSelected(SelectionEvent e) {
     67         mConfigChooser.selectDevice(mDevice);
     68         mConfigChooser.onDeviceChange();
     69     }
     70 
     71     static void show(final ConfigurationChooser chooser, ToolItem combo) {
     72         Configuration configuration = chooser.getConfiguration();
     73         Device current = configuration.getDevice();
     74         Menu menu = new Menu(chooser.getShell(), SWT.POP_UP);
     75 
     76         Collection<Device> deviceCollection = chooser.getDevices();
     77         Sdk sdk = Sdk.getCurrent();
     78         if (sdk != null) {
     79             AvdManager avdManager = sdk.getAvdManager();
     80             if (avdManager != null) {
     81                 boolean separatorNeeded = false;
     82                 AvdInfo[] avds = avdManager.getValidAvds();
     83                 for (AvdInfo avd : avds) {
     84                     for (Device device : deviceCollection) {
     85                         if (device.getManufacturer().equals(avd.getDeviceManufacturer())
     86                                 && device.getName().equals(avd.getDeviceName())) {
     87                             separatorNeeded = true;
     88                             MenuItem item = new MenuItem(menu, SWT.CHECK);
     89                             item.setText(avd.getName());
     90                             item.setSelection(current == device);
     91 
     92                             item.addSelectionListener(new DeviceMenuListener(chooser, device));
     93                         }
     94                     }
     95                 }
     96 
     97                 if (separatorNeeded) {
     98                     @SuppressWarnings("unused")
     99                     MenuItem separator = new MenuItem(menu, SWT.SEPARATOR);
    100                 }
    101             }
    102         }
    103 
    104         // Group the devices by manufacturer, then put them in the menu.
    105         // If we don't have anything but Nexus devices, group them together rather than
    106         // make many manufacturer submenus.
    107         boolean haveNexus = false;
    108         boolean haveNonNexus = false;
    109         if (!deviceCollection.isEmpty()) {
    110             Map<String, List<Device>> manufacturers = new TreeMap<String, List<Device>>();
    111             for (Device device : deviceCollection) {
    112                 List<Device> devices;
    113                 if (isNexus(device)) {
    114                     haveNexus = true;
    115                 } else if (!isGeneric(device)) {
    116                     haveNonNexus = true;
    117                 }
    118                 if (manufacturers.containsKey(device.getManufacturer())) {
    119                     devices = manufacturers.get(device.getManufacturer());
    120                 } else {
    121                     devices = new ArrayList<Device>();
    122                     manufacturers.put(device.getManufacturer(), devices);
    123                 }
    124                 devices.add(device);
    125             }
    126             if (haveNonNexus) {
    127                 for (List<Device> devices : manufacturers.values()) {
    128                     Menu manufacturerMenu = menu;
    129                     if (manufacturers.size() > 1) {
    130                         MenuItem item = new MenuItem(menu, SWT.CASCADE);
    131                         item.setText(devices.get(0).getManufacturer());
    132                         manufacturerMenu = new Menu(menu);
    133                         item.setMenu(manufacturerMenu);
    134                     }
    135                     for (final Device device : devices) {
    136                         MenuItem deviceItem = new MenuItem(manufacturerMenu, SWT.CHECK);
    137                         deviceItem.setText(getGenericLabel(device));
    138                         deviceItem.setSelection(current == device);
    139                         deviceItem.addSelectionListener(new DeviceMenuListener(chooser, device));
    140                     }
    141                 }
    142             } else {
    143                 List<Device> nexus = new ArrayList<Device>();
    144                 List<Device> generic = new ArrayList<Device>();
    145                 if (haveNexus) {
    146                     // Nexus
    147                     for (List<Device> devices : manufacturers.values()) {
    148                         for (Device device : devices) {
    149                             if (isNexus(device)) {
    150                                 if (device.getManufacturer().equals(MANUFACTURER_GENERIC)) {
    151                                     generic.add(device);
    152                                 } else {
    153                                     nexus.add(device);
    154                                 }
    155                             } else {
    156                                 generic.add(device);
    157                             }
    158                         }
    159                     }
    160                 }
    161 
    162                 if (!nexus.isEmpty()) {
    163                     sortNexusList(nexus);
    164                     for (final Device device : nexus) {
    165                         MenuItem item = new MenuItem(menu, SWT.CHECK);
    166                         item.setText(getNexusLabel(device));
    167                         item.setSelection(current == device);
    168                         item.addSelectionListener(new DeviceMenuListener(chooser, device));
    169                     }
    170 
    171                     @SuppressWarnings("unused")
    172                     MenuItem separator = new MenuItem(menu, SWT.SEPARATOR);
    173                 }
    174 
    175                 // Generate the generic menu.
    176                 Collections.reverse(generic);
    177                 for (final Device device : generic) {
    178                     MenuItem item = new MenuItem(menu, SWT.CHECK);
    179                     item.setText(getGenericLabel(device));
    180                     item.setSelection(current == device);
    181                     item.addSelectionListener(new DeviceMenuListener(chooser, device));
    182                 }
    183             }
    184         }
    185 
    186         @SuppressWarnings("unused")
    187         MenuItem separator = new MenuItem(menu, SWT.SEPARATOR);
    188 
    189         ConfigurationMenuListener.addTogglePreviewModeAction(menu,
    190                 "Preview All Screens", chooser, RenderPreviewMode.SCREENS);
    191 
    192 
    193         Rectangle bounds = combo.getBounds();
    194         Point location = new Point(bounds.x, bounds.y + bounds.height);
    195         location = combo.getParent().toDisplay(location);
    196         menu.setLocation(location.x, location.y);
    197         menu.setVisible(true);
    198     }
    199 }
    200