| /* |
| * 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; |
| } |
| } |
| } |
| } |