From 60fdd26cd6b9d738966ad60dd08e0127cf5b73a6 Mon Sep 17 00:00:00 2001 From: Alexander Lobas Date: Wed, 10 Jun 2020 22:34:17 +0300 Subject: [PATCH] IDEA-174109 Rework Status bar: presentation mode GitOrigin-RevId: d9bc1cab12932f4cd75c26bea5c94e8fe20e73f1 --- .../wm/impl/status/InfoAndProgressPanel.java | 24 ++++- .../impl/status/InlineProgressIndicator.java | 2 +- .../status/PresentationModeProgressPanel.java | 10 +- .../wm/impl/status/ProcessBalloon.java | 102 ++++++++++++------ .../openapi/wm/impl/status/ProcessPopup.java | 4 +- 5 files changed, 101 insertions(+), 41 deletions(-) diff --git a/platform/platform-impl/src/com/intellij/openapi/wm/impl/status/InfoAndProgressPanel.java b/platform/platform-impl/src/com/intellij/openapi/wm/impl/status/InfoAndProgressPanel.java index a72b93a70b9e..9004c84e225c 100644 --- a/platform/platform-impl/src/com/intellij/openapi/wm/impl/status/InfoAndProgressPanel.java +++ b/platform/platform-impl/src/com/intellij/openapi/wm/impl/status/InfoAndProgressPanel.java @@ -57,7 +57,7 @@ import java.util.*; public final class InfoAndProgressPanel extends JPanel implements CustomStatusBarWidget { private final ProcessPopup myPopup; - private final ProcessBalloon myBalloon = new ProcessBalloon(); + private final ProcessBalloon myBalloon = new ProcessBalloon(3); private final StatusPanel myInfoPanel = new StatusPanel(); private final JPanel myRefreshAndInfoPanel = new JPanel(); @@ -553,15 +553,15 @@ public final class InfoAndProgressPanel extends JPanel implements CustomStatusBa public void updateProgressNow() { super_updateProgressNow(); mySuspendUpdateRunnable.run(); - boolean painting = getInfo().isCancellable() && !isStopping(); - myCancelButton.setPainting(painting); - myCancelButton.setVisible(painting || !mySuspendButton.isVisible()); + updateCancelButton(mySuspendButton, myCancelButton); } } class MyInlineProgressIndicator extends InlineProgressIndicator { private ProgressIndicatorEx myOriginal; PresentationModeProgressPanel myPresentationModeProgressPanel; + Balloon myPresentationModeBalloon; + boolean myPresentationModeShowBalloon; MyInlineProgressIndicator(@NotNull TaskInfo task, @NotNull ProgressIndicatorEx original) { this(true, task, original); @@ -605,6 +605,18 @@ public final class InfoAndProgressPanel extends JPanel implements CustomStatusBa return JBIterable.of(createSuspendButton()).append(super.createEastButtons()); } + protected void updateCancelButton(@NotNull InplaceButton suspend, @NotNull InplaceButton cancel) { + boolean painting = getInfo().isCancellable() && !isStopping(); + cancel.setPainting(painting); + cancel.setVisible(painting || !suspend.isVisible()); + } + + JBIterable createPresentationButtons() { + ProgressButton suspend = createSuspendButton(); + ProgressButton cancel = createCancelButton(); + return JBIterable.of(suspend).append(new ProgressButton(cancel.button, () -> updateCancelButton(suspend.button, cancel.button))); + } + private ProgressButton createSuspendButton() { InplaceButton suspendButton = new InplaceButton("", AllIcons.Actions.Pause, e -> createSuspendRunnable().run()).setFillBg(false); return new ProgressButton(suspendButton, createSuspendUpdateRunnable(suspendButton)); @@ -726,6 +738,10 @@ public final class InfoAndProgressPanel extends JPanel implements CustomStatusBa super.updateProgressNow(); if (myPresentationModeProgressPanel != null) myPresentationModeProgressPanel.update(); } + + public boolean showInPresentationMode() { + return !isProcessWindowOpen(); + } } private void runQuery() { diff --git a/platform/platform-impl/src/com/intellij/openapi/wm/impl/status/InlineProgressIndicator.java b/platform/platform-impl/src/com/intellij/openapi/wm/impl/status/InlineProgressIndicator.java index 1010e69fc567..1a96d48908db 100644 --- a/platform/platform-impl/src/com/intellij/openapi/wm/impl/status/InlineProgressIndicator.java +++ b/platform/platform-impl/src/com/intellij/openapi/wm/impl/status/InlineProgressIndicator.java @@ -122,7 +122,7 @@ public class InlineProgressIndicator extends ProgressIndicatorBase implements Di return JBIterable.of(createCancelButton()); } - private ProgressButton createCancelButton() { + protected final ProgressButton createCancelButton() { InplaceButton cancelButton = new InplaceButton( new IconButton(myInfo.getCancelTooltipText(), myCompact ? AllIcons.Process.StopSmall : AllIcons.Process.Stop, diff --git a/platform/platform-impl/src/com/intellij/openapi/wm/impl/status/PresentationModeProgressPanel.java b/platform/platform-impl/src/com/intellij/openapi/wm/impl/status/PresentationModeProgressPanel.java index a63d7697557e..4db480a939bb 100644 --- a/platform/platform-impl/src/com/intellij/openapi/wm/impl/status/PresentationModeProgressPanel.java +++ b/platform/platform-impl/src/com/intellij/openapi/wm/impl/status/PresentationModeProgressPanel.java @@ -5,6 +5,7 @@ import com.intellij.ide.ui.UISettings; import com.intellij.openapi.editor.colors.EditorColorsManager; import com.intellij.openapi.util.registry.Registry; import com.intellij.openapi.util.text.StringUtil; +import com.intellij.openapi.wm.impl.status.InfoAndProgressPanel.MyInlineProgressIndicator; import com.intellij.ui.TransparentPanel; import com.intellij.ui.scale.JBUIScale; import com.intellij.util.containers.JBIterable; @@ -20,7 +21,7 @@ import java.awt.*; * @author Konstantin Bulenkov */ public class PresentationModeProgressPanel { - private final InlineProgressIndicator myProgress; + private final MyInlineProgressIndicator myProgress; private final JBIterable myEastButtons; private JLabel myText; private JProgressBar myProgressBar; @@ -28,14 +29,14 @@ public class PresentationModeProgressPanel { private JPanel myRootPanel; private JPanel myButtonPanel; - public PresentationModeProgressPanel(@NotNull InlineProgressIndicator progress) { + public PresentationModeProgressPanel(@NotNull MyInlineProgressIndicator progress) { myProgress = progress; Font font = JBUI.Fonts.label(11); myText.setFont(font); myText2.setFont(font); myText.setIcon(JBUI.scale(EmptyIcon.create(1, 16))); myText2.setIcon(JBUI.scale(EmptyIcon.create(1, 16))); - myEastButtons = myProgress.createEastButtons(); + myEastButtons = myProgress.createPresentationButtons(); myButtonPanel.add(InlineProgressIndicator.createButtonPanel(myEastButtons.map(b -> b.button))); myRootPanel.setPreferredSize(new JBDimension(250, 60)); myProgressBar.setPreferredSize(new Dimension(JBUIScale.scale(250), myProgressBar.getPreferredSize().height)); @@ -79,6 +80,9 @@ public class PresentationModeProgressPanel { myRootPanel = new TransparentPanel(0.5f) { @Override public boolean isVisible() { + if (!myProgress.showInPresentationMode()) { + return false; + } UISettings ui = UISettings.getInstance(); return ui.getPresentationMode() || !ui.getShowStatusBar() && Registry.is("ide.show.progress.without.status.bar"); } diff --git a/platform/platform-impl/src/com/intellij/openapi/wm/impl/status/ProcessBalloon.java b/platform/platform-impl/src/com/intellij/openapi/wm/impl/status/ProcessBalloon.java index de33cc161c27..4ea181f178b3 100644 --- a/platform/platform-impl/src/com/intellij/openapi/wm/impl/status/ProcessBalloon.java +++ b/platform/platform-impl/src/com/intellij/openapi/wm/impl/status/ProcessBalloon.java @@ -28,39 +28,93 @@ import java.awt.*; import java.util.ArrayList; import java.util.List; -public class ProcessBalloon { +class ProcessBalloon { private final List myIndicators = new ArrayList<>(); + private final int myMaxVisible; + private int myVisible; - void addIndicator(@Nullable JRootPane pane, @NotNull MyInlineProgressIndicator indicator) { - if (pane == null) { - return; - } + ProcessBalloon(int visibleCount) { + myMaxVisible = visibleCount; + } - myIndicators.add(indicator); - - if (myIndicators.size() == 1) { + public void addIndicator(@Nullable JRootPane pane, @NotNull MyInlineProgressIndicator indicator) { + if (pane != null) { + myIndicators.add(indicator); show(pane); } } - void removeIndicator(@Nullable JRootPane pane, @NotNull MyInlineProgressIndicator indicator) { + public void removeIndicator(@Nullable JRootPane pane, @NotNull MyInlineProgressIndicator indicator) { myIndicators.remove(indicator); - if (pane != null && indicator.myPresentationModeProgressPanel != null && !myIndicators.isEmpty()) { - show(pane); + if (indicator.myPresentationModeProgressPanel != null) { + myVisible--; + + if (pane != null && !myIndicators.isEmpty()) { + show(pane); + } } } private void show(@NotNull JRootPane pane) { - MyInlineProgressIndicator indicator = myIndicators.get(0); + List indicators = new ArrayList<>(); - indicator.myPresentationModeProgressPanel = new PresentationModeProgressPanel(indicator); - indicator.updateProgressNow(); + for (MyInlineProgressIndicator indicator : myIndicators) { + if (indicator.myPresentationModeProgressPanel == null) { + if (myVisible == myMaxVisible) { + continue; + } - show(pane, indicator, indicator.myPresentationModeProgressPanel.getProgressPanel()); + myVisible++; + + indicator.myPresentationModeProgressPanel = new PresentationModeProgressPanel(indicator); + indicator.updateProgressNow(); + + indicator.myPresentationModeBalloon = create(pane, indicator, indicator.myPresentationModeProgressPanel.getProgressPanel()); + indicator.myPresentationModeShowBalloon = true; + + indicators.add(indicator); + } + else if (!indicator.myPresentationModeBalloon.isDisposed()) { + indicators.add(indicator); + } + } + + for (MyInlineProgressIndicator indicator : indicators) { + if (indicator.myPresentationModeShowBalloon) { + indicator.myPresentationModeShowBalloon = false; + + indicator.myPresentationModeBalloon.show(new PositionTracker(getAnchor(pane)) { + @Override + public RelativePoint recalculateLocation(Balloon balloon) { + Component c = getAnchor(pane); + int y = c.getHeight() - JBUIScale.scale(45); + + BalloonLayoutImpl balloonLayout = getBalloonLayout(pane); + if (balloonLayout != null && !isBottomSideToolWindowsVisible(pane)) { + Component component = balloonLayout.getTopBalloonComponent(); + if (component != null) { + y = SwingUtilities.convertPoint(component, 0, -JBUIScale.scale(45), c).y; + } + } + + if (myVisible > 1) { + int index = myIndicators.indexOf(indicator); + int rowHeight = balloon.getPreferredSize().height + JBUI.scale(5); + y -= rowHeight * (myVisible - index - 1); + } + + return new RelativePoint(c, new Point(c.getWidth() - JBUIScale.scale(150), y)); + } + }, Balloon.Position.above); + } + else { + indicator.myPresentationModeBalloon.revalidate(); + } + } } - private static void show(@NotNull JRootPane pane, @NotNull Disposable parentDisposable, @NotNull JComponent content) { + private static @NotNull Balloon create(@NotNull JRootPane pane, @NotNull Disposable parentDisposable, @NotNull JComponent content) { Balloon balloon = JBPopupFactory.getInstance().createBalloonBuilder(content) .setFadeoutTime(0) .setFillColor(Gray.TRANSPARENT) @@ -101,21 +155,7 @@ public class ProcessBalloon { balloon.addListener(new MyListener()); } - balloon.show(new PositionTracker(getAnchor(pane)) { - @Override - public RelativePoint recalculateLocation(Balloon object) { - Component c = getAnchor(pane); - int y = c.getHeight() - JBUIScale.scale(45); - if (balloonLayout != null && !isBottomSideToolWindowsVisible(pane)) { - Component component = balloonLayout.getTopBalloonComponent(); - if (component != null) { - y = SwingUtilities.convertPoint(component, 0, -JBUIScale.scale(45), c).y; - } - } - - return new RelativePoint(c, new Point(c.getWidth() - JBUIScale.scale(150), y)); - } - }, Balloon.Position.above); + return balloon; } private static @Nullable BalloonLayoutImpl getBalloonLayout(@NotNull JRootPane pane) { diff --git a/platform/platform-impl/src/com/intellij/openapi/wm/impl/status/ProcessPopup.java b/platform/platform-impl/src/com/intellij/openapi/wm/impl/status/ProcessPopup.java index ce1f298f5bb6..68f7610a335d 100644 --- a/platform/platform-impl/src/com/intellij/openapi/wm/impl/status/ProcessPopup.java +++ b/platform/platform-impl/src/com/intellij/openapi/wm/impl/status/ProcessPopup.java @@ -27,7 +27,7 @@ import java.awt.*; import static javax.swing.ScrollPaneConstants.HORIZONTAL_SCROLLBAR_NEVER; import static javax.swing.ScrollPaneConstants.VERTICAL_SCROLLBAR_AS_NEEDED; -public class ProcessPopup { +class ProcessPopup { public static final Key KEY = new Key<>("ProgressPanel"); private final InfoAndProgressPanel myProgressPanel; @@ -35,7 +35,7 @@ public class ProcessPopup { private final JScrollPane myContentPanel; private JBPopup myPopup; - public ProcessPopup(@NotNull InfoAndProgressPanel progressPanel) { + ProcessPopup(@NotNull InfoAndProgressPanel progressPanel) { myProgressPanel = progressPanel; myIndicatorPanel = new JBPanelWithEmptyText().withEmptyText(IdeBundle.message("progress.window.empty.text")).andTransparent();