mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
tooltips: timing and sizing fixes
This commit is contained in:
@@ -38,6 +38,9 @@ public interface Balloon extends Disposable {
|
||||
|
||||
void hide();
|
||||
|
||||
boolean wasFadedIn();
|
||||
boolean wasFadedOut();
|
||||
|
||||
enum Position {
|
||||
below, above, atLeft, atRight
|
||||
}
|
||||
|
||||
@@ -20,7 +20,6 @@ import com.intellij.openapi.components.ApplicationComponent;
|
||||
import com.intellij.openapi.ui.popup.Balloon;
|
||||
import com.intellij.openapi.ui.popup.BalloonBuilder;
|
||||
import com.intellij.openapi.ui.popup.JBPopupFactory;
|
||||
import com.intellij.openapi.util.SystemInfo;
|
||||
import com.intellij.openapi.util.registry.Registry;
|
||||
import com.intellij.openapi.util.registry.RegistryValue;
|
||||
import com.intellij.openapi.util.registry.RegistryValueListener;
|
||||
@@ -52,6 +51,7 @@ public class IdeTooltipManager implements ApplicationComponent, AWTEventListener
|
||||
|
||||
private int myX;
|
||||
private int myY;
|
||||
private RegistryValue myMode;
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
@@ -65,6 +65,8 @@ public class IdeTooltipManager implements ApplicationComponent, AWTEventListener
|
||||
|
||||
@Override
|
||||
public void initComponent() {
|
||||
myMode = Registry.get("ide.tooltip.mode");
|
||||
|
||||
myIsEnabled = Registry.get("ide.tooltip.callout");
|
||||
myIsEnabled.addListener(new RegistryValueListener.Adapter() {
|
||||
@Override
|
||||
@@ -98,8 +100,12 @@ public class IdeTooltipManager implements ApplicationComponent, AWTEventListener
|
||||
}
|
||||
} else if (me.getID() == MouseEvent.MOUSE_MOVED) {
|
||||
if (me.getComponent() == myCurrentComponent) {
|
||||
myX = me.getX();
|
||||
myY = me.getY();
|
||||
if (myCurrentTip != null && myCurrentTip.wasFadedIn()) {
|
||||
hideCurrent();
|
||||
} else {
|
||||
myX = me.getX();
|
||||
myY = me.getY();
|
||||
}
|
||||
} else if (myCurrentComponent == null) {
|
||||
maybeShowFor(c, me);
|
||||
}
|
||||
@@ -137,7 +143,7 @@ public class IdeTooltipManager implements ApplicationComponent, AWTEventListener
|
||||
public void run() {
|
||||
show(c, e, tooltipText, toCenter);
|
||||
}
|
||||
}, myShowDelay ? 1200 : 750);
|
||||
}, myShowDelay ? 1500 : 900);
|
||||
}
|
||||
|
||||
private void show(Component c, MouseEvent e, String tooltipText, boolean toCenter) {
|
||||
@@ -145,7 +151,17 @@ public class IdeTooltipManager implements ApplicationComponent, AWTEventListener
|
||||
|
||||
myTipLabel.setText(tooltipText);
|
||||
|
||||
boolean useSystem = Registry.is("ide.tooltip.useSystemColors") || (!UIUtil.isUnderAquaLookAndFeel());
|
||||
boolean useSystem;
|
||||
|
||||
if ("default".equalsIgnoreCase(myMode.asString())) {
|
||||
useSystem = false;
|
||||
} else if ("system".equalsIgnoreCase(myMode.asString())) {
|
||||
useSystem = true;
|
||||
} else if ("graphite".equalsIgnoreCase(myMode.asString())) {
|
||||
useSystem = false;
|
||||
} else {
|
||||
useSystem = false;
|
||||
}
|
||||
|
||||
Color bg = useSystem ? UIManager.getColor("ToolTip.background") : new Color(100, 100, 100, 230);
|
||||
Color fg = useSystem ? UIManager.getColor("ToolTip.foreground") : Color.white;
|
||||
|
||||
@@ -122,6 +122,9 @@ public class BalloonImpl implements Disposable, Balloon, LightweightWindow, Posi
|
||||
private PositionTracker<Balloon> myTracker;
|
||||
private int myAnimationCycle = 500;
|
||||
|
||||
private boolean myFadedIn;
|
||||
private boolean myFadedOut;
|
||||
|
||||
private boolean isInsideBalloon(MouseEvent me) {
|
||||
if (!me.getComponent().isShowing()) return true;
|
||||
if (SwingUtilities.isDescendingFrom(me.getComponent(), myComp) || me.getComponent() == myComp) return true;
|
||||
@@ -261,7 +264,7 @@ public class BalloonImpl implements Disposable, Balloon, LightweightWindow, Posi
|
||||
if (myShowPointer) {
|
||||
Rectangle rec = getRecForPosition(myPosition, true);
|
||||
|
||||
if (!myPosition.isOkToHavePointer(myTargetPoint, rec, getPointerLength(), getPointerWidth(), getArc(), getNormalInset())) {
|
||||
if (!myPosition.isOkToHavePointer(myTargetPoint, rec, getPointerLength(myPosition), getPointerWidth(myPosition), getArc(), getNormalInset())) {
|
||||
rec = getRecForPosition(myPosition, false);
|
||||
|
||||
Rectangle lp = new Rectangle(new Point(myContainerInsets.left, myContainerInsets.top), myLayeredPane.getSize());
|
||||
@@ -294,7 +297,7 @@ public class BalloonImpl implements Disposable, Balloon, LightweightWindow, Posi
|
||||
|
||||
Rectangle rec = myComp.getBounds();
|
||||
|
||||
if (myShowPointer && !myPosition.isOkToHavePointer(myTargetPoint, rec, getPointerLength(), getPointerWidth(), getArc(), getNormalInset())) {
|
||||
if (myShowPointer && !myPosition.isOkToHavePointer(myTargetPoint, rec, getPointerLength(myPosition), getPointerWidth(myPosition), getArc(), getNormalInset())) {
|
||||
myShowPointer = false;
|
||||
myComp.removeAll();
|
||||
myLayeredPane.remove(myComp);
|
||||
@@ -404,6 +407,8 @@ public class BalloonImpl implements Disposable, Balloon, LightweightWindow, Posi
|
||||
myComp.clear();
|
||||
myComp.repaint();
|
||||
|
||||
myFadedIn = true;
|
||||
|
||||
startFadeoutTimer();
|
||||
}
|
||||
else {
|
||||
@@ -441,20 +446,16 @@ public class BalloonImpl implements Disposable, Balloon, LightweightWindow, Posi
|
||||
return 3;
|
||||
}
|
||||
|
||||
int getPointerWidth() {
|
||||
return 11;
|
||||
int getPointerWidth(Position position) {
|
||||
return position.isTopBottomPointer() ? 14 : 11;
|
||||
}
|
||||
|
||||
int getNormalInset() {
|
||||
return 3;
|
||||
}
|
||||
|
||||
int getShadowShift() {
|
||||
return 10;
|
||||
}
|
||||
|
||||
int getPointerLength() {
|
||||
return 8;
|
||||
int getPointerLength(Position position) {
|
||||
return position.isTopBottomPointer() ? 10 : 8;
|
||||
}
|
||||
|
||||
public void hide() {
|
||||
@@ -464,6 +465,8 @@ public class BalloonImpl implements Disposable, Balloon, LightweightWindow, Posi
|
||||
for (JBPopupListener each : myListeners) {
|
||||
each.onClosed(new LightweightWindowEvent(this));
|
||||
}
|
||||
|
||||
myFadedOut = true;
|
||||
}
|
||||
|
||||
public void addListener(JBPopupListener listener) {
|
||||
@@ -651,7 +654,7 @@ public class BalloonImpl implements Disposable, Balloon, LightweightWindow, Posi
|
||||
}
|
||||
|
||||
EmptyBorder createBorder(final BalloonImpl balloon) {
|
||||
return new EmptyBorder(balloon.getPointerLength() + balloon.getNormalInset(), balloon.getNormalInset(), balloon.getNormalInset(), balloon.getNormalInset());
|
||||
return new EmptyBorder(balloon.getPointerLength(this) + balloon.getNormalInset(), balloon.getNormalInset(), balloon.getNormalInset(), balloon.getNormalInset());
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -665,23 +668,23 @@ public class BalloonImpl implements Disposable, Balloon, LightweightWindow, Posi
|
||||
}
|
||||
|
||||
protected void convertBoundsToContent(final Rectangle bounds, final BalloonImpl balloon) {
|
||||
bounds.y += balloon.getPointerLength();
|
||||
bounds.height -= balloon.getPointerLength() - 1;
|
||||
bounds.y += balloon.getPointerLength(this);
|
||||
bounds.height -= balloon.getPointerLength(this) - 1;
|
||||
}
|
||||
|
||||
protected Shape getPointingShape(final Rectangle bounds, final Graphics2D g, final Point pointTarget, final BalloonImpl balloon) {
|
||||
final Shaper shaper = new Shaper(balloon, bounds, pointTarget, SwingUtilities.TOP);
|
||||
shaper.line(balloon.getPointerWidth() / 2, balloon.getPointerLength()).toRightCurve().roundRightDown().toBottomCurve().roundLeftDown()
|
||||
shaper.line(balloon.getPointerWidth(this) / 2, balloon.getPointerLength(this)).toRightCurve().roundRightDown().toBottomCurve().roundLeftDown()
|
||||
.toLeftCurve().roundLeftUp().toTopCurve().roundUpRight()
|
||||
.lineTo(pointTarget.x - balloon.getPointerWidth() / 2, shaper.getCurrent().y).lineTo(pointTarget.x, pointTarget.y);
|
||||
.lineTo(pointTarget.x - balloon.getPointerWidth(this) / 2, shaper.getCurrent().y).lineTo(pointTarget.x, pointTarget.y);
|
||||
shaper.close();
|
||||
|
||||
return shaper.getShape();
|
||||
}
|
||||
|
||||
protected Shape getShape(final Rectangle bounds, final Graphics2D g, final Point pointTarget, final BalloonImpl balloon) {
|
||||
bounds.y += balloon.getPointerLength();
|
||||
bounds.height += balloon.getPointerLength();
|
||||
bounds.y += balloon.getPointerLength(this);
|
||||
bounds.height += balloon.getPointerLength(this);
|
||||
return new RoundRectangle2D.Double(bounds.x, bounds.y, bounds.width, bounds.height, balloon.getArc(), balloon.getArc());
|
||||
}
|
||||
|
||||
@@ -702,7 +705,7 @@ public class BalloonImpl implements Disposable, Balloon, LightweightWindow, Posi
|
||||
EmptyBorder createBorder(final BalloonImpl balloon) {
|
||||
return new EmptyBorder(balloon.getNormalInset(),
|
||||
balloon.getNormalInset(),
|
||||
balloon.getPointerLength(),
|
||||
balloon.getPointerLength(this),
|
||||
balloon.getNormalInset());
|
||||
}
|
||||
|
||||
@@ -717,21 +720,21 @@ public class BalloonImpl implements Disposable, Balloon, LightweightWindow, Posi
|
||||
}
|
||||
|
||||
protected void convertBoundsToContent(final Rectangle bounds, final BalloonImpl balloon) {
|
||||
bounds.height -= balloon.getPointerLength() - 1;
|
||||
bounds.height -= balloon.getPointerLength(this) - 1;
|
||||
}
|
||||
|
||||
protected Shape getShape(final Rectangle bounds, final Graphics2D g, final Point pointTarget, final BalloonImpl balloon) {
|
||||
bounds.y -= balloon.getPointerLength();
|
||||
bounds.height -= balloon.getPointerLength();
|
||||
bounds.y -= balloon.getPointerLength(this);
|
||||
bounds.height -= balloon.getPointerLength(this);
|
||||
return new RoundRectangle2D.Double(bounds.x, bounds.y, bounds.width, bounds.height, balloon.getArc(), balloon.getArc());
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Shape getPointingShape(final Rectangle bounds, final Graphics2D g, final Point pointTarget, final BalloonImpl balloon) {
|
||||
final Shaper shaper = new Shaper(balloon, bounds, pointTarget, SwingUtilities.BOTTOM);
|
||||
shaper.line(-balloon.getPointerWidth() / 2, -balloon.getPointerLength() + 1);
|
||||
shaper.line(-balloon.getPointerWidth(this) / 2, -balloon.getPointerLength(this) + 1);
|
||||
shaper.toLeftCurve().roundLeftUp().toTopCurve().roundUpRight().toRightCurve().roundRightDown().toBottomCurve().line(0, 2)
|
||||
.roundLeftDown().lineTo(pointTarget.x + balloon.getPointerWidth() / 2, shaper.getCurrent().y).lineTo(pointTarget.x, pointTarget.y)
|
||||
.roundLeftDown().lineTo(pointTarget.x + balloon.getPointerWidth(this) / 2, shaper.getCurrent().y).lineTo(pointTarget.x, pointTarget.y)
|
||||
.close();
|
||||
|
||||
|
||||
@@ -752,7 +755,7 @@ public class BalloonImpl implements Disposable, Balloon, LightweightWindow, Posi
|
||||
}
|
||||
|
||||
EmptyBorder createBorder(final BalloonImpl balloon) {
|
||||
return new EmptyBorder(balloon.getNormalInset(), balloon.getPointerLength() + balloon.getNormalInset(), balloon.getNormalInset(), balloon.getNormalInset());
|
||||
return new EmptyBorder(balloon.getNormalInset(), balloon.getPointerLength(this) + balloon.getNormalInset(), balloon.getNormalInset(), balloon.getNormalInset());
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -768,21 +771,21 @@ public class BalloonImpl implements Disposable, Balloon, LightweightWindow, Posi
|
||||
@Override
|
||||
protected Shape getPointingShape(final Rectangle bounds, final Graphics2D g, final Point pointTarget, final BalloonImpl balloon) {
|
||||
final Shaper shaper = new Shaper(balloon, bounds, pointTarget, SwingUtilities.LEFT);
|
||||
shaper.line(balloon.getPointerLength(), -balloon.getPointerWidth() / 2).toTopCurve().roundUpRight().toRightCurve().roundRightDown()
|
||||
shaper.line(balloon.getPointerLength(this), -balloon.getPointerWidth(this) / 2).toTopCurve().roundUpRight().toRightCurve().roundRightDown()
|
||||
.toBottomCurve().roundLeftDown().toLeftCurve().roundLeftUp()
|
||||
.lineTo(shaper.getCurrent().x, pointTarget.y + balloon.getPointerWidth() / 2).lineTo(pointTarget.x, pointTarget.y).close();
|
||||
.lineTo(shaper.getCurrent().x, pointTarget.y + balloon.getPointerWidth(this) / 2).lineTo(pointTarget.x, pointTarget.y).close();
|
||||
|
||||
return shaper.getShape();
|
||||
}
|
||||
|
||||
protected void convertBoundsToContent(final Rectangle bounds, final BalloonImpl balloon) {
|
||||
bounds.x += balloon.getPointerLength();
|
||||
bounds.width -= balloon.getPointerLength();
|
||||
bounds.x += balloon.getPointerLength(this);
|
||||
bounds.width -= balloon.getPointerLength(this);
|
||||
}
|
||||
|
||||
protected Shape getShape(final Rectangle bounds, final Graphics2D g, final Point pointTarget, final BalloonImpl balloon) {
|
||||
bounds.x += balloon.getPointerLength();
|
||||
bounds.width -= balloon.getPointerLength();
|
||||
bounds.x += balloon.getPointerLength(this);
|
||||
bounds.width -= balloon.getPointerLength(this);
|
||||
return new RoundRectangle2D.Double(bounds.x, bounds.y, bounds.width, bounds.height, balloon.getArc(), balloon.getArc());
|
||||
}
|
||||
}
|
||||
@@ -800,7 +803,7 @@ public class BalloonImpl implements Disposable, Balloon, LightweightWindow, Posi
|
||||
}
|
||||
|
||||
EmptyBorder createBorder(final BalloonImpl balloon) {
|
||||
return new EmptyBorder(balloon.getNormalInset(), balloon.getNormalInset(), balloon.getNormalInset(), balloon.getPointerLength() + balloon.getNormalInset());
|
||||
return new EmptyBorder(balloon.getNormalInset(), balloon.getNormalInset(), balloon.getNormalInset(), balloon.getPointerLength(this) + balloon.getNormalInset());
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -814,20 +817,20 @@ public class BalloonImpl implements Disposable, Balloon, LightweightWindow, Posi
|
||||
}
|
||||
|
||||
protected void convertBoundsToContent(final Rectangle bounds, final BalloonImpl balloon) {
|
||||
bounds.width -= balloon.getPointerLength();
|
||||
bounds.width -= balloon.getPointerLength(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Shape getPointingShape(final Rectangle bounds, final Graphics2D g, final Point pointTarget, final BalloonImpl balloon) {
|
||||
final Shaper shaper = new Shaper(balloon, bounds, pointTarget, SwingUtilities.RIGHT);
|
||||
shaper.line(-balloon.getPointerLength(), balloon.getPointerWidth() / 2);
|
||||
shaper.line(-balloon.getPointerLength(this), balloon.getPointerWidth(this) / 2);
|
||||
shaper.toBottomCurve().roundLeftDown().toLeftCurve().roundLeftUp().toTopCurve().roundUpRight().toRightCurve().roundRightDown()
|
||||
.lineTo(shaper.getCurrent().x, pointTarget.y - balloon.getPointerWidth() / 2).lineTo(pointTarget.x, pointTarget.y).close();
|
||||
.lineTo(shaper.getCurrent().x, pointTarget.y - balloon.getPointerWidth(this) / 2).lineTo(pointTarget.x, pointTarget.y).close();
|
||||
return shaper.getShape();
|
||||
}
|
||||
|
||||
protected Shape getShape(final Rectangle bounds, final Graphics2D g, final Point pointTarget, final BalloonImpl balloon) {
|
||||
bounds.width -= balloon.getPointerLength();
|
||||
bounds.width -= balloon.getPointerLength(this);
|
||||
return new RoundRectangle2D.Double(bounds.x, bounds.y, bounds.width, bounds.height, balloon.getArc(), balloon.getArc());
|
||||
}
|
||||
}
|
||||
@@ -964,7 +967,7 @@ public class BalloonImpl implements Disposable, Balloon, LightweightWindow, Posi
|
||||
|
||||
if (isVisible() && myCloseRec.isVisible()) {
|
||||
Rectangle lpBounds = SwingUtilities.convertRectangle(getParent(), bounds, myLayeredPane);
|
||||
lpBounds = myPosition.getPointlessContentRec(lpBounds, myBalloon.getPointerLength());
|
||||
lpBounds = myPosition.getPointlessContentRec(lpBounds, myBalloon.getPointerLength(myPosition));
|
||||
|
||||
int iconWidth = myBalloon.myCloseButton.getIconWidth();
|
||||
int iconHeight = myBalloon.myCloseButton.getIconHeight();
|
||||
@@ -1039,7 +1042,7 @@ public class BalloonImpl implements Disposable, Balloon, LightweightWindow, Posi
|
||||
|
||||
|
||||
private int getTargetDelta(int effectiveSide) {
|
||||
return effectiveSide == myTargetSide ? myBalloon.getPointerLength() : 0;
|
||||
return effectiveSide == myTargetSide ? myBalloon.getPointerLength(myBalloon.myPosition) : 0;
|
||||
}
|
||||
|
||||
public Shaper toRightCurve() {
|
||||
@@ -1131,4 +1134,13 @@ public class BalloonImpl implements Disposable, Balloon, LightweightWindow, Posi
|
||||
frame.show();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean wasFadedIn() {
|
||||
return myFadedIn;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean wasFadedOut() {
|
||||
return myFadedOut;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -60,7 +60,8 @@ ide.tree.uiLockAttempt=250
|
||||
ide.splitter.mouseZone=6
|
||||
|
||||
ide.tooltip.callout=true
|
||||
ide.tooltip.useSystemColors=false
|
||||
ide.tooltip.mode=default
|
||||
ide.tooltip.description=Available options are: default,system,graphite
|
||||
|
||||
ide.tabbedPane.bufferedPaint=true
|
||||
|
||||
|
||||
Reference in New Issue
Block a user