From a880dfebca39093bb7cc04fa1db3c79fee9e8fa8 Mon Sep 17 00:00:00 2001 From: Maxim Shafirov Date: Mon, 21 Feb 2005 14:08:42 +0300 Subject: [PATCH] repackaging com.jetbrains.fbq --- openapi/src/com/intellij/ui/DrawUtil.java | 39 ++ .../src/com/intellij/ui/LineEndDecorator.java | 35 ++ openapi/src/com/intellij/ui/ScreenUtil.java | 78 ++++ openapi/src/com/intellij/ui/UI.java | 60 +++ .../com/intellij/ui/awt/RelativePoint.java | 90 ++++ .../intellij/ui/awt/RelativeRectangle.java | 62 +++ .../ui/components/labels/LinkLabel.java | 302 ++++++++++++++ .../ui/components/labels/LinkListener.java | 18 + .../components/panels/FlowLayoutWrapper.java | 23 ++ .../ui/components/panels/HorizontalBox.java | 38 ++ .../ui/components/panels/NonOpaquePanel.java | 41 ++ .../ui/components/panels/OpaquePanel.java | 37 ++ .../ui/components/panels/OpaqueWrapper.java | 31 ++ .../ui/components/panels/VerticalBox.java | 21 + .../ui/components/panels/Wrapper.java | 79 ++++ .../src/com/intellij/ui/messager/Callout.java | 99 +++++ .../ui/messager/CalloutComponent.java | 383 ++++++++++++++++++ .../intellij}/diagnostic/AbstractMessage.java | 2 +- .../diagnostic/DefaultIdeaErrorLogger.java | 1 - .../diagnostic/GroupedLogMessage.java | 2 +- .../intellij}/diagnostic/IdeErrorsDialog.java | 6 +- .../intellij}/diagnostic/IdeMessagePanel.java | 8 +- .../intellij}/diagnostic/LogMessage.java | 2 +- .../intellij}/diagnostic/MessagePool.java | 2 +- .../diagnostic/MessagePoolListener.java | 2 +- .../ide/reporter/ConnectionException.java | 2 +- .../openapi/wm/impl/status/StatusBarImpl.java | 4 +- 27 files changed, 1450 insertions(+), 17 deletions(-) create mode 100644 openapi/src/com/intellij/ui/DrawUtil.java create mode 100644 openapi/src/com/intellij/ui/LineEndDecorator.java create mode 100644 openapi/src/com/intellij/ui/ScreenUtil.java create mode 100644 openapi/src/com/intellij/ui/UI.java create mode 100644 openapi/src/com/intellij/ui/awt/RelativePoint.java create mode 100644 openapi/src/com/intellij/ui/awt/RelativeRectangle.java create mode 100644 openapi/src/com/intellij/ui/components/labels/LinkLabel.java create mode 100644 openapi/src/com/intellij/ui/components/labels/LinkListener.java create mode 100644 openapi/src/com/intellij/ui/components/panels/FlowLayoutWrapper.java create mode 100644 openapi/src/com/intellij/ui/components/panels/HorizontalBox.java create mode 100644 openapi/src/com/intellij/ui/components/panels/NonOpaquePanel.java create mode 100644 openapi/src/com/intellij/ui/components/panels/OpaquePanel.java create mode 100644 openapi/src/com/intellij/ui/components/panels/OpaqueWrapper.java create mode 100644 openapi/src/com/intellij/ui/components/panels/VerticalBox.java create mode 100644 openapi/src/com/intellij/ui/components/panels/Wrapper.java create mode 100644 openapi/src/com/intellij/ui/messager/Callout.java create mode 100644 openapi/src/com/intellij/ui/messager/CalloutComponent.java rename source/{jetbrains/fbq => com/intellij}/diagnostic/AbstractMessage.java (97%) rename source/{jetbrains/fbq => com/intellij}/diagnostic/GroupedLogMessage.java (96%) rename source/{jetbrains/fbq => com/intellij}/diagnostic/IdeErrorsDialog.java (98%) rename source/{jetbrains/fbq => com/intellij}/diagnostic/IdeMessagePanel.java (96%) rename source/{jetbrains/fbq => com/intellij}/diagnostic/LogMessage.java (97%) rename source/{jetbrains/fbq => com/intellij}/diagnostic/MessagePool.java (99%) rename source/{jetbrains/fbq => com/intellij}/diagnostic/MessagePoolListener.java (85%) rename source/{jetbrains/fbq => com/intellij}/ide/reporter/ConnectionException.java (91%) diff --git a/openapi/src/com/intellij/ui/DrawUtil.java b/openapi/src/com/intellij/ui/DrawUtil.java new file mode 100644 index 000000000000..16e4acada3f9 --- /dev/null +++ b/openapi/src/com/intellij/ui/DrawUtil.java @@ -0,0 +1,39 @@ +/* + * Copyright (c) 2000-2004 by JetBrains s.r.o. All Rights Reserved. + * Use is subject to license terms. + */ +package com.intellij.ui; + +import java.awt.*; + +/** + * @author kir + */ +public class DrawUtil { + + public static void drawRoundRect(Graphics g, double x1d, double y1d, double x2d, double y2d, Color color) { + final Color oldColor = g.getColor(); + g.setColor(color); + + int x1 = (int) Math.round(x1d); + int x2 = (int) Math.round(x2d); + int y1 = (int) Math.round(y1d); + int y2 = (int) Math.round(y2d); + + g.drawLine(x1 + 1, y1, x2 - 1, y1); + g.drawLine(x1 + 1, y2, x2 - 1, y2); + + g.drawLine(x1, y1 + 1, x1, y2 - 1); + g.drawLine(x2, y1 + 1, x2, y2 - 1); + + g.setColor(oldColor); + } + + public static void drawPlainRect(Graphics g, int x1, int y1, int x2, int y2) { + g.drawLine(x1, y1, x2 - 1, y1); + g.drawLine(x2, y1, x2, y2 - 1); + g.drawLine(x1 + 1, y2, x2, y2); + g.drawLine(x1, y1 + 1, x1, y2); + } + +} diff --git a/openapi/src/com/intellij/ui/LineEndDecorator.java b/openapi/src/com/intellij/ui/LineEndDecorator.java new file mode 100644 index 000000000000..4b7630fa0fc4 --- /dev/null +++ b/openapi/src/com/intellij/ui/LineEndDecorator.java @@ -0,0 +1,35 @@ +/* + * Copyright (c) 2000-2004 by JetBrains s.r.o. All Rights Reserved. + * Use is subject to license terms. + */ +package com.intellij.ui; + +import java.awt.*; +import java.awt.geom.AffineTransform; +import java.awt.geom.Line2D; +import java.awt.geom.Point2D; + +public class LineEndDecorator { + + private static int myArrowSize = 9; + private static Shape myArrowPolygon = new Polygon(new int[] {0, myArrowSize, 0, 0}, new int[] {0, myArrowSize /2, myArrowSize, 0}, 4); + + public static Shape getArrowShape(Line2D line, Point2D intersectionPoint) { + final double deltaY = line.getP2().getY() - line.getP1().getY(); + final double length = Math.sqrt(Math.pow(deltaY, 2) + Math.pow(line.getP2().getX() - line.getP1().getX(), 2)); + + double theta = Math.asin(deltaY / length); + + if (line.getP1().getX() > line.getP2().getX()) { + theta = Math.PI - theta; + } + + AffineTransform rotate = AffineTransform.getRotateInstance(theta, myArrowSize, myArrowSize / 2); + Shape polygon = rotate.createTransformedShape(myArrowPolygon); + + AffineTransform move = AffineTransform.getTranslateInstance(intersectionPoint.getX() - myArrowSize, intersectionPoint.getY() - myArrowSize /2); + polygon = move.createTransformedShape(polygon); + return polygon; + } + +} diff --git a/openapi/src/com/intellij/ui/ScreenUtil.java b/openapi/src/com/intellij/ui/ScreenUtil.java new file mode 100644 index 000000000000..dd8d4394d38e --- /dev/null +++ b/openapi/src/com/intellij/ui/ScreenUtil.java @@ -0,0 +1,78 @@ +/* + * Copyright (c) 2000-2004 by JetBrains s.r.o. All Rights Reserved. + * Use is subject to license terms. + */ +package com.intellij.ui; + +import java.awt.*; + +/** + * @author kir + */ +public class ScreenUtil { + + public static final Rectangle getScreenRectangle(int aTargetX, int aTargetY) { + GraphicsConfiguration targetGraphicsConfiguration = null; + GraphicsEnvironment env = GraphicsEnvironment.getLocalGraphicsEnvironment(); + GraphicsDevice[] devices = env.getScreenDevices(); + for (int i = 0; i < devices.length; i++) { + GraphicsDevice device = devices[i]; + GraphicsConfiguration graphicsConfiguration = device.getDefaultConfiguration(); + Rectangle r = graphicsConfiguration.getBounds(); + if (r.x <= aTargetX && aTargetX <= r.x + r.width && r.y <= aTargetY && aTargetY <= r.y + r.height) { + targetGraphicsConfiguration = graphicsConfiguration; + break; + } + } + if (targetGraphicsConfiguration == null && devices.length > 0) { + targetGraphicsConfiguration = env.getDefaultScreenDevice().getDefaultConfiguration(); + } + if (targetGraphicsConfiguration == null) { + throw new IllegalStateException( + "It's impossible to determine target graphics environment for point (" + aTargetX + "," + aTargetY + ")" + ); + } + + // Determine real client area of target graphics configuration + + Insets insets = Toolkit.getDefaultToolkit().getScreenInsets(targetGraphicsConfiguration); + Rectangle targetRectangle = targetGraphicsConfiguration.getBounds(); + targetRectangle.x += insets.left; + targetRectangle.y += insets.top; + targetRectangle.width -= insets.left + insets.right; + targetRectangle.height -= insets.top + insets.bottom; + + return targetRectangle; + } + + + public static boolean isOutsideOnTheRightOFScreen(Rectangle aRectangle) { + int screenX = aRectangle.x; + int screenY = aRectangle.y; + Rectangle screen = getScreenRectangle(screenX, screenY); + return aRectangle.getMaxX() > screen.width; + } + + public static void moveRectangleToFitTheScreen(Rectangle aRectangle) { + int screenX = aRectangle.x; + int screenY = aRectangle.y; + Rectangle screen = getScreenRectangle(screenX, screenY); + + if (aRectangle.getMaxX() > screen.getMaxX()) { + aRectangle.x = (int) screen.getMaxX() - aRectangle.width; + } + + + if (aRectangle.getMinX() < screen.getMinX()) { + aRectangle.x = (int) screen.getMinX(); + } + + if (aRectangle.getMaxY() > screen.getMaxY()) { + aRectangle.y = (int) screen.getMaxY() - aRectangle.height; + } + + if (aRectangle.getMinY() < screen.getMinY()) { + aRectangle.y = (int) screen.getMinY(); + } + } +} diff --git a/openapi/src/com/intellij/ui/UI.java b/openapi/src/com/intellij/ui/UI.java new file mode 100644 index 000000000000..7a00ff0bb65c --- /dev/null +++ b/openapi/src/com/intellij/ui/UI.java @@ -0,0 +1,60 @@ +package com.intellij.ui; + +import javax.swing.*; +import java.awt.*; +import java.util.HashMap; +import java.util.Map; + +/** + * Created by IntelliJ IDEA. + * User: max + * Date: Feb 17, 2005 + * Time: 4:22:50 PM + * To change this template use File | Settings | File Templates. + */ +public class UI { + private static Map ourColors = new HashMap(); + + static { + ourColors.put("panel.border.color", new Color(102, 101, 84)); + ourColors.put("panel.separator.color", new Color(180, 179, 169)); + + ourColors.put("panel.custom.background", new Color(250, 249, 245)); + + ourColors.put("link.foreground", new Color(82, 99, 155)); + ourColors.put("link.pressed.foreground", new Color(240, 0, 0)); + ourColors.put("link.visited.foreground", new Color(128, 0, 128)); + + ourColors.put("bar.separator.foreground", UI.getColor("panel.separator.color")); + ourColors.put("bar.selected.separator.foreground", new Color(232, 231, 228)); + ourColors.put("bar.background", UIManager.getColor("Panel.background")); + ourColors.put("bar.hover.background", UIManager.getColor("Tree.selectionBackground")); + ourColors.put("bar.selected.background", UI.getColor("panel.custom.background")); + ourColors.put("bar.hover.frame.foreground", UIManager.getColor("Tree.selectionBackground").darker()); + + ourColors.put("popup.selected.background", UIManager.getColor("Tree.selectionBackground")); + ourColors.put("popup.selected.frame.foreground", UIManager.getColor("Tree.selectionBackground").darker()); + ourColors.put("popup.separator.foreground", Color.gray); + + ourColors.put("callout.background", Color.white); + ourColors.put("callout.frame.color", Color.red); + + ourColors.put("underline.error", Color.red); + ourColors.put("underline.warning", Color.yellow); + + ourColors.put("tooltip.error", Color.red); + ourColors.put("tooltip.warning", Color.yellow.darker()); + + ourColors.put("toolbar.background", UIManager.getColor("Panel.background")); + ourColors.put("toolbar.hover.background", UIManager.getColor("Tree.selectionBackground")); + ourColors.put("toolbar.selected.background", UI.getColor("panel.custom.background")); + ourColors.put("toolbar.hover.frame.foreground", UIManager.getColor("Tree.selectionBackground").darker()); + + ourColors.put("speedsearch.background", new Color(244, 249, 181)); + ourColors.put("speedsearch.foreground", Color.black); + } + + public static Color getColor(String id) { + return ourColors.get(id); + } +} diff --git a/openapi/src/com/intellij/ui/awt/RelativePoint.java b/openapi/src/com/intellij/ui/awt/RelativePoint.java new file mode 100644 index 000000000000..290a4198b683 --- /dev/null +++ b/openapi/src/com/intellij/ui/awt/RelativePoint.java @@ -0,0 +1,90 @@ +/* + * Copyright (c) 2000-2004 by JetBrains s.r.o. All Rights Reserved. + * Use is subject to license terms. + */ +package com.intellij.ui.awt; + +import javax.swing.*; +import java.awt.*; +import java.awt.event.MouseEvent; + +public class RelativePoint { + + private Component myComponent; + private Point myPointOnComponent; + + public RelativePoint(MouseEvent event) { + this(event.getComponent(), event.getPoint()); + } + + public RelativePoint(Component aComponent, Point aPointOnComponent) { + if (aComponent.isShowing()) { + myComponent = SwingUtilities.getRootPane(aComponent); + myPointOnComponent = SwingUtilities.convertPoint(aComponent, aPointOnComponent, myComponent); + } + else { + myComponent = aComponent; + myPointOnComponent = aPointOnComponent; + } + } + + public Component getComponent() { + return myComponent; + } + + public Point getPoint() { + return myPointOnComponent; + } + + public Point getPoint(Component aTargetComponent) { +//todo: remove that after implementation of DND to html design time controls + if (aTargetComponent == null || aTargetComponent.getParent() == null || SwingUtilities.getWindowAncestor(aTargetComponent) == null) return new Point(); + + return SwingUtilities.convertPoint(getComponent(), getPoint(), aTargetComponent); + } + + public RelativePoint getPointOn(Component aTargetComponent) { + final Point point = getPoint(aTargetComponent); + return new RelativePoint(aTargetComponent, point); + } + + public Point getScreenPoint() { + final Point point = (Point) getPoint().clone(); + SwingUtilities.convertPointToScreen(point, getComponent()); + return point; + } + + public String toString() { + return getPoint() + " on " + getComponent().toString(); + } + + public static RelativePoint getCenterOf(JComponent component) { + final Rectangle visibleRect = component.getVisibleRect(); + final Point point = new Point(visibleRect.x + visibleRect.width/2, visibleRect.y + visibleRect.height/2); + return new RelativePoint(component, point); + } + + public static RelativePoint getSouthEastOf(JComponent component) { + final Rectangle visibleRect = component.getVisibleRect(); + final Point point = new Point(visibleRect.x + visibleRect.width, visibleRect.y + visibleRect.height); + return new RelativePoint(component, point); + } + + public static RelativePoint getSouthWestOf(JComponent component) { + final Rectangle visibleRect = component.getVisibleRect(); + final Point point = new Point(visibleRect.x, visibleRect.y + visibleRect.height); + return new RelativePoint(component, point); + } + + public static RelativePoint getNorthWestOf(JComponent component) { + final Rectangle visibleRect = component.getVisibleRect(); + final Point point = new Point(visibleRect.x, visibleRect.y); + return new RelativePoint(component, point); + } + + public static RelativePoint getNorthEastOf(JComponent component) { + final Rectangle visibleRect = component.getVisibleRect(); + final Point point = new Point(visibleRect.x + visibleRect.width, visibleRect.y); + return new RelativePoint(component, point); + } +} diff --git a/openapi/src/com/intellij/ui/awt/RelativeRectangle.java b/openapi/src/com/intellij/ui/awt/RelativeRectangle.java new file mode 100644 index 000000000000..f5ca43085098 --- /dev/null +++ b/openapi/src/com/intellij/ui/awt/RelativeRectangle.java @@ -0,0 +1,62 @@ +/* + * Copyright (c) 2000-2004 by JetBrains s.r.o. All Rights Reserved. + * Use is subject to license terms. + */ +package com.intellij.ui.awt; + +import javax.swing.*; +import java.awt.*; + +public class RelativeRectangle { + + private RelativePoint myPoint; + private Dimension myDimension; + + public RelativeRectangle() { + this(new RelativePoint(new JLabel(), new Point()), new Dimension()); + } + + public RelativeRectangle(JComponent component) { + this(new RelativePoint(component.getParent(), component.getBounds().getLocation()), component.getBounds().getSize()); + } + + public RelativeRectangle(Component component, Rectangle rectangle) { + this(new RelativePoint(component, rectangle.getLocation()), rectangle.getSize()); + } + + public RelativeRectangle(RelativePoint point, Dimension dimension) { + myDimension = dimension; + myPoint = point; + } + + public Dimension getDimension() { + return myDimension; + } + + public RelativePoint getPoint() { + return myPoint; + } + + public RelativePoint getMaxPoint() { + return new RelativePoint(myPoint.getComponent(), + new Point(myPoint.getPoint().x + myDimension.width, myPoint.getPoint().y + myDimension.height)); + } + + public Rectangle getRectangleOn(Component target) { + return new Rectangle(getPoint().getPoint(target), getDimension()); + } + + public Rectangle getScreenRectangle() { + return new Rectangle(getPoint().getScreenPoint(), getDimension()); + } + + public static RelativeRectangle fromScreen(JComponent target, Rectangle screenRectangle) { + Point relativePoint = screenRectangle.getLocation(); + SwingUtilities.convertPointFromScreen(relativePoint, target); + return new RelativeRectangle(new RelativePoint(target, relativePoint), screenRectangle.getSize()); + } + + public Component getComponent() { + return getPoint().getComponent(); + } +} diff --git a/openapi/src/com/intellij/ui/components/labels/LinkLabel.java b/openapi/src/com/intellij/ui/components/labels/LinkLabel.java new file mode 100644 index 000000000000..651b3b7290b2 --- /dev/null +++ b/openapi/src/com/intellij/ui/components/labels/LinkLabel.java @@ -0,0 +1,302 @@ +/* + * Copyright (c) 2000-2004 by JetBrains s.r.o. All Rights Reserved. + * Use is subject to license terms. + */ +package com.intellij.ui.components.labels; + +import com.intellij.openapi.project.Project; +import com.intellij.openapi.project.ProjectManager; +import com.intellij.openapi.util.IconLoader; +import com.intellij.openapi.wm.WindowManager; +import com.intellij.ui.UI; + +import javax.swing.*; +import javax.swing.border.Border; +import javax.swing.border.EmptyBorder; +import java.awt.*; +import java.awt.event.MouseAdapter; +import java.awt.event.MouseEvent; +import java.awt.event.MouseMotionListener; +import java.util.HashSet; +import java.util.Set; + +/** + * @author kir + */ +public class LinkLabel extends JLabel { + private boolean myUnderline; + + private LinkListener myLinkListener; + private Object myLinkData; + + private static Set ourVisitedLinks = new HashSet(); + + private boolean myIsLinkActive; + + private String myVisitedLinksKey; + private int myIconWidth; + private Icon myHoveringIcon; + private Icon myInactiveIcon; + + private boolean myClickIsBeingProcessed; + private boolean myPaintDefaultIcon = false; + protected final int DEFAULT_ICON_GAP = 2; + private static final Icon LINK = IconLoader.getIcon("/ide/link.png"); + + public LinkLabel(String text, Icon icon) { + this(text, icon, null, null, null); + } + + public LinkLabel(String text, Icon icon, LinkListener aListener) { + this(text, icon, aListener, null, null); + } + + public LinkLabel(String text, Icon icon, LinkListener aListener, Object aLinkData) { + this(text, icon, aListener, aLinkData, null); + } + + public LinkLabel(String text, Icon icon, LinkListener aListener, Object aLinkData, String aVisitedLinksKey) { + super(text, icon, JLabel.LEFT); + setOpaque(false); + + setListener(aListener, aLinkData); + + myIconWidth = getIcon() == null ? 0 : getIcon().getIconWidth() + getIconTextGap(); + myInactiveIcon = getIcon(); + + MyMouseHandler mouseHandler = new MyMouseHandler(); + addMouseListener(mouseHandler); + addMouseMotionListener(mouseHandler); + + myVisitedLinksKey = aVisitedLinksKey; + } + + public void setHoveringIcon(Icon iconForHovering) { + myHoveringIcon = iconForHovering; + } + + public void setListener(LinkListener listener, Object linkData) { + myLinkListener = listener; + myLinkData = linkData; + } + + public void doClick() { + if (myClickIsBeingProcessed) return; + + myClickIsBeingProcessed = true; + myLinkListener.linkSelected(this, myLinkData); + ourVisitedLinks.add(myVisitedLinksKey); + repaint(); + myClickIsBeingProcessed = false; + } + + public boolean isVisited() { + return myVisitedLinksKey != null ? ourVisitedLinks.contains(myVisitedLinksKey) : false; + } + + protected void paintComponent(Graphics g) { + final Border border = getBorder(); + int shiftX = 0, shiftY = 0; + + if (border != null) { + shiftX = border.getBorderInsets(this).left; + shiftY = border.getBorderInsets(this).top; + } + + setForeground(myIsLinkActive ? getActive() : isVisited() ? getVisited() : getNormal()); + + super.paintComponent(g); + + + if (getText() != null) { + g.setColor(myIsLinkActive ? getActive() : isVisited() ? getVisited() : getNormal()); + int x = myIconWidth; + int y = getTextBaseLine(); + + if (myUnderline) { + int k = 1; + if (getFont().getSize() > 11) { + k += (getFont().getSize() - 11); + } + + y += k; + + if (getHorizontalAlignment() == LEFT) { + g.drawLine(x + shiftX, y + shiftY, x + getFontMetrics(getFont()).stringWidth(getText()) + shiftX, y + shiftY); + } + else { + g.drawLine(getWidth() - 1 - getFontMetrics(getFont()).stringWidth(getText()) + shiftX, y + shiftY, getWidth() - 1 + shiftX, + y + shiftY); + } + } + else { + } + + if (myPaintDefaultIcon) { + int endX = myIconWidth + getFontMetrics(getFont()).stringWidth(getText()); + int endY = getHeight() / 2 - LINK.getIconHeight() / 2 + 1; + + LINK.paintIcon(this, g, endX + shiftX + DEFAULT_ICON_GAP, endY); + } + } + } + + public Dimension getPreferredSize() { + final Dimension size = super.getPreferredSize(); + size.width += myPaintDefaultIcon ? LINK.getIconWidth() + DEFAULT_ICON_GAP : 0; + return size; + } + + + public void removeNotify() { + super.removeNotify(); + disableUnderline(); + } + + private void setActive(boolean isActive) { + myIsLinkActive = isActive; + repaint(); + } + + private int getTextBaseLine() { + FontMetrics fm = getFontMetrics(getFont()); + return getHeight() / 2 + (fm.getHeight() / 2 - fm.getDescent()); + } + + private boolean isInClickableArea(Point pt) { + if (getIcon() != null) { + if (pt.getX() < getIcon().getIconWidth() && pt.getY() < getIcon().getIconHeight()) { + return true; + } + } + if (getText() != null) { + FontMetrics fm = getFontMetrics(getFont()); + int height = fm.getHeight() + 1; + int y = getHeight() / 2 - fm.getHeight() / 2; + int width = fm.stringWidth(getText()); + if (myPaintDefaultIcon) { + width += LINK.getIconWidth() + DEFAULT_ICON_GAP; + } + + if (getHorizontalAlignment() == LEFT) { + return (new Rectangle(myIconWidth, y, width, height).contains(pt)); + } + else { + return (new Rectangle(getWidth() - width - 1, y, getWidth() - 1, height).contains(pt)); + } + } + + return false; + } + + private void enableUnderline() { + setCursor(Cursor.getPredefinedCursor(Cursor.HAND_CURSOR)); + myUnderline = true; + if (myHoveringIcon != null) { + setIcon(myHoveringIcon); + } + setStatusBarText(getToolTipText()); + repaint(); + } + + private void disableUnderline() { + setCursor(Cursor.getDefaultCursor()); + myUnderline = false; + setIcon(myInactiveIcon); + setStatusBarText(null); + setActive(false); + } + + private void setStatusBarText(String statusBarText) { + final Project[] projects = ProjectManager.getInstance().getOpenProjects(); + for (int i = 0; i < projects.length; i++) { + WindowManager.getInstance().getStatusBar(projects[i]).setInfo(statusBarText); + } + } + + public static void clearVisitedHistory() { + ourVisitedLinks.clear(); + } + + private static Color getVisited() { + return UI.getColor("link.visited.foreground"); + } + + private static Color getActive() { + return UI.getColor("link.pressed.foreground"); + } + + private static Color getNormal() { + return UI.getColor("link.foreground"); + } + + public void entered(MouseEvent e) { + enableUnderline(); + } + + public void exited(MouseEvent e) { + disableUnderline(); + } + + public void pressed(MouseEvent e) { + doClick(); + } + + private class MyMouseHandler extends MouseAdapter implements MouseMotionListener { + public void mouseClicked(MouseEvent e) { + if (isInClickableArea(e.getPoint()) && e.getClickCount() == 1) { + doClick(); + } + } + + public void mousePressed(MouseEvent e) { + if (isInClickableArea(e.getPoint())) { + setActive(true); + } + } + + public void mouseReleased(MouseEvent e) { + setActive(false); + } + + public void mouseMoved(MouseEvent e) { + if (isInClickableArea(e.getPoint())) { + enableUnderline(); + } + else { + disableUnderline(); + } + } + + public void mouseExited(MouseEvent e) { + disableUnderline(); + } + + public void mouseDragged(MouseEvent e) { + } + } + + public void setDefaultIconPainted(boolean paintDefaultIcon) { + myPaintDefaultIcon = paintDefaultIcon; + } + + public static void main(String[] args) { + final JFrame jFrame = new JFrame(); + final Container contentPane = jFrame.getContentPane(); + contentPane.setLayout(new FlowLayout()); + + final LinkLabel linkLabel = new LinkLabel("text", LINK); + // linkLabel.setFont(linkLabel.getFont().deriveFont(25f)); + linkLabel.setDefaultIconPainted(true); + + contentPane.add(linkLabel); + + jFrame.setBounds(100, 100, 100, 100); + jFrame.show(); + + linkLabel.setBorder(new EmptyBorder(10, 10, 10, 10)); + + + } + +} diff --git a/openapi/src/com/intellij/ui/components/labels/LinkListener.java b/openapi/src/com/intellij/ui/components/labels/LinkListener.java new file mode 100644 index 000000000000..9bd7ef6406c5 --- /dev/null +++ b/openapi/src/com/intellij/ui/components/labels/LinkListener.java @@ -0,0 +1,18 @@ +/* + * Copyright (c) 2000-2004 by JetBrains s.r.o. All Rights Reserved. + * Use is subject to license terms. + */ +package com.intellij.ui.components.labels; + + + +public interface LinkListener { + + LinkListener NULL = new LinkListener() { + public void linkSelected(LinkLabel aSource, Object aLinkData) { + } + }; + + void linkSelected(LinkLabel aSource, Object aLinkData); + +} diff --git a/openapi/src/com/intellij/ui/components/panels/FlowLayoutWrapper.java b/openapi/src/com/intellij/ui/components/panels/FlowLayoutWrapper.java new file mode 100644 index 000000000000..3c132083510e --- /dev/null +++ b/openapi/src/com/intellij/ui/components/panels/FlowLayoutWrapper.java @@ -0,0 +1,23 @@ +/* + * Copyright (c) 2000-2004 by JetBrains s.r.o. All Rights Reserved. + * Use is subject to license terms. + */ +package com.intellij.ui.components.panels; + +import javax.swing.*; +import javax.swing.border.Border; +import java.awt.*; + +/** + * @author kir + */ +public class FlowLayoutWrapper extends NonOpaquePanel { + public FlowLayoutWrapper(JComponent wrapped) { + super(new FlowLayout(FlowLayout.LEFT, 0, 0), wrapped); + } + + public FlowLayoutWrapper(JComponent component, Border border) { + this(component); + setBorder(border); + } +} diff --git a/openapi/src/com/intellij/ui/components/panels/HorizontalBox.java b/openapi/src/com/intellij/ui/components/panels/HorizontalBox.java new file mode 100644 index 000000000000..edcdaae0aff3 --- /dev/null +++ b/openapi/src/com/intellij/ui/components/panels/HorizontalBox.java @@ -0,0 +1,38 @@ +/* + * Copyright (c) 2000-2004 by JetBrains s.r.o. All Rights Reserved. + * Use is subject to license terms. + */ +package com.intellij.ui.components.panels; + +import javax.swing.*; +import java.awt.*; + +public class HorizontalBox extends JPanel { + + private Box myBox; + + public HorizontalBox() { + setLayout(new BorderLayout()); + myBox = new Box(BoxLayout.X_AXIS) { + public Component add(Component comp) { + ((JComponent) comp).setAlignmentY(0f); + return super.add(comp); + } + }; + add(myBox, BorderLayout.CENTER); + setOpaque(false); + } + + public Component add(Component aComponent) { + return myBox.add(aComponent); + } + + public void remove(Component aComponent) { + myBox.remove(aComponent); + } + + public void removeAll() { + myBox.removeAll(); + } + +} diff --git a/openapi/src/com/intellij/ui/components/panels/NonOpaquePanel.java b/openapi/src/com/intellij/ui/components/panels/NonOpaquePanel.java new file mode 100644 index 000000000000..22ac19d20881 --- /dev/null +++ b/openapi/src/com/intellij/ui/components/panels/NonOpaquePanel.java @@ -0,0 +1,41 @@ +/* + * Copyright (c) 2000-2004 by JetBrains s.r.o. All Rights Reserved. + * Use is subject to license terms. + */ +package com.intellij.ui.components.panels; + +import javax.swing.*; +import java.awt.*; + +public class NonOpaquePanel extends Wrapper { + + public NonOpaquePanel() { + setOpaque(false); + } + + public NonOpaquePanel(JComponent wrapped) { + super(wrapped); + setOpaque(false); + } + + public NonOpaquePanel(LayoutManager layout, JComponent wrapped) { + super(layout, wrapped); + setOpaque(false); + } + + public NonOpaquePanel(boolean isDoubleBuffered) { + super(isDoubleBuffered); + setOpaque(false); + } + + public NonOpaquePanel(LayoutManager layout) { + super(layout); + setOpaque(false); + } + + public NonOpaquePanel(LayoutManager layout, boolean isDoubleBuffered) { + super(layout, isDoubleBuffered); + setOpaque(false); + } + +} diff --git a/openapi/src/com/intellij/ui/components/panels/OpaquePanel.java b/openapi/src/com/intellij/ui/components/panels/OpaquePanel.java new file mode 100644 index 000000000000..43aaa2725d32 --- /dev/null +++ b/openapi/src/com/intellij/ui/components/panels/OpaquePanel.java @@ -0,0 +1,37 @@ +/* + * Copyright (c) 2000-2004 by JetBrains s.r.o. All Rights Reserved. + * Use is subject to license terms. + */ +package com.intellij.ui.components.panels; + +import javax.swing.*; +import java.awt.*; + +/** + * @author Eugene Belyaev + */ +public class OpaquePanel extends JPanel { + + public OpaquePanel() { + this(null, null); + } + + public OpaquePanel(LayoutManager layout) { + this(layout, null); + } + + public OpaquePanel(Color color) { + this(null, color); + } + + public OpaquePanel(LayoutManager layoutManager, Color color) { + super(layoutManager); + setBackground(color); + } + + protected void paintComponent(Graphics g) { + g.setColor(getBackground()); + Dimension size = getSize(); + g.fillRect(0, 0, size.width, size.height); + } +} diff --git a/openapi/src/com/intellij/ui/components/panels/OpaqueWrapper.java b/openapi/src/com/intellij/ui/components/panels/OpaqueWrapper.java new file mode 100644 index 000000000000..009e9c9fb87b --- /dev/null +++ b/openapi/src/com/intellij/ui/components/panels/OpaqueWrapper.java @@ -0,0 +1,31 @@ +/* + * Copyright (c) 2000-2004 by JetBrains s.r.o. All Rights Reserved. + * Use is subject to license terms. + */ +package com.intellij.ui.components.panels; + + +import javax.swing.*; +import java.awt.*; + +/** + * @author Eugene Belyaev + */ +public class OpaqueWrapper extends Wrapper { + + public OpaqueWrapper(JComponent wrapped, Color color) { + super(wrapped); + setBackground(color); + } + + public OpaqueWrapper(LayoutManager layoutManager, JComponent wrapped, Color color) { + super(layoutManager, wrapped); + setBackground(color); + } + + protected void paintComponent(Graphics g) { + g.setColor(getBackground()); + Dimension size = getSize(); + g.fillRect(0, 0, size.width, size.height); + } +} diff --git a/openapi/src/com/intellij/ui/components/panels/VerticalBox.java b/openapi/src/com/intellij/ui/components/panels/VerticalBox.java new file mode 100644 index 000000000000..ef15d16c0578 --- /dev/null +++ b/openapi/src/com/intellij/ui/components/panels/VerticalBox.java @@ -0,0 +1,21 @@ +/* + * Copyright (c) 2000-2004 by JetBrains s.r.o. All Rights Reserved. + * Use is subject to license terms. + */ +package com.intellij.ui.components.panels; + +import javax.swing.*; +import java.awt.*; + +public class VerticalBox extends Box { + + public VerticalBox() { + super(BoxLayout.Y_AXIS); + setOpaque(false); + } + + public Component add(Component comp) { + ((JComponent) comp).setAlignmentX(0f); + return super.add(comp); + } +} diff --git a/openapi/src/com/intellij/ui/components/panels/Wrapper.java b/openapi/src/com/intellij/ui/components/panels/Wrapper.java new file mode 100644 index 000000000000..2b0e4de7bba1 --- /dev/null +++ b/openapi/src/com/intellij/ui/components/panels/Wrapper.java @@ -0,0 +1,79 @@ +/* + * Copyright (c) 2000-2004 by JetBrains s.r.o. All Rights Reserved. + * Use is subject to license terms. + */ +package com.intellij.ui.components.panels; + +import javax.swing.*; +import java.awt.*; + +public class Wrapper extends JPanel { + + public Wrapper() { + setLayout(new BorderLayout()); + } + + public Wrapper(JComponent wrapped) { + setLayout(new BorderLayout()); + add(wrapped, BorderLayout.CENTER); + } + + public Wrapper(LayoutManager layout, JComponent wrapped) { + super(layout); + add(wrapped); + } + + public Wrapper(boolean isDoubleBuffered) { + super(isDoubleBuffered); + } + + public Wrapper(LayoutManager layout) { + super(layout); + } + + public Wrapper(LayoutManager layout, boolean isDoubleBuffered) { + super(layout, isDoubleBuffered); + } + + public void setContent(JComponent wrapped) { + if (wrapped == getTargetComponent()) { + return; + } + + removeAll(); + setLayout(new BorderLayout()); + if (wrapped != null) { + add(wrapped, BorderLayout.CENTER); + } + } + + public void requestFocus() { + if (getTargetComponent() == this) { + super.requestFocus(); + return; + } + getTargetComponent().requestFocus(); + } + + public final boolean requestFocusInWindow() { + if (getTargetComponent() == this) { + return super.requestFocusInWindow(); + } + return getTargetComponent().requestFocusInWindow(); + } + + public final boolean requestFocus(boolean temporary) { + if (getTargetComponent() == this) { + return super.requestFocus(temporary); + } + return getTargetComponent().requestFocus(temporary); + } + + private JComponent getTargetComponent() { + if (getComponentCount() == 1) { + return (JComponent) getComponent(0); + } else { + return this; + } + } +} diff --git a/openapi/src/com/intellij/ui/messager/Callout.java b/openapi/src/com/intellij/ui/messager/Callout.java new file mode 100644 index 000000000000..1ed98d3a7b09 --- /dev/null +++ b/openapi/src/com/intellij/ui/messager/Callout.java @@ -0,0 +1,99 @@ +/* + * Copyright (c) 2000-2004 by JetBrains s.r.o. All Rights Reserved. + * Use is subject to license terms. + */ +package com.intellij.ui.messager; + +import com.intellij.openapi.application.ApplicationManager; +import com.intellij.ui.TreeUtils; +import com.intellij.ui.awt.RelativePoint; + +import javax.swing.*; +import javax.swing.tree.TreePath; +import java.awt.*; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; + +/** + * @author kir + */ +public class Callout { + + public static final int NORTH_WEST = 1; + public static final int NORTH_EAST = 2; + public static final int SOUTH_WEST = 3; + public static final int SOUTH_EAST = 4; + + public static void showText(JTree tree, TreePath path, int direction, String text) { + showText(TreeUtils.getPointForPath(tree, path), direction, text); + } + + public static void showTextBelow(JComponent component, String text) { + final RelativePoint calloutPoint = RelativePoint.getSouthWestOf(component); + calloutPoint.getPoint().x += 5; + Callout.showText(calloutPoint, Callout.SOUTH_EAST, text); + } + + public static void showText(RelativePoint aPoint, int direction, String text) { + if (ApplicationManager.getApplication().isUnitTestMode()) return; + + JLabel label = new JLabel(text); + label.setHorizontalAlignment(JLabel.CENTER); + + final CalloutComponent callout = new CalloutComponent(label); + callout.show(direction, aPoint); + } + + public static void showText(JComponent component, int direction, String text) { + final RelativePoint point = new RelativePoint(component, new Point(component.getWidth() / 2, component.getHeight() / 2)); + showText(point, direction, text); + } + + + public static void main(String[] args) { + JFrame frame = new JFrame("Portlet Test"); + frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); + frame.setLocation(300, 300); + frame.setSize(200, 200); + + JPanel pane = new JPanel(new FlowLayout()); + + + final JButton first = new JButton("North east"); + first.addActionListener(new ActionListener() { + public void actionPerformed(ActionEvent e) { + Callout.showText(first, Callout.NORTH_EAST, "North east"); + } + }); + pane.add(first); + + final JButton second = new JButton("North west"); + second.addActionListener(new ActionListener() { + public void actionPerformed(ActionEvent e) { + Callout.showText(second, Callout.NORTH_WEST, "North west"); + } + }); + pane.add(second); + + final JButton third = new JButton("South east"); + third.addActionListener(new ActionListener() { + public void actionPerformed(ActionEvent e) { + Callout.showText(third, Callout.SOUTH_EAST, "South east"); + } + }); + pane.add(third); + + final JButton fourth = new JButton("South west"); + fourth.addActionListener(new ActionListener() { + public void actionPerformed(ActionEvent e) { + Callout.showText(fourth, Callout.SOUTH_WEST, "South west"); + } + }); + pane.add(fourth); + + frame.getContentPane().setLayout(new GridBagLayout()); + frame.getContentPane().add(pane); + + frame.setVisible(true); + } +} diff --git a/openapi/src/com/intellij/ui/messager/CalloutComponent.java b/openapi/src/com/intellij/ui/messager/CalloutComponent.java new file mode 100644 index 000000000000..78baa5a57bfb --- /dev/null +++ b/openapi/src/com/intellij/ui/messager/CalloutComponent.java @@ -0,0 +1,383 @@ +/* + * Copyright (c) 2000-2004 by JetBrains s.r.o. All Rights Reserved. + * Use is subject to license terms. + */ +package com.intellij.ui.messager; + + +import com.intellij.ui.DrawUtil; +import com.intellij.ui.LineEndDecorator; +import com.intellij.ui.ScreenUtil; +import com.intellij.ui.UI; +import com.intellij.ui.awt.RelativePoint; +import com.intellij.ui.awt.RelativeRectangle; +import com.intellij.ui.components.panels.NonOpaquePanel; + +import javax.swing.*; +import java.awt.*; +import java.awt.event.*; +import java.awt.geom.Line2D; + +/** + * @author kir + */ +public class CalloutComponent { + + private static final int POINTER_LENGTH = 20; + + private JDialog myFrame; + + private JComponent myInnerComponent; + + private ComponentListener myComponentListener; + private WindowListener myWindowListener; + private WindowStateListener myWindowStateListener; + private AWTEventListener myMulticastListener; + private KeyEventDispatcher myKeyEventDispatcher; + + protected JComponent myTargetComponent; + protected Window myTargetWindow; + protected Pointer myPointerComponent; + private KeyboardFocusManager myKeyboardFocusManager; + + public CalloutComponent(JComponent component) { + super(); + + myKeyboardFocusManager = KeyboardFocusManager.getCurrentKeyboardFocusManager(); + myInnerComponent = component; + myInnerComponent.setBorder(BorderFactory.createEmptyBorder(3, 3, 3, 3)); + + myFrame = new JDialog(); + myFrame.setUndecorated(true); + myFrame.setFocusable(false); + myFrame.setDefaultCloseOperation(JDialog.DO_NOTHING_ON_CLOSE); + myFrame.setFocusableWindowState(false); + + myFrame.getContentPane().setLayout(new BorderLayout()); + myFrame.getContentPane().add(new Wrapper(myInnerComponent), BorderLayout.CENTER); + } + + public void show(int location, final RelativePoint target) { + myFrame.pack(); + Dimension frameSize = myFrame.getPreferredSize(); + + final Point targetScreenPoint = target.getScreenPoint(); + Point framePoint = new Point(); + + switch (location) { + case Callout.NORTH_WEST: + framePoint.x = targetScreenPoint.x - frameSize.width - getPointerShift(); + framePoint.y = targetScreenPoint.y - frameSize.height - getPointerShift(); + break; + case Callout.NORTH_EAST: + framePoint.x = targetScreenPoint.x + getPointerShift(); + framePoint.y = targetScreenPoint.y - frameSize.height - getPointerShift(); + break; + case Callout.SOUTH_EAST: + framePoint.x = targetScreenPoint.x + getPointerShift(); + framePoint.y = targetScreenPoint.y + getPointerShift(); + break; + case Callout.SOUTH_WEST: + framePoint.x = targetScreenPoint.x - frameSize.width - getPointerShift(); + framePoint.y = targetScreenPoint.y + getPointerShift(); + break; + } + + myPointerComponent = new Pointer(location); + + final Rectangle frameBounds = new Rectangle(framePoint, frameSize); + ScreenUtil.moveRectangleToFitTheScreen(frameBounds); + + myTargetComponent = (JComponent) target.getComponent(); + myTargetWindow = SwingUtilities.getWindowAncestor(myTargetComponent); + + final JLayeredPane layered = getLayeredPane(myTargetWindow); + final Rectangle layeredBounds = new RelativeRectangle(layered).getScreenRectangle(); + + final boolean[] outside = getOutsideAxisCodes(layeredBounds, frameBounds); + if (outside != null) { + boolean x = outside[0]; + boolean y = outside[1]; + + switch (location) { + case Callout.NORTH_WEST: + if (x) { + frameBounds.x = layeredBounds.x - frameBounds.width; + } + if (y) { + frameBounds.y = layeredBounds.y - frameBounds.height; + } + break; + case Callout.NORTH_EAST: + if (x) { + frameBounds.x = (int) layeredBounds.getMaxX(); + } + if (y) { + frameBounds.y = layeredBounds.y - frameBounds.height; + } + break; + case Callout.SOUTH_EAST: + if (x) { + frameBounds.x = (int)layeredBounds.getMaxX(); + } + if (y) { + frameBounds.y = (int) layeredBounds.getMaxY(); + } + break; + case Callout.SOUTH_WEST: + if (x) { + frameBounds.x = layeredBounds.x - frameBounds.width; + } + if (y) { + frameBounds.y = (int) layeredBounds.getMaxY(); + } + break; + } + } + + + Point targetLayeredPoint = target.getPoint(layered); + Rectangle frameLayeredBounds = RelativeRectangle.fromScreen(layered, frameBounds).getRectangleOn(layered); + + Rectangle pointerBounds = new Rectangle(); + final int extraPoint = 1; + switch (location) { + case Callout.NORTH_WEST: + pointerBounds.x = (int) frameLayeredBounds.getMaxX() - extraPoint; + pointerBounds.y = (int) frameLayeredBounds.getMaxY() - extraPoint; + pointerBounds.width = targetLayeredPoint.x - pointerBounds.x; + pointerBounds.height = targetLayeredPoint.y - pointerBounds.y; + break; + case Callout.NORTH_EAST: + pointerBounds.x = targetLayeredPoint.x; + pointerBounds.y = (int) frameLayeredBounds.getMaxY() - extraPoint; + pointerBounds.width = frameLayeredBounds.x + extraPoint - targetLayeredPoint.x; + pointerBounds.height = targetLayeredPoint.y - pointerBounds.y; + break; + case Callout.SOUTH_EAST: + pointerBounds.x = targetLayeredPoint.x; + pointerBounds.y = targetLayeredPoint.y; + pointerBounds.width = frameLayeredBounds.x + extraPoint - targetLayeredPoint.x; + pointerBounds.height = (int)frameLayeredBounds.getMaxY() + extraPoint - targetLayeredPoint.y - frameLayeredBounds.height; + break; + case Callout.SOUTH_WEST: + pointerBounds.x = (int) frameLayeredBounds.getMaxX() - extraPoint; + pointerBounds.y = targetLayeredPoint.y; + pointerBounds.width = targetLayeredPoint.x - pointerBounds.x; + pointerBounds.height = frameLayeredBounds.y + extraPoint - targetLayeredPoint.y; + break; + } + + layered.add(myPointerComponent, JLayeredPane.POPUP_LAYER); + myPointerComponent.setBounds(pointerBounds); + + myFrame.setBounds(frameBounds); + myFrame.show(); + + SwingUtilities.invokeLater(new Runnable() { + public void run() { + installDisposeListeners(); + myFrame.show(); + } + }); + } + + private boolean[] getOutsideAxisCodes(final Rectangle layeredBounds, final Rectangle frameBounds) { + boolean x = frameBounds.getMaxX() < layeredBounds.x || layeredBounds.getMaxX() < frameBounds.x; + boolean y = frameBounds.getMaxY() < layeredBounds.y || layeredBounds.getMaxY() < frameBounds.y; + + if (x || y) { + return new boolean[] {x, y}; + } else { + return null; + } + } + + private void installDisposeListeners() { + myKeyEventDispatcher = new KeyEventDispatcher() { + public boolean dispatchKeyEvent(KeyEvent e) { + dispose(); + return false; + } + }; + myKeyboardFocusManager.addKeyEventDispatcher(myKeyEventDispatcher); + + myMulticastListener = new AWTEventListener() { + public void eventDispatched(AWTEvent event) { + switch (event.getID()) { + case MouseEvent.MOUSE_PRESSED: + dispose(); + } + } + }; + + Toolkit.getDefaultToolkit().addAWTEventListener(myMulticastListener, AWTEvent.MOUSE_EVENT_MASK ); + + myComponentListener = new ComponentListener() { + public void componentHidden(ComponentEvent e) { + dispose(); + } + + public void componentMoved(ComponentEvent e) { + dispose(); + } + + public void componentResized(ComponentEvent e) { + dispose(); + } + + public void componentShown(ComponentEvent e) { + dispose(); + } + }; + + myWindowListener = new WindowListener() { + public void windowActivated(WindowEvent e) { + dispose(); + } + + public void windowClosed(WindowEvent e) { + dispose(); + } + + public void windowClosing(WindowEvent e) { + dispose(); + } + + public void windowDeactivated(WindowEvent e) { + dispose(); + } + + public void windowDeiconified(WindowEvent e) { + dispose(); + } + + public void windowIconified(WindowEvent e) { + dispose(); + } + + public void windowOpened(WindowEvent e) { + dispose(); + } + }; + myTargetWindow.addWindowListener(myWindowListener); + + myWindowStateListener = new WindowStateListener() { + public void windowStateChanged(WindowEvent e) { + dispose(); + } + }; + myTargetWindow.addWindowStateListener(myWindowStateListener); + } + + private void dispose() { + + Runnable runnable = new Runnable() { + public void run() { + myFrame.dispose(); + + Toolkit.getDefaultToolkit().removeAWTEventListener(myMulticastListener); + myKeyboardFocusManager.removeKeyEventDispatcher(myKeyEventDispatcher); + + myTargetComponent.removeComponentListener(myComponentListener); + myTargetWindow.removeWindowListener(myWindowListener); + myTargetWindow.removeWindowStateListener(myWindowStateListener); + + final Container parent = myPointerComponent.getParent(); + final Rectangle bounds = myPointerComponent.getBounds(); + if (parent != null) { + parent.remove(myPointerComponent); + parent.repaint(bounds.x, bounds.y, bounds.width, bounds.height); + } + } + }; + + SwingUtilities.invokeLater(runnable); + } + + private int getPointerShift() { + return (int) Math.sqrt(POINTER_LENGTH * POINTER_LENGTH / 2); + } + + private Color getFillColor() { + return UI.getColor("callout.background"); + } + + private Color getBoundsColor() { + return UI.getColor("callout.frame.color"); + } + + private class Wrapper extends NonOpaquePanel { + + public Wrapper(JComponent component) { + setBorder(BorderFactory.createEmptyBorder(2, 3, 2, 3)); + setLayout(new BorderLayout()); + add(component, BorderLayout.CENTER); + } + + protected void paintComponent(Graphics g) { + Graphics2D g2 = (Graphics2D) g; + + final Object old = g2.getRenderingHint(RenderingHints.KEY_ANTIALIASING); + g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); + + g.setColor(getFillColor()); + g.fillRect(1, 1, getWidth() - 2, getHeight() - 2); + + DrawUtil.drawRoundRect(g, 0, 0, getWidth() - 1, getHeight() - 1, getBoundsColor()); + + g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, old); + } + } + + private class Pointer extends NonOpaquePanel { + private int myOrientation; + + public Pointer(int orientation) { + myOrientation = orientation; + } + + protected void paintComponent(Graphics g) { + Graphics2D g2 = (Graphics2D) g; + + final Object old = g2.getRenderingHint(RenderingHints.KEY_ANTIALIASING); + g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); + + g2.setColor(getBoundsColor()); + + Line2D line = new Line2D.Double(); + switch (myOrientation) { + case Callout.NORTH_WEST: + line.setLine(0, 0, getWidth() - 1, getHeight() - 1); + break; + case Callout.NORTH_EAST: + line.setLine(getWidth() - 1, 0, 0, getHeight() -1); + break; + case Callout.SOUTH_EAST: + line.setLine(getWidth() - 1, getHeight() - 1, 0, 0); + break; + case Callout.SOUTH_WEST: + line.setLine(0, getHeight() - 1, getWidth() - 1, 0); + break; + } + + g2.drawLine((int)line.getX1(), (int)line.getY1(), (int)line.getX2(), (int)line.getY2()); + + final Shape arrow = LineEndDecorator.getArrowShape(line, line.getP2()); + g2.fill(arrow); + + g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, old); + } + } + + private JLayeredPane getLayeredPane(Window window) { + if (window instanceof JFrame) { + return ((JFrame) window).getRootPane().getLayeredPane(); + } else if (window instanceof JDialog) { + return ((JDialog) window).getRootPane().getLayeredPane(); + } + + return null; + } + +} diff --git a/source/jetbrains/fbq/diagnostic/AbstractMessage.java b/source/com/intellij/diagnostic/AbstractMessage.java similarity index 97% rename from source/jetbrains/fbq/diagnostic/AbstractMessage.java rename to source/com/intellij/diagnostic/AbstractMessage.java index 88b14b6c9edf..25e485187fef 100644 --- a/source/jetbrains/fbq/diagnostic/AbstractMessage.java +++ b/source/com/intellij/diagnostic/AbstractMessage.java @@ -2,7 +2,7 @@ * Copyright (c) 2000-2004 by JetBrains s.r.o. All Rights Reserved. * Use is subject to license terms. */ -package jetbrains.fbq.diagnostic; +package com.intellij.diagnostic; import com.intellij.openapi.diagnostic.SubmittedReportInfo; diff --git a/source/com/intellij/diagnostic/DefaultIdeaErrorLogger.java b/source/com/intellij/diagnostic/DefaultIdeaErrorLogger.java index 1d6d33d47b2f..57fb186e5c02 100644 --- a/source/com/intellij/diagnostic/DefaultIdeaErrorLogger.java +++ b/source/com/intellij/diagnostic/DefaultIdeaErrorLogger.java @@ -10,7 +10,6 @@ import com.intellij.openapi.application.ex.ApplicationManagerEx; import com.intellij.openapi.diagnostic.ErrorLogger; import com.intellij.openapi.diagnostic.IdeaLoggingEvent; import com.intellij.openapi.util.SystemInfo; -import jetbrains.fbq.diagnostic.MessagePool; import javax.swing.*; import java.io.File; diff --git a/source/jetbrains/fbq/diagnostic/GroupedLogMessage.java b/source/com/intellij/diagnostic/GroupedLogMessage.java similarity index 96% rename from source/jetbrains/fbq/diagnostic/GroupedLogMessage.java rename to source/com/intellij/diagnostic/GroupedLogMessage.java index 4af52a56d8c5..a21826a6773e 100644 --- a/source/jetbrains/fbq/diagnostic/GroupedLogMessage.java +++ b/source/com/intellij/diagnostic/GroupedLogMessage.java @@ -2,7 +2,7 @@ * Copyright (c) 2000-2004 by JetBrains s.r.o. All Rights Reserved. * Use is subject to license terms. */ -package jetbrains.fbq.diagnostic; +package com.intellij.diagnostic; import java.util.List; diff --git a/source/jetbrains/fbq/diagnostic/IdeErrorsDialog.java b/source/com/intellij/diagnostic/IdeErrorsDialog.java similarity index 98% rename from source/jetbrains/fbq/diagnostic/IdeErrorsDialog.java rename to source/com/intellij/diagnostic/IdeErrorsDialog.java index a4e5144abd4f..aeae0e6d5134 100644 --- a/source/jetbrains/fbq/diagnostic/IdeErrorsDialog.java +++ b/source/com/intellij/diagnostic/IdeErrorsDialog.java @@ -2,17 +2,16 @@ * Copyright (c) 2000-2004 by JetBrains s.r.o. All Rights Reserved. * Use is subject to license terms. */ -package jetbrains.fbq.diagnostic; +package com.intellij.diagnostic; /** * @author kir */ -import com.intellij.diagnostic.ErrorHandlerExtension; -import com.intellij.diagnostic.PluginException; import com.intellij.ide.BrowserUtil; import com.intellij.ide.plugins.PluginDescriptor; import com.intellij.ide.plugins.PluginManager; +import com.intellij.ide.reporter.ScrData; import com.intellij.openapi.application.ApplicationManager; import com.intellij.openapi.diagnostic.ErrorReportSubmitter; import com.intellij.openapi.diagnostic.IdeaLoggingEvent; @@ -23,7 +22,6 @@ import com.intellij.openapi.ui.Splitter; import com.intellij.openapi.util.Comparing; import com.intellij.ui.SimpleColoredComponent; import com.intellij.ui.SimpleTextAttributes; -import jetbrains.fbq.ide.reporter.ScrData; import javax.swing.*; import javax.swing.event.ListSelectionEvent; diff --git a/source/jetbrains/fbq/diagnostic/IdeMessagePanel.java b/source/com/intellij/diagnostic/IdeMessagePanel.java similarity index 96% rename from source/jetbrains/fbq/diagnostic/IdeMessagePanel.java rename to source/com/intellij/diagnostic/IdeMessagePanel.java index 5c78d1bedf70..2371dd5d08eb 100644 --- a/source/jetbrains/fbq/diagnostic/IdeMessagePanel.java +++ b/source/com/intellij/diagnostic/IdeMessagePanel.java @@ -2,12 +2,12 @@ * Copyright (c) 2000-2004 by JetBrains s.r.o. All Rights Reserved. * Use is subject to license terms. */ -package jetbrains.fbq.diagnostic; +package com.intellij.diagnostic; import com.intellij.openapi.diagnostic.Logger; import com.intellij.openapi.util.IconLoader; -import jetbrains.fbq.ui.messager.Callout; -import jetbrains.fbq.util.awt.RelativePoint; +import com.intellij.ui.awt.RelativePoint; +import com.intellij.ui.messager.Callout; import javax.swing.*; import java.awt.*; @@ -18,7 +18,7 @@ import java.awt.event.MouseEvent; public class IdeMessagePanel extends JPanel implements MessagePoolListener { - private static final Logger LOG = Logger.getInstance("#jetbrains.fbq.diagnostic.IdeMessagePanel"); + private static final Logger LOG = Logger.getInstance("#com.intellij.diagnostic.IdeMessagePanel"); private IconPane myIdeFatal; diff --git a/source/jetbrains/fbq/diagnostic/LogMessage.java b/source/com/intellij/diagnostic/LogMessage.java similarity index 97% rename from source/jetbrains/fbq/diagnostic/LogMessage.java rename to source/com/intellij/diagnostic/LogMessage.java index ae41448fe09c..a114b1a5b181 100644 --- a/source/jetbrains/fbq/diagnostic/LogMessage.java +++ b/source/com/intellij/diagnostic/LogMessage.java @@ -2,7 +2,7 @@ * Copyright (c) 2000-2004 by JetBrains s.r.o. All Rights Reserved. * Use is subject to license terms. */ -package jetbrains.fbq.diagnostic; +package com.intellij.diagnostic; import com.intellij.openapi.diagnostic.IdeaLoggingEvent; import com.intellij.openapi.util.text.StringUtil; diff --git a/source/jetbrains/fbq/diagnostic/MessagePool.java b/source/com/intellij/diagnostic/MessagePool.java similarity index 99% rename from source/jetbrains/fbq/diagnostic/MessagePool.java rename to source/com/intellij/diagnostic/MessagePool.java index 6c0e6cc61a11..2517ffbc5b8d 100644 --- a/source/jetbrains/fbq/diagnostic/MessagePool.java +++ b/source/com/intellij/diagnostic/MessagePool.java @@ -2,7 +2,7 @@ * Copyright (c) 2000-2004 by JetBrains s.r.o. All Rights Reserved. * Use is subject to license terms. */ -package jetbrains.fbq.diagnostic; +package com.intellij.diagnostic; import com.intellij.openapi.diagnostic.IdeaLoggingEvent; import org.apache.log4j.Category; diff --git a/source/jetbrains/fbq/diagnostic/MessagePoolListener.java b/source/com/intellij/diagnostic/MessagePoolListener.java similarity index 85% rename from source/jetbrains/fbq/diagnostic/MessagePoolListener.java rename to source/com/intellij/diagnostic/MessagePoolListener.java index d38f8ed471f7..222e9382aefc 100644 --- a/source/jetbrains/fbq/diagnostic/MessagePoolListener.java +++ b/source/com/intellij/diagnostic/MessagePoolListener.java @@ -2,7 +2,7 @@ * Copyright (c) 2000-2004 by JetBrains s.r.o. All Rights Reserved. * Use is subject to license terms. */ -package jetbrains.fbq.diagnostic; +package com.intellij.diagnostic; public interface MessagePoolListener { diff --git a/source/jetbrains/fbq/ide/reporter/ConnectionException.java b/source/com/intellij/ide/reporter/ConnectionException.java similarity index 91% rename from source/jetbrains/fbq/ide/reporter/ConnectionException.java rename to source/com/intellij/ide/reporter/ConnectionException.java index eced4f547523..3a1cc336d5c2 100644 --- a/source/jetbrains/fbq/ide/reporter/ConnectionException.java +++ b/source/com/intellij/ide/reporter/ConnectionException.java @@ -2,7 +2,7 @@ * Copyright (c) 2000-2004 by JetBrains s.r.o. All Rights Reserved. * Use is subject to license terms. */ -package jetbrains.fbq.ide.reporter; +package com.intellij.ide.reporter; public class ConnectionException extends Exception { diff --git a/source/com/intellij/openapi/wm/impl/status/StatusBarImpl.java b/source/com/intellij/openapi/wm/impl/status/StatusBarImpl.java index eaed76b5f7d4..3bbb36eb20b5 100644 --- a/source/com/intellij/openapi/wm/impl/status/StatusBarImpl.java +++ b/source/com/intellij/openapi/wm/impl/status/StatusBarImpl.java @@ -1,5 +1,7 @@ package com.intellij.openapi.wm.impl.status; +import com.intellij.diagnostic.IdeMessagePanel; +import com.intellij.diagnostic.MessagePool; import com.intellij.ide.ui.UISettings; import com.intellij.ide.ui.UISettingsListener; import com.intellij.openapi.actionSystem.ActionManager; @@ -7,8 +9,6 @@ import com.intellij.openapi.actionSystem.impl.EmptyIcon; import com.intellij.openapi.util.IconLoader; import com.intellij.openapi.wm.ex.StatusBarEx; import com.intellij.ui.EdgeBorder; -import jetbrains.fbq.diagnostic.IdeMessagePanel; -import jetbrains.fbq.diagnostic.MessagePool; import javax.swing.*; import javax.swing.border.Border;