/********************************************************************************
* *
* (c) Copyright 2010 Verizon Communications USA and The Open University UK *
* *
* This software is freely distributed in accordance with *
* the GNU Lesser General Public (LGPL) license, version 3 or later *
* as published by the Free Software Foundation. *
* For details see LGPL: http://www.fsf.org/licensing/licenses/lgpl.html *
* and GPL: http://www.fsf.org/licensing/licenses/gpl-3.0.html *
* *
* This software is provided by the copyright holders and contributors "as is" *
* and any express or implied warranties, including, but not limited to, the *
* implied warranties of merchantability and fitness for a particular purpose *
* are disclaimed. In no event shall the copyright owner or contributors be *
* liable for any direct, indirect, incidental, special, exemplary, or *
* consequential damages (including, but not limited to, procurement of *
* substitute goods or services; loss of use, data, or profits; or business *
* interruption) however caused and on any theory of liability, whether in *
* contract, strict liability, or tort (including negligence or otherwise) *
* arising in any way out of the use of this software, even if advised of the *
* possibility of such damage. *
* *
********************************************************************************/
package com.compendium.ui.movie;
import java.awt.AlphaComposite;
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Component;
import java.awt.Cursor;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Insets;
import java.awt.Point;
import java.awt.Rectangle;
import java.awt.event.FocusEvent;
import java.awt.event.FocusListener;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.awt.event.MouseMotionListener;
import java.io.File;
import java.io.IOException;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.Vector;
import javax.media.CannotRealizeException;
import javax.media.Manager;
import javax.media.MediaLocator;
import javax.media.NoDataSourceException;
import javax.media.NoPlayerException;
import javax.media.PackageManager;
import javax.media.Player;
import javax.media.PlugInManager;
import javax.media.Time;
import javax.media.control.FramePositioningControl;
import javax.media.protocol.DataSource;
import javax.swing.JComponent;
import javax.swing.JOptionPane;
import javax.swing.JViewport;
import javax.swing.SwingUtilities;
import javax.swing.border.AbstractBorder;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.compendium.LanguageProperties;
import com.compendium.ProjectCompendium;
import com.compendium.core.CoreUtilities;
import com.compendium.core.datamodel.Movie;
import com.compendium.core.datamodel.MovieMapView;
import com.compendium.core.datamodel.MovieProperties;
public class UIMoviePanel extends JComponent implements MouseListener, MouseMotionListener,
KeyListener, FocusListener {
/**
* class's own logger
*/
final Logger log = LoggerFactory.getLogger(getClass());
/** A reference to the selected property for PropertyChangeEvents.*/
public static final String SELECTED_PROPERTY = "movieselected"; //$NON-NLS-1$
/** A reference to the rollover property for PropertyChangeEvents.*/
public final static String ROLLOVER_PROPERTY = "moviesrollover"; //$NON-NLS-1$
public static final int BORDER_WIDTH = 6;
// The multiplier for the large size
private static final int LARGE_SIZE_MULTIPLIER = 2;
// The divider for the small size
private static final int SMALL_SIZE_DIVIDER = 2;
// The default width of the video
private static final int DEFAULT_WIDTH = 352;
// The offset of the key pressed
private static final int KEY_OFFSET = 5;
// The width to remove for key '4'
private static final int NEGATIVE_MULTIPLIER_WIDTH = 59;
// The width to add for key '6'
private static final int POSITIVE_MULTIPLIER_WIDTH = 118;
// The height to remove for key '4'
private static final int NEGATIVE_MULTIPLIER_HEIGHT = 48;
// The width to add for key '6'
private static final int POSITIVE_MULTIPLIER_HEIGHT = 96;
/** Is this movie currently selected?*/
private boolean bSelected = false;
/** Has the mouse rolled over this movie*/
private boolean bRollover = false;
private Component oMovieControls = null;
private Component oVideo = null;
private FramePositioningControl fpc = null;
private Player mediaPlayer = null;
/** The duration of this movie.*/
private Time duration = null;
/** The data object holding the map info on this Movie*/
private Movie oMovie = null;
/** The map data object this movie is in.*/
private MovieMapView oMovieMapView = null;
/** The map ui object this movie is in.*/
private UIMovieMapViewPane oMovieMapViewPane = null;
private boolean inTopLeftSquare = false;
private boolean inTopRightSquare = false;
private boolean inBottomLeftSquare = false;
private boolean inBottomRightSquare = false;
private Dimension movieSize = null;
private int videoWidth = 0;
private int videoHeight = 0;
private int lastMousePosX = 0;
private int lastMousePosY = 0;
//private RGBRenderer renderer = new RGBRenderer(new Effect[]{});
private DataSource dataSource = null;
private MovieProperties currentProps = null;
public UIMoviePanel(Movie movie, MovieMapView view, UIMovieMapViewPane pane) {
Vector<String> prefixes = new Vector<String>();
prefixes.add("com.omnividea"); //$NON-NLS-1$
prefixes.addAll(PackageManager.getProtocolPrefixList());
PackageManager.setProtocolPrefixList(prefixes);
oMovie = movie;
currentProps = movie.getStartingProperties();
oMovieMapView = view;
oMovieMapViewPane = pane;
addMouseListener(this);
addMouseMotionListener(this);
addKeyListener(this);
addFocusListener(this);
setLayout( new BorderLayout() );
setBorder(new MovieBorder(BORDER_WIDTH, this));
// Use lightweight components for Swing compatibility
Manager.setHint( Manager.LIGHTWEIGHT_RENDERER, true );
}
/**
* Create a new Player and load the Movie.
* @param movieFile the path to the movie to load.
* @return the new Player object, or null if there was an error.
*/
public Player createMoviePlayer(String movieFile) {
URL url = null;
try {
if (CoreUtilities.isFile(movieFile)) {
File file = new File(movieFile);
url = file.toURL();
} else {
url = new URL(movieFile);
}
// create a player to play the media specified in the URL
mediaPlayer = Manager.createRealizedPlayer( url );
duration = mediaPlayer.getDuration();
//So shows first frame when map opened.Else if just gray square.
mediaPlayer.prefetch();
// get the components for the video and the playback controls
oVideo = mediaPlayer.getVisualComponent();
if (oVideo != null) {
movieSize = oVideo.getPreferredSize();
videoWidth = movieSize.width;
videoHeight = movieSize.height;
if (currentProps == null) {
currentProps = oMovie.getStartingProperties();
}
oMovie.setDefaultWidth(videoWidth);
oMovie.setDefaultHeight(videoHeight);
oMovieControls = mediaPlayer.getControlPanelComponent();
add( oVideo, BorderLayout.CENTER ); // add video component
} else {
log.info("Video = null");
ProjectCompendium.APP.displayError(LanguageProperties.getString(LanguageProperties.MOVIE_BUNDLE, "UIMoviePanel.errorSorry")+"\n\n"+LanguageProperties.getString(LanguageProperties.MOVIE_BUNDLE, "UIMoviePanel.errorSorry2")); //$NON-NLS-1$
mediaPlayer = null;
}
} catch ( NoPlayerException noPlayerException ) {
ProjectCompendium.APP.displayError(LanguageProperties.getString(LanguageProperties.MOVIE_BUNDLE, "UIMoviePanel.errorSorry")+"\n\n"+LanguageProperties.getString(LanguageProperties.MOVIE_BUNDLE, "UIMoviePanel.errorSorry2")); //$NON-NLS-1$
log.info("No player found:"+noPlayerException.getLocalizedMessage()); //$NON-NLS-1$
mediaPlayer = null;
} catch ( CannotRealizeException cannotRealizeException ) {
ProjectCompendium.APP.displayError(LanguageProperties.getString(LanguageProperties.MOVIE_BUNDLE, "UIMoviePanel.errorSorry")+"\n\n"+LanguageProperties.getString(LanguageProperties.MOVIE_BUNDLE, "UIMoviePanel.errorSorry2")); //$NON-NLS-1$
log.info("Could not realize media player:"+cannotRealizeException.getLocalizedMessage()); //$NON-NLS-1$
mediaPlayer = null;
} catch (MalformedURLException e) {
ProjectCompendium.APP.displayError(LanguageProperties.getString(LanguageProperties.MOVIE_BUNDLE, "UIMoviePanel.errorSorry")+"\n\n"+LanguageProperties.getString(LanguageProperties.MOVIE_BUNDLE, "UIMoviePanel.errorSorry2")); //$NON-NLS-1$
log.info("MalformedURL:"+e.getLocalizedMessage()); //$NON-NLS-1$
mediaPlayer = null;
} catch ( IOException iOException ) {
ProjectCompendium.APP.displayError(LanguageProperties.getString(LanguageProperties.MOVIE_BUNDLE, "UIMoviePanel.errorSorry")+"\n\n"+LanguageProperties.getString(LanguageProperties.MOVIE_BUNDLE, "UIMoviePanel.errorSorry2")); //$NON-NLS-1$
log.info("IOException:"+iOException.getLocalizedMessage()); //$NON-NLS-1$
mediaPlayer = null;
}
return mediaPlayer;
}
/**
* Create a new Player and load the Grid Movie.
* @param sFile the path to the grid file for the grid movie
* @return the new Player object, or null if there was an error.
*/
public Player createGridStreamPlayer(String sFile, long seek, double scale) {
try {
PlugInManager.removePlugIn("com.sun.media.codec.video.h261.NativeDecoder", PlugInManager.CODEC); //$NON-NLS-1$
MediaLocator locator = new MediaLocator("recorded://" + sFile //$NON-NLS-1$
+ "?seek=" + seek + "&scale=" + scale); //$NON-NLS-1$ //$NON-NLS-2$
dataSource = (DataSource) Manager.createDataSource(locator);
mediaPlayer = Manager.createRealizedPlayer( dataSource );
duration = mediaPlayer.getDuration();
//So shows first frame when map opened.Else if just gray square.
mediaPlayer.prefetch();
// get the components for the video and the playback controls
oVideo = mediaPlayer.getVisualComponent();
if (oVideo != null) {
movieSize = oVideo.getPreferredSize();
videoWidth = movieSize.width;
videoHeight = movieSize.height;
if (currentProps == null) {
currentProps = oMovie.getStartingProperties();
}
oMovie.setDefaultWidth(videoWidth);
oMovie.setDefaultHeight(videoHeight);
oMovieControls = mediaPlayer.getControlPanelComponent();
add( oVideo, BorderLayout.CENTER ); // add video component
} else {
log.info("Video = null");
ProjectCompendium.APP.displayError(LanguageProperties.getString(LanguageProperties.MOVIE_BUNDLE, "UIMoviePanel.errorSorry")+"\n\n"+LanguageProperties.getString(LanguageProperties.MOVIE_BUNDLE, "UIMoviePanel.errorSorry2")); //$NON-NLS-1$
mediaPlayer = null;
}
} catch ( NoPlayerException noPlayerException ) {
ProjectCompendium.APP.displayError(LanguageProperties.getString(LanguageProperties.MOVIE_BUNDLE, "UIMoviePanel.errorSorry")+"\n\n"+LanguageProperties.getString(LanguageProperties.MOVIE_BUNDLE, "UIMoviePanel.errorSorry2")); //$NON-NLS-1$
log.error("No player found:", noPlayerException); //$NON-NLS-1$
mediaPlayer = null;
} catch ( CannotRealizeException cannotRealizeException ) {
ProjectCompendium.APP.displayError(LanguageProperties.getString(LanguageProperties.MOVIE_BUNDLE, "UIMoviePanel.errorSorry")+"\n\n"+LanguageProperties.getString(LanguageProperties.MOVIE_BUNDLE, "UIMoviePanel.errorSorry2")); //$NON-NLS-1$
log.error("Could not realize media player:", cannotRealizeException); //$NON-NLS-1$
mediaPlayer = null;
} catch (NoDataSourceException e) {
ProjectCompendium.APP.displayError(LanguageProperties.getString(LanguageProperties.MOVIE_BUNDLE, "UIMoviePanel.errorSorry")+"\n\n"+LanguageProperties.getString(LanguageProperties.MOVIE_BUNDLE, "UIMoviePanel.errorSorry2")); //$NON-NLS-1$
log.error("NoDataSourceException:", e); //$NON-NLS-1$
mediaPlayer = null;
} catch (MalformedURLException e) {
ProjectCompendium.APP.displayError(LanguageProperties.getString(LanguageProperties.MOVIE_BUNDLE, "UIMoviePanel.errorSorry")+"\n\n"+LanguageProperties.getString(LanguageProperties.MOVIE_BUNDLE, "UIMoviePanel.errorSorry2")); //$NON-NLS-1$
log.error("MalformedURL:", e); //$NON-NLS-1$
mediaPlayer = null;
} catch ( IOException iOException ) {
ProjectCompendium.APP.displayError(LanguageProperties.getString(LanguageProperties.MOVIE_BUNDLE, "UIMoviePanel.errorSorry")+"\n\n"+LanguageProperties.getString(LanguageProperties.MOVIE_BUNDLE, "UIMoviePanel.errorSorry2")); //$NON-NLS-1$
log.error("IOException:", iOException); //$NON-NLS-1$
mediaPlayer = null;
}
return mediaPlayer;
}
/**
* Returns the selected state of the node.
*
* @return boolean, the selected state of the node
*/
public boolean isSelected() {
return bSelected;
}
/**
* Sets the selected state of the node.
* <p>
* @param selected, the selected state
*/
public void setSelected(boolean selected) {
boolean oldValue = bSelected;
bSelected = selected;
firePropertyChange(SELECTED_PROPERTY, oldValue, bSelected);
repaint();
}
/**
* Returns the roll-over state of the node.
*
* @return boolean, true if the node is currently rolled over, else false.
*/
/*public boolean isRollover() {
return bRollover;
}*/
/**
* Sets the roll over state of the movie.
* <p>
* @param rollover, the roll over state of the movie.
*/
/*public void setRollover(boolean rollover) {
boolean oldValue = bRollover;
bRollover = rollover;
firePropertyChange(ROLLOVER_PROPERTY, new Boolean(oldValue), new Boolean(bRollover));
repaint();
}*/
/**
* Using a cached duration variable as Grid Streams where sending occasional spurious
* data which was messing up the progress bar.
* @return
*/
public Time getDuration() {
return duration;
}
public Component getControls() {
return oMovieControls;
}
public void start() {
mediaPlayer.start();
}
public void stop() {
mediaPlayer.stop();
}
public void reset() {
mediaPlayer.setMediaTime(new Time(0));
}
public Player getMediaPlayer() {
return mediaPlayer;
}
public Movie getMovieData() {
return oMovie;
}
public void setMovieData(Movie movie) {
oMovie = movie;
oMovie.setDefaultWidth(this.videoWidth);
oMovie.setDefaultHeight(this.videoHeight);
}
/**
* Set the current movie properties that apply at this time point.
* @param props
*/
public void setCurrentProperties(MovieProperties props) {
this.currentProps = props;
setLocation(props.getXPos(), props.getYPos());
setSize(props.getWidth(), props.getHeight());
setPreferredSize(new Dimension(props.getWidth(), props.getHeight()));
repaint();
}
/**
* Return the MovieProperties that this movie is currently using.
* @return the MovieProperties that this movie is currently using.
*/
public MovieProperties getCurrentProperties() {
return currentProps;
}
/**
* This method was overridden to apply transparency percentages to the movie panel.
*/
@Override public void paintComponent(Graphics graphics) {
Graphics2D g2d = (Graphics2D) graphics;
float trans = 0;
if (currentProps != null) {
trans = currentProps.getTransparency();
}
g2d.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER, trans));
super.paintComponent(graphics);
}
/** MOUSE EVENTS**/
public void mousePressed(MouseEvent e) {
Point p = SwingUtilities.convertPoint((Component)e.getSource(), e.getX(), e.getY(), null);
lastMousePosX = p.x;
lastMousePosY = p.y;
MovieBorder border = (MovieBorder)this.getBorder();
if (border.isInTopLeft(e.getPoint())) {
inTopLeftSquare = true;
} else if (border.isInTopRight(e.getPoint())) {
inTopRightSquare = true;
} else if (border.isInBottomLeft(e.getPoint())) {
inBottomLeftSquare = true;
} else if (border.isInBottomRight(e.getPoint())) {
inBottomRightSquare = true;
}
}
public void mouseReleased(MouseEvent e) {
lastMousePosX = 0;
lastMousePosY = 0;
/*if ((currentProps.getXPos() != this.getX())
|| (currentProps.getYPos() != this.getY())
|| (currentProps.getWidth() != this.getWidth())
|| (currentProps.getHeight() != this.getHeight())) {
try{
// Need to update the local movie at this point so later events get the new data.
currentProps = oMovieMapView.updateMovieProperties(currentProps.getId(), currentProps.getMovieID(), this.getX(), this.getY(), this.getWidth(), this.getHeight(), currentProps.getTransparency(), currentProps.getTime());
} catch (Exception ex) {
ProjectCompendium.APP.displayError("Unable to update movie location due to:\n\n"+ex.getLocalizedMessage());
this.setLocation(currentProps.getXPos(), currentProps.getYPos());
}
}*/
inTopLeftSquare = false;
inTopRightSquare = false;
inBottomLeftSquare = false;
inBottomRightSquare = false;
this.repaint();
}
public void mouseClicked(MouseEvent e){
this.stop();
boolean isRightMouse = SwingUtilities.isRightMouseButton(e);
boolean isLeftMouse = SwingUtilities.isLeftMouseButton(e);
if (ProjectCompendium.isMac &&
( (e.getButton() == 3 && e.isShiftDown()) ||
(e.getButton() == 1 && e.isControlDown()) )) {
isRightMouse = true;
isLeftMouse = false;
}
oMovieMapViewPane.setLayer(this, oMovieMapViewPane.MOVIE_LAYER, 0);
if (bSelected) {
this.requestFocusInWindow();
}
if (e.getClickCount() == 2 && isLeftMouse) {
((UIMovieMapViewFrame)oMovieMapViewPane.getViewFrame()).showMovieDialog(oMovie);
} else if(e.getClickCount() == 1 && isRightMouse) {
Point p = SwingUtilities.convertPoint(this, e.getX(), e.getY(), oMovieMapViewPane);
oMovieMapViewPane.showPopupMenu(oMovieMapViewPane.getUI(),p.x, p.y, this);
} else {
// Change it to the viewpane coordinate space so it draws the right-click menu etc correctly.
Point p = SwingUtilities.convertPoint(this, e.getX(), e.getY(), oMovieMapViewPane);
MouseEvent mouse = new MouseEvent(oMovieMapViewPane, e.getID(), e.getWhen(), e.getModifiers(), p.x, p.y, e.getClickCount(), e.isPopupTrigger(), e.getButton());
oMovieMapViewPane.getUI().mouseClicked(mouse);
}
repaint();
}
public void mouseEntered(MouseEvent e) {
setSelected(true);
}
public void mouseExited(MouseEvent e){
setSelected(false);
}
public void mouseDragged(MouseEvent e) {
UIMoviePanel panel = (UIMoviePanel)e.getSource();
Point p = SwingUtilities.convertPoint((Component)e.getSource(), e.getX(), e.getY(), null);
Dimension s = panel.getParent().getSize();
int pWidth = s.width;
int pHeight = s.height;
int diffX = p.x - lastMousePosX;
int diffY = p.y - lastMousePosY;
int minX, minY, maxX, maxY;
Dimension panelSize = getSize();
Point currentLocation = getLocation();
boolean bKeepProportional = false;
boolean bWidthRatio = true;
/*if ( (this.inBottomRightSquare || this.inTopRightSquare || this.inTopLeftSquare || this.inBottomLeftSquare) &&
e.isShiftDown()) {
bKeepProportional = true;
int calcY = diffY;
int calcX = diffX;
if (diffX < 0) calcX = diffX*-1;
if (diffY < 0) calcY = diffY*-1;
if (calcX > calcY) {
diffY = Math.round((diffX * videoHeight ) / videoWidth);
} else {
diffX = Math.round((diffY * videoWidth ) / videoHeight);
bWidthRatio = false;
}
if (diffY == 0 || diffX == 0) {
return;
}
}*/
minX = currentLocation.x + diffX;
minY = currentLocation.y + diffY;
maxX = minX + panelSize.width;
maxY = minY + panelSize.height;
//CHECK BOUNDARIES
if (maxX > pWidth) diffX = diffX - (maxX - pWidth);
if (maxY > pHeight) diffY = diffY - (maxY - pWidth);
if (bKeepProportional) {
if (bWidthRatio) {
diffY = Math.round((diffX * videoHeight ) / videoWidth);
} else {
diffX = Math.round((diffY * videoWidth ) / videoHeight);
}
}
if (inTopLeftSquare) {
// CHECK BOUNDARIES
if (minX < 0) diffX = diffX - minX;
if (minY < 0) diffY = diffY - minY;
if (bKeepProportional) {
if (bWidthRatio) {
diffY = Math.round((diffX * videoHeight ) / videoWidth);
} else {
diffX = Math.round((diffY * videoWidth ) / videoHeight);
}
}
//CALCULATE LOCATION
int newX = currentLocation.x+diffX;
int newY = currentLocation.y+diffY;
//CALCULATE SIZE
int newdiffX = diffX*-1;
int newdiffY = diffY*-1;
int newWidth = panelSize.width+newdiffX;
if (newWidth > pWidth) {
newWidth = pWidth;
}
int newHeight = panelSize.height+newdiffY;
if (newHeight > pHeight) {
newHeight = pHeight;
}
//Double check aspect ratio
if (bKeepProportional) {
double ratio = videoHeight/videoWidth;
if (newHeight/newWidth != ratio) {
newHeight = new Long( Math.round(ratio * newWidth)).intValue();
}
}
if (newHeight < 10 || newWidth < 10) return;
setLocation(newX, newY);
setSize(newWidth, newHeight);
setPreferredSize(new Dimension(newWidth, newHeight));
} else if (this.inTopRightSquare) {
// CHECK BOUNDARIES
if (minX+panelSize.width < 0) diffX = diffX - minX;
if (minY < 0) diffY = diffY - minY;
if (bKeepProportional) {
if (bWidthRatio) {
diffY = Math.round((diffX * videoHeight ) / videoWidth);
} else {
diffX = Math.round((diffY * videoWidth ) / videoHeight);
}
}
//CALCULATE LOCATION
int newY = currentLocation.y+diffY;
//CALCULATE SIZE
int newWidth = panelSize.width+diffX;
if (newWidth > pWidth) {
newWidth = pWidth;
}
int newdiffY = diffY*-1;
int newHeight = panelSize.height+newdiffY;
if (newHeight > pHeight) {
newHeight = pHeight;
}
//Double check aspect ratio
if (bKeepProportional) {
double ratio = videoHeight/videoWidth;
if (newHeight/newWidth != ratio) {
newHeight = new Long( Math.round(ratio * newWidth)).intValue();
}
}
if (newHeight < 10 || newWidth < 10) return;
setLocation(currentLocation.x, newY);
setSize(newWidth, newHeight);
setPreferredSize(new Dimension(newWidth, newHeight));
} else if (this.inBottomLeftSquare) {
// CHECK BOUNDARIES
if (minX < 0) diffX = diffX - minX;
if (minY+panelSize.height < 0) {
diffY = diffY - minY;
}
if (bKeepProportional) {
if (bWidthRatio) {
diffY = Math.round((diffX * videoHeight ) / videoWidth);
} else {
diffX = Math.round((diffY * videoWidth ) / videoHeight);
}
}
//CALCULATE LOCATION
int newX = currentLocation.x+diffX;
//CALCULATE SIZE
int newDiffY = diffY*-1;
int newWidth = panelSize.width-diffX;
int newHeight = panelSize.height-newDiffY;
//Double check aspect ratio
if (bKeepProportional) {
double ratio = videoHeight/videoWidth;
if (newHeight/newWidth != ratio) {
newHeight = new Long( Math.round(ratio * newWidth)).intValue();
}
}
if (newHeight < 10 || newWidth < 10) return;
setLocation(newX, currentLocation.y);
setSize(newWidth, newHeight);
setPreferredSize(new Dimension(newWidth, newHeight));
} else if (this.inBottomRightSquare) {
// CHECK BOUNDARIES
if (minX+panelSize.width < 0) {
diffX = diffX - minX;
}
if (minY+panelSize.height < 0) {
diffY = diffY - minY;
}
if (bKeepProportional) {
if (bWidthRatio) {
diffY = Math.round((diffX * videoHeight ) / videoWidth);
} else {
diffX = Math.round((diffY * videoWidth ) / videoHeight);
}
}
//CALCULATE LOCATION
//remains the same
//CALCULATE SIZE
int newWidth = panelSize.width+diffX;
int newHeight = panelSize.height+diffY;
//Double check aspect ratio
if (bKeepProportional) {
double ratio = videoHeight/videoWidth;
if (newHeight/newWidth != ratio) {
newHeight = new Long( Math.round(ratio * newWidth)).intValue();
}
}
if (newHeight < 10 || newWidth < 10) return;
setSize(newWidth, newHeight);
setPreferredSize(new Dimension(newWidth, newHeight));
} else {
// CHECK BOUNDARIES
if (minX < 0) diffX = diffX - minX;
if (minY < 0) diffY = diffY - minY;
int newX = currentLocation.x + diffX;
int newY = currentLocation.y + diffY;
Rectangle nodeBounds = panel.getBounds();
// NEED THIS SILLY DANCE TO FORCE BORDER TO RECALC INSETS AND SO DRAW CORRECTLY
this.setSize(nodeBounds.width+1, nodeBounds.height);
this.setSize(nodeBounds.width, nodeBounds.height);
setLocation(newX, newY);
// MAKE SURE MOVIE IS VISIBLE, SO IF DRAGGED OFF SCREEN - AUTO SCROLL
JViewport viewport = oMovieMapViewPane.getViewFrame().getViewport();
Point parentPos = SwingUtilities.convertPoint((Component)oMovieMapViewPane, newX, newY, viewport);
viewport.scrollRectToVisible( new Rectangle( parentPos.x, parentPos.y, nodeBounds.width, nodeBounds.height ) );
}
lastMousePosX = p.x;
lastMousePosY = p.y;
validate();
repaint();
}
public void mouseMoved(MouseEvent e) {
MovieBorder border = (MovieBorder)this.getBorder();
if (border.isInTopLeft(e.getPoint())) {
this.setCursor(new Cursor(java.awt.Cursor.NW_RESIZE_CURSOR));
} else if (border.isInTopRight(e.getPoint())) {
this.setCursor(new Cursor(java.awt.Cursor.NE_RESIZE_CURSOR));
} else if (border.isInBottomLeft(e.getPoint())) {
this.setCursor(new Cursor(java.awt.Cursor.SW_RESIZE_CURSOR));
} else if (border.isInBottomRight(e.getPoint())) {
this.setCursor(new Cursor(java.awt.Cursor.SE_RESIZE_CURSOR));
} else {
this.setCursor(new Cursor(java.awt.Cursor.DEFAULT_CURSOR));
}
//e.setSource(this);
this.oMovieMapViewPane.getUI().mouseMoved(e);
}
/**
* Reset the movie to its default size;
*/
public void resetMovieToDefaultSize() {
try{
MovieProperties newProps = oMovieMapView.updateMovieProperties(currentProps.getId(), currentProps.getMovieID(), currentProps.getXPos(), currentProps.getYPos(), videoWidth, videoHeight, currentProps.getTransparency(), currentProps.getTime());
oMovie.setProperties(newProps);
} catch (Exception ex) {
ProjectCompendium.APP.displayError(LanguageProperties.getString(LanguageProperties.MOVIE_BUNDLE, "UIMoviePanel.errorUpdateLocation")+":\n\n"+ex.getLocalizedMessage()); //$NON-NLS-1$
}
}
/*public MovieProperties getCurrentMovieProperties() {
return currentProps;
}*/
public void keyPressed(KeyEvent e) {
if (bSelected) {
int key = e.getKeyCode();
int modifiers = e.getModifiers();
Dimension size = new Dimension(movieSize);
// Calculate the default height and width
int width = DEFAULT_WIDTH;
int height = (int) ((DEFAULT_WIDTH * size.getHeight()) / size.getWidth());
if (currentProps != null ) {
if (key == '0') {
resetMovieToDefaultSize();
}
else if ((key >= '1') && (key <= '9') && modifiers == 0) {
int value = (key - '0') - KEY_OFFSET;
int wdiff = value < 0 ? NEGATIVE_MULTIPLIER_WIDTH : POSITIVE_MULTIPLIER_WIDTH;
int hdiff = value < 0 ? NEGATIVE_MULTIPLIER_HEIGHT : POSITIVE_MULTIPLIER_HEIGHT;
width = (width + (wdiff * value));
height = (height + (hdiff * value));
try{
oMovieMapView.updateMovieProperties(currentProps.getId(), currentProps.getMovieID(), currentProps.getXPos(), currentProps.getYPos(), width, height, currentProps.getTransparency(), currentProps.getTime());
} catch (Exception ex) {
ProjectCompendium.APP.displayError(LanguageProperties.getString(LanguageProperties.MOVIE_BUNDLE, "UIMoviePanel.errorUpdateLocation")+":\n\n"+ex.getLocalizedMessage()); //$NON-NLS-1$
}
} else if ( (key == KeyEvent.VK_DELETE && modifiers == 0) ||
key == KeyEvent.VK_BACK_SPACE && modifiers == 0) {
deleteMovie();
} else {
//e.setSource(this);
this.oMovieMapViewPane.getUI().keyPressed(e);
}
} else {
ProjectCompendium.APP.displayError(LanguageProperties.getString(LanguageProperties.MOVIE_BUNDLE, "UIMoviePanel.errorUpdateProperties")); //$NON-NLS-1$
}
}
}
/**
* Delete this movie from the map
*/
public void deleteMovie() {
File file = new File(oMovie.getLink());
int response = JOptionPane.showConfirmDialog(ProjectCompendium.APP, LanguageProperties.getString(LanguageProperties.MOVIE_BUNDLE, "UIMoviePanel.confirmDelete")+":\n\n"+file.getName()+"\n\n"+LanguageProperties.getString(LanguageProperties.MOVIE_BUNDLE, "UIMoviePanel.confirmDelete2")+"\n",LanguageProperties.getString(LanguageProperties.MOVIE_BUNDLE, "UIMoviePanel.confirmDeleteTitle"), JOptionPane.YES_NO_OPTION); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
if (response == JOptionPane.NO_OPTION || response == JOptionPane.CLOSED_OPTION) {
return;
} else {
try {
String sMovieID = oMovie.getId();
oMovieMapView.deleteMovie(sMovieID);
} catch (Exception ex) {
log.info(LanguageProperties.getString(LanguageProperties.MOVIE_BUNDLE, "UIMoviePanel.error")+":"+ex.getLocalizedMessage()); //$NON-NLS-1$
log.error("Error...", ex);
}
}
}
public void keyReleased(KeyEvent e) {
//this.oMovieMapViewPane.getUI().keyReleased(e);
}
public void keyTyped(KeyEvent e) {
//e.setSource(this);
this.oMovieMapViewPane.getUI().keyTyped(e);
}
public void focusGained(FocusEvent e) {
}
public void focusLost(FocusEvent e){
inTopLeftSquare = false;
inTopRightSquare = false;
inBottomLeftSquare = false;
inBottomRightSquare = false;
repaint();
}
/**
* Setting the size also sets the Video size.
*/
public void setSize() {
//oVideo.setSize(new Dimension(oMovie.getWidth(),oMovie.getHeight()));
//super.setSize(new Dimension(oMovie.getWidth(),oMovie.getHeight()));
}
private class MovieBorder extends AbstractBorder {
/** The colour to use for the border around the node if it has the focus.*/
private final Color FOCUSED_COLOR = Color.blue;
/** The colour to use for the movie border when the node is rolled over with the mouse.*/
private final Color BORDER_COLOR = Color.cyan;
/** The colour to use for the movie border when the node is rolled over with the mouse.*/
//private final Color SELECTED_COLOR = Color.yellow;
private Rectangle rTopLeft = null;
private Rectangle rTopRight = null;
private Rectangle rBottomLeft = null;
private Rectangle rBottomRight = null;
int left = 0;
int right = 0;
int top = 0;
int bottom = 0;
private int borderWidth = 0;
private UIMoviePanel oPanel = null;
public MovieBorder(int width, UIMoviePanel panel) {
this.borderWidth = width;
this.oPanel = panel;
this.left = borderWidth;
this.right = borderWidth;
this.top = borderWidth;
this.bottom = borderWidth;
}
/**
* Paints the border for the specified component with the
* specified position and size.
* @param c the component for which this border is being painted
* @param g the paint graphics
* @param x the x position of the painted border
* @param y the y position of the painted border
* @param width the width of the painted border
* @param height the height of the painted border
*/
public void paintBorder(Component c, Graphics g, int x, int y, int width, int height) {
if (bSelected || c.hasFocus()) {
Color oldColor = g.getColor();
g.setColor(BORDER_COLOR);
if (c.hasFocus()) {
g.setColor(this.FOCUSED_COLOR);
}
int borderX = x+left-1;
int borderY = y+top-1;
int borderWidth = width-(left+right)+1;
int borderHeight = height-(top+bottom)+1;
g.drawRect(borderX, borderY, borderWidth, borderHeight);
//Graphics2D g2d = (Graphics2D)g;
//g2d.setStroke(new BasicStroke(2));
borderX = x+left-2;
borderY = y+top-2;
borderWidth = width-(left+right)+3;
borderHeight = height-(top+bottom)+3;
g.drawRect(borderX, borderY, borderWidth, borderHeight);
rTopLeft = new Rectangle(x, y, left, top);
g.fillRect(x, y, left, top);
rTopRight = new Rectangle(x + width - right, y, right, top);
g.fillRect(x + width - right, y, right, top);
rBottomLeft = new Rectangle(x, y+height-bottom, left, bottom);
g.fillRect(x, y+height-bottom, left, bottom);
rBottomRight = new Rectangle(x+width-right, y+height-bottom, right, bottom);
g.fillRect(x+width-right, y+height-bottom, right, bottom);
g.setColor(oldColor);
}
}
public boolean isInTopLeft(Point mouse) {
if (rTopLeft != null && rTopLeft.contains(mouse)) {
return true;
}
return false;
}
public boolean isInTopRight(Point mouse) {
if (rTopRight != null && rTopRight.contains(mouse)) {
return true;
}
return false;
}
public boolean isInBottomLeft(Point mouse) {
if (rBottomLeft != null && rBottomLeft.contains(mouse)) {
return true;
}
return false;
}
public boolean isInBottomRight(Point mouse) {
if (rBottomRight != null && rBottomRight.contains(mouse)) {
return true;
}
return false;
}
public Insets calculateInsets() {
Point location = oPanel.getLocation();
Dimension dim = oVideo.getPreferredSize();
left = borderWidth;
right = borderWidth;
top = borderWidth;
bottom = borderWidth;
if (location.x < borderWidth) {
left = location.x;
}
if (location.y < borderWidth) {
top = location.y;
}
return new Insets(top, left, bottom, right);
}
public Insets getBorderInsets() {
return calculateInsets();
}
public Insets getBorderInsets(Component c) {
return calculateInsets();
}
public Insets getBorderInsets(Component c, Insets insets) {
return calculateInsets();
}
}
public void clean() {
if (mediaPlayer != null) {
this.removeAll();
this.validate();
this.setVisible(false);
}
}
}