/* * Copyright 2003-2016 JetBrains s.r.o. * * 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 jetbrains.mps.nodeEditor.cells.contextAssistant; import com.intellij.openapi.ui.popup.ListPopupStep; import com.intellij.openapi.wm.IdeFocusManager; import com.intellij.util.ui.JBUI; import jetbrains.mps.openapi.editor.menus.transformation.TransformationMenuItem; import org.jetbrains.annotations.NotNull; import javax.swing.Action; import javax.swing.JButton; import javax.swing.JComponent; import javax.swing.JPanel; import javax.swing.KeyStroke; import java.awt.Color; import java.awt.Dimension; import java.awt.KeyboardFocusManager; import java.awt.event.KeyEvent; /** * Displays a {@link ListPopupStep ListPopupStep<MenuItem>} as a row of buttons in a panel, with an overflow button ("More..."). */ public class ContextAssistantPanel implements ContextAssistantView { private final OverflowLayout myLayout = new OverflowLayout(JBUI.scale(2)); private final JComponent myComponent = PanelCustomizations.setupMenuBar(new JPanel(myLayout)); private final JButton myOverflowButton = createOverflowButton(); private final int myPreferredHeight; private final int myBaseline; private ListPopupStep<TransformationMenuItem> myStep; public ContextAssistantPanel() { // Compute preferred height and baseline (for layout purposes) JButton flatButton = ButtonCustomizations.setupMenuButton(new JButton("some text")); Dimension preferredSize = flatButton.getPreferredSize(); myPreferredHeight = preferredSize.height; myBaseline = flatButton.getBaseline(preferredSize.width, preferredSize.height); } public void setBackground(Color background) { myComponent.setBackground(background); } private JButton createOverflowButton() { return ButtonCustomizations.setupMenuButton(new AbstractStepComboBoxButton("More") { @Override protected ListPopupStep<?> getStep() { return SubListStep.subList(myStep, myLayout.getFitCount()); } }); } @NotNull public JComponent getComponent() { return myComponent; } public int getPreferredHeight() { return myPreferredHeight; } public int getBaseline() { return myBaseline; } @Override public boolean hasFocus() { return myComponent.isFocusOwner() || myComponent.isAncestorOf(KeyboardFocusManager.getCurrentKeyboardFocusManager().getFocusOwner()); } @Override public void requestFocus() { IdeFocusManager.findInstanceByComponent(myComponent).requestFocus(myComponent, true); } public void setMaximumWidth(int maximumWidth) { Dimension oldSize = myComponent.isMaximumSizeSet() ? myComponent.getMaximumSize() : null; Dimension newSize = new Dimension(maximumWidth, myComponent.getPreferredSize().height); if (newSize.equals(oldSize)) { return; } myComponent.setMaximumSize(newSize); myComponent.revalidate(); } @Override public void showMenu(@NotNull ListPopupStep<TransformationMenuItem> items) { setStep(items); setVisible(true); } @Override public void hideMenu() { setStep(MenuItemListStep.EMPTY); setVisible(false); } public void setEscapeAction(Action action) { Object actionMapKey = new Object(); myComponent.getActionMap().put(actionMapKey, action); myComponent.getInputMap(JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT).put(KeyStroke.getKeyStroke(KeyEvent.VK_ESCAPE, 0), actionMapKey); } private void setVisible(boolean visible) { myComponent.setVisible(visible); } private void setStep(ListPopupStep<TransformationMenuItem> step) { myStep = step; updateButtons(); } private void updateButtons() { myComponent.removeAll(); for (TransformationMenuItem item : myStep.getValues()) { JButton button = createButton(item); myComponent.add(button); } myComponent.add(myOverflowButton, OverflowLayout.SHOW_ON_OVERFLOW); } private JButton createButton(TransformationMenuItem item) { return ButtonCustomizations.setupMenuButton(createBaseButton(item)); } private JButton createBaseButton(final TransformationMenuItem item) { return item.accept(new TopLevelButtonCreatingVisitor(myStep)); } }