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

Source Code of org.jdesktop.wonderland.modules.appbase.client.cell.view.viewdefault.View2DCell

/**
* 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.cell.view.viewdefault;

import org.jdesktop.mtgame.Entity;
import com.jme.math.Quaternion;
import com.jme.math.Vector2f;
import com.jme.math.Vector3f;
import java.util.logging.Logger;
import org.jdesktop.wonderland.client.cell.Cell;
import org.jdesktop.wonderland.client.cell.MovableComponent;
import org.jdesktop.wonderland.common.ExperimentalAPI;
import org.jdesktop.wonderland.common.cell.CellTransform;
import org.jdesktop.wonderland.modules.appbase.client.Window2D;
import org.jdesktop.wonderland.modules.appbase.client.cell.App2DCell;
import org.jdesktop.wonderland.modules.appbase.client.view.GeometryNode;
import org.jdesktop.wonderland.modules.appbase.client.view.View2D.Type;
import org.jdesktop.wonderland.modules.appbase.client.view.View2DDisplayer;
import org.jdesktop.wonderland.modules.appbase.client.view.View2DEntity;
import java.awt.Dimension;

/**
* A subclass of <code>View2DEntity</code> which provides additional capabilities above and beyond its super class.
* In particular, a <code>View2DCell</code> can be rotated in addition to being translated
* (see <code>applyDeltaRotationUser</code>). It can also have an optionally attached frame.
*
* @author dj
*/
@ExperimentalAPI
public class View2DCell extends View2DEntity {

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

    /** The amount of space between views in the view stack.*/
    private static float STACK_GAP = 0.01f;

    /** The cell in which this view is displayed. */
    private App2DCell cell;

    /** The next delta rotation to apply. */
    private Quaternion deltaRotationToApply;

    /** The frame of a decorated view. */
    private Frame2DCell frame;

    /** Did we create our own movable component? */
    private boolean selfCreatedMovableComponent;

    /** The resize rectangle for this view. */
    private ResizeRectangle resizeRect;

    /**
     * Create an instance of View2DCell with default geometry node.
     * @param cell The cell in which the view is displayed.
     * @param window The window displayed in this view.
     */
    public View2DCell (App2DCell cell, Window2D window) {
        this(cell, window, null);
    }

    /**
     * Create an instance of View2DCell with a specified geometry node.
     * @param cell The cell in which the view is displayed.
     * @param window The window displayed in this view.
     * @param geometryNode The geometry node on which to display the view.
     */
    public View2DCell (App2DCell cell, Window2D window, GeometryNode geometryNode) {
        super(window, geometryNode);
        this.cell = cell;

        changeMask = CHANGED_ALL;

        // Note: first-visible optimization: don't update now because not visible.
        // A later set visible to true will update everything.
    }

    /** Clean up resources. */
    @Override
    public synchronized void cleanup () {
        super.cleanup();

        if (resizeRect != null) {
            resizeRect.cleanup();
            resizeRect = null;
        }

        if (frame != null) {
            frame.cleanup();
            frame = null;
        }

        if (selfCreatedMovableComponent) {
            cell.removeComponent(MovableComponent.class);
        }

        cell = null;
    }

    /** Returns this view's cell */
    public App2DCell getCell () {
        return cell;
    }

    /** {@inheritDoc} */
    public View2DDisplayer getDisplayer () {
        return getCell();
    }

    /** {@inheritDoc} */
    public void applyDeltaRotationUser (Quaternion deltaRotation) {
        applyDeltaRotationUser(deltaRotation, true);
    }

    /** {@inheritDoc} */
    public void applyDeltaRotationUser (Quaternion deltaRotation, boolean update) {
        deltaRotationToApply = deltaRotation.clone();
        changeMask |= CHANGED_USER_TRANSFORM;
        if (update) {
            update();
            updateFrame();
        }
    }
       
    public synchronized void userRotateYStart (float dy) {
    }

    public synchronized void userRotateYUpdate (float dy) {
    }

    public synchronized void userRotateYFinish () {
    }

    // Uses: type, parent
    @Override
    protected Entity getParentEntity () {
        App2DCellRendererJME renderer = (App2DCellRendererJME) cell.getCellRenderer(Cell.RendererType.RENDERER_JME);
        if (renderer == null) return null;
        Entity cellEntity = renderer.getEntity();

        switch (type) {

        case UNKNOWN:
        case PRIMARY:
            // Attach primaries directly to cell entity
            return cellEntity;
       
        default:
            // Attach non-primaries to the entity of their parent, if possible
            if (parent == null) {
                logger.warning("Attempt to attach a non-primary view without a parent");
                logger.warning("cell = " + cell);
                logger.warning("view = " + this);
                logger.warning("view type = " + type);
                // This is the best we can do
                return cellEntity;
            } else {
                return parent.getEntity();
            }
        }
    }               

    // Uses: type, ortho, parent, stack
    @Override
    protected Vector3f calcStackTranslation () {
        if (isOrtho()) {
            return new Vector3f(0f, 0f, 0f);
        } else {
            int stackPos = window.getStackPosition();
            if (stackPos < 0) {
                logger.info("ERROR: stack position cannot be calculated for window " + window);
                stackPos = 0;
            }
            logger.fine("View " + this);
            logger.fine("zOrder = " + window.getZOrder());
            logger.fine("stackPos = " + stackPos);
            float localZ;
            if ((type == Type.POPUP || type == Type.SECONDARY) && parent != null) {
                Window2D parentWindow = ((View2DCell)parent).window;
                if (parentWindow == null) {
                    localZ = 0f;
                } else {
                    int stackPosParent = parentWindow.getStackPosition();
                    logger.fine("stackPosParent = " + stackPosParent);
                    logger.fine("zOrder Parent = " + parentWindow.getZOrder());
                    localZ = (stackPos - stackPosParent) * STACK_GAP;
                }
            } else {
                localZ = stackPos * STACK_GAP;
            }

            logger.fine("localZ = " + localZ);
            return new Vector3f(0f, 0f, localZ);
        }
    }

    /** {@inheritDoc} */
    // Uses: deltaRotationToApply, deltaTranslationToApply
    @Override
    protected void userTransformApplyDeltas (CellTransform userTransform) {
        userTransformApplyDeltaRotation(userTransform);
        userTransformApplyDeltaTranslation(userTransform);
    }

    // Apply any pending rotation delta to the given user transform.
    protected void userTransformApplyDeltaRotation (CellTransform userTransform) {
        if (deltaRotationToApply != null) {
            CellTransform transform = new CellTransform(null, null);
            transform.setRotation(deltaRotationToApply);
            userTransform.mul(transform);
            deltaRotationToApply = null;
        }
    }

    // TODO: eventually need to complete this
    @Override
    protected void updatePrimaryTransform (CellTransform newTransform) {
        /* TODO
        // To update a user transformations on a primary view we directly change the cell. Create and add
        // a movable component to the cell if it doesn't already have one.
        MovableComponent mc = (MovableComponent) cell.getComponent(MovableComponent.class);
        if (mc == null) {
            mc = new MovableComponent(cell);
            cell.addComponent(mc);
            selfCreatedMovableComponent = true;
        }
        mc.localMoveRequest(newTransform);
        */
    }

    /** {@inheritDoc} */
    @Override
    protected boolean hasFrame () {
        return frame != null;
    }

    /** {@inheritDoc} */
    @Override
    protected void attachFrame () {
        if (frame == null) {
            logger.fine("Create new frame for view " + this);
            frame = new Frame2DCell(this);
        }
        logger.fine("Attach frame to view " + this);
        frame.attachToViewEntity();
    }

    /** {@inheritDoc} */
    @Override
    protected void detachFrame () {
        if (frame != null) {
            logger.fine("Detach frame from view");
            frame.detachFromViewEntity();
        }
    }

    /** {@inheritDoc} */
    @Override
    protected void reattachFrame () {
        logger.fine("Reattach new frame, frame = " + frame);
        detachFrame();
        attachFrame();
    }

    /** {@inheritDoc} */
    @Override
    protected void frameUpdateTitle () {
        if (frame != null) {
            // Note: doesn't need to be done in render updater
            frame.setTitle(getTitle());
        }
    }

    /** {@inheritDoc} */
    @Override
    protected void frameUpdateUserResizable () {
        if (frame != null) {
            frame.setUserResizable(isUserResizable());
        }
    }

    /** {@inheritDoc} */
    @Override
    protected void frameUpdate () {
        if (frame != null) {
            try {
                frame.update();
            } catch (InstantiationException ex) {
                logger.warning("Exception during view frame update, ex = " + ex);
            }
        }
    }

    /**
     * Returns the frame of this view.
     */
    protected Frame2DCell getFrame () {
        return frame;
    }

    /**
     * Immediately sets the this view's user cell transform to the given transform.
     * Note: you must call update after calling this to have the setting take effect.
     */
    public void setUserTransformCellLocal (CellTransform transform) {
        userTransformCell = transform.clone(null);
        userTransformCellReplaced = true;
        userTransformCellChangedLocalOnly = true;
        changeMask |= CHANGED_USER_TRANSFORM;
    }

    /**
     * Return the cell user transform of this view.
     */
    public CellTransform getUserTransformCell () {
        return userTransformCell.clone(null);
    }

    protected void userResizeFrameUpdate (float newWidth3D, float newHeight3D, Dimension newSize) {
        try {
            frame.update(newWidth3D, newHeight3D, newSize);
        } catch (InstantiationException ex) {
            logger.warning("Instantiation exception during user resize of frame");
        }
    }

    /** {@inheritDoc} */
    public synchronized void setUserResizable (boolean userResizable, boolean update) {
        super.setUserResizable(userResizable, update);

        if (userResizable) {
            resizeRect = new ResizeRectangle(this);
        } else {
            if (resizeRect != null) {
                resizeRect.cleanup();
                resizeRect = null;
            }
        }
    }
   
    /**
     * {@inheritDoc}
     */
    @Override
    public void userResizeStart () {
        if (resizeRect != null) {
            resizeRect.updateSizeFromView();
            resizeRect.setVisible(true);
        }
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public void userResizeUpdate (Vector2f dragVector) {
        if (resizeRect != null) {
            resizeRect.sizeAdd(dragVector);
        }
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public void userResizeFinish () {
        if (resizeRect != null) {
            Dimension userResizeNewSize = resizeRect.getViewSize();
            resizeRect.setVisible(false);
            window.userSetSize(userResizeNewSize.width, userResizeNewSize.height);
        }
    }
}

TOP

Related Classes of org.jdesktop.wonderland.modules.appbase.client.cell.view.viewdefault.View2DCell

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.