diff --git a/platform/platform-api/src/com/intellij/openapi/ui/DialogWrapper.java b/platform/platform-api/src/com/intellij/openapi/ui/DialogWrapper.java index e701abde77e0..1dad0efb81db 100644 --- a/platform/platform-api/src/com/intellij/openapi/ui/DialogWrapper.java +++ b/platform/platform-api/src/com/intellij/openapi/ui/DialogWrapper.java @@ -523,6 +523,7 @@ public abstract class DialogWrapper { } } + myPeer.setTouchBarButtons(rightSideButtons); return createSouthPanel(leftSideButtons, rightSideButtons, hasHelpToMoveToLeftSide); } diff --git a/platform/platform-api/src/com/intellij/openapi/ui/DialogWrapperPeer.java b/platform/platform-api/src/com/intellij/openapi/ui/DialogWrapperPeer.java index 040a94e86e4a..fc68f3b62097 100644 --- a/platform/platform-api/src/com/intellij/openapi/ui/DialogWrapperPeer.java +++ b/platform/platform-api/src/com/intellij/openapi/ui/DialogWrapperPeer.java @@ -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 buttons) {} } \ No newline at end of file diff --git a/platform/platform-impl/src/com/intellij/openapi/ui/impl/DialogWrapperPeerImpl.java b/platform/platform-impl/src/com/intellij/openapi/ui/impl/DialogWrapperPeerImpl.java index 4952d51d28ed..788167a11c39 100644 --- a/platform/platform-impl/src/com/intellij/openapi/ui/impl/DialogWrapperPeerImpl.java +++ b/platform/platform-impl/src/com/intellij/openapi/ui/impl/DialogWrapperPeerImpl.java @@ -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 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 buttons) { + if (!TouchBarsManager.isTouchBarAvailable()) + return; + myTouchBarButtons = buttons; + } } diff --git a/platform/platform-impl/src/com/intellij/ui/mac/touchbar/NST.java b/platform/platform-impl/src/com/intellij/ui/mac/touchbar/NST.java index abe935833a12..940f7c014c46 100644 --- a/platform/platform-impl/src/com/intellij/ui/mac/touchbar/NST.java +++ b/platform/platform-impl/src/com/intellij/ui/mac/touchbar/NST.java @@ -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()); } diff --git a/platform/platform-impl/src/com/intellij/ui/mac/touchbar/TouchBarActionBase.java b/platform/platform-impl/src/com/intellij/ui/mac/touchbar/TouchBarActionBase.java index f3babbaaac23..3bf5c26311c1 100644 --- a/platform/platform-impl/src/com/intellij/ui/mac/touchbar/TouchBarActionBase.java +++ b/platform/platform-impl/src/com/intellij/ui/mac/touchbar/TouchBarActionBase.java @@ -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 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(); diff --git a/platform/platform-impl/src/com/intellij/ui/mac/touchbar/TouchBarsManager.java b/platform/platform-impl/src/com/intellij/ui/mac/touchbar/TouchBarsManager.java index 899ea08ec655..614dfb1c0641 100644 --- a/platform/platform-impl/src/com/intellij/ui/mac/touchbar/TouchBarsManager.java +++ b/platform/platform-impl/src/com/intellij/ui/mac/touchbar/TouchBarsManager.java @@ -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 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 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 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 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 {