blob: a3384212e0f38b2e0994fe5f88298606a078dc9f [file] [log] [blame]
/*
* Copyright 2000-2009 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.ui;
import com.intellij.openapi.util.Weighted;
import com.intellij.openapi.wm.IdeGlassPane;
import com.intellij.ui.awt.RelativePoint;
import com.intellij.ui.popup.AbstractPopup;
import org.intellij.lang.annotations.JdkConstants;
import javax.swing.*;
import java.awt.*;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.event.MouseMotionListener;
/**
* User: anna
* Date: 13-Mar-2006
*/
public class ResizeComponentListener extends MouseAdapter implements MouseMotionListener, Weighted {
private static final int SENSITIVITY = 4;
private final AbstractPopup myPopup;
private final AbstractPopup.MyContentPanel myComponent;
private Point myStartPoint = null;
@JdkConstants.CursorType private int myDirection = -1;
private final IdeGlassPane myGlassPane;
public ResizeComponentListener(final AbstractPopup popup, IdeGlassPane glassPane) {
myPopup = popup;
myComponent = (AbstractPopup.MyContentPanel)popup.getContent();
myGlassPane = glassPane;
}
@Override
public double getWeight() {
return 0.5;
}
public void mousePressed(MouseEvent e) {
final Window popupWindow = SwingUtilities.windowForComponent(myComponent);
if (popupWindow != null) {
myStartPoint = new RelativePoint(e).getScreenPoint();
myDirection = getDirection(myStartPoint, popupWindow.getBounds());
if (myDirection == Cursor.DEFAULT_CURSOR){
myStartPoint = null;
} else {
if (isToShowBorder()) {
myComponent.setBorder(BorderFactory.createMatteBorder(2, 2, 2, 2, Color.black.brighter()));
}
}
}
}
public void mouseClicked(MouseEvent e) {
endOperation();
}
public void mouseReleased(MouseEvent e) {
endOperation();
}
public void mouseExited(MouseEvent e) {
final Window popupWindow = SwingUtilities.windowForComponent(myComponent);
if (popupWindow == null) return;
clearBorder(popupWindow);
}
private void endOperation() {
final Window popupWindow = SwingUtilities.windowForComponent(myComponent);
if (popupWindow != null) {
if (isToShowBorder()) {
myComponent.setBorder(BorderFactory.createEmptyBorder(2,2,2,2));
}
Dimension size = popupWindow.getSize();
Dimension minSize = popupWindow.getMinimumSize();
if (size.width < minSize.width) {
size.width = minSize.width;
}
if (size.height < minSize.height) {
size.height = minSize.height;
}
popupWindow.setSize(size);
popupWindow.validate();
popupWindow.repaint();
setWindowCursor(Cursor.DEFAULT_CURSOR);
myPopup.storeDimensionSize(popupWindow.getSize());
}
myStartPoint = null;
myDirection = Cursor.CUSTOM_CURSOR;
}
private boolean isToShowBorder() {
return false;
}
private void doResize(final Point point) {
final Window popupWindow = SwingUtilities.windowForComponent(myComponent);
final Rectangle bounds = popupWindow.getBounds();
final Point location = popupWindow.getLocation();
switch (myDirection){
case Cursor.NW_RESIZE_CURSOR :
popupWindow.setBounds(location.x + point.x - myStartPoint.x,
location.y + point.y - myStartPoint.y,
bounds.width + myStartPoint.x - point.x,
bounds.height + myStartPoint.y - point.y );
break;
case Cursor.N_RESIZE_CURSOR :
popupWindow.setBounds(location.x,
location.y + point.y - myStartPoint.y,
bounds.width,
bounds.height + myStartPoint.y - point.y);
break;
case Cursor.NE_RESIZE_CURSOR :
popupWindow.setBounds(location.x,
location.y + point.y - myStartPoint.y,
bounds.width + point.x - myStartPoint.x,
bounds.height + myStartPoint.y - point.y);
break;
case Cursor.E_RESIZE_CURSOR :
popupWindow.setBounds(location.x ,
location.y,
bounds.width + point.x - myStartPoint.x,
bounds.height);
break;
case Cursor.SE_RESIZE_CURSOR :
popupWindow.setBounds(location.x,
location.y,
bounds.width + point.x - myStartPoint.x,
bounds.height + point.y - myStartPoint.y);
break;
case Cursor.S_RESIZE_CURSOR :
popupWindow.setBounds(location.x,
location.y,
bounds.width ,
bounds.height + point.y - myStartPoint.y);
break;
case Cursor.SW_RESIZE_CURSOR :
popupWindow.setBounds(location.x + point.x - myStartPoint.x,
location.y,
bounds.width + myStartPoint.x - point.x,
bounds.height + point.y - myStartPoint.y);
break;
case Cursor.W_RESIZE_CURSOR :
popupWindow.setBounds(location.x + point.x - myStartPoint.x,
location.y,
bounds.width + myStartPoint.x - point.x,
bounds.height);
break;
}
popupWindow.validate();
}
public void mouseMoved(MouseEvent e) {
Point point = new RelativePoint(e).getScreenPoint();
final Window popupWindow = SwingUtilities.windowForComponent(myComponent);
if (popupWindow == null) return;
final int cursor = getDirection(point, popupWindow.getBounds());
if (cursor != Cursor.DEFAULT_CURSOR){
if (isToShowBorder()) {
if (myStartPoint == null) {
myComponent.setBorder(BorderFactory.createMatteBorder(2, 2, 2, 2, Color.black.brighter()));
}
}
setWindowCursor(cursor);
e.consume();
} else {
clearBorder(popupWindow);
}
}
private void setWindowCursor(@JdkConstants.CursorType int cursor) {
myGlassPane.setCursor(Cursor.getPredefinedCursor(cursor), this);
}
private void clearBorder(final Window popupWindow) {
if (isToShowBorder()){
myComponent.setBorder(BorderFactory.createEmptyBorder(2, 2, 2, 2));
}
setWindowCursor(Cursor.DEFAULT_CURSOR);
}
public void mouseDragged(MouseEvent e) {
if (e.isConsumed()) return;
final Point point = new RelativePoint(e).getScreenPoint();
final Window popupWindow = SwingUtilities.windowForComponent(myComponent);
if (popupWindow == null) return;
if (myStartPoint != null) {
if (isToShowBorder()) {
setWindowCursor(myDirection);
}
doResize(point);
myStartPoint = point;
e.consume();
} else {
if (isToShowBorder()) {
final int cursor = getDirection(point, popupWindow.getBounds());
setWindowCursor(cursor);
}
}
}
@JdkConstants.CursorType
private int getDirection(Point startPoint, Rectangle bounds){
if (myPopup.isToDrawMacCorner()){
if (bounds.x + bounds.width - startPoint.x < 16 && //inside icon
bounds.y + bounds.height - startPoint.y < 16 &&
bounds.y + bounds.height - startPoint.y > 0 &&
bounds.x + bounds.width - startPoint.x > 0){
return Cursor.SE_RESIZE_CURSOR;
}
}
bounds = new Rectangle(bounds.x + 2, bounds.y + 2, bounds.width - 2, bounds.height - 2);
if (!bounds.contains(startPoint)){
return Cursor.DEFAULT_CURSOR;
}
if (Math.abs(startPoint.x - bounds.x ) < SENSITIVITY){ //left bound
if (Math.abs(startPoint.y - bounds.y) < SENSITIVITY){ //top
return Cursor.NW_RESIZE_CURSOR;
} else if (Math.abs(bounds.y + bounds.height - startPoint.y) < SENSITIVITY) { //bottom
return Cursor.SW_RESIZE_CURSOR;
} else { //edge
return Cursor.W_RESIZE_CURSOR;
}
} else if (Math.abs(bounds.x + bounds.width - startPoint.x) < SENSITIVITY){ //right
if (Math.abs(startPoint.y - bounds.y) < SENSITIVITY){ //top
return Cursor.NE_RESIZE_CURSOR;
} else if (Math.abs(bounds.y + bounds.height - startPoint.y) < SENSITIVITY) { //bottom
return Cursor.SE_RESIZE_CURSOR;
} else { //edge
return Cursor.E_RESIZE_CURSOR;
}
} else { //other
if (Math.abs(startPoint.y - bounds.y) < SENSITIVITY){ //top
return Cursor.N_RESIZE_CURSOR;
} else if (Math.abs(bounds.y + bounds.height - startPoint.y) < SENSITIVITY) { //bottom
return Cursor.S_RESIZE_CURSOR;
} else { //edge
return Cursor.DEFAULT_CURSOR;
}
}
}
}