blob: 0bace9ae6e8f4829c900e600377368d3f201eb8b [file] [log] [blame]
/*
* Copyright 2000-2012 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.intellij.ide.dnd;
import com.intellij.icons.AllIcons;
import com.intellij.openapi.ui.MessageType;
import com.intellij.openapi.ui.popup.Balloon;
import com.intellij.openapi.ui.popup.JBPopupFactory;
import com.intellij.openapi.util.registry.Registry;
import com.intellij.ui.JBColor;
import com.intellij.ui.awt.RelativePoint;
import javax.swing.*;
import java.awt.*;
import java.util.ArrayList;
import java.util.List;
public class Highlighters implements DnDEvent.DropTargetHighlightingType {
private static final List<DropTargetHighlighter> ourHightlighters = new ArrayList<DropTargetHighlighter>();
private static final ArrayList<DropTargetHighlighter> ourCurrentHighlighters = new ArrayList<DropTargetHighlighter>();
static {
ourHightlighters.add(new RectangleHighlighter());
ourHightlighters.add(new FilledRectangleHighlighter());
ourHightlighters.add(new HorizontalLinesHighlighter());
ourHightlighters.add(new TextHighlighter());
ourHightlighters.add(new ErrorTextHighlighter());
ourHightlighters.add(new VerticalLinesHighlighter());
}
static void show(int aType, JLayeredPane aPane, Rectangle aRectangle, DnDEvent aEvent) {
List<DropTargetHighlighter> toShow = new ArrayList<DropTargetHighlighter>();
for (DropTargetHighlighter ourHightlighter : ourHightlighters) {
DropTargetHighlighter each = (DropTargetHighlighter)ourHightlighter;
if ((each.getMask() & aType) != 0) {
toShow.add(each);
}
}
for (int i = 0; i < toShow.size(); i++) {
DropTargetHighlighter each = toShow.get(i);
each.show(aPane, aRectangle, aEvent);
}
ourCurrentHighlighters.addAll(toShow);
}
static void hideAllBut(int aType) {
for (int i = 0; i < ourCurrentHighlighters.size(); i++) {
final DropTargetHighlighter each = ourCurrentHighlighters.get(i);
if ((each.getMask() & aType) == 0) {
each.vanish();
ourCurrentHighlighters.remove(each);
}
}
}
static void hide() {
for (int i = 0; i < ourCurrentHighlighters.size(); i++) {
(ourCurrentHighlighters.get(i)).vanish();
}
ourCurrentHighlighters.clear();
}
static void hide(int aType) {
for (int i = 0; i < ourCurrentHighlighters.size(); i++) {
final DropTargetHighlighter each = ourCurrentHighlighters.get(i);
if ((each.getMask() & aType) != 0) {
each.vanish();
ourCurrentHighlighters.remove(each);
}
}
}
static boolean isVisibleExcept(int type) {
int resultType = type;
for (int i = 0; i < ourCurrentHighlighters.size(); i++) {
final DropTargetHighlighter each = ourCurrentHighlighters.get(i);
resultType = resultType | each.getMask();
}
return type != resultType;
}
static boolean isVisible() {
return ourCurrentHighlighters.size() > 0;
}
private static abstract class AbstractComponentHighlighter extends JPanel implements DropTargetHighlighter {
protected AbstractComponentHighlighter() {
setOpaque(false);
setLayout(new BorderLayout());
}
public final void show(JLayeredPane aPane, Rectangle aRectangle, DnDEvent aEvent) {
if (getParent() != aPane) {
vanish();
aPane.add(this, getLayer());
}
_show(aPane, aRectangle, aEvent);
}
protected Integer getLayer() {
return JLayeredPane.MODAL_LAYER;
}
public void vanish() {
final Container parent = getParent();
Rectangle bounds = getBounds();
if (parent != null) {
parent.remove(this);
parent.repaint(bounds.x, bounds.y, bounds.width, bounds.height);
}
}
protected abstract void _show(JLayeredPane aPane, Rectangle aRectangle, DnDEvent aEvent);
}
public abstract static class BaseTextHighlighter implements DropTargetHighlighter {
private Balloon myCurrentBalloon;
private MessageType myMessageType;
public BaseTextHighlighter(MessageType type) {
myMessageType = type;
}
public void show(JLayeredPane aPane, Rectangle aRectangle, DnDEvent aEvent) {
if (!Registry.is("ide.dnd.textHints")) return;
final String result = aEvent.getExpectedDropResult();
if (result != null && result.length() > 0) {
RelativePoint point = null;
for (DropTargetHighlighter each : ourHightlighters) {
if (each instanceof AbstractComponentHighlighter) {
Rectangle rec = ((AbstractComponentHighlighter)each).getBounds();
point = new RelativePoint(aPane, new Point(rec.x + rec.width, rec.y + rec.height / 2));
break;
}
}
if (point == null) {
point = new RelativePoint(aPane, new Point(aRectangle.x + aRectangle.width, aRectangle.y + aRectangle.height / 2));
}
myCurrentBalloon = JBPopupFactory.getInstance().createHtmlTextBalloonBuilder(result, myMessageType, null).createBalloon();
myCurrentBalloon.show(point, Balloon.Position.atRight);
}
}
public void vanish() {
if (myCurrentBalloon != null) {
myCurrentBalloon.hide();
myCurrentBalloon = null;
}
}
protected Integer getLayer() {
return JLayeredPane.POPUP_LAYER;
}
}
public static class TextHighlighter extends BaseTextHighlighter {
public TextHighlighter() {
super(MessageType.INFO);
}
public int getMask() {
return TEXT;
}
}
private static class ErrorTextHighlighter extends BaseTextHighlighter {
public ErrorTextHighlighter() {
super(MessageType.ERROR);
}
public int getMask() {
return ERROR_TEXT;
}
}
private static class FilledRectangleHighlighter extends AbstractComponentHighlighter {
public FilledRectangleHighlighter() {
super();
setOpaque(true);
setBorder(BorderFactory.createLineBorder(JBColor.RED));
setBackground(JBColor.RED);
}
protected void _show(JLayeredPane aPane, Rectangle aRectangle, DnDEvent aEvent) {
setBounds(aRectangle);
}
public int getMask() {
return FILLED_RECTANGLE;
}
}
private static class RectangleHighlighter extends AbstractComponentHighlighter {
public RectangleHighlighter() {
super();
setOpaque(false);
setBorder(BorderFactory.createLineBorder(JBColor.RED));
}
protected void _show(JLayeredPane aPane, Rectangle aRectangle, DnDEvent aEvent) {
setBounds(aRectangle);
}
public int getMask() {
return RECTANGLE;
}
}
private static class HorizontalLinesHighlighter extends AbstractComponentHighlighter {
protected void _show(JLayeredPane aPane, Rectangle aRectangle, DnDEvent aEvent) {
final Rectangle rectangle = new Rectangle(aRectangle.x - AllIcons.Ide.Dnd.Left.getIconWidth(), aRectangle.y - AllIcons.Ide.Dnd.Left
.getIconHeight(), aRectangle.width + AllIcons.Ide.Dnd.Left.getIconWidth() + AllIcons.Ide.Dnd.Right.getIconWidth(), aRectangle.height + AllIcons.Ide.Dnd.Left
.getIconHeight());
setBounds(rectangle);
}
protected void paintComponent(Graphics g) {
AllIcons.Ide.Dnd.Left.paintIcon(this, g, 0, (getHeight() / 2));
AllIcons.Ide.Dnd.Right.paintIcon(this, g, getWidth() - AllIcons.Ide.Dnd.Right.getIconWidth(), (getHeight() / 2));
}
public int getMask() {
return H_ARROWS;
}
}
private static class VerticalLinesHighlighter extends AbstractComponentHighlighter {
private static final Icon TOP = AllIcons.Ide.Dnd.Top;
private static final Icon BOTTOM = AllIcons.Ide.Dnd.Bottom;
protected void _show(JLayeredPane aPane, Rectangle aRectangle, DnDEvent aEvent) {
final Rectangle rectangle = new Rectangle(aRectangle.x, aRectangle.y - TOP.getIconHeight(), aRectangle.width, aRectangle.height + TOP.getIconHeight() + BOTTOM
.getIconHeight());
setBounds(rectangle);
}
protected void paintComponent(Graphics g) {
TOP.paintIcon(this, g, (getWidth() - TOP.getIconWidth()) / 2, 0);
BOTTOM.paintIcon(this, g, (getWidth() - BOTTOM.getIconWidth()) / 2, getHeight() - BOTTOM.getIconHeight());
}
public int getMask() {
return V_ARROWS;
}
}
}