diff --git a/platform/lang-impl/src/com/intellij/codeInsight/hint/ParameterInfoComponent.java b/platform/lang-impl/src/com/intellij/codeInsight/hint/ParameterInfoComponent.java index f747e3e324d2..fd82f3913f66 100644 --- a/platform/lang-impl/src/com/intellij/codeInsight/hint/ParameterInfoComponent.java +++ b/platform/lang-impl/src/com/intellij/codeInsight/hint/ParameterInfoComponent.java @@ -67,7 +67,6 @@ class ParameterInfoComponent extends JPanel{ myObjects = objects; setLayout(new GridBagLayout()); - setBorder(BorderFactory.createCompoundBorder(LineBorder.createGrayLineBorder(), BorderFactory.createEmptyBorder(0, 5, 0, 5))); setBackground(BACKGROUND_COLOR); myHandler = handler; @@ -314,7 +313,11 @@ class ParameterInfoComponent extends JPanel{ Dimension normalPreferredSize = super.getPreferredSize(); // some fonts (for example, Arial Black Cursiva) have NORMAL characters wider than BOLD characters - return new Dimension(Math.max(boldPreferredSize.width, normalPreferredSize.width), Math.max(boldPreferredSize.height, normalPreferredSize.height)); + Dimension d = new Dimension(Math.max(boldPreferredSize.width, normalPreferredSize.width), + Math.max(boldPreferredSize.height, normalPreferredSize.height)); + + System.out.println("d = " + d); + return d; } } } diff --git a/platform/platform-impl/src/com/intellij/ide/IdeTooltipManager.java b/platform/platform-impl/src/com/intellij/ide/IdeTooltipManager.java index 7d4d43dd76c1..4de43e5babbb 100644 --- a/platform/platform-impl/src/com/intellij/ide/IdeTooltipManager.java +++ b/platform/platform-impl/src/com/intellij/ide/IdeTooltipManager.java @@ -472,7 +472,8 @@ public class IdeTooltipManager implements ApplicationComponent, AWTEventListener if (prefSizeOriginal.width > fitWidth) { setSize(new Dimension(fitWidth, Integer.MAX_VALUE)); Dimension fixedWidthSize = super.getPreferredSize(); - prefSize.set(new Dimension(fitWidth, fixedWidthSize.height)); + Dimension minSize = super.getMinimumSize(); + prefSize.set(new Dimension(fitWidth > minSize.width ? fitWidth : minSize.width, fixedWidthSize.height)); } else { prefSize.set(new Dimension(prefSizeOriginal)); diff --git a/platform/platform-impl/src/com/intellij/openapi/progress/util/ProgressWindow.java b/platform/platform-impl/src/com/intellij/openapi/progress/util/ProgressWindow.java index d2a297431da3..c055dd7739a8 100644 --- a/platform/platform-impl/src/com/intellij/openapi/progress/util/ProgressWindow.java +++ b/platform/platform-impl/src/com/intellij/openapi/progress/util/ProgressWindow.java @@ -678,7 +678,7 @@ public class ProgressWindow extends BlockingProgressIndicator implements Disposa protected void init() { super.init(); setUndecorated(true); - myPanel.setBorder(PopupBorder.Factory.create(true)); + myPanel.setBorder(PopupBorder.Factory.create(true, true)); } protected boolean isProgressDialog() { diff --git a/platform/platform-impl/src/com/intellij/ui/BalloonImpl.java b/platform/platform-impl/src/com/intellij/ui/BalloonImpl.java index 92373029be56..0241f7886fcd 100644 --- a/platform/platform-impl/src/com/intellij/ui/BalloonImpl.java +++ b/platform/platform-impl/src/com/intellij/ui/BalloonImpl.java @@ -78,7 +78,7 @@ public class BalloonImpl implements Disposable, Balloon, LightweightWindow, Posi private MyComponent myComp; private JLayeredPane myLayeredPane; - private Position myPosition; + private AbstractPosition myPosition; private Point myTargetPoint; private final boolean myHideOnFrameResize; @@ -226,7 +226,13 @@ public class BalloonImpl implements Disposable, Balloon, LightweightWindow, Posi } public void show(final RelativePoint target, final Balloon.Position position) { - Position pos = BELOW; + AbstractPosition pos = getAbstractPositionFor(position); + + show(target, pos); + } + + private static AbstractPosition getAbstractPositionFor(Position position) { + AbstractPosition pos = BELOW; switch (position) { case atLeft: pos = AT_LEFT; @@ -241,12 +247,11 @@ public class BalloonImpl implements Disposable, Balloon, LightweightWindow, Posi pos = ABOVE; break; } - - show(target, pos); + return pos; } public void show(PositionTracker tracker, Balloon.Position position) { - Position pos = BELOW; + AbstractPosition pos = BELOW; switch (position) { case atLeft: pos = AT_LEFT; @@ -266,11 +271,11 @@ public class BalloonImpl implements Disposable, Balloon, LightweightWindow, Posi } - private void show(RelativePoint target, Position position) { + private void show(RelativePoint target, AbstractPosition position) { show(new PositionTracker.Static(target), position); } - private void show(PositionTracker tracker, Position position) { + private void show(PositionTracker tracker, AbstractPosition position) { assert !myDisposed : "Balloon is already disposed"; if (isVisible()) return; @@ -279,7 +284,7 @@ public class BalloonImpl implements Disposable, Balloon, LightweightWindow, Posi myTracker = tracker; myTracker.init(this); - Position originalPreferred = position; + AbstractPosition originalPreferred = position; JRootPane root = null; JDialog dialog = IJSwingUtilities.findParentOfType(tracker.getComponent(), JDialog.class); @@ -324,9 +329,9 @@ public class BalloonImpl implements Disposable, Balloon, LightweightWindow, Posi Rectangle2D currentSquare = lp.createIntersection(rec); double maxSquare = currentSquare.getWidth() * currentSquare.getHeight(); - Position targetPosition = myPosition; + AbstractPosition targetPosition = myPosition; - for (Position eachPosition : myPosition.getOtherPositions()) { + for (AbstractPosition eachPosition : myPosition.getOtherPositions()) { Rectangle2D eachIntersection = lp.createIntersection(getRecForPosition(eachPosition, false)); double eachSquare = eachIntersection.getWidth() * eachIntersection.getHeight(); if (maxSquare < eachSquare) { @@ -383,7 +388,7 @@ public class BalloonImpl implements Disposable, Balloon, LightweightWindow, Posi }, this); } - private Rectangle getRecForPosition(Position position, boolean adjust) { + private Rectangle getRecForPosition(AbstractPosition position, boolean adjust) { Dimension size = getContentSizeFor(position); Rectangle rec = new Rectangle(new Point(0, 0), size); @@ -398,7 +403,7 @@ public class BalloonImpl implements Disposable, Balloon, LightweightWindow, Posi return rec; } - private Dimension getContentSizeFor(Position position) { + private Dimension getContentSizeFor(AbstractPosition position) { Insets insets = position.createBorder(this).getBorderInsets(); if (insets == null) { insets = new Insets(0, 0, 0, 0); @@ -514,18 +519,23 @@ public class BalloonImpl implements Disposable, Balloon, LightweightWindow, Posi return 3; } - int getPointerWidth(Position position) { + int getPointerWidth(AbstractPosition position) { return position.isTopBottomPointer() ? 14 : 11; } - int getNormalInset() { + public static int getNormalInset() { return 3; } - int getPointerLength(Position position) { + static int getPointerLength(AbstractPosition position) { return position.isTopBottomPointer() ? 10 : 8; } + public static int getPointerLength(Position position) { + return getPointerLength((getAbstractPositionFor(position))); + } + + public void hide() { Disposer.dispose(this); @@ -596,14 +606,14 @@ public class BalloonImpl implements Disposable, Balloon, LightweightWindow, Posi } } - public abstract static class Position { + public abstract static class AbstractPosition { abstract EmptyBorder createBorder(final BalloonImpl balloon); abstract void setRecToRelativePosition(Rectangle rec, Point targetPoint); - abstract int getChangeShift(Position original, int xShift, int yShift); + abstract int getChangeShift(AbstractPosition original, int xShift, int yShift); public void updateBounds(final BalloonImpl balloon) { balloon.myComp._setBounds(getUpdatedBounds(balloon.myLayeredPane.getSize(), @@ -690,8 +700,8 @@ public class BalloonImpl implements Disposable, Balloon, LightweightWindow, Posi protected abstract Rectangle getPointlessContentRec(Rectangle bounds, int pointerLength); - public Set getOtherPositions() { - HashSet all = new HashSet(); + public Set getOtherPositions() { + HashSet all = new HashSet(); all.add(BELOW); all.add(ABOVE); all.add(AT_RIGHT); @@ -705,13 +715,13 @@ public class BalloonImpl implements Disposable, Balloon, LightweightWindow, Posi public abstract Point getShiftedPoint(Point targetPoint, int shift); } - public static final Position BELOW = new Below(); - public static final Position ABOVE = new Above(); - public static final Position AT_RIGHT = new AtRight(); - public static final Position AT_LEFT = new AtLeft(); + public static final AbstractPosition BELOW = new Below(); + public static final AbstractPosition ABOVE = new Above(); + public static final AbstractPosition AT_RIGHT = new AtRight(); + public static final AbstractPosition AT_LEFT = new AtLeft(); - private static class Below extends Position { + private static class Below extends AbstractPosition { @Override @@ -720,7 +730,7 @@ public class BalloonImpl implements Disposable, Balloon, LightweightWindow, Posi } @Override - int getChangeShift(Position original, int xShift, int yShift) { + int getChangeShift(AbstractPosition original, int xShift, int yShift) { return original == ABOVE ? yShift : 0; } @@ -772,7 +782,7 @@ public class BalloonImpl implements Disposable, Balloon, LightweightWindow, Posi } - private static class Above extends Position { + private static class Above extends AbstractPosition { @Override public Point getShiftedPoint(Point targetPoint, int shift) { @@ -780,7 +790,7 @@ public class BalloonImpl implements Disposable, Balloon, LightweightWindow, Posi } @Override - int getChangeShift(Position original, int xShift, int yShift) { + int getChangeShift(AbstractPosition original, int xShift, int yShift) { return original == BELOW ? -yShift : 0; } @@ -834,7 +844,7 @@ public class BalloonImpl implements Disposable, Balloon, LightweightWindow, Posi } } - private static class AtRight extends Position { + private static class AtRight extends AbstractPosition { @Override public Point getShiftedPoint(Point targetPoint, int shift) { @@ -842,7 +852,7 @@ public class BalloonImpl implements Disposable, Balloon, LightweightWindow, Posi } @Override - int getChangeShift(Position original, int xShift, int yShift) { + int getChangeShift(AbstractPosition original, int xShift, int yShift) { return original == AT_LEFT ? xShift : 0; } @@ -892,7 +902,7 @@ public class BalloonImpl implements Disposable, Balloon, LightweightWindow, Posi } } - private static class AtLeft extends Position { + private static class AtLeft extends AbstractPosition { @Override public Point getShiftedPoint(Point targetPoint, int shift) { @@ -900,7 +910,7 @@ public class BalloonImpl implements Disposable, Balloon, LightweightWindow, Posi } @Override - int getChangeShift(Position original, int xShift, int yShift) { + int getChangeShift(AbstractPosition original, int xShift, int yShift) { return original == AT_RIGHT ? -xShift : 0; } diff --git a/platform/platform-impl/src/com/intellij/ui/LightweightHint.java b/platform/platform-impl/src/com/intellij/ui/LightweightHint.java index ee8865ba3a0e..900089dc08a2 100644 --- a/platform/platform-impl/src/com/intellij/ui/LightweightHint.java +++ b/platform/platform-impl/src/com/intellij/ui/LightweightHint.java @@ -20,14 +20,17 @@ import com.intellij.ide.IdeTooltip; import com.intellij.ide.IdeTooltipManager; import com.intellij.ide.TooltipEvent; import com.intellij.openapi.diagnostic.Logger; +import com.intellij.openapi.ui.popup.Balloon; import com.intellij.openapi.ui.popup.JBPopup; import com.intellij.openapi.ui.popup.JBPopupFactory; import com.intellij.openapi.util.UserDataHolderBase; import com.intellij.openapi.wm.ex.LayoutFocusTraversalPolicyExt; import com.intellij.ui.awt.RelativePoint; +import com.intellij.ui.components.panels.OpaquePanel; import org.jetbrains.annotations.NotNull; import javax.swing.*; +import javax.swing.border.LineBorder; import javax.swing.event.EventListenerList; import java.awt.*; import java.awt.event.ActionEvent; @@ -177,13 +180,26 @@ public class LightweightHint extends UserDataHolderBase implements Hint { } else { myIsRealPopup = true; - myPopup = JBPopupFactory.getInstance().createComponentPopupBuilder(myComponent, myFocusRequestor) + Point actualPoint = new Point(x, y); + JComponent actualComponent = new OpaquePanel(new BorderLayout()); + actualComponent.add(myComponent, BorderLayout.CENTER); + if (myHintHint.isAwtTooltip()) { + fixActualPoint(actualPoint); + + + int inset = BalloonImpl.getNormalInset(); + actualComponent.setBorder(new LineBorder(hintHint.getTextBackground(), inset)); + actualComponent.setBackground(hintHint.getTextBackground()); + actualComponent.validate(); + } + + myPopup = JBPopupFactory.getInstance().createComponentPopupBuilder(actualComponent, myFocusRequestor) .setRequestFocus(myFocusRequestor != null) .setResizable(myResizable) .setMovable(myTitle != null) .setTitle(myTitle) .setModalContext(false) - .setShowShadow(!myForceLightweightPopup && myForceShowAsPopup) + .setShowShadow(isRealPopup()) .setCancelKeyEnabled(false) .setCancelOnClickOutside(myCancelOnClickOutside) .setCancelOnOtherWindowOpen(myCancelOnOtherWindowOpen) @@ -191,7 +207,30 @@ public class LightweightHint extends UserDataHolderBase implements Hint { .createPopup(); beforeShow(); - myPopup.show(new RelativePoint(myParentComponent, new Point(x, y))); + myPopup.show(new RelativePoint(myParentComponent, new Point(actualPoint.x, actualPoint.y))); + } + } + + private void fixActualPoint(Point actualPoint) { + if (!myHintHint.isAwtTooltip()) return; + if (!myIsRealPopup) return; + + Dimension size = myComponent.getPreferredSize(); + Balloon.Position position = myHintHint.getPreferredPosition(); + int shift = BalloonImpl.getPointerLength(position); + switch (position) { + case below: + actualPoint.y += shift; + break; + case above: + actualPoint.y -= (shift + size.height); + break; + case atLeft: + actualPoint.x -= (shift + size.width); + break; + case atRight: + actualPoint.y += shift; + break; } } @@ -203,7 +242,17 @@ public class LightweightHint extends UserDataHolderBase implements Hint { if (hintHint.isAwtTooltip()) { Dimension size = component.getPreferredSize(); Dimension paneSize = pane.getSize(); - return size.width < paneSize.width && size.height < paneSize.height; + + Point target = desiredLocation.getPointOn(pane).getPoint(); + Balloon.Position pos = hintHint.getPreferredPosition(); + int pointer = BalloonImpl.getPointerLength(pos) + BalloonImpl.getNormalInset(); + if (pos == Balloon.Position.above || pos == Balloon.Position.below) { + boolean hieghtFit = target.y - size.height - pointer > 0 || target.y + size.height + pointer < paneSize.height; + return hieghtFit && size.width + pointer < paneSize.width; + } else { + boolean widthFit = target.x - size.width - pointer > 0 || target.x + size.width + pointer < paneSize.width; + return widthFit && size.height + pointer < paneSize.height; + } } else { final Rectangle lpRect = new Rectangle(pane.getLocationOnScreen().x, pane.getLocationOnScreen().y, pane.getWidth(), pane.getHeight()); Rectangle componentRect = new Rectangle(desiredLocation.getScreenPoint().x, @@ -296,7 +345,9 @@ public class LightweightHint extends UserDataHolderBase implements Hint { private void updateBounds(int x, int y, boolean updateLocation) { setSize(myComponent.getPreferredSize()); if (updateLocation) { - setLocation(new RelativePoint(myParentComponent, new Point(x, y))); + Point point = new Point(x, y); + fixActualPoint(point); + setLocation(new RelativePoint(myParentComponent, point)); } } diff --git a/platform/platform-impl/src/com/intellij/ui/popup/AbstractPopup.java b/platform/platform-impl/src/com/intellij/ui/popup/AbstractPopup.java index 87d293e51546..ad17e1a026f7 100644 --- a/platform/platform-impl/src/com/intellij/ui/popup/AbstractPopup.java +++ b/platform/platform-impl/src/com/intellij/ui/popup/AbstractPopup.java @@ -16,7 +16,6 @@ package com.intellij.ui.popup; import com.intellij.codeInsight.hint.HintUtil; -import com.intellij.ide.ui.UISettings; import com.intellij.openapi.Disposable; import com.intellij.openapi.actionSystem.DataContext; import com.intellij.openapi.actionSystem.JBAwtEventQueue; @@ -27,7 +26,6 @@ import com.intellij.openapi.diagnostic.Logger; import com.intellij.openapi.editor.Editor; import com.intellij.openapi.editor.ex.EditorEx; import com.intellij.openapi.project.Project; -import com.intellij.openapi.ui.impl.ShadowBorderPainter; import com.intellij.openapi.ui.popup.*; import com.intellij.openapi.util.*; import com.intellij.openapi.util.registry.Registry; @@ -50,17 +48,13 @@ import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import javax.swing.*; -import javax.swing.border.EmptyBorder; import java.awt.*; import java.awt.event.*; -import java.awt.image.BufferedImage; import java.util.ArrayList; import java.util.HashSet; import java.util.List; import java.util.Set; -import static com.intellij.openapi.ui.impl.ShadowBorderPainter.*; - public class AbstractPopup implements JBPopup { private static final Logger LOG = Logger.getInstance("#com.intellij.ui.popup.AbstractPopup"); @@ -196,7 +190,7 @@ public class AbstractPopup implements JBPopup { myProject = project; myComponent = component; - myPopupBorder = PopupBorder.Factory.create(true); + myPopupBorder = PopupBorder.Factory.create(true, showShadow); myShadowed = showShadow; myPaintShadow = showShadow && !SystemInfo.isMac && !movable && !resizable && Registry.is("ide.popup.dropShadow"); myContent = createContentPanel(resizable, myPopupBorder, isToDrawMacCorner() && resizable); @@ -301,7 +295,7 @@ public class AbstractPopup implements JBPopup { @NotNull protected MyContentPanel createContentPanel(final boolean resizable, PopupBorder border, boolean isToDrawMacCorner) { - return new MyContentPanel(resizable, border, isToDrawMacCorner, myPaintShadow); + return new MyContentPanel(resizable, border, isToDrawMacCorner); } public static boolean isToDrawMacCorner() { @@ -1030,40 +1024,15 @@ public class AbstractPopup implements JBPopup { public static class MyContentPanel extends JPanel { private final boolean myResizable; private final boolean myDrawMacCorner; - private final boolean myPaintShadow; public MyContentPanel(final boolean resizable, final PopupBorder border, boolean drawMacCorner) { - this(resizable, border, drawMacCorner, false); - } - - public MyContentPanel(final boolean resizable, final PopupBorder border, boolean drawMacCorner, boolean shadowed) { super(new BorderLayout()); myResizable = resizable; myDrawMacCorner = drawMacCorner; - myPaintShadow = shadowed && !UISettings.isRemoteDesktopConnected(); - if (myPaintShadow) { - setOpaque(false); - setBorder(new EmptyBorder(POPUP_TOP_SIZE, POPUP_SIDE_SIZE, POPUP_BOTTOM_SIZE, POPUP_SIDE_SIZE) { - @Override - public void paintBorder(Component c, Graphics g, int x, int y, int width, int height) { - border.paintBorder(c, g, - x + POPUP_SIDE_SIZE - 1, - y + POPUP_TOP_SIZE - 1, - width - 2 * POPUP_SIDE_SIZE + 2, - height - POPUP_TOP_SIZE - POPUP_BOTTOM_SIZE + 2); - } - }); - } - else { - setBorder(border); - } + setBorder(border); } public void paint(Graphics g) { - if (myPaintShadow) { - paintShadow(g); - } - super.paint(g); if (myResizable && myDrawMacCorner) { @@ -1073,21 +1042,6 @@ public class AbstractPopup implements JBPopup { this); } } - - private void paintShadow(final Graphics g) { - BufferedImage capture = null; - try { - final Point onScreen = getLocationOnScreen(); - capture = new Robot().createScreenCapture( - new Rectangle(onScreen.x, onScreen.y, getWidth() + 2 * POPUP_SIDE_SIZE, getHeight() + POPUP_TOP_SIZE + POPUP_BOTTOM_SIZE)); - final BufferedImage shadow = ShadowBorderPainter.createPopupShadow(this, getWidth(), getHeight()); - ((Graphics2D)capture.getGraphics()).drawImage(shadow, null, null); - } - catch (Exception e) { - LOG.info(e); - } - if (capture != null) g.drawImage(capture, 0, 0, null); - } } public boolean isCancelOnClickOutside() { diff --git a/platform/util/src/com/intellij/ui/PopupBorder.java b/platform/util/src/com/intellij/ui/PopupBorder.java index 1eff0a877522..675a7edb52a2 100644 --- a/platform/util/src/com/intellij/ui/PopupBorder.java +++ b/platform/util/src/com/intellij/ui/PopupBorder.java @@ -29,9 +29,9 @@ public interface PopupBorder extends Border { private Factory() { } - public static PopupBorder create(boolean active) { + public static PopupBorder create(boolean active, boolean windowWithShadow) { final BaseBorder border = - SystemInfo.isMac ? new BaseBorder() : new BaseBorder(true, CaptionPanel.getBorderColor(true), CaptionPanel.getBorderColor(false)); + SystemInfo.isMac && windowWithShadow ? new BaseBorder() : new BaseBorder(true, CaptionPanel.getBorderColor(true), CaptionPanel.getBorderColor(false)); border.setActive(active); return border; }