blob: 39c2820ca814d25935dd4f78d2bc6f3dcefd1a1a [file] [log] [blame]
/*
* Copyright (C) 2014 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.android.tools.idea.avdmanager;
import com.android.sdklib.SdkVersionInfo;
import com.android.sdklib.repository.descriptors.IdDisplay;
import com.android.tools.idea.npw.ChooseApiLevelDialog;
import com.intellij.openapi.Disposable;
import com.intellij.openapi.util.Disposer;
import com.intellij.openapi.util.IconLoader;
import com.intellij.ui.HyperlinkAdapter;
import com.intellij.ui.HyperlinkLabel;
import com.intellij.ui.JBColor;
import com.intellij.ui.components.JBLabel;
import com.intellij.util.ui.GraphicsUtil;
import com.intellij.util.ui.UIUtil;
import icons.AndroidIcons;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import javax.swing.*;
import javax.swing.event.HyperlinkEvent;
import java.awt.*;
import java.awt.image.BufferedImage;
/**
* Displays information about a {@link com.android.sdklib.SystemImage}, including its
* launch graphic, platform and API level, and target CPU architecture.
*/
public class SystemImagePreview {
private JBLabel myReleaseName;
private JBLabel myReleaseIcon;
private JBLabel myApiLevel;
private JBLabel myAndroidVersion;
private JBLabel myAbi;
private HyperlinkLabel myDocumentationLink;
private JBLabel myVendor;
private JPanel myRootPanel;
private JPanel myMainPanel;
private JSeparator mySeparator;
private HaxmAlert myHaxmAlert;
private SystemImageDescription myImageDescription;
private Disposable myDisposable;
ApiLevelHyperlinkListener myApiLevelListener = new ApiLevelHyperlinkListener();
private static final String NO_SYSTEM_IMAGE_SELECTED = "No System Image Selected";
private static final String MAIN_CONTENT = "main";
private static final String NO_IMAGE_CONTENT = "none";
public SystemImagePreview(@Nullable Disposable disposable) {
myDisposable = disposable;
myRootPanel.setLayout(new CardLayout());
myReleaseName.setFont(AvdWizardConstants.TITLE_FONT);
myApiLevel.setFont(AvdWizardConstants.TITLE_FONT);
myAndroidVersion.setFont(AvdWizardConstants.TITLE_FONT);
myVendor.setFont(AvdWizardConstants.TITLE_FONT);
myDocumentationLink.setOpaque(false);
myAbi.setFont(AvdWizardConstants.TITLE_FONT);
myRootPanel.add(myMainPanel, MAIN_CONTENT);
JPanel nonePanel = new JPanel(new BorderLayout());
JBLabel noneLabel = new JBLabel(NO_SYSTEM_IMAGE_SELECTED);
noneLabel.setHorizontalAlignment(JBLabel.CENTER);
nonePanel.add(noneLabel, BorderLayout.CENTER);
nonePanel.setBackground(JBColor.WHITE);
myRootPanel.add(nonePanel, NO_IMAGE_CONTENT);
myMainPanel.setBackground(JBColor.WHITE);
mySeparator.setForeground(JBColor.BLACK);
myDocumentationLink.addHyperlinkListener(myApiLevelListener);
myDocumentationLink.setHtmlText("See the <a>API level distribution chart</a>");
}
/**
* Set the image to display.
*/
public void setImage(@Nullable SystemImageDescription image) {
myImageDescription = image;
myHaxmAlert.setSystemImageDescription(image);
((CardLayout)myRootPanel.getLayout()).show(myRootPanel, NO_IMAGE_CONTENT);
if (image != null) {
((CardLayout)myRootPanel.getLayout()).show(myRootPanel, MAIN_CONTENT);
int apiLevel = image.getVersion().getApiLevel();
myApiLevelListener.setApiLevel(apiLevel);
String codeName = getCodeName(myImageDescription);
if (codeName != null) {
myReleaseName.setText(codeName);
}
Icon icon = getIcon(codeName);
if (icon != null) {
myReleaseIcon.setIcon(icon);
}
myApiLevel.setText(image.getVersion().getApiString());
myAndroidVersion.setVisible(!image.getVersion().isPreview());
myAndroidVersion.setText(SdkVersionInfo.getVersionString(apiLevel));
String vendorName;
IdDisplay tag = myImageDescription.getTag();
if (tag.getId().equals("android-wear") || tag.getId().equals("android-tv")) {
vendorName = "Android";
} else {
vendorName = myImageDescription.getVendor();
}
myVendor.setText("<html>" + vendorName + "</html>");
myAbi.setText(myImageDescription.getAbiType());
}
}
/**
* @return the codename for the given System Image's API level
*/
@Nullable
public static String getCodeName(@NotNull SystemImageDescription description) {
String codeName = description.getVersion().getCodename();
if (codeName == null) {
codeName = SdkVersionInfo.getCodeName(description.getVersion().getApiLevel());
}
return codeName;
}
/**
* Get the launch graphic which corresponds with the given codename, or a question mark
* if we don't have an icon for that codename.
*/
@Nullable
public static Icon getIcon(@Nullable String codename) {
if (codename == null) {
return null;
}
Icon icon = null;
try {
icon = IconLoader.findIcon(String.format("/icons/versions/%1$s.png", codename), AndroidIcons.class);
} catch (RuntimeException ignored) {
}
if (icon != null) {
return icon;
}
try {
icon = IconLoader.findIcon("/icons/versions/Default.png", AndroidIcons.class);
} catch (RuntimeException ignored) {
}
if (icon != null) {
return icon;
}
int size = 128;
Image image = UIUtil.createImage(size, size, BufferedImage.TYPE_INT_ARGB);
Graphics g = image.getGraphics();
GraphicsUtil.setupAntialiasing(g);
GraphicsUtil.setupAAPainting(g);
Font f = UIUtil.getLabelFont();
Font font = new Font(f.getName(), f.getStyle() | Font.BOLD, 100);
g.setColor(JBColor.background());
g.fillRect(0, 0, size, size);
g.setColor(JBColor.foreground());
g.setFont(font);
int height = g.getFontMetrics().getHeight();
int width = g.getFontMetrics().stringWidth("?");
g.drawString("?", (size - width) / 2, height + (size - height) / 2);
return new ImageIcon(image);
}
private void createUIComponents() {
myHaxmAlert = new HaxmAlert();
myHaxmAlert.setSystemImageDescription(myImageDescription);
}
private class ApiLevelHyperlinkListener extends HyperlinkAdapter {
private int myApiLevel = -1;
@Override
protected void hyperlinkActivated(HyperlinkEvent e) {
ChooseApiLevelDialog dialog = new ChooseApiLevelDialog(null, myApiLevel) {
@NotNull
@Override
protected Action[] createActions() {
Action close = getCancelAction();
close.putValue(Action.NAME, "Close");
return new Action[] {close};
}
};
Disposer.register(myDisposable, dialog.getDisposable());
dialog.show();
}
public void setApiLevel(int apiLevel) {
myApiLevel = apiLevel;
}
}
}