IDEA-149210 Rework IDE notifications

This commit is contained in:
Alexander Lobas
2016-02-16 13:00:06 +03:00
parent 80a33c24ee
commit 1fd2764dea
6 changed files with 107 additions and 22 deletions
@@ -278,15 +278,15 @@ public class NotificationsManagerImpl extends NotificationsManager {
@Nullable
public static Window findWindowForBalloon(@Nullable Project project) {
Window frame = WindowManager.getInstance().getFrame(project);
if (frame == null && project == null) {
frame = (Window)WelcomeFrame.getInstance();
}
if (frame == null && project == null) {
frame = KeyboardFocusManager.getCurrentKeyboardFocusManager().getActiveWindow();
while (frame instanceof DialogWrapperDialog && ((DialogWrapperDialog)frame).getDialogWrapper().isModalProgress()) {
frame = frame.getOwner();
}
}
if (frame == null && project == null) {
frame = (Window)WelcomeFrame.getInstance();
}
return frame;
}
@@ -434,11 +434,11 @@ public class NotificationsManagerImpl extends NotificationsManager {
}
if (!defaultButton.isNull()) {
content.addPropertyChangeListener("ancestor", new PropertyChangeListener() {
UIUtil.addParentChangeListener(content, new PropertyChangeListener() {
@Override
public void propertyChange(PropertyChangeEvent event) {
if (event.getOldValue() == null && event.getNewValue() != null) {
content.removePropertyChangeListener("ancestor", this);
UIUtil.removeParentChangeListener(content, this);
JRootPane rootPane = UIUtil.getRootPane(content);
if (rootPane != null) {
rootPane.setDefaultButton(defaultButton.get());
@@ -462,7 +462,10 @@ public class NotificationsManagerImpl extends NotificationsManager {
final BalloonLayoutData layoutData = new BalloonLayoutData();
layoutDataRef.set(layoutData);
final Color foreground = new JBColor(Gray._0, Gray._191);
Color foregroundR = Gray._0;
Color foregroundD = Gray._191;
final Color foreground = new JBColor(foregroundR, foregroundD);
final JBColor fillColor = new JBColor(Gray._242, new Color(78, 80, 82));
final JEditorPane text = new JEditorPane() {
@@ -490,7 +493,11 @@ public class NotificationsManagerImpl extends NotificationsManager {
int prefSize = new JLabel(NotificationsUtil.buildHtml(notification, null, true, null, fontStyle)).getPreferredSize().width;
String style = prefSize > BalloonLayoutConfiguration.MaxWidth ? BalloonLayoutConfiguration.MaxWidthStyle : null;
text.setText(NotificationsUtil.buildHtml(notification, style, true, foreground, fontStyle));
String textR = NotificationsUtil.buildHtml(notification, style, true, foregroundR, fontStyle);
String textD = NotificationsUtil.buildHtml(notification, style, true, foregroundD, fontStyle);
LafHandler lafHandler = new LafHandler(text, textR, textD);
layoutData.lafHandler = lafHandler;
text.setEditable(false);
text.setOpaque(false);
@@ -639,9 +646,11 @@ public class NotificationsManagerImpl extends NotificationsManager {
content.add(centerPanel, BorderLayout.CENTER);
if (notification.isTitle()) {
String titleValue = NotificationsUtil
.buildHtml(notification, StringUtil.defaultIfEmpty(fontStyle, "") + "white-space:nowrap;", false, foreground, null);
JLabel title = new JLabel(titleValue);
String titleStyle = StringUtil.defaultIfEmpty(fontStyle, "") + "white-space:nowrap;";
String titleR = NotificationsUtil.buildHtml(notification, titleStyle, false, foregroundR, null);
String titleD = NotificationsUtil.buildHtml(notification, titleStyle, false, foregroundD, null);
JLabel title = new JLabel();
lafHandler.setTitle(title, titleR, titleD);
title.setOpaque(false);
if (UIUtil.isUnderNimbusLookAndFeel()) {
title.setBackground(UIUtil.TRANSPARENT_COLOR);
@@ -1049,4 +1058,44 @@ public class NotificationsManagerImpl extends NotificationsManager {
}
}
}
private static class LafHandler implements Runnable {
private final JEditorPane myContent;
private final String myContentTextR;
private final String myContentTextD;
private JLabel myTitle;
private String myTitleTextR;
private String myTitleTextD;
public LafHandler(@NotNull JEditorPane content, @NotNull String textR, @NotNull String textD) {
myContent = content;
myContentTextR = textR;
myContentTextD = textD;
updateContent();
}
public void setTitle(@NotNull JLabel title, @NotNull String textR, @NotNull String textD) {
myTitle = title;
myTitleTextR = textR;
myTitleTextD = textD;
updateTitle();
}
private void updateTitle() {
myTitle.setText(UIUtil.isUnderDarcula() ? myTitleTextD : myTitleTextR);
}
private void updateContent() {
myContent.setText(UIUtil.isUnderDarcula() ? myContentTextD : myContentTextR);
}
@Override
public void run() {
if (myTitle != null) {
updateTitle();
}
updateContent();
}
}
}
@@ -108,7 +108,8 @@ public class NotificationsUtil {
result.append("<b").append(titleColor == null ? ">" : " color=\"" + titleColor + "\">").append(title).append("</b>");
}
if (!StringUtil.isEmpty(subtitle)) {
result.append("&nbsp;").append(subtitle);
result.append("&nbsp;").append(titleColor == null ? "" : "<span color=\"" + titleColor + "\">").append(subtitle)
.append(titleColor == null ? "" : "</span>");
}
if (!StringUtil.isEmpty(content)) {
result.append("<p").append(contentStyle == null ? "" : " style=\"" + contentStyle + "\"")
@@ -996,8 +996,9 @@ public class BalloonImpl implements Balloon, IdeTooltip.Ui {
getUpdatedBounds(balloon.myLayeredPane.getSize(), balloon.myForcedBounds, balloon.myComp.getPreferredSize(), balloon.myShowPointer,
balloon.myTargetPoint, balloon.myContainerInsets);
final Point point = getShiftedPoint(bounds.getLocation(), balloon.getShadowBorderInsets());
bounds.setLocation(point);
if (balloon.myShadowBorderProvider == null) {
bounds.setLocation(getShiftedPoint(bounds.getLocation(), balloon.getShadowBorderInsets()));
}
balloon.myComp._setBounds(bounds);
}
@@ -36,4 +36,6 @@ public class BalloonLayoutData {
public Project project;
public BalloonLayoutConfiguration configuration;
public Runnable lafHandler;
}
@@ -15,6 +15,8 @@
*/
package com.intellij.ui;
import com.intellij.ide.ui.LafManager;
import com.intellij.ide.ui.LafManagerListener;
import com.intellij.openapi.Disposable;
import com.intellij.openapi.ui.popup.Balloon;
import com.intellij.openapi.util.Disposer;
@@ -29,6 +31,8 @@ import javax.swing.*;
import java.awt.*;
import java.awt.event.ComponentAdapter;
import java.awt.event.ComponentEvent;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
@@ -66,6 +70,8 @@ public class BalloonLayoutImpl implements BalloonLayout {
}
};
private LafManagerListener myLafListener;
public BalloonLayoutImpl(@NotNull JRootPane parent, @NotNull Insets insets) {
myParent = parent;
myLayeredPane = parent.getLayeredPane();
@@ -76,6 +82,15 @@ public class BalloonLayoutImpl implements BalloonLayout {
queueRelayout();
}
});
UIUtil.addParentChangeListener(parent, new PropertyChangeListener() {
@Override
public void propertyChange(PropertyChangeEvent event) {
if (event.getOldValue() != null && event.getNewValue() == null && myLafListener != null) {
LafManager.getInstance().removeLafManagerListener(myLafListener);
myLafListener = null;
}
}
});
}
@Override
@@ -99,6 +114,20 @@ public class BalloonLayoutImpl implements BalloonLayout {
}
});
if (myLafListener == null && layoutData != null) {
myLafListener = new LafManagerListener() {
@Override
public void lookAndFeelChanged(LafManager source) {
for (BalloonLayoutData layoutData : myLayoutData.values()) {
if (layoutData.lafHandler != null) {
layoutData.lafHandler.run();
}
}
}
};
LafManager.getInstance().addLafManagerListener(myLafListener);
}
calculateSize();
relayout();
balloon.show(myLayeredPane);
@@ -198,14 +227,8 @@ public class BalloonLayoutImpl implements BalloonLayout {
int eachY = toolbarsOffset;
int columnSize = eachColumn.size();
if (columnSize > 0) {
BalloonImpl balloon = (BalloonImpl)eachColumn.get(0);
if (balloon.hasShadow()) {
eachY -= balloon.getShadowBorderInsets().top;
}
else {
eachY += 4;
}
if (columnSize > 0 && !((BalloonImpl)eachColumn.get(0)).hasShadow()) {
eachY += 4;
}
eachColumnX -= eachWidth.intValue();
@@ -249,7 +272,8 @@ public class BalloonLayoutImpl implements BalloonLayout {
}
else if (hasShadow) {
eachY += space - shadow.top;
} else {
}
else {
eachY += space - next.getShadowBorderInsets().bottom;
}
}
@@ -1947,6 +1947,14 @@ public class UIUtil {
});
}
public static void addParentChangeListener(@NotNull Component component, @NotNull PropertyChangeListener listener) {
component.addPropertyChangeListener("ancestor", listener);
}
public static void removeParentChangeListener(@NotNull Component component, @NotNull PropertyChangeListener listener) {
component.removePropertyChangeListener("ancestor", listener);
}
public static void drawVDottedLine(Graphics2D g, int lineX, int startY, int endY, @Nullable final Color bgColor, final Color fgColor) {
if (bgColor != null) {
g.setColor(bgColor);