IDEA-65266 Pressing Ctrl+P hid text under cursor + other hint fixes

This commit is contained in:
Kirill Kalishev
2011-02-17 20:37:38 +03:00
parent 4e45f7dd08
commit 74a71a2b44
7 changed files with 110 additions and 91 deletions
@@ -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;
}
}
}
@@ -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));
@@ -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() {
@@ -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<Balloon> 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<Balloon>(target), position);
}
private void show(PositionTracker<Balloon> tracker, Position position) {
private void show(PositionTracker<Balloon> 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<Position> getOtherPositions() {
HashSet<Position> all = new HashSet<Position>();
public Set<AbstractPosition> getOtherPositions() {
HashSet<AbstractPosition> all = new HashSet<AbstractPosition>();
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;
}
@@ -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));
}
}
@@ -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() {
@@ -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;
}