Package org.jdesktop.wonderland.modules.appbase.client.view

Source Code of org.jdesktop.wonderland.modules.appbase.client.view.Gui2DInterior$InteriorKeyListener

/**
* Project Wonderland
*
* Copyright (c) 2004-2009, Sun Microsystems, Inc., All Rights Reserved
*
* Redistributions in source code form must reproduce the above
* copyright and this condition.
*
* The contents of this file are subject to the GNU General Public
* License, Version 2 (the "License"); you may not use this file
* except in compliance with the License. A copy of the License is
* available at http://www.opensource.org/licenses/gpl-license.php.
*
* Sun designates this particular file as subject to the "Classpath"
* exception as provided by Sun in the License file that accompanied
* this code.
*/
package org.jdesktop.wonderland.modules.appbase.client.view;

import java.awt.event.KeyEvent;
import java.awt.event.MouseEvent;
import java.util.logging.Logger;
import org.jdesktop.mtgame.Entity;
import org.jdesktop.wonderland.client.input.Event;
import org.jdesktop.wonderland.client.input.EventClassListener;
import org.jdesktop.wonderland.client.jme.input.KeyEvent3D;
import org.jdesktop.wonderland.client.jme.input.MouseEvent3D;
import org.jdesktop.wonderland.common.InternalAPI;
import org.jdesktop.wonderland.modules.appbase.client.ControlArb;
import javax.swing.SwingUtilities;
import org.jdesktop.wonderland.client.jme.input.InputManager3D;
import org.jdesktop.wonderland.modules.appbase.client.App2D;

/**
* The event handler code which handles the 2D window interior. It supports sending
* all events to the app group when the user has control of the window
* and also all global events.
*
* @author deronj
*/
@InternalAPI
public class Gui2DInterior extends Gui2D {

    private static final Logger logger = Logger.getLogger(Gui2DInterior.class.getName());

    /** A listener for keys pressed and released */
    protected InteriorKeyListener keyListener;

    /** This Gui's app. */
    private App2D app;

    /** The focus entity of this Gui's app. */
    private Entity appFocusEntity;

    /**
     * Create a new instance of Gui2DInterior.
     *
     * @param view The view associated with the component that uses this Gui.
     */
    public Gui2DInterior(View2DEntity view) {
        super(view);
        app = view.getWindow().getApp();
        appFocusEntity = app.getFocusEntity();
    }

    /**
     * {@inheritDoc}
     */
    @Override
    protected void attachMouseListener(Entity entity) {
        mouseListener = new InteriorMouseListener();
        mouseListener.addToEntity(entity);
    }

    /**
     * {@inheritDoc}
     */
    @Override
    protected void detachMouseListener(Entity entity) {
        if (mouseListener != null && entity != null) {
            mouseListener.removeFromEntity(entity);
        }
    }

    /**
     * This Gui's listener for mouse events.
     * <br>
     * If the user has control of the app, this method sends the event to the corresponding view for this gui.
     * <br>
     * If user doesn't have control of the app, the event is checked to see if it is a recognized action.
     * If an action is recognized the action is performed.
     */
    protected class InteriorMouseListener extends Gui2D.MouseListener {

        @Override
        public boolean propagatesToParent (Event event) {
            return false;
        }

        @Override
        public boolean consumesEvent(Event event) {
            if (!super.consumesEvent(event)) {
                // Not a mouse event.
                return false;
            }
            logger.fine("Mouse event is meant for this listener, event = " + event);

            // Always consume the control change event over the interior even when the app
            // doesn't have control and the app entity doesn't have focus
            MouseEvent3D me3d = (MouseEvent3D) event;
            if (isChangeControlEvent((MouseEvent) me3d.getAwtEvent())) {
                return true;
            }

            if (app == null || app.getControlArb() == null) return false;
            if (!app.getControlArb().hasControl()) {
                return false;
            }
            logger.fine("User has control of app");

            // When the app has control only consume if app has focus.
            boolean entityHasFocus = InputManager3D.entityHasFocus(event, appFocusEntity);
            logger.fine("Entity has focus = " + entityHasFocus);
            return entityHasFocus;
        }

        @Override
        public void commitEvent(Event event) {
            logger.fine("Interior mouse commitEvent, event = " + event);
            final MouseEvent3D me3d = (MouseEvent3D) event;

            // When user has control all events over the interior are sent to the app.
            // First send it to the app's view for conversion to a 2D event.
           
            if (view != null) {
                if (view.getWindow().getApp().getControlArb().hasControl()) {
                    SwingUtilities.invokeLater(new Runnable () {
                        public void run () {
                            if (view != null) {
                                view.deliverEvent(view.getWindow(), me3d);
                            }
                        }
                    });
                    return;
                }
            }

            MouseEvent me = (MouseEvent) me3d.getAwtEvent();

            // Handle miscellaneous events over interior when user doesn't have control
            Action action = determineIfMiscAction(me, me3d);
            if (action != null) {
                performMiscAction(action, me, me3d);
                return;
            }

            super.commitEvent(event);
        }
    }

    /**
     * {@inheritDoc}
     */
    @Override
    protected void attachKeyListener(Entity entity) {
        keyListener = new InteriorKeyListener();
        keyListener.addToEntity(entity);
    }

    /**
     * {@inheritDoc}
     */
    @Override
    protected void detachKeyListener(Entity entity) {
        if (keyListener != null && entity != null) {
            keyListener.removeFromEntity(entity);
        }
    }

    /**
     * This Gui's listener for key events.
     * <br>
     * If the key is Shift-F12, user control is released for all apps in the client session.
     * <br>
     * Otherwise, if the user has control of the app, this method sends the event directly to the
     * corresponding window for this gui.
     * <br>
     * If user doesn't have control of the app then the event is discarded.
     */
    protected class InteriorKeyListener extends EventClassListener {

        @Override
        public boolean propagatesToParent (Event event) {
            return false;
        }

        @Override
        public Class[] eventClassesToConsume() {
            return new Class[]{KeyEvent3D.class};
        }

        @Override
        public boolean consumesEvent(Event event) {
            if (!super.consumesEvent(event)) {
                // Not meant for us
                return false;
            }
            logger.fine("Key event is meant for this listener, event = " + event);

            if (app == null || app.getControlArb() == null) return false;
            if (!app.getControlArb().hasControl()) {
                return false;
            }
            logger.fine("User has control of app");

            // When the app has control only consume if app has focus.
            boolean entityHasFocus = InputManager3D.entityHasFocus(event, appFocusEntity);
            logger.fine("Entity has focus = " + entityHasFocus);
            return entityHasFocus;
        }

        @Override
        public void commitEvent(Event event) {
            logger.fine("Interior key commitEvent, event = " + event);
            KeyEvent3D ke3d = (KeyEvent3D) event;
            final KeyEvent ke = (KeyEvent) ke3d.getAwtEvent();

            /* For ortho subwindow debugging -- TODO: doesn't work. See bug 203
            if (ke3d.isPressed() &&
                ke.getKeyCode() == KeyEvent.VK_F11 &&
                (ke.getModifiersEx() & KeyEvent.SHIFT_DOWN_MASK) != 0) {
                System.err.println("******* toggleortho");
                view.getWindow().toggleOrtho();
                return;
            }
            */

            if (view != null) {
                final ControlArb controlArb = view.getWindow().getApp().getControlArb();
                if (controlArb.hasControl()) {
                    SwingUtilities.invokeLater(new Runnable () {
                        public void run () {
                            // Note: currently no special GUI processing is needed for key events
                            // so they are all just sent to the app group if it has control
                            controlArb.deliverEvent(view.getWindow(), ke);
                        }
                    });
                }
            }
        }
    }
}
TOP

Related Classes of org.jdesktop.wonderland.modules.appbase.client.view.Gui2DInterior$InteriorKeyListener

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.