/**
* author: Marcel Genzmehr
* 29.11.2011
*/
package org.freeplane.core.ui.components;
import java.awt.Color;
import java.awt.Component;
import java.awt.Container;
import java.awt.Cursor;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import javax.swing.JComponent;
import javax.swing.JPanel;
/**
*
*/
public class OneTouchCollapseResizer extends JResizer {
private static final long serialVersionUID = 3836146387249880446L;
public enum CollapseDirection {COLLAPSE_LEFT, COLLAPSE_RIGHT};
private Dimension lastComponentSize;
protected boolean expanded;
private JPanel hotspot;
private CollapseDirection collapseDirection;
private int inset = 2;
private final Direction direction;
private Integer resizeComponentIndex;
/***********************************************************************************
* CONSTRUCTORS
**********************************************************************************/
/**
* @param d
*/
public OneTouchCollapseResizer(final Direction d, final CollapseDirection collapseDirection) {
super(d);
direction = d;
this.setDividerSize(7);
this.collapseDirection = collapseDirection;
MouseListener listener = new MouseListener() {
private void resetCursor() {
if(d.equals(Direction.RIGHT)){
setCursor(Cursor.getPredefinedCursor(Cursor.W_RESIZE_CURSOR));
}
else if(d.equals(Direction.LEFT)){
setCursor(Cursor.getPredefinedCursor(Cursor.E_RESIZE_CURSOR));
}
else if(d.equals(Direction.UP)){
setCursor(Cursor.getPredefinedCursor(Cursor.S_RESIZE_CURSOR));
}
else /*Direction.DOWN*/ {
setCursor(Cursor.getPredefinedCursor(Cursor.N_RESIZE_CURSOR));
}
}
public void mouseReleased(MouseEvent e) {
}
public void mousePressed(MouseEvent e) {
}
public void mouseExited(MouseEvent e) {
if(e.getComponent() == getHotSpot()) {
resetCursor();
}
if(expanded) {
resetCursor();
}
}
public void mouseEntered(MouseEvent e) {
if(e.getComponent() == getHotSpot()) {
getHotSpot().setCursor(Cursor.getPredefinedCursor(Cursor.HAND_CURSOR));
}
if(!expanded) {
e.getComponent().setCursor(Cursor.getPredefinedCursor(Cursor.HAND_CURSOR));
}
}
public void mouseClicked(MouseEvent e) {
final JComponent parent = (JComponent) getParent();
final Component resizedComponent = parent.getComponent(resizeComponentIndex);
if(e.getComponent() == getHotSpot()) {
final Dimension size = new Dimension(resizedComponent.getPreferredSize());
if (expanded) {
getHotSpot().setEnabled(true);
lastComponentSize = new Dimension(size);
// if(d.equals(Direction.RIGHT) || d.equals(Direction.LEFT)){
// size.width = getDivederSize();
// }
// else if(d.equals(Direction.UP) || d.equals(Direction.DOWN)){
// size.height = getDivederSize();
// }
resizedComponent.setPreferredSize(new Dimension(0,0));
expanded = false;
}
else {
resizedComponent.setPreferredSize(lastComponentSize);
expanded = true;
}
parent.revalidate();
parent.repaint();
}
else {
if (!expanded) {
resizedComponent.setPreferredSize(lastComponentSize);
expanded = true;
parent.revalidate();
parent.repaint();
}
}
}
};
getHotSpot().addMouseListener(listener);
addMouseListener(listener);
add(getHotSpot());
}
/***********************************************************************************
* METHODS
**********************************************************************************/
public void setDividerSize(int size) {
final int w;
final int h;
if(direction.equals(Direction.RIGHT)){
w = size;
h = 0;
}
else if(direction.equals(Direction.LEFT)){
h = size;
w = 0;
}
else if(direction.equals(Direction.UP)){
h = 0;
w = size;
}
else /*Direction.DOWN*/ {
h = 0;
w = size;
}
setPreferredSize(new Dimension(w, h));
}
public int getDivederSize() {
if(direction.equals(Direction.RIGHT) || direction.equals(Direction.LEFT)){
return getPreferredSize().width;
}
else /*Direction.DOWN || Direction.UP*/ {
return getPreferredSize().height;
}
}
private Component getResizedParent() {
final JComponent parent = (JComponent) getParent();
return parent.getComponent(resizeComponentIndex);
}
public void paint(Graphics g) {
if(resizeComponentIndex == null) {
resizeComponentIndex = getIndex();
lastComponentSize = new Dimension(getResizedParent().getPreferredSize());
}
super.paint(g);
int center_y = getHeight()/2;
int divSize = getDivederSize();
getHotSpot().setBounds(0, center_y-15, divSize, 30);
Dimension size = getResizedParent().getPreferredSize();
if((direction.equals(Direction.RIGHT) || direction.equals(Direction.LEFT)) && size.width <= getDivederSize()) {
expanded = false;
}
else if((direction.equals(Direction.UP) || direction.equals(Direction.DOWN)) && size.height <= getDivederSize()){
expanded = false;
}
else {
expanded = true;
//getHotSpot().setBounds(0, 0, getDividerSize(), 24);
}
getHotSpot().paint(g.create(getHotSpot().getLocation().x, getHotSpot().getLocation().y, getHotSpot().getWidth(), getHotSpot().getHeight()));
}
private Component getHotSpot() {
if(hotspot == null) {
hotspot = new JPanel() {
private static final long serialVersionUID = -5321517835206976034L;
public void paint(Graphics g) {
if (expanded) {
drawCollapseLabel(g);
}
else {
drawExpandLabel(g);
}
}
};
}
return hotspot;
}
private void drawCollapseLabel(Graphics g) {
Dimension size = g.getClipBounds().getSize();
int half_length = Math.round(g.getClipBounds().height*0.2f);
int center_y = size.height / 2;
g.setColor(getBackground());
g.fillRect(0, 0, size.width, size.height-0);
//g.setColor();
if(this.collapseDirection.equals(CollapseDirection.COLLAPSE_LEFT)) {
arrowLeft(g, size, half_length, center_y);
}
else if(this.collapseDirection.equals(CollapseDirection.COLLAPSE_RIGHT)) {
arrowRight(g, half_length, center_y);
}
}
private void drawExpandLabel(Graphics g) {
Dimension size = g.getClipBounds().getSize();
int half_length = (g.getClipBounds().height-(inset*6))/2;
int center_y = size.height / 2;
g.setColor(getBackground());
g.fillRect(0, 0, size.width, size.height-0);
if(this.collapseDirection.equals(CollapseDirection.COLLAPSE_LEFT)) {
arrowRight(g, half_length, center_y);
}
else if(this.collapseDirection.equals(CollapseDirection.COLLAPSE_RIGHT)) {
arrowLeft(g, size, half_length, center_y);
}
}
/**
* @param g
* @param size
* @param half_length
* @param center_y
*/
private void arrowLeft(Graphics g, Dimension size, int half_length, int center_y) {
int[] x = new int[]{inset, size.width - inset, size.width - inset};
int[] y = new int[]{center_y, center_y-half_length, center_y + half_length};
g.setColor(Color.DARK_GRAY);
g.fillPolygon(x, y, 3);
g.setColor(Color.DARK_GRAY);
g.drawLine(inset, center_y, size.width - inset, center_y - half_length);
g.setColor(Color.GRAY);
g.drawLine( size.width - inset, center_y + half_length, inset, center_y);
g.setColor(Color.GRAY);
g.drawLine( size.width - inset, center_y - half_length, size.width - inset, center_y + half_length);
}
/**
* @param g
* @param half_length
* @param center_y
*/
private void arrowRight(Graphics g, int half_length, int center_y) {
int[] x = new int[]{inset, inset, getSize().width - inset};
int[] y = new int[]{center_y+half_length, center_y-half_length, center_y};
g.setColor( Color.DARK_GRAY);
g.fillPolygon(x,y,3);
g.setColor( Color.DARK_GRAY);
g.drawLine( inset, center_y + half_length, inset, center_y - half_length);
g.setColor(Color.GRAY);
g.drawLine( inset, center_y - half_length, getSize().width - inset, center_y);
g.setColor( Color.LIGHT_GRAY);
g.drawLine( getSize().width - inset, center_y, inset, center_y + half_length);
}
private int getIndex() {
final Container parent = getParent();
for(int i = 0; i < parent.getComponentCount(); i++ ){
if(OneTouchCollapseResizer.this.equals(parent.getComponent(i))){
if(direction.equals(Direction.RIGHT)){
return i + 1;
}
else if(direction.equals(Direction.LEFT)){
return i - 1;
}
else if(direction.equals(Direction.UP)){
return i - 1;
}
else if(direction.equals(Direction.DOWN)){
return i + 1;
}
}
}
return -1;
}
/***********************************************************************************
* REQUIRED METHODS FOR INTERFACES
**********************************************************************************/
}