This started with a need posted from @sgold dealing with leveraging the ToolTips feature and sort of grew from there… however, I wanted people using the library to be aware of the addition of event support. Here is the post from the other thread that gives a basic rundown of what it is and how to use it:
To start, the following events will be handled (I want a bit more time to consider keyboard and touch events… specifically multi-touch)
MouseButtonListener
MouseWheelListener
MouseFocusListener
MouseMovementListener
Here is a quick vid of mouse focus + contextual right-click menus for scene objects:
[video]http://youtu.be/Gqhq5LXksCo[/video]
The code to make the above work was grueling:
ExtendedNode.java
[java]
import com.jme3.scene.Node;
import tonegod.gui.listeners.MouseButtonListener;
import tonegod.gui.listeners.MouseFocusListener;
/**
*
-
@author t0neg0d
*/
public abstract class ExtendedNode extends Node implements MouseFocusListener, MouseButtonListener { }
[/java]
Main.java
[java]
import com.jme3.app.SimpleApplication;
import com.jme3.input.event.MouseButtonEvent;
import com.jme3.input.event.MouseMotionEvent;
import com.jme3.material.Material;
import com.jme3.math.ColorRGBA;
import com.jme3.math.Vector2f;
import com.jme3.renderer.RenderManager;
import com.jme3.scene.Geometry;
import com.jme3.scene.Mesh;
import com.jme3.scene.Node;
import com.jme3.scene.shape.Box;
import com.jme3.scene.shape.Sphere;
import tonegod.gui.controls.menuing.Menu;
import tonegod.gui.core.*;
/**
-
test
-
@author t0neg0d
*/
public class Main extends SimpleApplication {
private Screen screen;
private Menu menu, menu2;public static void main(String[] args) {
Main app = new Main();
app.start();
}@Override
public void simpleInitApp() {
setupCamera();
createGUIScreen();
layoutGUI();flyCam.setDragToRotate(true); inputManager.setCursorVisible(true);
}
private void setupCamera() {
inputManager.setCursorVisible(true);
flyCam.setMoveSpeed(50);
}private void createGUIScreen() {
screen = new Screen(this);
screen.setUse3DSceneSupport(true);
guiNode.addControl(screen);
}private void layoutGUI() {
createMenus();Box box = new Box(1,1,1); Sphere sphere = new Sphere(12,12,1); Material mat = new Material(assetManager,"Common/MatDefs/Misc/Unshaded.j3md"); mat.setColor("Color", ColorRGBA.Blue); Node n = this.getNewGUINode(box, mat.clone(), menu); Node n2 = this.getNewGUINode(sphere, mat.clone(), menu2); n2.setLocalTranslation(3,0,0); rootNode.attachChild(n); rootNode.attachChild(n2);
}
private void createMenus() {
menu = new Menu(screen, Vector2f.ZERO, false) {
@Override
public void onMenuItemClicked(int index, Object value, boolean isToggled) {} }; menu.addMenuItem("Contextual Box Menu Item 1", 0, null); menu.addMenuItem("Contextual Box Menu Item 2", 1, null); menu.addMenuItem("Contextual Box Menu Item 3", 2, null); menu.addMenuItem("Contextual Box Menu Item 4", 3, null); screen.addElement(menu); menu2 = new Menu(screen, Vector2f.ZERO, false) { @Override public void onMenuItemClicked(int index, Object value, boolean isToggled) { } }; menu2.addMenuItem("Contextual Sphere Menu Item 1", 0, null); menu2.addMenuItem("Contextual Sphere Menu Item 2", 1, null); menu2.addMenuItem("Contextual Sphere Menu Item 3", 2, null); menu2.addMenuItem("Contextual Sphere Menu Item 4", 3, null); screen.addElement(menu2);
}
private Node getNewGUINode(Mesh mesh, Material mat, final Menu menu) {
Geometry geom = new Geometry();
geom.setMesh(mesh);
ExtendedNode node = new ExtendedNode() {
public void onGetFocus(MouseMotionEvent evt) {
((Geometry)getChild(0)).getMaterial().setColor(“Color”, ColorRGBA.Yellow);
evt.setConsumed();
}
public void onLoseFocus(MouseMotionEvent evt) {
((Geometry)getChild(0)).getMaterial().setColor(“Color”, ColorRGBA.Blue);
evt.setConsumed();
}
public void onMouseLeftPressed(MouseButtonEvent evt) { }
public void onMouseLeftReleased(MouseButtonEvent evt) { }
public void onMouseRightPressed(MouseButtonEvent evt) { }
public void onMouseRightReleased(MouseButtonEvent evt) {
menu.showMenu(null, screen.getMouseXY().x, screen.getMouseXY().y-menu.getHeight());
evt.setConsumed();
}
};
node.attachChild(geom);
node.setMaterial(mat);
return node;
}@Override
public void simpleUpdate(float tpf) { }
@Override
public void simpleRender(RenderManager rm) { }
}
[/java]
Lastly, I wanted to note how to leverage custom cursors for your 3D scene spatials. When using the MouseFocusListener, in onGetFocus, add:
[java]
screen.setForcedCursor(StyleManager.CursorType.HAND); // Or whatever cursor/custom cursor you want
[/java]
And in onLoseFocus, add:
[java]
screen.releaseForcedCursor();
[/java]
Everything else is fairly self-explanatory. But, do feel free to ask questions if you decide to use this for event handling in your game.
Screen.java has been updated for this and the changes committed.