/*
* 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.internal.avd.AvdInfo;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.Maps;
import com.intellij.icons.AllIcons;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.ui.JBMenuItem;
import com.intellij.openapi.ui.JBPopupMenu;
import com.intellij.ui.IdeBorderFactory;
import com.intellij.ui.components.JBLabel;
import org.jetbrains.annotations.NotNull;
import javax.swing.*;
import javax.swing.border.Border;
import javax.swing.border.EmptyBorder;
import java.awt.*;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.util.List;
import java.util.Map;
/**
* An action panel that behaves similarly to an Android overflow menu. Actions which
* do not fit in the space provided are relegated to an overflow menu that can be invoked by
* clicking on the last icon of the menu.
*/
public class AvdActionPanel extends JPanel implements AvdUiAction.AvdInfoProvider {
private static final Logger LOG = Logger.getInstance(AvdActionPanel.class);
@NotNull private final AvdInfo myAvdInfo;
private final AvdRefreshProvider myRefreshProvider;
private Map<JComponent, AvdUiAction> myButtonActionMap = Maps.newHashMap();
private final JBPopupMenu myOverflowMenu = new JBPopupMenu();
private final JBLabel myOverflowMenuButton = new JBLabel(AllIcons.ToolbarDecorator.Mac.MoveDown);
private final Border myMargins = IdeBorderFactory.createEmptyBorder(5, 3, 5, 3);
public interface AvdRefreshProvider {
void refreshAvds();
}
public AvdActionPanel(@NotNull AvdInfo avdInfo, int numVisibleActions, AvdRefreshProvider refreshProvider) {
myRefreshProvider = refreshProvider;
setOpaque(true);
setBorder(IdeBorderFactory.createEmptyBorder(10, 10, 10, 10));
myAvdInfo = avdInfo;
List<AvdUiAction> actions = getActions();
setLayout(new FlowLayout(FlowLayout.RIGHT, 3, 0));
int visibleActionCount = 0;
MouseAdapter mouseAdapter = new MouseAdapter() {
@Override
public void mouseClicked(MouseEvent e) {
myButtonActionMap.get(e.getSource()).actionPerformed(null);
}
};
boolean errorState = false;
if (avdInfo.getStatus() != AvdInfo.AvdStatus.OK) {
if (AvdManagerConnection.isAvdRepairable(avdInfo.getStatus())) {
JBLabel repairAction = new JBLabel("Repair Device", AllIcons.General.BalloonWarning, SwingConstants.LEADING);
myButtonActionMap.put(repairAction, new EditAvdAction(this));
repairAction.addMouseListener(mouseAdapter);
add(repairAction, "Repair Device");
} else {
add(new JBLabel("Failed to load", AllIcons.General.BalloonError, SwingConstants.LEADING));
}
numVisibleActions = 0;
errorState = true;
}
for (AvdUiAction action : actions) {
JComponent actionLabel;
// Add extra items to the overflow menu
if (numVisibleActions != -1 && visibleActionCount >= numVisibleActions) {
JBMenuItem menuItem = new JBMenuItem(action);
menuItem.setText(action.getText());
myOverflowMenu.add(menuItem);
actionLabel = menuItem;
} else {
// Add visible items to the panel
actionLabel = new JBLabel(action.getIcon());
add(actionLabel);
actionLabel.addMouseListener(mouseAdapter);
visibleActionCount++;
}
actionLabel.setToolTipText(action.getDescription());
actionLabel.setBorder(myMargins);
myButtonActionMap.put(actionLabel, action);
}
if (!errorState) {
myOverflowMenuButton.setBorder(myMargins);
add(myOverflowMenuButton);
myOverflowMenuButton.addMouseListener(new MouseAdapter() {
@Override
public void mouseClicked(MouseEvent e) {
myOverflowMenu.show(myOverflowMenuButton, e.getX(), e.getY());
}
});
}
}
@NotNull
private List<AvdUiAction> getActions() {
return ImmutableList.of(new RunAvdAction(this),
new EditAvdAction(this),
new DuplicateAvdAction(this),
//new ExportAvdAction(this), // TODO: implement export/import
new ShowAvdOnDiskAction(this),
new WipeAvdDataAction(this),
new DeleteAvdAction(this));
}
@NotNull
@Override
public AvdInfo getAvdInfo() {
return myAvdInfo;
}
@Override
public void refreshAvds() {
myRefreshProvider.refreshAvds();
}
public void showPopup(@NotNull Component c, @NotNull MouseEvent e) {
myOverflowMenu.show(c, e.getX(), e.getY());
}
}