mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
Merge branch 'balloons'
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
|
||||
}
|
||||
|
||||
@@ -51,6 +51,7 @@ public class IdeTooltipManager implements ApplicationComponent, AWTEventListener
|
||||
|
||||
private int myX;
|
||||
private int myY;
|
||||
private RegistryValue myMode;
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
@@ -64,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
|
||||
@@ -97,8 +100,18 @@ 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);
|
||||
}
|
||||
} else if (me.getID() == MouseEvent.MOUSE_PRESSED) {
|
||||
if (me.getComponent() == myCurrentComponent) {
|
||||
hideCurrent();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -130,7 +143,7 @@ public class IdeTooltipManager implements ApplicationComponent, AWTEventListener
|
||||
public void run() {
|
||||
show(c, e, tooltipText, toCenter);
|
||||
}
|
||||
}, myShowDelay ? 750 : 250);
|
||||
}, myShowDelay ? 1500 : 900);
|
||||
}
|
||||
|
||||
private void show(Component c, MouseEvent e, String tooltipText, boolean toCenter) {
|
||||
@@ -138,15 +151,30 @@ public class IdeTooltipManager implements ApplicationComponent, AWTEventListener
|
||||
|
||||
myTipLabel.setText(tooltipText);
|
||||
|
||||
Color bg = new Color(100, 100, 100, 230);
|
||||
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;
|
||||
Color border = useSystem ? Color.darkGray : bg;
|
||||
|
||||
BalloonBuilder builder = myPopupFactory.createBalloonBuilder(myTipLabel)
|
||||
.setPreferredPosition(Balloon.Position.above)
|
||||
.setFillColor(bg)
|
||||
.setBorderColor(bg)
|
||||
.setBorderColor(border)
|
||||
.setAnimationCycle(150)
|
||||
.setShowCallout(true);
|
||||
myTipLabel.setForeground(Color.white);
|
||||
myTipLabel.setBorder(new EmptyBorder(0, 2, 0, 2));
|
||||
myTipLabel.setForeground(fg);
|
||||
myTipLabel.setBorder(new EmptyBorder(1, 3, 2, 3));
|
||||
Font font = UIManager.getFont("Label.font");
|
||||
myTipLabel.setFont(font.deriveFont(Font.PLAIN, font.getSize() - 2));
|
||||
myCurrentTip = builder.createBalloon();
|
||||
@@ -168,7 +196,7 @@ public class IdeTooltipManager implements ApplicationComponent, AWTEventListener
|
||||
if (toCenter) {
|
||||
Rectangle bounds = e.getComponent().getBounds();
|
||||
point.x = toCenterX ? bounds.width / 2 : point.x;
|
||||
point.y = toCenterY ? (bounds.height / 2 - (bounds.height / 5)) : point.y;
|
||||
point.y = toCenterY ? (bounds.height / 2) : point.y;
|
||||
}
|
||||
|
||||
myCurrentTip.show(new RelativePoint(c, point), Balloon.Position.above);
|
||||
|
||||
@@ -29,19 +29,22 @@ import com.intellij.ui.awt.RelativePoint;
|
||||
import com.intellij.ui.components.panels.NonOpaquePanel;
|
||||
import com.intellij.ui.components.panels.Wrapper;
|
||||
import com.intellij.util.Alarm;
|
||||
import com.intellij.util.IJSwingUtilities;
|
||||
import com.intellij.util.Range;
|
||||
import com.intellij.util.containers.HashSet;
|
||||
import com.intellij.util.ui.*;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import javax.swing.*;
|
||||
import javax.swing.border.EmptyBorder;
|
||||
import javax.swing.border.LineBorder;
|
||||
import javax.swing.text.html.HTMLEditorKit;
|
||||
import java.awt.*;
|
||||
import java.awt.event.*;
|
||||
import java.awt.geom.GeneralPath;
|
||||
import java.awt.geom.Rectangle2D;
|
||||
import java.awt.geom.RoundRectangle2D;
|
||||
import java.awt.image.BufferedImage;
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.CopyOnWriteArraySet;
|
||||
|
||||
public class BalloonImpl implements Disposable, Balloon, LightweightWindow, PositionTracker.Client<Balloon> {
|
||||
@@ -55,7 +58,7 @@ public class BalloonImpl implements Disposable, Balloon, LightweightWindow, Posi
|
||||
private final Color myBorderColor;
|
||||
private final Color myFillColor;
|
||||
|
||||
private final Insets myContainerInsets = new Insets(4, 4, 4, 4);
|
||||
private final Insets myContainerInsets = new Insets(2, 2, 2, 2);
|
||||
|
||||
private boolean myLastMoveWasInsideBalloon;
|
||||
|
||||
@@ -119,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;
|
||||
@@ -232,17 +238,17 @@ public class BalloonImpl implements Disposable, Balloon, LightweightWindow, Posi
|
||||
myTracker = tracker;
|
||||
myTracker.init(this);
|
||||
|
||||
final Window window = SwingUtilities.getWindowAncestor(tracker.getComponent());
|
||||
|
||||
JRootPane root = null;
|
||||
if (window instanceof JFrame) {
|
||||
root = ((JFrame)window).getRootPane();
|
||||
}
|
||||
else if (window instanceof JDialog) {
|
||||
root = ((JDialog)window).getRootPane();
|
||||
}
|
||||
else {
|
||||
assert false : window;
|
||||
JDialog dialog = IJSwingUtilities.findParentOfType(tracker.getComponent(), JDialog.class);
|
||||
if (dialog != null) {
|
||||
root = dialog.getRootPane();
|
||||
} else {
|
||||
JFrame frame = IJSwingUtilities.findParentOfType(tracker.getComponent(), JFrame.class);
|
||||
if (frame != null) {
|
||||
root = frame.getRootPane();
|
||||
} else {
|
||||
assert false;
|
||||
}
|
||||
}
|
||||
|
||||
myVisible = true;
|
||||
@@ -252,19 +258,51 @@ public class BalloonImpl implements Disposable, Balloon, LightweightWindow, Posi
|
||||
|
||||
myLayeredPane.addComponentListener(myComponentListener);
|
||||
|
||||
myTargetPoint = myTracker.recalculateLocation(this).getPoint(myLayeredPane);
|
||||
|
||||
|
||||
if (myShowPointer) {
|
||||
Rectangle rec = getRecForPosition(myPosition, true);
|
||||
|
||||
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());
|
||||
lp.width -= myContainerInsets.right;
|
||||
lp.height -= myContainerInsets.bottom;
|
||||
|
||||
if (!lp.contains(rec)) {
|
||||
Rectangle2D currentSquare = lp.createIntersection(rec);
|
||||
|
||||
double maxSquare = currentSquare.getWidth() * currentSquare.getHeight();
|
||||
Position targetPosition = myPosition;
|
||||
|
||||
for (Position eachPosition : myPosition.getOtherPositions()) {
|
||||
Rectangle2D eachIntersection = lp.createIntersection(getRecForPosition(eachPosition, false));
|
||||
double eachSquare = eachIntersection.getWidth() * eachIntersection.getHeight();
|
||||
if (maxSquare < eachSquare) {
|
||||
maxSquare = eachSquare;
|
||||
targetPosition = eachPosition;
|
||||
}
|
||||
}
|
||||
|
||||
myPosition = targetPosition;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
createComponent();
|
||||
|
||||
myComp.validate();
|
||||
Rectangle compBounds = myComp.getBounds();
|
||||
|
||||
Rectangle contentRec = SwingUtilities.convertRectangle(myContent.getParent(), myContent.getBounds(), myLayeredPane);
|
||||
Rectangle rec = myComp.getBounds();
|
||||
|
||||
if (myShowPointer && !myPosition.isOkToHavePointer(myTargetPoint, contentRec, this)) {
|
||||
if (myShowPointer && !myPosition.isOkToHavePointer(myTargetPoint, rec, getPointerLength(myPosition), getPointerWidth(myPosition), getArc(), getNormalInset())) {
|
||||
myShowPointer = false;
|
||||
myComp.removeAll();
|
||||
myLayeredPane.remove(myComp);
|
||||
|
||||
myForcedBounds = myPosition.getPointlessContentRec(compBounds, this);
|
||||
myForcedBounds = rec;
|
||||
createComponent();
|
||||
}
|
||||
|
||||
@@ -283,19 +321,46 @@ public class BalloonImpl implements Disposable, Balloon, LightweightWindow, Posi
|
||||
KeyEvent.KEY_EVENT_MASK);
|
||||
}
|
||||
|
||||
private Rectangle getRecForPosition(Position position, boolean adjust) {
|
||||
Dimension size = getContentSizeFor(position);
|
||||
|
||||
Rectangle rec = new Rectangle(new Point(0, 0), size);
|
||||
|
||||
position.setRecToRelativePosition(rec, myTargetPoint);
|
||||
|
||||
if (adjust) {
|
||||
rec = myPosition
|
||||
.getUpdatedBounds(myLayeredPane.getSize(), myForcedBounds, rec.getSize(), myShowPointer, myTargetPoint, myContainerInsets);
|
||||
}
|
||||
|
||||
return rec;
|
||||
}
|
||||
|
||||
private Dimension getContentSizeFor(Position position) {
|
||||
Insets insets = position.createBorder(this).getBorderInsets();
|
||||
if (insets == null) {
|
||||
insets = new Insets(0, 0, 0, 0);
|
||||
}
|
||||
|
||||
Dimension size = myContent.getPreferredSize();
|
||||
size.width += insets.left + insets.right;
|
||||
size.height += insets.top + insets.bottom;
|
||||
|
||||
return size;
|
||||
}
|
||||
|
||||
private void createComponent() {
|
||||
myComp = new MyComponent(myContent, this, myShowPointer
|
||||
? myPosition.createBorder(this)
|
||||
: getPointlessBorder());
|
||||
|
||||
myTargetPoint = myTracker.recalculateLocation(this).getPoint(myLayeredPane);
|
||||
|
||||
myComp.clear();
|
||||
myComp.myAlpha = 0f;
|
||||
|
||||
|
||||
myLayeredPane.add(myComp, JLayeredPane.POPUP_LAYER);
|
||||
myPosition.updateLocation(this);
|
||||
myPosition.updateBounds(this);
|
||||
}
|
||||
|
||||
|
||||
@@ -308,7 +373,7 @@ public class BalloonImpl implements Disposable, Balloon, LightweightWindow, Posi
|
||||
|
||||
if (newPosition != null) {
|
||||
myTargetPoint = newPosition.getPoint(myLayeredPane);
|
||||
myPosition.updateLocation(this);
|
||||
myPosition.updateBounds(this);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -342,6 +407,8 @@ public class BalloonImpl implements Disposable, Balloon, LightweightWindow, Posi
|
||||
myComp.clear();
|
||||
myComp.repaint();
|
||||
|
||||
myFadedIn = true;
|
||||
|
||||
startFadeoutTimer();
|
||||
}
|
||||
else {
|
||||
@@ -376,23 +443,19 @@ public class BalloonImpl implements Disposable, Balloon, LightweightWindow, Posi
|
||||
|
||||
|
||||
int getArc() {
|
||||
return 6;
|
||||
return 3;
|
||||
}
|
||||
|
||||
int getPointerWidth() {
|
||||
return 12;
|
||||
int getPointerWidth(Position position) {
|
||||
return position.isTopBottomPointer() ? 14 : 11;
|
||||
}
|
||||
|
||||
int getNormalInset() {
|
||||
return 4;
|
||||
return 3;
|
||||
}
|
||||
|
||||
int getShadowShift() {
|
||||
return 10;
|
||||
}
|
||||
|
||||
int getPointerLength() {
|
||||
return 12;
|
||||
int getPointerLength(Position position) {
|
||||
return position.isTopBottomPointer() ? 10 : 8;
|
||||
}
|
||||
|
||||
public void hide() {
|
||||
@@ -402,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) {
|
||||
@@ -447,7 +512,7 @@ public class BalloonImpl implements Disposable, Balloon, LightweightWindow, Posi
|
||||
public void setBounds(Rectangle bounds) {
|
||||
myForcedBounds = bounds;
|
||||
if (myPosition != null) {
|
||||
myPosition.updateLocation(this);
|
||||
myPosition.updateBounds(this);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -469,22 +534,36 @@ public class BalloonImpl implements Disposable, Balloon, LightweightWindow, Posi
|
||||
abstract EmptyBorder createBorder(final BalloonImpl balloon);
|
||||
|
||||
|
||||
public void updateLocation(final BalloonImpl balloon) {
|
||||
Rectangle bounds = balloon.myForcedBounds;
|
||||
abstract void setRecToRelativePosition(Rectangle rec, Point targetPoint);
|
||||
|
||||
|
||||
public void updateBounds(final BalloonImpl balloon) {
|
||||
balloon.myComp._setBounds(getUpdatedBounds(balloon.myLayeredPane.getSize(),
|
||||
balloon.myForcedBounds,
|
||||
balloon.myComp.getPreferredSize(),
|
||||
balloon.myShowPointer,
|
||||
balloon.myTargetPoint,
|
||||
balloon.myContainerInsets));
|
||||
}
|
||||
|
||||
public Rectangle getUpdatedBounds(Dimension layeredPaneSize,
|
||||
Rectangle forcedBounds,
|
||||
Dimension preferredSize,
|
||||
boolean showPointer,
|
||||
Point targetPoint, Insets containerInsets) {
|
||||
|
||||
Rectangle bounds = forcedBounds;
|
||||
|
||||
if (bounds == null) {
|
||||
final Dimension size = balloon.myComp.getPreferredSize();
|
||||
balloon.myComp.setSize(size);
|
||||
final Dimension layeredPaneSize = balloon.myLayeredPane.getSize();
|
||||
Point location = balloon.myShowPointer
|
||||
? getLocation(layeredPaneSize, balloon.myTargetPoint, size)
|
||||
: new Point(balloon.myTargetPoint.x - size.width / 2, balloon.myTargetPoint.y - size.height / 2);
|
||||
bounds = new Rectangle(location.x, location.y, size.width, size.height);
|
||||
Point location = showPointer
|
||||
? getLocation(layeredPaneSize, targetPoint, preferredSize)
|
||||
: new Point(targetPoint.x - preferredSize.width / 2, targetPoint.y - preferredSize.height / 2);
|
||||
bounds = new Rectangle(location.x, location.y, preferredSize.width, preferredSize.height);
|
||||
|
||||
ScreenUtil.moveToFit(bounds, new Rectangle(0, 0, layeredPaneSize.width, layeredPaneSize.height), balloon.myContainerInsets);
|
||||
ScreenUtil.moveToFit(bounds, new Rectangle(0, 0, layeredPaneSize.width, layeredPaneSize.height), containerInsets);
|
||||
}
|
||||
|
||||
balloon.myComp._setBounds(bounds);
|
||||
return bounds;
|
||||
}
|
||||
|
||||
abstract Point getLocation(final Dimension containerSize, final Point targetPoint, final Dimension balloonSize);
|
||||
@@ -513,31 +592,21 @@ public class BalloonImpl implements Disposable, Balloon, LightweightWindow, Posi
|
||||
final Point pointTarget,
|
||||
final BalloonImpl balloon);
|
||||
|
||||
public boolean isOkToHavePointer(Point targetPoint, Rectangle bounds, BalloonImpl balloon) {
|
||||
if (bounds.contains(targetPoint)) {
|
||||
return false;
|
||||
}
|
||||
public boolean isOkToHavePointer(Point targetPoint, Rectangle bounds, int pointerLength, int pointerWidth, int arc, int normalInset) {
|
||||
if (bounds.x < targetPoint.x && bounds.x + bounds.width > targetPoint.x && bounds.y < targetPoint.y && bounds.y + bounds.height < targetPoint.y) return false;
|
||||
|
||||
Rectangle pointless = getPointlessContentRec(bounds, balloon);
|
||||
Rectangle pointless = getPointlessContentRec(bounds, pointerLength);
|
||||
|
||||
pointless.x += (balloon.getArc() + 1);
|
||||
pointless.width -= (balloon.getArc() * 2 + 2);
|
||||
pointless.y += (balloon.getArc() + 1);
|
||||
pointless.height -= (balloon.getArc() * 2 + 2);
|
||||
|
||||
|
||||
int size = getDistanceToTarget(bounds, targetPoint);
|
||||
if (size < balloon.getPointerLength() + balloon.getNormalInset()) return false;
|
||||
|
||||
int pointerWidth = balloon.getPointerWidth();
|
||||
int size = getDistanceToTarget(pointless, targetPoint);
|
||||
if (size < pointerLength) return false;
|
||||
|
||||
Range<Integer> balloonRange;
|
||||
Range<Integer> pointerRange;
|
||||
if (isTopBottomPointer()) {
|
||||
balloonRange = new Range<Integer>(bounds.x, bounds.x + bounds.width);
|
||||
balloonRange = new Range<Integer>(bounds.x + arc, bounds.x + bounds.width - arc * 2);
|
||||
pointerRange = new Range<Integer>(targetPoint.x - pointerWidth / 2, targetPoint.x + pointerWidth / 2);
|
||||
} else {
|
||||
balloonRange = new Range<Integer>(bounds.y, bounds.y + bounds.height);
|
||||
balloonRange = new Range<Integer>(bounds.y + arc, bounds.y + bounds.height - arc * 2);
|
||||
pointerRange = new Range<Integer>(targetPoint.y - pointerWidth / 2, targetPoint.y + pointerWidth / 2);
|
||||
}
|
||||
|
||||
@@ -550,8 +619,19 @@ public class BalloonImpl implements Disposable, Balloon, LightweightWindow, Posi
|
||||
return this instanceof Below || this instanceof Above;
|
||||
}
|
||||
|
||||
protected abstract Rectangle getPointlessContentRec(Rectangle bounds, BalloonImpl balloon);
|
||||
protected abstract Rectangle getPointlessContentRec(Rectangle bounds, int pointerLength);
|
||||
|
||||
public Set<Position> getOtherPositions() {
|
||||
HashSet<Position> all = new HashSet<Position>();
|
||||
all.add(BELOW);
|
||||
all.add(ABOVE);
|
||||
all.add(AT_RIGHT);
|
||||
all.add(AT_LEFT);
|
||||
|
||||
all.remove(this);
|
||||
|
||||
return all;
|
||||
}
|
||||
}
|
||||
|
||||
public static final Position BELOW = new Below();
|
||||
@@ -569,12 +649,17 @@ public class BalloonImpl implements Disposable, Balloon, LightweightWindow, Posi
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Rectangle getPointlessContentRec(Rectangle bounds, BalloonImpl balloon) {
|
||||
return new Rectangle(bounds.x, bounds.y + balloon.getPointerLength(), bounds.width, bounds.height - balloon.getPointerLength());
|
||||
protected Rectangle getPointlessContentRec(Rectangle bounds, int pointerLength) {
|
||||
return new Rectangle(bounds.x, bounds.y + pointerLength, bounds.width, bounds.height - pointerLength);
|
||||
}
|
||||
|
||||
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
|
||||
void setRecToRelativePosition(Rectangle rec, Point targetPoint) {
|
||||
rec.setLocation(new Point(targetPoint.x - rec.width / 2, targetPoint.y));
|
||||
}
|
||||
|
||||
Point getLocation(final Dimension containerSize, final Point targetPoint, final Dimension balloonSize) {
|
||||
@@ -583,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());
|
||||
}
|
||||
|
||||
@@ -613,12 +698,20 @@ public class BalloonImpl implements Disposable, Balloon, LightweightWindow, Posi
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Rectangle getPointlessContentRec(Rectangle bounds, BalloonImpl balloon) {
|
||||
return new Rectangle(bounds.x, bounds.y, bounds.width, bounds.height - balloon.getPointerLength());
|
||||
protected Rectangle getPointlessContentRec(Rectangle bounds, int pointerLength) {
|
||||
return new Rectangle(bounds.x, bounds.y, bounds.width, bounds.height - pointerLength);
|
||||
}
|
||||
|
||||
EmptyBorder createBorder(final BalloonImpl balloon) {
|
||||
return new EmptyBorder(balloon.getNormalInset(), balloon.getNormalInset(), balloon.getPointerLength() + balloon.getNormalInset(), balloon.getNormalInset());
|
||||
return new EmptyBorder(balloon.getNormalInset(),
|
||||
balloon.getNormalInset(),
|
||||
balloon.getPointerLength(this),
|
||||
balloon.getNormalInset());
|
||||
}
|
||||
|
||||
@Override
|
||||
void setRecToRelativePosition(Rectangle rec, Point targetPoint) {
|
||||
rec.setLocation(targetPoint.x - rec.width / 2, targetPoint.y - rec.height);
|
||||
}
|
||||
|
||||
Point getLocation(final Dimension containerSize, final Point targetPoint, final Dimension balloonSize) {
|
||||
@@ -627,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();
|
||||
|
||||
|
||||
@@ -657,12 +750,17 @@ public class BalloonImpl implements Disposable, Balloon, LightweightWindow, Posi
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Rectangle getPointlessContentRec(Rectangle bounds, BalloonImpl balloon) {
|
||||
return new Rectangle(bounds.x + balloon.getPointerLength(), bounds.y, bounds.width - balloon.getPointerLength(), bounds.height);
|
||||
protected Rectangle getPointlessContentRec(Rectangle bounds, int pointerLength) {
|
||||
return new Rectangle(bounds.x + pointerLength, bounds.y, bounds.width - pointerLength, bounds.height);
|
||||
}
|
||||
|
||||
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
|
||||
void setRecToRelativePosition(Rectangle rec, Point targetPoint) {
|
||||
rec.setLocation(targetPoint.x, targetPoint.y - rec.height / 2);
|
||||
}
|
||||
|
||||
Point getLocation(final Dimension containerSize, final Point targetPoint, final Dimension balloonSize) {
|
||||
@@ -673,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());
|
||||
}
|
||||
}
|
||||
@@ -700,12 +798,17 @@ public class BalloonImpl implements Disposable, Balloon, LightweightWindow, Posi
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Rectangle getPointlessContentRec(Rectangle bounds, BalloonImpl balloon) {
|
||||
return new Rectangle(bounds.x, bounds.y, bounds.width - balloon.getPointerLength(), bounds.height);
|
||||
protected Rectangle getPointlessContentRec(Rectangle bounds, int pointerLength) {
|
||||
return new Rectangle(bounds.x, bounds.y, bounds.width - pointerLength, bounds.height);
|
||||
}
|
||||
|
||||
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
|
||||
void setRecToRelativePosition(Rectangle rec, Point targetPoint) {
|
||||
rec.setLocation(targetPoint.x - rec.width, targetPoint.y - rec.height / 2);
|
||||
}
|
||||
|
||||
Point getLocation(final Dimension containerSize, final Point targetPoint, final Dimension balloonSize) {
|
||||
@@ -714,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());
|
||||
}
|
||||
}
|
||||
@@ -864,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);
|
||||
lpBounds = myPosition.getPointlessContentRec(lpBounds, myBalloon.getPointerLength(myPosition));
|
||||
|
||||
int iconWidth = myBalloon.myCloseButton.getIconWidth();
|
||||
int iconHeight = myBalloon.myCloseButton.getIconHeight();
|
||||
@@ -939,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() {
|
||||
@@ -1001,7 +1104,7 @@ public class BalloonImpl implements Disposable, Balloon, LightweightWindow, Posi
|
||||
|
||||
pane.setBorder(new LineBorder(Color.blue));
|
||||
|
||||
balloon.set(new BalloonImpl(pane, Color.black, MessageType.ERROR.getPopupBackground(), true, true, true, true, 0, true, null, false, 500));
|
||||
balloon.set(new BalloonImpl(pane, Color.black, MessageType.ERROR.getPopupBackground(), true, true, true, false, 0, true, null, false, 500));
|
||||
balloon.get().setShowPointer(true);
|
||||
|
||||
if (e.isShiftDown()) {
|
||||
@@ -1020,8 +1123,24 @@ public class BalloonImpl implements Disposable, Balloon, LightweightWindow, Posi
|
||||
}
|
||||
});
|
||||
|
||||
tree.addMouseMotionListener(new MouseMotionAdapter() {
|
||||
@Override
|
||||
public void mouseMoved(MouseEvent e) {
|
||||
System.out.println(e.getPoint());
|
||||
}
|
||||
});
|
||||
|
||||
frame.setBounds(300, 300, 300, 300);
|
||||
frame.show();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean wasFadedIn() {
|
||||
return myFadedIn;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean wasFadedOut() {
|
||||
return myFadedOut;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -60,6 +60,8 @@ ide.tree.uiLockAttempt=250
|
||||
ide.splitter.mouseZone=6
|
||||
|
||||
ide.tooltip.callout=true
|
||||
ide.tooltip.mode=default
|
||||
ide.tooltip.description=Available options are: default,system,graphite
|
||||
|
||||
ide.tabbedPane.bufferedPaint=true
|
||||
|
||||
|
||||
Reference in New Issue
Block a user