package com.intellij.lang.javascript.flex.projectStructure.ui;
import com.intellij.ProjectTopics;
import com.intellij.icons.AllIcons;
import com.intellij.lang.javascript.flex.FlexBundle;
import com.intellij.lang.javascript.flex.FlexModuleType;
import com.intellij.lang.javascript.flex.projectStructure.model.FlexBuildConfiguration;
import com.intellij.lang.javascript.flex.projectStructure.model.FlexBuildConfigurationManager;
import com.intellij.lang.javascript.flex.projectStructure.options.BCUtils;
import com.intellij.openapi.fileEditor.FileEditorManagerEvent;
import com.intellij.openapi.module.Module;
import com.intellij.openapi.module.ModuleManager;
import com.intellij.openapi.module.ModuleType;
import com.intellij.openapi.module.ModuleUtil;
import com.intellij.openapi.project.ModuleListener;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.roots.ModuleRootEvent;
import com.intellij.openapi.roots.ModuleRootListener;
import com.intellij.openapi.ui.popup.ListPopup;
import com.intellij.openapi.util.Disposer;
import com.intellij.openapi.util.SystemInfo;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.openapi.wm.CustomStatusBarWidget;
import com.intellij.openapi.wm.StatusBar;
import com.intellij.openapi.wm.StatusBarWidget;
import com.intellij.openapi.wm.WindowManager;
import com.intellij.openapi.wm.impl.status.EditorBasedWidget;
import com.intellij.ui.ClickListener;
import com.intellij.ui.HintHint;
import com.intellij.ui.LightweightHint;
import com.intellij.ui.awt.RelativePoint;
import com.intellij.util.ui.JBUI;
import com.intellij.util.ui.UIUtil;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import javax.swing.*;
import java.awt.*;
import java.awt.event.MouseEvent;
public class ActiveBuildConfigurationWidget {
private final Project myProject;
@Nullable
private MyWidget myWidget;
public ActiveBuildConfigurationWidget(final Project project) {
myProject = project;
myProject.getMessageBus().connect(myProject).subscribe(ProjectTopics.MODULES, new ModuleListener() {
@Override
public void moduleAdded(@NotNull final Project project, @NotNull final Module module) {
showOrHideWidget(false);
}
@Override
public void moduleRemoved(@NotNull final Project project, @NotNull final Module module) {
showOrHideWidget(false);
}
});
showOrHideWidget(false);
}
public void destroy() {
showOrHideWidget(true);
}
private void showOrHideWidget(boolean forceRemove) {
StatusBar statusBar = WindowManager.getInstance().getStatusBar(myProject);
if (statusBar == null) {
return;
}
boolean showWidget = !forceRemove && shouldShowWidget();
if (showWidget) {
if (myWidget == null) {
myWidget = new MyWidget(myProject);
statusBar.addWidget(myWidget, MyWidget.getAnchor());
}
}
else {
if (myWidget != null) {
statusBar.removeWidget(myWidget.ID());
myWidget = null;
}
}
}
private boolean shouldShowWidget() {
for (Module module : ModuleManager.getInstance(myProject).getModules()) {
if (ModuleType.get(module) == FlexModuleType.getInstance()) {
return true;
}
}
return false;
}
private static class MyWidget extends EditorBasedWidget implements CustomStatusBarWidget, StatusBarWidget.Multiframe {
private final JLabel myEnabledLabel = new JLabel();
private final JLabel myDisabledLabel = new JLabel(FlexBundle.message("active.bc.widget.empty.text"));
private final JPanel myPanel;
private final JLabel myUpDownLabel = new JLabel(AllIcons.Ide.Statusbar_arrows);
private MyWidget(@NotNull Project project) {
super(project);
Disposer.register(project, this);
project.getMessageBus().connect(this).subscribe(ProjectTopics.PROJECT_ROOTS, new ModuleRootListener() {
@Override
public void rootsChanged(final ModuleRootEvent event) {
update();
}
});
myEnabledLabel.setFont(SystemInfo.isMac ? UIUtil.getLabelFont().deriveFont(11.0f) : UIUtil.getLabelFont());
myEnabledLabel.setCursor(Cursor.getPredefinedCursor(Cursor.HAND_CURSOR));
myDisabledLabel.setHorizontalAlignment(SwingConstants.CENTER);
myDisabledLabel.setToolTipText(FlexBundle.message("active.bc.widget.empty.tooltip"));
myDisabledLabel.setForeground(UIUtil.getInactiveTextColor());
myDisabledLabel.setCursor(Cursor.getPredefinedCursor(Cursor.HAND_CURSOR));
myPanel = new JPanel(new GridBagLayout()) {
@Override
public Dimension getPreferredSize() {
int max = getFontMetrics(getFont()).stringWidth(myDisabledLabel.getText());
return new Dimension(20 + max, getMinimumSize().height);
}
};
myPanel.setOpaque(false);
myPanel.setCursor(Cursor.getPredefinedCursor(Cursor.HAND_CURSOR));
myPanel.setBorder(WidgetBorder.INSTANCE);
GridBagConstraints c =
new GridBagConstraints(0, 0, 1, 1, 1, 1, GridBagConstraints.WEST, GridBagConstraints.NONE, JBUI.emptyInsets(), 0, 0);
myPanel.add(myEnabledLabel, c);
c.gridx++;
c.anchor = GridBagConstraints.CENTER;
myPanel.add(myDisabledLabel, c);
c.gridx++;
c.weightx = 0;
myPanel.add(myUpDownLabel, c);
ClickListener listener = new ClickListener() {
@Override
public boolean onClick(@NotNull MouseEvent e, int clickCount) {
Module module = findCurrentFlexModule();
if (module != null) {
ListPopup popup = ChooseActiveBuildConfigurationAction.createPopup(module);
final Dimension dimension = popup.getContent().getPreferredSize();
final Point at = new Point(0, -dimension.height);
popup.show(new RelativePoint(e.getComponent(), at));
}
else {
HintHint hintHint = new HintHint(e).setShowImmediately(true).setAwtTooltip(true);
new LightweightHint(new JLabel(myDisabledLabel.getToolTipText())).show(myPanel, e.getX(), e.getY(), myPanel, hintHint);
}
return true;
}
};
listener.installOn(myEnabledLabel);
listener.installOn(myDisabledLabel);
listener.installOn(myPanel);
listener.installOn(myUpDownLabel);
update();
}
@Override
public JComponent getComponent() {
return myPanel;
}
@Override
@Nullable
public WidgetPresentation getPresentation(@NotNull final PlatformType type) {
return null;
}
private void update() {
if (myStatusBar == null) {
showDisabled();
return;
}
final Module module = findCurrentFlexModule();
if (module == null) {
showDisabled();
return;
}
FlexBuildConfiguration bc = FlexBuildConfigurationManager.getInstance(module).getActiveConfiguration();
myEnabledLabel.setText(BCUtils.renderBuildConfiguration(bc, null, false).toString());
myEnabledLabel.setToolTipText(FlexBundle.message("active.bc.widget.tooltip", bc.getName(), module.getName()));
myPanel.setToolTipText(myEnabledLabel.getToolTipText());
myEnabledLabel.setIcon(bc.getIcon());
myEnabledLabel.setVisible(true);
myDisabledLabel.setVisible(false);
myUpDownLabel.setVisible(true);
myStatusBar.updateWidget(ID());
}
private void showDisabled() {
myEnabledLabel.setVisible(false);
myUpDownLabel.setVisible(false);
myDisabledLabel.setVisible(true);
myPanel.setToolTipText(myDisabledLabel.getToolTipText());
}
public StatusBarWidget copy() {
return new MyWidget(getProject());
}
@NotNull
public String ID() {
return "ActiveFlexBuildConfiguration";
}
@Override
public void selectionChanged(@NotNull FileEditorManagerEvent event) {
update();
}
@Nullable
private Module findCurrentFlexModule() {
final VirtualFile selectedFile = getSelectedFile();
if (selectedFile == null) {
return null;
}
final Module module = ModuleUtil.findModuleForFile(selectedFile, getProject());
if (module == null || FlexModuleType.getInstance() != ModuleType.get(module)) {
return null;
}
return module;
}
public static String getAnchor() {
return "after " + (SystemInfo.isMac ? "Encoding" : "InsertOverwrite");
}
}
}