All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.metsci.glimpse.layout.GlimpseTouchWrapper Maven / Gradle / Ivy

There is a newer version: 4.0.0
Show newest version
/*
 * Copyright (c) 2012, Metron, Inc.
 * All rights reserved.
 *
 * 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 Metron, Inc. 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 METRON, INC. 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.metsci.glimpse.layout;

import static com.metsci.glimpse.context.TargetStackUtil.popTo;
import static com.metsci.glimpse.context.TargetStackUtil.pushToBottom;

import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.CopyOnWriteArrayList;
import java.util.logging.Logger;

import com.metsci.glimpse.axis.listener.touch.AxisGestureListener;
import com.metsci.glimpse.axis.listener.touch.AxisGestureListener1D;
import com.metsci.glimpse.axis.listener.touch.AxisGestureListener2D;
import com.metsci.glimpse.context.GlimpseBounds;
import com.metsci.glimpse.context.GlimpseTarget;
import com.metsci.glimpse.context.GlimpseTargetStack;
import com.metsci.glimpse.event.touch.GlimpseGestureEvent;
import com.metsci.glimpse.event.touch.GlimpseGestureListener;
import com.metsci.glimpse.event.touch.GlimpseLongPressGestureEvent;
import com.metsci.glimpse.event.touch.GlimpsePanGestureEvent;
import com.metsci.glimpse.event.touch.GlimpsePinchGestureEvent;
import com.metsci.glimpse.event.touch.GlimpseSwipeGestureEvent;
import com.metsci.glimpse.event.touch.GlimpseTapGestureEvent;
import com.metsci.glimpse.event.touch.GlimpseTouchEvent;
import com.metsci.glimpse.event.touch.GlimpseTouchListener;
import com.metsci.glimpse.event.touch.Touchable;
import com.metsci.glimpse.painter.base.GlimpsePainterCallback;

/**
 * Provides a layout wrapper to augment any layout (and descendants) with
 * gesture support.  This wrapper sets EventConsumer and EventGenerator to
 * false for any child layouts.  Then, all the touch events get sent to this
 * layout.  Then this layout will find the actual target and get the gesture
 * listeners associated with that layout and execute them.
 *
 * 

* We may want to preemptively add touch support to all layouts, like we do * mouse support. In that case, this class should be removed. *

* * @author borkholder */ public class GlimpseTouchWrapper extends GlimpseLayout implements Touchable { private static final Logger LOGGER = Logger.getLogger( GlimpseTouchWrapper.class.getName( ) ); protected Map> gestureListeners; public GlimpseTouchWrapper( GlimpseLayout parent ) { super( parent ); gestureListeners = new HashMap>( ); } protected void addGestureListenersRecursive( GlimpseLayout layout ) { layout.setEventGenerator( false ); layout.setEventConsumer( false ); addGestureListenerVarying( layout ); for ( GlimpseTarget child : layout.getTargetChildren( ) ) { if ( child instanceof GlimpseLayout ) { addGestureListenersRecursive( ( GlimpseLayout ) child ); } } } protected void removeGestureListenersRecursive( GlimpseLayout layout ) { gestureListeners.remove( layout ); for ( GlimpseTarget child : layout.getTargetChildren( ) ) { if ( child instanceof GlimpseLayout ) { removeGestureListenersRecursive( ( GlimpseLayout ) child ); } } } protected void addGestureListenerVarying( GlimpseLayout layout ) { if ( layout instanceof GlimpseAxisLayoutX ) { addGlimpseGestureListener( createAxisGestureListener1D( true ), layout ); } else if ( layout instanceof GlimpseAxisLayoutY ) { addGlimpseGestureListener( createAxisGestureListener1D( false ), layout ); } else if ( layout instanceof GlimpseAxisLayout2D ) { addGlimpseGestureListener( createAxisGestureListener2D( ), layout ); } } protected AxisGestureListener createAxisGestureListener1D( boolean horizontal ) { return new AxisGestureListener1D( ); } protected AxisGestureListener createAxisGestureListener2D( ) { return new AxisGestureListener2D( ); } public void addGlimpseGestureListener( GlimpseGestureListener listener, GlimpseLayout child ) { List list = gestureListeners.get( child ); if ( list == null ) { list = new CopyOnWriteArrayList( ); gestureListeners.put( child, list ); } list.add( listener ); } @Override public String toString( ) { return getClass( ).getSimpleName( ); } @Override public void addGlimpseGestureListener( GlimpseGestureListener listener ) { LOGGER.fine( "Do not add gesture listeners directly, use addGlimpseGestureListener(GlimpseGestureListener, GlimpseLayout)" ); } @Override public void addGlimpseTouchListener( GlimpseTouchListener listener ) { LOGGER.finer( "This class does not support touch listeners" ); } protected GlimpseTargetStack getActualTargetStack( GlimpseGestureEvent event ) { GlimpseTargetStack stack = event.getTargetStack( ); int x = event.getX( ) + stack.getBounds( ).getX( ); int y = event.getY( ) + stack.getBounds( ).getY( ); stack = popTo( stack, this ); if ( stack == null ) { return null; } stack = pushToBottom( stack, x, y ); return stack; } @SuppressWarnings( "unchecked" ) protected E convertEvent( E event, GlimpseTargetStack stack ) { int x = event.getX( ); int y = event.getY( ); GlimpseBounds bounds = event.getTargetStack( ).getBounds( ); x += bounds.getX( ); y += bounds.getY( ); bounds = stack.getBounds( ); x -= bounds.getX( ); y -= bounds.getY( ); return ( E ) event.withNewTarget( stack, x, y ); } @Override public void panDetected( GlimpsePanGestureEvent event ) { GlimpseTargetStack stack = getActualTargetStack( event ); if ( stack == null ) { return; } GlimpsePanGestureEvent e = convertEvent( event, stack ); List listeners = gestureListeners.get( stack.getTarget( ) ); if ( listeners == null ) { return; } for ( GlimpseGestureListener listener : listeners ) { listener.panDetected( e ); } } @Override public void pinchDetected( GlimpsePinchGestureEvent event ) { GlimpseTargetStack stack = getActualTargetStack( event ); if ( stack == null ) { return; } GlimpsePinchGestureEvent e = convertEvent( event, stack ); List listeners = gestureListeners.get( stack.getTarget( ) ); if ( listeners == null ) { return; } for ( GlimpseGestureListener listener : listeners ) { listener.pinchDetected( e ); } } @Override public void tapDetected( GlimpseTapGestureEvent event ) { GlimpseTargetStack stack = getActualTargetStack( event ); if ( stack == null ) { return; } GlimpseTapGestureEvent e = convertEvent( event, stack ); List listeners = gestureListeners.get( stack.getTarget( ) ); if ( listeners == null ) { return; } for ( GlimpseGestureListener listener : listeners ) { listener.tapDetected( e ); } } @Override public void longPressDetected( GlimpseLongPressGestureEvent event ) { GlimpseTargetStack stack = getActualTargetStack( event ); if ( stack == null ) { return; } GlimpseLongPressGestureEvent e = convertEvent( event, stack ); List listeners = gestureListeners.get( stack.getTarget( ) ); if ( listeners == null ) { return; } for ( GlimpseGestureListener listener : listeners ) { listener.longPressDetected( e ); } } @Override public void swipeDetected( GlimpseSwipeGestureEvent event ) { GlimpseTargetStack stack = getActualTargetStack( event ); if ( stack == null ) { return; } GlimpseSwipeGestureEvent e = convertEvent( event, stack ); List listeners = gestureListeners.get( stack.getTarget( ) ); if ( listeners == null ) { return; } for ( GlimpseGestureListener listener : listeners ) { listener.swipeDetected( e ); } } @Override public void touchesBegan( GlimpseTouchEvent event ) { // nop } @Override public void touchesMoved( GlimpseTouchEvent event ) { // nop } @Override public void touchesEnded( GlimpseTouchEvent event ) { // nop } @Override public void removeGlimpseGestureListener( GlimpseGestureListener listener ) { for ( List listeners : gestureListeners.values( ) ) { listeners.remove( listener ); } } public void removeGlimpseGestureListeners( GlimpseLayout layout ) { gestureListeners.remove( layout ); } @Override public void removeGlimpseTouchListener( GlimpseTouchListener listener ) { // nop } @Override public Collection getGlimpseGestureListeners( ) { List all = new ArrayList( ); for ( List listeners : gestureListeners.values( ) ) { all.addAll( listeners ); } return Collections.unmodifiableList( all ); } @Override public Collection getGlimpseTouchListeners( ) { return Collections.emptyList( ); } @Override public void removeAllGlimpseGestureListeners( ) { for ( List listeners : gestureListeners.values( ) ) { listeners.clear( ); } } @Override public void addLayout( GlimpseLayout layout, GlimpsePainterCallback callback, int zOrder ) { super.addLayout( layout, callback, zOrder ); addGestureListenersRecursive( layout ); } @Override public void removeLayout( GlimpseLayout layout ) { super.removeLayout( layout ); removeGestureListenersRecursive( layout ); } @Override public void removeAll( ) { super.removeAll( ); gestureListeners.clear( ); } public static GlimpseTouchWrapper wrap( GlimpseLayout parent, GlimpseLayout childAsTouchable ) { GlimpseTouchWrapper wrapper = new GlimpseTouchWrapper( parent ); wrapper.addLayout( childAsTouchable ); return wrapper; } }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy