/* * Jajuk * Copyright (C) The Jajuk Team * http://jajuk.info * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2 * of the License, or any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * */ package org.jajuk.ui.helpers.animations; import java.awt.Dimension; import java.awt.GraphicsEnvironment; import java.awt.Insets; import java.awt.Point; import java.awt.Rectangle; import java.awt.Toolkit; import java.awt.Window; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import javax.swing.SwingUtilities; import javax.swing.Timer; import org.jajuk.util.log.Log; /** * Slide animation implementation. */ public class SlideAnimation extends AbstractAnimation { private ScreenPosition screenPosition; private StartingPosition startingPosition; private Direction direction; private Timer animationTimer; private long animationStart; private Rectangle start; private Rectangle windowBounds; /** Time (ms) of a frame displaying. */ private static final int FRAME_DURATION = 5; /** * Instantiates a new slide animation. * * @param window * @param screenPosition * @param startingPosition * @param direction */ public SlideAnimation(Window window, ScreenPosition screenPosition, StartingPosition startingPosition, Direction direction) { super(window); this.screenPosition = screenPosition; this.startingPosition = startingPosition; this.direction = direction; } /* * (non-Javadoc) * * @see org.jajuk.ui.helpers.animations.IAnimation#animate(int) */ @Override public void animate(final int animationTime) { window.pack(); windowBounds = window.getBounds(); start = startingPosition.getStartingPosition(screenPosition.getScreenPosition(windowBounds)); start.width = windowBounds.width; start.height = windowBounds.height; if (!AWTUtilities.isAvailable()) { SwingUtilities.invokeLater(new Runnable() { @Override public void run() { window.setLocation(direction.getCurrentLocation(start, 1)); new Thread(new Runnable() { @Override public void run() { try { Thread.sleep(animationTime); } catch (Exception ex) { Log.error(ex); } animationCompleted(); } }).start(); } }); return; } ActionListener animationLogic = new ActionListener() { @Override public void actionPerformed(ActionEvent e) { long elapsed = System.currentTimeMillis() - animationStart; if (elapsed > animationTime) { animationTimer.stop(); animationCompleted(); } else { float progress = (float) elapsed / animationTime; window.setLocation(direction.getCurrentLocation(start, progress)); window.setVisible(true); window.repaint(); } } }; animationTimer = new Timer(FRAME_DURATION, animationLogic); animationStart = System.currentTimeMillis(); animationTimer.start(); } /** * Gets the direction. * * @return the direction */ public Direction getDirection() { return direction; } /** * Gets the screen position. * * @return the screen position */ public ScreenPosition getScreenPosition() { return screenPosition; } /** * Gets the starting position. * * @return the starting position */ public StartingPosition getStartingPosition() { return startingPosition; } /** * . */ public interface ScreenPosition { /** * Gets the screen position. * * @param size * * @return the screen position */ Rectangle getScreenPosition(Rectangle size); } /** * . */ public interface StartingPosition { /** * Gets the starting position. * * @param position * * @return the starting position */ Rectangle getStartingPosition(Rectangle position); } /** * . */ public interface Direction { /** * Gets the current location. * * @param start * @param progress * * @return the current location */ Point getCurrentLocation(Rectangle start, float progress); /** * Gets the showing bounds. * * @param start * @param progress * * @return the showing bounds */ Rectangle getShowingBounds(Rectangle start, float progress); } /** * . */ public enum ScreenPositions implements ScreenPosition { TOP_LEFT { @Override public Rectangle getScreenPosition(Rectangle size) { Rectangle bounds = getDesktopBounds(); Rectangle position = new Rectangle(); position.x = bounds.x; position.y = bounds.y; position.width = size.width; position.height = size.height; return position; } }, TOP_RIGHT { @Override public Rectangle getScreenPosition(Rectangle size) { Rectangle bounds = getDesktopBounds(); Rectangle position = new Rectangle(); position.x = bounds.x + bounds.width - size.width; position.y = bounds.y; position.width = size.width; position.height = size.height; return position; } }, BOTTOM_LEFT { @Override public Rectangle getScreenPosition(Rectangle size) { Rectangle bounds = getDesktopBounds(); Rectangle position = new Rectangle(); position.x = bounds.x; position.y = bounds.y + bounds.height - size.height; position.width = size.width; position.height = size.height; return position; } }, BOTTOM_RIGHT { @Override public Rectangle getScreenPosition(Rectangle size) { Rectangle bounds = getDesktopBounds(); Rectangle position = new Rectangle(); position.x = bounds.x + bounds.width - size.width; position.y = bounds.y + bounds.height - size.height; position.width = size.width; position.height = size.height; return position; } }, CURRENT { @Override public Rectangle getScreenPosition(Rectangle size) { return new Rectangle(size); } }; /** * Gets the desktop bounds. * * @return the desktop bounds */ protected Rectangle getDesktopBounds() { // Remove 50 px is useful under Linux as we can't get actual desktop // insets and popup is too low in most cases (see // http://forums.sun.com/thread.jspa?threadID=5169228) Insets insets = Toolkit.getDefaultToolkit().getScreenInsets( GraphicsEnvironment.getLocalGraphicsEnvironment().getDefaultScreenDevice() .getDefaultConfiguration()); if (insets.equals(new Insets(0, 0, 0, 0))) { insets.bottom = 50; } Dimension size = Toolkit.getDefaultToolkit().getScreenSize(); return new Rectangle(insets.left, insets.top, size.width - insets.left - insets.right, size.height - insets.top - insets.bottom); } } /** * . */ public enum StartingPositions implements StartingPosition { TOP { @Override public Rectangle getStartingPosition(Rectangle position) { Rectangle size = new Rectangle(); size.x = position.x; size.y = position.y; size.width = position.width; size.height = 0; return size; } }, BOTTOM { @Override public Rectangle getStartingPosition(Rectangle position) { Rectangle size = new Rectangle(); size.x = position.x; size.y = position.y + position.height; size.width = position.width; size.height = 0; return size; } }, LEFT { @Override public Rectangle getStartingPosition(Rectangle position) { Rectangle size = new Rectangle(); size.x = position.x; size.y = position.y; size.width = 0; size.height = position.height; return size; } }, RIGHT { @Override public Rectangle getStartingPosition(Rectangle position) { Rectangle size = new Rectangle(); size.x = position.x + position.width; size.y = position.y; size.width = 0; size.height = position.height; return size; } }, TOP_LEFT { @Override public Rectangle getStartingPosition(Rectangle position) { Rectangle size = new Rectangle(); size.x = position.x; size.y = position.y; size.width = 0; size.height = 0; return size; } }, TOP_RIGHT { @Override public Rectangle getStartingPosition(Rectangle position) { Rectangle size = new Rectangle(); size.x = position.x + position.width; size.y = position.y; size.width = 0; size.height = 0; return size; } }, BOTTOM_LEFT { @Override public Rectangle getStartingPosition(Rectangle position) { Rectangle size = new Rectangle(); size.x = position.x; size.y = position.y + position.height; size.width = 0; size.height = 0; return size; } }, BOTTOM_RIGHT { @Override public Rectangle getStartingPosition(Rectangle position) { Rectangle size = new Rectangle(); size.x = position.x + position.width; size.y = position.y + position.height; size.width = 0; size.height = 0; return size; } }, FULL { @Override public Rectangle getStartingPosition(Rectangle position) { return new Rectangle(position); } }; } /** * . */ public enum InDirections implements Direction { UP { @Override public Point getCurrentLocation(Rectangle start, float progress) { Point current = new Point(); current.x = start.x; current.y = start.y - (int) (start.height * progress); return current; } @Override public Rectangle getShowingBounds(Rectangle start, float progress) { Rectangle current = new Rectangle(); current.width = start.width; current.height = (int) (start.height * progress); current.x = 0; current.y = 0; return current; } }, DOWN { @Override public Point getCurrentLocation(Rectangle start, float progress) { Point current = new Point(); current.x = start.x; current.y = start.y - (start.height - (int) (start.height * progress)); return current; } @Override public Rectangle getShowingBounds(Rectangle start, float progress) { Rectangle current = new Rectangle(); current.width = start.width; current.height = (int) (start.height * progress); current.x = 0; current.y = start.height - current.height; return current; } }, LEFT { @Override public Point getCurrentLocation(Rectangle start, float progress) { Point current = new Point(); current.x = start.x - (int) (start.width * progress); current.y = start.y; return current; } @Override public Rectangle getShowingBounds(Rectangle start, float progress) { Rectangle current = new Rectangle(); current.width = (int) (start.width * progress); current.height = start.height; current.x = 0; current.y = 0; return current; } }, RIGHT { @Override public Point getCurrentLocation(Rectangle start, float progress) { Point current = new Point(); current.x = start.x - (start.width - (int) (start.width * progress)); current.y = start.y; return current; } @Override public Rectangle getShowingBounds(Rectangle start, float progress) { Rectangle current = new Rectangle(); current.width = (int) (start.width * progress); current.height = start.height; current.x = start.width - current.width; current.y = 0; return current; } }, UP_LEFT { @Override public Point getCurrentLocation(Rectangle start, float progress) { Point current = new Point(); current.x = start.x - (int) (start.width * progress); current.y = start.y - (int) (start.height * progress); return current; } @Override public Rectangle getShowingBounds(Rectangle start, float progress) { Rectangle current = new Rectangle(); current.width = (int) (start.width * progress); current.height = (int) (start.height * progress); current.x = 0; current.y = 0; return current; } }, UP_RIGHT { @Override public Point getCurrentLocation(Rectangle start, float progress) { Point current = new Point(); current.x = start.x - (start.width - (int) (start.width * progress)); current.y = start.y - (int) (start.height * progress); return current; } @Override public Rectangle getShowingBounds(Rectangle start, float progress) { Rectangle current = new Rectangle(); current.width = (int) (start.width * progress); current.height = (int) (start.height * progress); current.x = start.width - current.width; current.y = 0; return current; } }, DOWN_LEFT { @Override public Point getCurrentLocation(Rectangle start, float progress) { Point current = new Point(); current.x = start.x - (int) (start.width * progress); current.y = start.y - (start.height - (int) (start.height * progress)); return current; } @Override public Rectangle getShowingBounds(Rectangle start, float progress) { Rectangle current = new Rectangle(); current.width = (int) (start.width * progress); current.height = (int) (start.height * progress); current.x = 0; current.y = start.height - current.height; return current; } }, DOWN_RIGHT { @Override public Point getCurrentLocation(Rectangle start, float progress) { Point current = new Point(); current.x = start.x - (start.width - (int) (start.width * progress)); current.y = start.y - (start.height - (int) (start.height * progress)); return current; } @Override public Rectangle getShowingBounds(Rectangle start, float progress) { Rectangle current = new Rectangle(); current.width = (int) (start.width * progress); current.height = (int) (start.height * progress); current.x = start.width - current.width; current.y = start.height - current.height; return current; } }; } /** * . */ public enum OutDirections implements Direction { UP { @Override public Point getCurrentLocation(Rectangle start, float progress) { Point current = new Point(); current.x = start.x; current.y = start.y - (int) (start.height * progress); return current; } @Override public Rectangle getShowingBounds(Rectangle start, float progress) { Rectangle current = new Rectangle(); current.width = start.width; current.height = (int) (start.height * (1 - progress)); current.x = 0; current.y = start.height - current.height; return current; } }, DOWN { @Override public Point getCurrentLocation(Rectangle start, float progress) { Point current = new Point(); current.x = start.x; current.y = start.y + (int) (start.height * progress); return current; } @Override public Rectangle getShowingBounds(Rectangle start, float progress) { Rectangle current = new Rectangle(); current.width = start.width; current.height = (int) (start.height * (1 - progress)); current.x = 0; current.y = 0; return current; } }, LEFT { @Override public Point getCurrentLocation(Rectangle start, float progress) { Point current = new Point(); current.x = start.x - (int) (start.width * progress); current.y = start.y; return current; } @Override public Rectangle getShowingBounds(Rectangle start, float progress) { Rectangle current = new Rectangle(); current.width = (int) (start.width * (1 - progress)); current.height = start.height; current.x = start.width - current.width; current.y = 0; return current; } }, RIGHT { @Override public Point getCurrentLocation(Rectangle start, float progress) { Point current = new Point(); current.x = start.x + (int) (start.width * progress); current.y = start.y; return current; } @Override public Rectangle getShowingBounds(Rectangle start, float progress) { Rectangle current = new Rectangle(); current.width = (int) (start.width * (1 - progress)); current.height = start.height; current.x = 0; current.y = 0; return current; } }, UP_LEFT { @Override public Point getCurrentLocation(Rectangle start, float progress) { Point current = new Point(); current.x = start.x - (int) (start.width * progress); current.y = start.y - (int) (start.height * progress); return current; } @Override public Rectangle getShowingBounds(Rectangle start, float progress) { Rectangle current = new Rectangle(); current.width = (int) (start.width * (1 - progress)); current.height = (int) (start.height * (1 - progress)); current.x = start.width - current.width; current.y = start.height - current.height; return current; } }, UP_RIGHT { @Override public Point getCurrentLocation(Rectangle start, float progress) { Point current = new Point(); current.x = start.x + (int) (start.width * progress); current.y = start.y - (int) (start.height * progress); return current; } @Override public Rectangle getShowingBounds(Rectangle start, float progress) { Rectangle current = new Rectangle(); current.width = (int) (start.width * (1 - progress)); current.height = (int) (start.height * (1 - progress)); current.x = 0; current.y = start.height - current.height; return current; } }, DOWN_LEFT { @Override public Point getCurrentLocation(Rectangle start, float progress) { Point current = new Point(); current.x = start.x - (int) (start.width * progress); current.y = start.y + (int) (start.height * progress); return current; } @Override public Rectangle getShowingBounds(Rectangle start, float progress) { Rectangle current = new Rectangle(); current.width = (int) (start.width * (1 - progress)); current.height = (int) (start.height * (1 - progress)); current.x = start.width - current.width; current.y = 0; return current; } }, DOWN_RIGHT { @Override public Point getCurrentLocation(Rectangle start, float progress) { Point current = new Point(); current.x = start.x + (int) (start.width * progress); current.y = start.y + (int) (start.height * progress); return current; } @Override public Rectangle getShowingBounds(Rectangle start, float progress) { Rectangle current = new Rectangle(); current.width = (int) (start.width * (1 - progress)); current.height = (int) (start.height * (1 - progress)); current.x = 0; current.y = 0; return current; } }; } }