/**
* Copyright (c) 2003-2009, Xith3D Project Group all rights reserved.
*
* Portions based on the Java3D interface, Copyright by Sun Microsystems.
* Many thanks to the developers of Java3D and Sun Microsystems for their
* innovation and design.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* Neither the name of the 'Xith3D Project Group' nor the names of its
* contributors may be used to endorse or promote products derived from this
* software without specific prior written permission.
*
* 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) A
* RISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE
*/
package org.xith3d.utility.hud.editor;
import java.awt.Toolkit;
import java.awt.datatransfer.Clipboard;
import java.awt.datatransfer.StringSelection;
import org.jagatoo.input.devices.components.MouseButton;
import org.jagatoo.input.devices.components.MouseButtons;
import org.jagatoo.opengl.enums.TextureFormat;
import org.jagatoo.opengl.enums.TextureImageFormat;
import org.openmali.vecmath2.Point2f;
import org.openmali.vecmath2.Tuple2f;
import org.xith3d.scenegraph.TextureImage2D;
import org.xith3d.scenegraph.Texture2D;
import org.xith3d.ui.hud.HUD;
import org.xith3d.ui.hud.base.Widget;
import org.xith3d.ui.hud.base.WidgetContainer;
import org.xith3d.ui.hud.listeners.WidgetEventsReceiverAdapter;
import org.xith3d.ui.hud.widgets.Image;
/**
* Wraps a Widget and adds handles to resize the Widget. It also makes the
* Widget draggable.
*
* @author Amos Wenger (aka BlueSky)
* @author Marvin Froehlich (aka Qudus)
*/
public class WidgetManipulator
{
private Image nwHandle, neHandle, swHandle, seHandle;
private final int HANDLE_X_SIZE = 10;
private final int HANDLE_Y_SIZE = 10;
protected Widget widget;
private Tuple2f old_nwHandle = null;
private Tuple2f old_neHandle = null;
private Tuple2f old_swHandle = null;
private Tuple2f old_seHandle = null;
private boolean isEventResizing = false;
private boolean isManipulatorReady = false;
private StackTraceElement stackTraceElement;
private WERA wera;
private class WERA extends WidgetEventsReceiverAdapter
{
@Override
public void onWidgetLocationChanged( Widget widget, float oldLeft, float oldTop, float newLeft, float newTop )
{
if ( ( !isEventResizing ) && ( widget.getHUD() != null ) )
{
isEventResizing = true; // avoid deadlock or stack-overflow
if ( widget == WidgetManipulator.this.widget )
{
repositionHandles();
}
else if ( widget == nwHandle )
{
resizeWidget();
}
else if ( widget == neHandle )
{
resizeWidget();
}
else if ( widget == swHandle )
{
resizeWidget();
}
else if ( widget == seHandle )
{
resizeWidget();
}
isEventResizing = false; // avoid deadlock or stack-overflow
}
}
@Override
public void onWidgetAttachedToContainer( Widget widget, WidgetContainer container )
{
if ( widget == WidgetManipulator.this.widget )
{
widget.getContainer().addWidget( nwHandle );
widget.getContainer().addWidget( neHandle );
widget.getContainer().addWidget( swHandle );
widget.getContainer().addWidget( seHandle );
}
}
@Override
public void onWidgetAttachedToHUD( Widget widget, HUD hud )
{
if ( widget == WidgetManipulator.this.widget )
{
// hud.getOperationScheduler().scheduleOperation( WidgetManipulator.this );
}
}
@Override
public void onWidgetDetachedFromContainer( Widget widget, WidgetContainer container )
{
// System.out.println( "onWidgetDetachedFromContainer" );
}
@Override
public void onWidgetDetachedFromHUD( Widget widget, HUD hud )
{
// System.out.println( "onWidgetDetachedFromHUD" );
}
/**
* {@inheritDoc}
*/
@Override
public void onMouseButtonPressed( Widget widget, MouseButton button, float x, float y, long when, long lastWhen, boolean isTopMost, boolean hasFocus )
{
if ( widget == WidgetManipulator.this.widget && button == MouseButtons.MIDDLE_BUTTON )
{
StringBuffer buff = new StringBuffer();
String name = WidgetManipulator.this.widget.getClass().getSimpleName().toLowerCase() + ".";
buff.append( name );
buff.append( "setLocation(" );
buff.append( widget.getLeft() );
buff.append( "f," );
buff.append( widget.getTop() );
buff.append( "f);\n" );
buff.append( name );
buff.append( "setSize(" );
buff.append( widget.getWidth() );
buff.append( "f," );
buff.append( widget.getHeight() );
buff.append( "f);" );
StringSelection stringSelection = new StringSelection( buff.toString() );
Clipboard clipboard = Toolkit.getDefaultToolkit().getSystemClipboard();
clipboard.setContents( stringSelection, null );
System.err.println( "Clicked : " + stackTraceElement );
}
}
}
public WidgetManipulator( final Widget widget )
{
stackTraceElement = Thread.currentThread().getStackTrace()[ 2 ];
wera = new WERA();
this.widget = widget;
widget.setDraggable( true );
widget.addLocationListener( wera );
Texture2D tex = new Texture2D( TextureFormat.RGB );
tex.setImage( 0, new TextureImage2D( TextureImageFormat.LUMINANCE, 8, 8, new byte[]
{
-1, -1, -1, -1, -1, -1, -1, -1, -1, 0, 0, 0, 0, 0,
0, -1, -1, 0, 0, 0, 0, 0, 0, -1, -1, 0, 0, 0, 0, 0, 0,
-1, -1, 0, 0, 0, 0, 0, 0, -1, -1, 0, 0, 0, 0, 0, 0, -1,
-1, 0, 0, 0, 0, 0, 0, -1, -1, -1, -1, -1, -1, -1, -1,
-1
} ) );
final int handleZIndex = widget.getZIndex() + 1;
nwHandle = new Image( HANDLE_X_SIZE, HANDLE_Y_SIZE, tex );
nwHandle.setZIndex( handleZIndex );
nwHandle.setDraggable( true );
nwHandle.addLocationListener( wera );
if ( widget.getContainer() != null )
{
widget.getContainer().addWidget( nwHandle );
}
neHandle = new Image( HANDLE_X_SIZE, HANDLE_Y_SIZE, tex );
neHandle.setZIndex( handleZIndex );
neHandle.setDraggable( true );
neHandle.addLocationListener( wera );
if ( widget.getContainer() != null )
{
widget.getContainer().addWidget( neHandle );
}
swHandle = new Image( HANDLE_X_SIZE, HANDLE_Y_SIZE, tex );
swHandle.setZIndex( handleZIndex );
swHandle.setDraggable( true );
swHandle.addLocationListener( wera );
if ( widget.getContainer() != null )
{
widget.getContainer().addWidget( swHandle );
}
seHandle = new Image( HANDLE_X_SIZE, HANDLE_Y_SIZE, tex );
seHandle.setZIndex( handleZIndex );
seHandle.setDraggable( true );
seHandle.addLocationListener( wera );
if ( widget.getContainer() != null )
{
widget.getContainer().addWidget( seHandle );
}
repositionHandles();
if ( widget.getContainer() == null )
{
widget.addContainerListener( wera );
}
widget.addMouseListener( wera );
this.isManipulatorReady = true;
}
private void repositionHandles()
{
if ( old_nwHandle != null )
old_nwHandle.set( nwHandle.getLeft(), nwHandle.getTop() );
nwHandle.setLocation( widget.getLeft() - HANDLE_X_SIZE / 2f, widget.getTop() - HANDLE_Y_SIZE / 2f );
if ( old_nwHandle == null )
old_nwHandle = new Point2f( nwHandle.getLeft(), nwHandle.getTop() );
if ( old_neHandle != null )
old_neHandle.set( neHandle.getLeft(), neHandle.getTop() );
neHandle.setLocation( widget.getLeft() + widget.getWidth() - HANDLE_X_SIZE / 2f, widget.getTop() - HANDLE_Y_SIZE / 2f );
if ( old_neHandle == null )
old_neHandle = new Point2f( neHandle.getLeft(), neHandle.getTop() );
if ( old_swHandle != null )
old_swHandle.set( swHandle.getLeft(), swHandle.getTop() );
swHandle.setLocation( widget.getLeft() - HANDLE_X_SIZE / 2f, widget.getTop() + widget.getHeight() - HANDLE_Y_SIZE / 2f );
if ( old_swHandle == null )
old_swHandle = new Point2f( swHandle.getLeft(), swHandle.getTop() );
if ( old_seHandle != null )
old_seHandle.set( seHandle.getLeft(), seHandle.getTop() );
seHandle.setLocation( widget.getLeft() + widget.getWidth() - HANDLE_X_SIZE / 2f, widget.getTop() + widget.getHeight() - HANDLE_Y_SIZE / 2f );
if ( old_seHandle == null )
old_seHandle = new Point2f( seHandle.getLeft(), seHandle.getTop() );
}
private void resizeWidget()
{
if ( isManipulatorReady )
{
boolean anyChange = false;
if ( ( old_nwHandle.getX() != nwHandle.getLeft() ) || ( old_nwHandle.getY() != nwHandle.getTop() ) )
{
widget.setLocation( widget.getLeft() + nwHandle.getLeft() - old_nwHandle.getX(), widget.getTop() + nwHandle.getTop() - old_nwHandle.getY() );
widget.setSize( widget.getWidth() - nwHandle.getLeft() + old_nwHandle.getX(), widget.getHeight() - nwHandle.getTop() + old_nwHandle.getY() );
old_nwHandle.set( nwHandle.getLeft(), nwHandle.getTop() );
anyChange = true;
}
else if ( ( old_neHandle.getX() != neHandle.getLeft() ) || ( old_neHandle.getY() != neHandle.getTop() ) )
{
widget.setLocation( widget.getLeft(), widget.getTop() + neHandle.getTop() - old_neHandle.getY() );
widget.setSize( widget.getWidth() + neHandle.getLeft() - old_neHandle.getX(), widget.getHeight() - neHandle.getTop() + old_neHandle.getY() );
old_neHandle.set( neHandle.getLeft(), neHandle.getTop() );
anyChange = true;
}
else if ( ( old_swHandle.getX() != swHandle.getLeft() ) || ( old_swHandle.getY() != swHandle.getTop() ) )
{
widget.setLocation( widget.getLeft() + swHandle.getLeft() - old_swHandle.getX(), widget.getTop() );
widget.setSize( widget.getWidth() - swHandle.getLeft() + old_swHandle.getX(), widget.getHeight() + swHandle.getTop() - old_swHandle.getY() );
old_swHandle.set( swHandle.getLeft(), swHandle.getTop() );
anyChange = true;
}
else if ( ( old_seHandle.getX() != seHandle.getLeft() ) || ( old_seHandle.getY() != seHandle.getTop() ) )
{
widget.setSize( widget.getWidth() + seHandle.getLeft() - old_seHandle.getX(), widget.getHeight() + seHandle.getTop() - old_seHandle.getY() );
old_seHandle.set( seHandle.getLeft(), seHandle.getTop() );
anyChange = true;
}
if ( anyChange )
{
repositionHandles();
old_nwHandle.set( nwHandle.getLeft(), nwHandle.getTop() );
old_neHandle.set( neHandle.getLeft(), neHandle.getTop() );
old_swHandle.set( swHandle.getLeft(), swHandle.getTop() );
old_seHandle.set( seHandle.getLeft(), seHandle.getTop() );
}
}
}
}