IDEA-163208: show buttons from southPanel of dialogs

This commit is contained in:
Artem Bochkarev
2018-04-20 19:49:37 +07:00
parent 8fbbe7abf6
commit 0de12eb514
6 changed files with 125 additions and 22 deletions
@@ -523,6 +523,7 @@ public abstract class DialogWrapper {
}
}
myPeer.setTouchBarButtons(rightSideButtons);
return createSouthPanel(leftSideButtons, rightSideButtons, hasHelpToMoveToLeftSide);
}
@@ -25,6 +25,7 @@ import java.awt.*;
import java.awt.event.KeyListener;
import java.awt.event.MouseListener;
import java.awt.event.MouseMotionListener;
import java.util.List;
public abstract class DialogWrapperPeer {
public static Object HAVE_INITIAL_SELECTION = new Object();
@@ -160,4 +161,6 @@ public abstract class DialogWrapperPeer {
public Object[] getCurrentModalEntities() {
return ArrayUtil.EMPTY_OBJECT_ARRAY;
}
public void setTouchBarButtons(List<JButton> buttons) {}
}
@@ -39,6 +39,8 @@ import com.intellij.ui.components.JBLayeredPane;
import com.intellij.ui.mac.foundation.Foundation;
import com.intellij.ui.mac.foundation.ID;
import com.intellij.ui.mac.foundation.MacUtil;
import com.intellij.ui.mac.touchbar.TouchBar;
import com.intellij.ui.mac.touchbar.TouchBarsManager;
import com.intellij.util.IJSwingUtilities;
import com.intellij.util.ui.GraphicsUtil;
import com.intellij.util.ui.JBInsets;
@@ -73,6 +75,9 @@ public class DialogWrapperPeerImpl extends DialogWrapperPeer {
private Project myProject;
private ActionCallback myTypeAheadCallback;
private TouchBar myTouchBar;
private List<JButton> myTouchBarButtons;
protected DialogWrapperPeerImpl(@NotNull DialogWrapper wrapper, @Nullable Project project, boolean canBeParent, @NotNull DialogWrapper.IdeModalityType ideModalityType) {
boolean headless = isHeadlessEnv();
myWrapper = wrapper;
@@ -250,6 +255,8 @@ public class DialogWrapperPeerImpl extends DialogWrapperPeer {
myDialog.remove(myDialog.getRootPane());
}
});
TouchBarsManager.closeTempTouchBar(myTouchBar);
};
UIUtil.invokeLaterIfNeeded(disposer);
@@ -422,6 +429,9 @@ public class DialogWrapperPeerImpl extends DialogWrapperPeer {
myDialog.getWindow().setAutoRequestFocus(true);
if (myTouchBarButtons != null && myProject != null)
myTouchBar = TouchBarsManager.showTempButtonsBar(myTouchBarButtons, myProject);
try {
myDialog.show();
}
@@ -997,4 +1007,11 @@ public class DialogWrapperPeerImpl extends DialogWrapperPeer {
public void setAutoRequestFocus(boolean b) {
UIUtil.setAutoRequestFocus((JDialog)myDialog, b);
}
@Override
public void setTouchBarButtons(List<JButton> buttons) {
if (!TouchBarsManager.isTouchBarAvailable())
return;
myTouchBarButtons = buttons;
}
}
@@ -76,12 +76,10 @@ public class NST {
}
public static void releaseTouchBar(ID tbObj) {
ApplicationManager.getApplication().assertIsDispatchThread();
ourNSTLibrary.releaseTouchBar(tbObj);
}
public static void setTouchBar(TouchBar tb) {
ApplicationManager.getApplication().assertIsDispatchThread();
ourNSTLibrary.setTouchBar(tb == null ? ID.NIL : tb.getNativePeer());
}
@@ -5,18 +5,20 @@ import com.intellij.execution.ExecutionListener;
import com.intellij.execution.ExecutionManager;
import com.intellij.execution.process.ProcessHandler;
import com.intellij.execution.runners.ExecutionEnvironment;
import com.intellij.openapi.actionSystem.ActionManager;
import com.intellij.openapi.actionSystem.AnAction;
import com.intellij.openapi.actionSystem.Presentation;
import com.intellij.openapi.actionSystem.TimerListener;
import com.intellij.ide.DataManager;
import com.intellij.openapi.actionSystem.*;
import com.intellij.openapi.actionSystem.impl.PresentationFactory;
import com.intellij.openapi.actionSystem.impl.Utils;
import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.application.ModalityState;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.project.Project;
import com.intellij.ui.components.JBOptionButton;
import com.intellij.util.containers.ContainerUtil;
import com.intellij.util.messages.MessageBus;
import org.jetbrains.annotations.NotNull;
import java.util.List;
import java.awt.*;
public class TouchBarActionBase extends TouchBarProjectBase implements ExecutionListener {
@@ -75,6 +77,18 @@ public class TouchBarActionBase extends TouchBarProjectBase implements Execution
return butt;
}
public void addActionGroupButtons(ActionGroup actionGroup, JBOptionButton forCtx, ModalityState modality) {
final DataContext dctx = DataManager.getInstance().getDataContext(forCtx);
List<AnAction> visibleActions = ContainerUtil.newArrayListWithCapacity(10);
Utils.expandActionGroup(false, actionGroup, visibleActions, myPresentationFactory, dctx, ActionPlaces.UNKNOWN, ActionManager.getInstance());
for (AnAction act: visibleActions) {
if (act instanceof Separator)
continue;
addAnActionButton(act, false, TBItemAnActionButton.SHOWMODE_TEXT_ONLY, forCtx, modality);
}
}
@Override
public void processStarted(@NotNull String executorId, @NotNull ExecutionEnvironment env, @NotNull ProcessHandler handler) {
_updateActionItems();
@@ -1,25 +1,34 @@
// Copyright 2000-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
package com.intellij.ui.mac.touchbar;
import com.intellij.openapi.actionSystem.AnAction;
import com.intellij.openapi.actionSystem.AnActionEvent;
import com.intellij.openapi.actionSystem.DefaultActionGroup;
import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.application.ModalityState;
import com.intellij.openapi.application.impl.LaterInvocator;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.editor.Editor;
import com.intellij.openapi.editor.ex.EditorEx;
import com.intellij.openapi.editor.ex.FocusChangeListener;
import com.intellij.openapi.project.DumbAwareAction;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.project.ProjectManager;
import com.intellij.openapi.project.ProjectManagerListener;
import com.intellij.openapi.ui.OptionAction;
import com.intellij.openapi.ui.popup.JBPopupListener;
import com.intellij.openapi.ui.popup.LightweightWindowEvent;
import com.intellij.openapi.ui.popup.ListPopupStep;
import com.intellij.openapi.wm.ex.ToolWindowManagerEx;
import com.intellij.openapi.wm.ex.ToolWindowManagerListener;
import com.intellij.ui.components.JBOptionButton;
import com.intellij.ui.mac.foundation.Foundation;
import com.intellij.ui.mac.foundation.ID;
import com.intellij.ui.popup.list.ListPopupImpl;
import org.jetbrains.annotations.NotNull;
import javax.swing.*;
import java.awt.event.ActionEvent;
import java.awt.event.KeyEvent;
import java.util.ArrayDeque;
import java.util.ArrayList;
@@ -73,6 +82,12 @@ public class TouchBarsManager {
);
}
public static TouchBar showTempButtonsBar(List<JButton> jbuttons, Project project) {
final TouchBar tb = _createButtonsBar(jbuttons, project);
showTempTouchBar(tb);
return tb;
}
public static void initialize() {
if (!isTouchBarAvailable())
return;
@@ -210,27 +225,82 @@ public class TouchBarsManager {
LOG.trace(String.format(fmt, args));
}
private static TouchBar _createScrubberBarFromPopup(@NotNull ListPopupImpl listPopup) {
final TouchBar result = new TouchBar("popup_scrubber_bar" + listPopup);
private static TouchBar _createButtonsBar(List<JButton> jbuttons, Project project) {
try (NSAutoreleaseLock lock = new NSAutoreleaseLock()) {
TouchBarActionBase result = new TouchBarActionBase("dialog_buttons", project);
final ModalityState ms = LaterInvocator.getCurrentModalityState();
for (JButton jb : jbuttons) {
if (jb instanceof JBOptionButton) {
JBOptionButton ob = (JBOptionButton)jb;
Action[] opts = ob.getOptions();
DefaultActionGroup ag = new DefaultActionGroup();
for (Action a : opts) {
if (a == null)
continue;
AnAction anAct = _createAnAction(a, ob);
if (anAct == null)
continue;
ag.add(anAct);
}
List<TBItemScrubber.ItemData> items = new ArrayList<>();
@NotNull ListPopupStep listPopupStep = listPopup.getListStep();
for (Object obj: listPopupStep.getValues()) {
final Icon ic = listPopupStep.getIconFor(obj);
final String txt = listPopupStep.getTextFor(obj);
if (ag.getChildrenCount() > 0)
result.addActionGroupButtons(ag, ob, ms);
}
final Runnable action = () -> {
listPopup.getList().setSelectedValue(obj, false);
listPopup.handleSelect(true);
};
final NSTLibrary.Action act = () -> ApplicationManager.getApplication().invokeLater(() -> jb.doClick(), ms);
result.addButton(null, jb.getText(), act);
}
items.add(new TBItemScrubber.ItemData(ic, txt, ()-> ApplicationManager.getApplication().invokeLater(() -> action.run())));
return result;
}
final TBItemScrubber scrub = result.addScrubber();
scrub.setItems(items);
}
result.selectVisibleItemsToShow();
return result;
private static AnAction _createAnAction(@NotNull Action action, JBOptionButton fromButton) {
final Object anAct = action.getValue(OptionAction.AN_ACTION);
if (anAct == null) {
// LOG.warn("null AnAction in action: '" + action + "', use wrapper");
return new DumbAwareAction() {
{
setEnabledInModalContext(true);
final Object name = action.getValue(Action.NAME);
getTemplatePresentation().setText(name != null && name instanceof String ? (String)name : "");
}
@Override
public void actionPerformed(AnActionEvent e) { action.actionPerformed(new ActionEvent(fromButton, ActionEvent.ACTION_PERFORMED, null)); }
@Override
public void update(AnActionEvent e) { e.getPresentation().setEnabled(action.isEnabled()); }
};
}
if (!(anAct instanceof AnAction)) {
// LOG.warn("unknown type of awt.Action's property: " + anAct.getClass().toString());
return null;
}
return (AnAction)anAct;
}
private static TouchBar _createScrubberBarFromPopup(@NotNull ListPopupImpl listPopup) {
try (NSAutoreleaseLock lock = new NSAutoreleaseLock()) {
final TouchBar result = new TouchBar("popup_scrubber_bar" + listPopup);
List<TBItemScrubber.ItemData> items = new ArrayList<>();
@NotNull ListPopupStep listPopupStep = listPopup.getListStep();
for (Object obj : listPopupStep.getValues()) {
final Icon ic = listPopupStep.getIconFor(obj);
final String txt = listPopupStep.getTextFor(obj);
final Runnable action = () -> {
listPopup.getList().setSelectedValue(obj, false);
listPopup.handleSelect(true);
};
items.add(new TBItemScrubber.ItemData(ic, txt, () -> ApplicationManager.getApplication().invokeLater(() -> action.run())));
}
final TBItemScrubber scrub = result.addScrubber();
scrub.setItems(items);
result.selectVisibleItemsToShow();
return result;
}
}
private static class TempBarContainer implements BarContainer {