From a7db080f4d1d8ed2a94a2b91a69d7ad6c0357cc0 Mon Sep 17 00:00:00 2001 From: Artem Bochkarev Date: Wed, 11 Apr 2018 10:10:48 +0700 Subject: [PATCH] IDEA-163208: show touchbar with popup content when popup opened --- .../ui/mac/touchbar/BarContainer.java | 2 + .../intellij/ui/mac/touchbar/TouchBar.java | 3 + .../ui/mac/touchbar/TouchBarsManager.java | 70 ++++++++++++++++++- .../intellij/ui/popup/PopupFactoryImpl.java | 3 + 4 files changed, 75 insertions(+), 3 deletions(-) diff --git a/platform/platform-impl/src/com/intellij/ui/mac/touchbar/BarContainer.java b/platform/platform-impl/src/com/intellij/ui/mac/touchbar/BarContainer.java index bc857921a306..6f783cd9bf97 100644 --- a/platform/platform-impl/src/com/intellij/ui/mac/touchbar/BarContainer.java +++ b/platform/platform-impl/src/com/intellij/ui/mac/touchbar/BarContainer.java @@ -4,4 +4,6 @@ package com.intellij.ui.mac.touchbar; public interface BarContainer { TouchBar get(); void release(); + + default boolean isPopup() { return false; } } diff --git a/platform/platform-impl/src/com/intellij/ui/mac/touchbar/TouchBar.java b/platform/platform-impl/src/com/intellij/ui/mac/touchbar/TouchBar.java index 8bb1fd1dfd6b..f0344b6aec4c 100644 --- a/platform/platform-impl/src/com/intellij/ui/mac/touchbar/TouchBar.java +++ b/platform/platform-impl/src/com/intellij/ui/mac/touchbar/TouchBar.java @@ -26,6 +26,9 @@ public class TouchBar implements NSTLibrary.ItemCreator { myNativePeer = NST.createTouchBar(touchbarName, this); } + @Override + public String toString() { return myName; } + @Override public ID createItem(@NotNull String uid) { TBItem item = findItem(uid); 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 0abd4441d38f..564a2ae0321a 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 @@ -9,14 +9,21 @@ import com.intellij.openapi.editor.ex.FocusChangeListener; import com.intellij.openapi.project.Project; import com.intellij.openapi.project.ProjectManager; import com.intellij.openapi.project.ProjectManagerListener; +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.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.KeyEvent; import java.util.ArrayDeque; +import java.util.ArrayList; +import java.util.List; public class TouchBarsManager { private final static boolean IS_LOGGING_ENABLED = false; @@ -34,14 +41,44 @@ public class TouchBarsManager { editor.addFocusListener(new FocusChangeListener() { private BarContainer myEditorBar = ProjectBarsStorage.instance(proj).getBarContainer(ProjectBarsStorage.EDITOR); - @Override - public void focusGained(Editor editor) { showTouchBar(myEditorBar); } + public void focusGained(Editor editor) { + if (!hasVisiblePopup()) + showTouchBar(myEditorBar); + } @Override - public void focusLost(Editor editor) { closeTouchBar(myEditorBar); } + public void focusLost(Editor editor) { + if (!hasVisiblePopup()) + closeTouchBar(myEditorBar); + } }); } + public static void attachPopupBar(@NotNull ListPopupImpl listPopup) { + if (!isTouchBarAvailable()) + return; + + listPopup.addPopupListener(new JBPopupListener() { + BarContainer myPopupBar = new SingleBarContainer(()->_createScrubberBarFromPopup(listPopup)) { + @Override + public boolean isPopup() { return true; } + }; + @Override + public void beforeShown(LightweightWindowEvent event) { + System.out.println("open popup: " + listPopup); + showTouchBar(myPopupBar); + } + @Override + public void onClosed(LightweightWindowEvent event) { + System.out.println("closed popup: " + listPopup); + closeTouchBar(myPopupBar); + myPopupBar.release(); + myPopupBar = null; + } + } + ); + } + public static void initialize() { if (!isTouchBarAvailable()) return; @@ -111,6 +148,10 @@ public class TouchBarsManager { } } + synchronized public static boolean hasVisiblePopup() { + return ourTouchBarStack.stream().anyMatch((bc)->bc.isPopup()); + } + synchronized public static void showTouchBar(@NotNull BarContainer bar) { final BarContainer top = ourTouchBarStack.peek(); if (top == bar) @@ -148,4 +189,27 @@ public class TouchBarsManager { if (IS_LOGGING_ENABLED) LOG.trace(String.format(fmt, args)); } + + private static TouchBar _createScrubberBarFromPopup(@NotNull ListPopupImpl listPopup) { + 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; + } } diff --git a/platform/platform-impl/src/com/intellij/ui/popup/PopupFactoryImpl.java b/platform/platform-impl/src/com/intellij/ui/popup/PopupFactoryImpl.java index e9d54333402d..9728f98d4f6e 100644 --- a/platform/platform-impl/src/com/intellij/ui/popup/PopupFactoryImpl.java +++ b/platform/platform-impl/src/com/intellij/ui/popup/PopupFactoryImpl.java @@ -33,6 +33,7 @@ import com.intellij.ui.ScrollPaneFactory; import com.intellij.ui.awt.RelativePoint; import com.intellij.ui.components.JBList; import com.intellij.ui.components.panels.NonOpaquePanel; +import com.intellij.ui.mac.touchbar.TouchBarsManager; import com.intellij.ui.popup.list.ListPopupImpl; import com.intellij.ui.popup.mock.MockConfirmation; import com.intellij.ui.popup.tree.TreePopupImpl; @@ -227,6 +228,8 @@ public class PopupFactoryImpl extends JBPopupFactory { ActionMenu.showDescriptionInStatusBar(true, myComponent, presentation.getDescription()); } }); + + TouchBarsManager.attachPopupBar(this); } @NotNull