/*********************************************************************** * mt4j Copyright (c) 2008 - 2010 Christopher Ruff, Fraunhofer-Gesellschaft All rights reserved. * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see <http://www.gnu.org/licenses/>. * ***********************************************************************/ package org.mt4j.components.visibleComponents.widgets; import org.apache.log4j.ConsoleAppender; import org.apache.log4j.Level; import org.apache.log4j.Logger; import org.apache.log4j.SimpleLayout; import org.mt4j.MTApplication; import org.mt4j.components.MTCanvas; import org.mt4j.components.MTComponent; import org.mt4j.components.visibleComponents.shapes.AbstractShape; import org.mt4j.components.visibleComponents.shapes.MTRectangle; import org.mt4j.input.inputData.InputCursor; import org.mt4j.input.inputProcessors.IGestureEventListener; import org.mt4j.input.inputProcessors.MTGestureEvent; import org.mt4j.input.inputProcessors.componentProcessors.dragProcessor.DragEvent; import org.mt4j.input.inputProcessors.componentProcessors.dragProcessor.DragProcessor; import org.mt4j.sceneManagement.Iscene; import org.mt4j.util.MT4jSettings; import org.mt4j.util.MTColor; import org.mt4j.util.math.Tools3D; import org.mt4j.util.math.Vector3D; import org.mt4j.util.opengl.GLTextureSettings; import org.mt4j.util.opengl.GLTexture; import org.mt4j.util.opengl.GLTexture.WRAP_MODE; import processing.core.PApplet; import processing.core.PImage; /** * The Class MTSceneMenu. A menu used in scenes to close the scene and/or pop back to another scene. * * @author Christopher Ruff */ public class MTSceneMenu extends MTRectangle{ /** The Constant logger. */ private static final Logger logger = Logger.getLogger(MTSceneMenu.class.getName()); static{ // logger.setLevel(Level.ERROR); // logger.setLevel(Level.WARN); // logger.setLevel(Level.DEBUG); logger.setLevel(Level.INFO); SimpleLayout l = new SimpleLayout(); ConsoleAppender ca = new ConsoleAppender(l); logger.addAppender(ca); } /** The app. */ private MTApplication app; /** The scene. */ private Iscene scene; /** The overlay group. */ private MTComponent overlayGroup; /** The scene texture. */ private MTSceneTexture sceneTexture; /** The windowed scene. */ private boolean windowedScene; /** The menu image. */ private static PImage menuImage; /** The close button image. */ private static PImage closeButtonImage; /** The restore button image. */ private static PImage restoreButtonImage; //TODO maybe add minimize mode -> dont show scene but dont destroy it -> maby keep it in a MTList /** * Instantiates a new mT scene menu. * * @param scene the scene * @param x the x * @param y the y * @param width the width * @param height the height * @param app the app */ public MTSceneMenu(Iscene scene, float x, float y, float width, float height, MTApplication app) { super(x, y, width, height, app); this.app = app; this.scene = scene; this.windowedScene = false; this.init(x, y, width, height); } /** * Instantiates a new mT scene menu. * * @param sceneTexture the scene texture * @param x the x * @param y the y * @param width the width * @param height the height * @param app the app */ public MTSceneMenu(MTSceneTexture sceneTexture, float x, float y, float width, float height, MTApplication app) { super(x, y, width, height, app); this.app = app; this.scene = sceneTexture.getScene(); this.sceneTexture = sceneTexture; this.windowedScene = true; this.init(x, y, width, height); } /** * Inits the. * * @param x the x * @param y the y * @param width the width * @param height the height */ private void init(float x, float y, float width, float height){ // this.setNoFill(true); this.setNoStroke(true); // this.setFillColor(new MTColor(255,100,100,100)); this.setFillColor(new MTColor(255,255,255,150)); // this.unregisterAllInputProcessors(); // this.setPickable(false); overlayGroup = new MTOverlayContainer(app, "Window Menu Overlay Group"); if (menuImage == null){ menuImage = app.loadImage(MT4jSettings.getInstance().getDefaultImagesPath() + "blackRoundSolidCorner64sh2.png"); } if (MT4jSettings.getInstance().isOpenGlMode()){ // GLTextureParameters tp = new GLTextureParameters(); // tp.wrap_s = GL.GL_CLAMP; // tp.wrap_t = GL.GL_CLAMP; //// GLTexture glTex = new GLTexture(app, MT4jSettings.getInstance().getDefaultImagesPath()+ //// "blackRoundSolidCorner64sh2.png", tp); // GLTexture glTex = new GLTexture(app, menuImage.width, menuImage.height, tp); // glTex.putPixelsIntoTexture(menuImage); // this.setTexture(glTex); GLTextureSettings ts = new GLTextureSettings(); ts.wrappingHorizontal = WRAP_MODE.CLAMP; ts.wrappingVertical = WRAP_MODE.CLAMP; GLTexture glTex = new GLTexture(app, menuImage.width, menuImage.height, ts); glTex.loadGLTexture(menuImage); this.setTexture(glTex); }else{ this.setTexture(menuImage); } AbstractShape menuShape = this; menuShape.unregisterAllInputProcessors(); menuShape.removeAllGestureEventListeners(DragProcessor.class); menuShape.registerInputProcessor(new DragProcessor(app)); float buttonWidth = 80; float buttonHeight = 80; final float buttonOpacity = 170; //CLOSE BUTTON // Vector3D a = new Vector3D(-width * 1.2f, height/2f); Vector3D a = new Vector3D(-width * 1.55f, 0); a.rotateZ(PApplet.radians(80)); final MTRectangle closeButton = new MTRectangle(x + a.x, y + a.y, buttonWidth, buttonHeight, app); if (closeButtonImage == null){ closeButtonImage = app.loadImage(MT4jSettings.getInstance().getDefaultImagesPath() + // "close_32.png")); // "126182-simple-black-square-icon-alphanumeric-circled-x3_cr.png")); // "124241-matte-white-square-icon-alphanumeric-circled-x3_cr.png"); "closeButton64.png"); } closeButton.setTexture(closeButtonImage); closeButton.setFillColor(new MTColor(255, 255, 255, buttonOpacity)); closeButton.setNoStroke(true); closeButton.setVisible(false); this.addChild(closeButton); //Check if this menu belongs to a window Scene (MTSceneWindow) //or was added to a normal scene //-> if its not a windowed scene we dont display the Restore button if (this.windowedScene){ //RESTORE BUTTON Vector3D b = new Vector3D(-width * 1.55f, 0); b.rotateZ(PApplet.radians(10)); final MTRectangle restoreButton = new MTRectangle(x + b.x, y + b.y, buttonWidth, buttonHeight, app); if (restoreButtonImage == null){ restoreButtonImage = app.loadImage(MT4jSettings.getInstance().getDefaultImagesPath() + // "window_app_32.png")); // "126630-simple-black-square-icon-business-document10-sc1_cr.png"); // restoreButton.setFillColor(new MTColor(150, 150, 250, 200)); "restoreButton64.png"); } restoreButton.setTexture(restoreButtonImage); restoreButton.setFillColor(new MTColor(255, 255, 255, buttonOpacity)); restoreButton.setNoStroke(true); restoreButton.setVisible(false); this.addChild(restoreButton); menuShape.addGestureListener(DragProcessor.class, new IGestureEventListener() { public boolean processGestureEvent(MTGestureEvent ge) { DragEvent de = (DragEvent)ge; switch (de.getId()) { case MTGestureEvent.GESTURE_DETECTED: restoreButton.setVisible(true); closeButton.setVisible(true); unhighlightButton(closeButton, buttonOpacity); unhighlightButton(restoreButton, buttonOpacity); break; case MTGestureEvent.GESTURE_UPDATED: //Mouse over effect if (closeButton.containsPointGlobal(de.getTo())){ highlightButton(closeButton); }else{ unhighlightButton(closeButton, buttonOpacity); } if (restoreButton.containsPointGlobal(de.getTo())){ highlightButton(restoreButton); }else{ unhighlightButton(restoreButton, buttonOpacity); } break; case MTGestureEvent.GESTURE_ENDED: unhighlightButton(closeButton, buttonOpacity); unhighlightButton(restoreButton, buttonOpacity); InputCursor cursor = de.getDragCursor(); Vector3D restoreButtonIntersection = restoreButton.getIntersectionGlobal(Tools3D.getCameraPickRay(getRenderer(), restoreButton, cursor.getCurrentEvtPosX(), cursor.getCurrentEvtPosY())); if (restoreButtonIntersection != null){ logger.debug("--> RESTORE!"); MTSceneMenu.this.sceneTexture.restore(); } Vector3D closeButtonIntersection = closeButton.getIntersectionGlobal(Tools3D.getCameraPickRay(getRenderer(), closeButton, cursor.getCurrentEvtPosX(), cursor.getCurrentEvtPosY())); if (closeButtonIntersection != null){ // if (app.popScene()){ // app.removeScene(scene); //FIXME wont work if the scene has a transition because we cant remove the still active scene //// destroy(); //this will be destroyed with the scene // sceneTexture.destroy(); //destroys also the MTSceneWindow and with it the scene // logger.debug("--> CLOSE!"); // } if (sceneTexture.restore()){ // app.removeScene(scene); //FIXME wont work if the scene has a transition because we cant remove the still active scene // destroy(); //this will be destroyed with the scene sceneTexture.destroy(); //destroys also the MTSceneWindow and with it the scene logger.debug("--> CLOSE!"); } } restoreButton.setVisible(false); closeButton.setVisible(false); break; default: break; } return false; } }); }else{ if (scene != null){ menuShape.addGestureListener(DragProcessor.class, new IGestureEventListener() { public boolean processGestureEvent(MTGestureEvent ge) { DragEvent de = (DragEvent)ge; switch (de.getId()) { case MTGestureEvent.GESTURE_DETECTED: closeButton.setVisible(true); unhighlightButton(closeButton, buttonOpacity); break; case MTGestureEvent.GESTURE_UPDATED: //Mouse over effect if (closeButton.containsPointGlobal(de.getTo())){ highlightButton(closeButton); }else{ unhighlightButton(closeButton, buttonOpacity); } break; case MTGestureEvent.GESTURE_ENDED: unhighlightButton(closeButton, buttonOpacity); InputCursor cursor = de.getDragCursor(); Vector3D closeButtonIntersection = closeButton.getIntersectionGlobal(Tools3D.getCameraPickRay(getRenderer(), closeButton, cursor.getCurrentEvtPosX(), cursor.getCurrentEvtPosY())); if (closeButtonIntersection != null){ if (app.popScene()){ destroy(); //Destroy this scene.destroy(); //Destroy the scene logger.debug("--> CLOSE!"); } } closeButton.setVisible(false); break; default: break; } return false; } }); } } } // private void restoreSceneWindow(){ // this.removeFromScene(); // } // // private void closeSceneWindow(){ // MTSceneWindow.this.destroy(); // } /** * Highlight button. * * @param shape the shape */ private void highlightButton(AbstractShape shape){ MTColor c = shape.getFillColor(); c.setAlpha(255); shape.setFillColor(c); } /** * Unhighlight button. * * @param shape the shape * @param opacity the opacity */ private void unhighlightButton(AbstractShape shape, float opacity){ MTColor c = shape.getFillColor(); c.setAlpha(opacity); shape.setFillColor(c); } /** * Adds the to scene. */ public void addToScene(){ MTComponent cursorTraceContainer = null; MTCanvas canvas = scene.getCanvas(); /* //Re-use cursor trace group which is always on top for this menu MTComponent[] children = canvas.getChildren(); for (int i = 0; i < children.length; i++) { MTComponent component = children[i]; if (component instanceof MTOverlayContainer && component.getName().equalsIgnoreCase("Cursor Trace group")){ cursorTraceContainer = component; component.addChild(0, this); //add to cursor trace overlay container } } */ // /* //cursor tracer group NOT found in the scene -> add overlay container to canvas if (cursorTraceContainer == null){ overlayGroup.addChild(this); canvas.addChild(overlayGroup); } // */ } /** * Removes the from scene. */ public void removeFromScene(){ MTComponent cursorTraceContainer = null; MTCanvas canvas = scene.getCanvas(); /* //Re-use cursor trace group which is always on top for this menu MTComponent[] children = canvas.getChildren(); for (int i = 0; i < children.length; i++) { MTComponent component = children[i]; if (component instanceof MTOverlayContainer && component.getName().equalsIgnoreCase("Cursor Trace group")){ cursorTraceContainer = component; if (cursorTraceContainer.containsChild(this)){ cursorTraceContainer.removeChild(this); } } } */ // /* //cursor tracer group NOT found in the scene -> add overlay container to canvas if (cursorTraceContainer == null){ if (canvas.containsChild(overlayGroup)){ canvas.removeChild(overlayGroup); } } // */ } }