Advertisement
Guest User

GuiElement for use with JME 3

a guest
Dec 29th, 2013
87
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Java 35.16 KB | None | 0 0
  1. package strongdk.jme.gui;
  2.  
  3. import com.jme3.app.Application;
  4. import com.jme3.asset.AssetManager;
  5. import com.jme3.bounding.BoundingBox;
  6. import com.jme3.font.BitmapFont;
  7. import com.jme3.font.BitmapText;
  8. import com.jme3.font.LineWrapMode;
  9. import com.jme3.font.Rectangle;
  10. import com.jme3.input.InputManager;
  11. import com.jme3.input.KeyInput;
  12. import com.jme3.input.MouseInput;
  13. import com.jme3.input.RawInputListener;
  14. import com.jme3.input.event.JoyAxisEvent;
  15. import com.jme3.input.event.JoyButtonEvent;
  16. import com.jme3.input.event.KeyInputEvent;
  17. import com.jme3.input.event.MouseButtonEvent;
  18. import com.jme3.input.event.MouseMotionEvent;
  19. import com.jme3.input.event.TouchEvent;
  20. import com.jme3.material.Material;
  21. import com.jme3.material.RenderState;
  22. import com.jme3.math.ColorRGBA;
  23. import com.jme3.math.Vector2f;
  24. import com.jme3.math.Vector3f;
  25. import com.jme3.renderer.ViewPort;
  26. import com.jme3.scene.Geometry;
  27. import com.jme3.scene.Node;
  28. import com.jme3.scene.Spatial;
  29. import com.jme3.scene.shape.Quad;
  30. import java.util.List;
  31.  
  32.  
  33. /**
  34.  *
  35.  * A simple Spatial that can be very easily added to a guiNode and provide a button, label, or text field functionality.
  36.  *
  37.  * The motivation here is to be able to add functional gui elements without needing an actual gui library. Most useful for prototyping or debugging.
  38.  *
  39.  * There are no features (or plans for features) for windows, panels, layout management, or extensive customizability.
  40.  *
  41.  * If youre looking for a JME3 gui system with lots of features consider looking at Nifty, t0neg0dgui, or Lemur.
  42.  *
  43.  * @author Daniel Strong aka icamefromspace Dec 2013
  44.  */
  45. public final class GuiElement extends Node {
  46.  
  47.         private ViewPort guiViewport;
  48.         private InputManager inputManager;
  49.         private boolean rawInputListenersAdded = false;
  50.         private boolean enabled = true;
  51.         private boolean pressed = false;
  52.         private boolean hovered = false;
  53.         private boolean toggleable = false;
  54.         private boolean toggled = false;
  55.         private boolean editable = false;
  56.         private boolean editFocus = false;
  57.         private Quad quad;
  58.         private Geometry geom;
  59.         private Material mat, hoverMat, clickedMat;
  60.         private float textInset = 10;
  61.         private BitmapText bitmapText;
  62.         private BitmapText inputCursorBitmapText;
  63.         private float inputCursorBlinkDuration = .4f;
  64.         private GuiElementListener guiElementListener;
  65.         private GeRawInputListener rawInputListener;
  66.  
  67.         /**
  68.          * this is the same as the other constructor, but assumes the obvious values from Application to save typing.
  69.          * @param app
  70.          * @param text
  71.          * @param width
  72.          * @param height
  73.          */
  74.         public GuiElement(Application app, String text, float width, float height) {
  75.                 this(app.getGuiViewPort(), app.getInputManager(), text, width, height, darkGrayMat(app.getAssetManager()), lightGrayMat(app.getAssetManager()), blueMat(app.getAssetManager()), app.getAssetManager().loadFont("Interface/Fonts/Default.fnt"), ColorRGBA.Gray.mult(2));
  76.         }
  77.  
  78.         /**
  79.          * make a gui element with all the specified settings and resources for maximum personalization. It might be quicker to use the factory methods on this lass to create Gui Elements though
  80.          *
  81.          * @param guiViewport
  82.          * @param inputManager
  83.          * @param text
  84.          * @param width
  85.          * @param height
  86.          * @param mat
  87.          * @param hoverMat
  88.          * @param clickedMat
  89.          * @param font
  90.          * @param textColor
  91.          */
  92.         public GuiElement(ViewPort guiViewport, InputManager inputManager, String text, float width, float height, Material mat, Material hoverMat, Material clickedMat, BitmapFont font, ColorRGBA textColor) {
  93.                 super(text);
  94.                 this.guiViewport = guiViewport;
  95.                 this.inputManager = inputManager;
  96.                 this.mat = mat;
  97.                 this.hoverMat = hoverMat;
  98.                 this.clickedMat = clickedMat;
  99.  
  100.                 //textInset = height * .1f;
  101.  
  102.                 geom = new Geometry(getName() + " Geom");
  103.                 geom.setMaterial(mat);
  104.                 quad = new Quad(width, height);
  105.                 geom.setMesh(quad);
  106.                 attachChild(geom);
  107.  
  108.                 bitmapText = new BitmapText(font, false);
  109.                 bitmapText.setText(text);
  110.                 bitmapText.setSize(font.getCharSet().getRenderedSize());
  111.                 bitmapText.setColor(textColor);
  112.                 bitmapText.setLineWrapMode(LineWrapMode.Word);
  113.                 Rectangle rectangle = new Rectangle(0, 0, quad.getWidth() - textInset, quad.getHeight() - textInset);
  114.                 bitmapText.setBox(rectangle);
  115.                 bitmapText.setVerticalAlignment(BitmapFont.VAlign.Center);
  116.                 bitmapText.setAlignment(BitmapFont.Align.Center);
  117.                 attachChild(bitmapText);
  118.  
  119.                 bitmapText.setLocalTranslation(0, quad.getHeight() - (textInset / 2f), 0);
  120.  
  121.         }
  122.  
  123.         /**
  124.          * this listener is notified of mouse and keyboard interactions with the GuiElement
  125.          *
  126.          * Also note that there is a {@link GuiElementAdapter} available to help condense your code.
  127.          *
  128.          * @param listener
  129.          */
  130.         public void setListener(GuiElementListener listener) {
  131.                 this.guiElementListener = listener;
  132.         }
  133.  
  134.         public void removeListener() {
  135.                 this.guiElementListener = null;
  136.         }
  137.  
  138.         public Vector2f getDimensions() {
  139.                 return new Vector2f(quad.getWidth(), quad.getHeight());
  140.         }
  141.  
  142.         /**
  143.          * Sets the dimensions of the screen space for this element. The quad will have these dimensions
  144.          *
  145.          * and the text will attempt to wrap as to stay in the dimensions, but if the text doesnt fit it doesnt fit.
  146.          *
  147.          * @param width
  148.          * @param height
  149.          */
  150.         public void setDimensions(float width, float height) {
  151.                 //textInset = height * .1f;
  152.                 quad = new Quad(width, height);
  153.                 geom.setMesh(quad);
  154.  
  155.                 Rectangle rectangle = new Rectangle(0, 0, quad.getWidth() - textInset, quad.getHeight() - textInset);
  156.                 bitmapText.setBox(rectangle);
  157.                 bitmapText.setLocalTranslation(0, quad.getHeight() - (textInset / 2f), 0);
  158.  
  159.                 if (inputCursorBitmapText != null) {
  160.                         inputCursorBitmapText.setBox(rectangle);
  161.                 }
  162.         }
  163.  
  164.         /**
  165.          * @param mat the button's idle state material
  166.          */
  167.         @Override
  168.         public void setMaterial(Material mat) {
  169.                 this.mat = mat;
  170.                 if (!hovered && !pressed) {
  171.                         geom.setMaterial(getIdleMaterial());
  172.                 }
  173.         }
  174.  
  175.         /**
  176.          * @param hoverMat the buttons hover state material
  177.          */
  178.         public void setHoverMaterial(Material hoverMat) {
  179.                 this.hoverMat = hoverMat;
  180.                 if (hovered && !pressed) {
  181.                         geom.setMaterial(hoverMat);
  182.                 }
  183.         }
  184.  
  185.         /**
  186.          *
  187.          * @param clickedMat the buttons state while mouse is held down. This is also used as the idle state if setToggleable(true).
  188.          */
  189.         public void setClickedMaterial(Material clickedMat) {
  190.                 this.clickedMat = clickedMat;
  191.                 if (pressed) {
  192.                         geom.setMaterial(clickedMat);
  193.                 }
  194.         }
  195.  
  196.         public Material getMaterial() {
  197.                 return mat;
  198.         }
  199.  
  200.         public Material getHoverMaterial() {
  201.                 return hoverMat;
  202.         }
  203.  
  204.         public Material getClickedMaterial() {
  205.                 return clickedMat;
  206.         }
  207.  
  208.         public void setText(String text) {
  209.                 bitmapText.setText(text);
  210.         }
  211.  
  212.         public void appendText(String text) {
  213.                 bitmapText.setText(bitmapText.getText() + text);
  214.         }
  215.  
  216.         public void appendTextBackspace() {
  217.                 String text = getText();
  218.                 if (!text.isEmpty()) {
  219.                         text = text.substring(0, text.length() - 1);
  220.                         setText(text);
  221.                 }
  222.         }
  223.  
  224.         public void clearText() {
  225.                 bitmapText.setText("");
  226.         }
  227.  
  228.         public String getText() {
  229.                 return bitmapText.getText();
  230.         }
  231.  
  232.         public void setTextColor(ColorRGBA color) {
  233.                 bitmapText.setColor(color);
  234.         }
  235.  
  236.         public void setTextColor(int start, int end, ColorRGBA color) {
  237.                 bitmapText.setColor(start, end, color);
  238.         }
  239.  
  240.         public void setTextColor(String regexp, ColorRGBA color) {
  241.                 bitmapText.setColor(regexp, color);
  242.         }
  243.  
  244.         public ColorRGBA getTextColor() {
  245.                 return bitmapText.getColor();
  246.         }
  247.  
  248.         public void setTextAlignment(BitmapFont.Align align) {
  249.                 bitmapText.setAlignment(align);
  250.                 if (inputCursorBitmapText != null) {
  251.                         inputCursorBitmapText.setAlignment(align);
  252.                 }
  253.         }
  254.  
  255.         public BitmapFont.Align getTextAlignment() {
  256.                 return bitmapText.getAlignment();
  257.         }
  258.  
  259.         /**
  260.          * enabled or disables the processing of mouse input on this gui element.
  261.          *
  262.          * The Gui Element will simply "freeze" in its state and ignores mouse interactions. If you want the element to appear disabled you will need to manually change the material/s.
  263.          *
  264.          * @param enabled
  265.          */
  266.         public void setEnabled(boolean enabled) {
  267.                 this.enabled = enabled;
  268.                 if (hasEditFocus()) {
  269.                         setEditFocus(false);
  270.                 }
  271.  
  272.                 if (!enabled) {
  273.                         pressed = false;
  274.                         hovered = false;
  275.                         validateIdleState();
  276.                 }
  277.         }
  278.  
  279.         /**
  280.          * returns true if this gui element responds to mouse and keyboard input
  281.          *
  282.          * @return
  283.          */
  284.         public boolean isEnabled() {
  285.                 return enabled;
  286.         }
  287.  
  288.         /**
  289.          *
  290.          * Note: if isEnabled() == false, then this value will not change
  291.          *
  292.          * @return true if the mouse button is being held down on the button
  293.          */
  294.         public boolean isPressed() {
  295.                 return pressed;
  296.         }
  297.  
  298.         /**
  299.          * Note: if isEnabled() == false, then this value will not change. instead use isMouseOverlappingButton() if youre curious (or do regular checks like you would any other spatial)
  300.          *
  301.          * @return true if the mouse is overlapping the buttons world bound.
  302.          */
  303.         public boolean isHovered() {
  304.                 return hovered;
  305.         }
  306.  
  307.         /**
  308.          *
  309.          * useful only if isToggleable() == true.
  310.          *
  311.          * @param toggled manually set the toggle state of the button, note that the listener will not be informed of this event.
  312.          */
  313.         public void setToggled(boolean toggled) {
  314.                 this.toggled = toggled;
  315.                 validateIdleState();
  316.         }
  317.  
  318.         /**
  319.          * if isToggleable() == false then this will always be false
  320.          *
  321.          * @return true if the button is in the "toggled on" state.
  322.          */
  323.         public boolean isToggled() {
  324.                 return toggled && toggleable;
  325.         }
  326.  
  327.         /**
  328.          * returns true if this is a "toggle" button (sort of like a checkbox)
  329.          *
  330.          * @return
  331.          */
  332.         public boolean isToggleable() {
  333.                 return toggleable;
  334.         }
  335.  
  336.         /**
  337.          * @param toggleable true if the button should toggle off and on when it is clicked, false if the button should behave like a normal button
  338.          */
  339.         public void setToggleable(boolean toggleable) {
  340.                 this.toggleable = toggleable;
  341.                 this.editable = false;
  342.                 validateIdleState();
  343.         }
  344.  
  345.         /**
  346.          * returns true if the user can edit the text when clicking on this gui elemnt.
  347.          *
  348.          * @return
  349.          */
  350.         public boolean isEditable() {
  351.                 return editable;
  352.         }
  353.  
  354.         /**
  355.          * turn on and off giving the ability for the user to change the text
  356.          *
  357.          * @param editable
  358.          */
  359.         public void setEditable(boolean editable) {
  360.                 this.editable = editable;
  361.                 this.toggleable = false;
  362.  
  363.                 if (editable && inputCursorBitmapText == null) {
  364.                         inputCursorBitmapText = new BitmapText(bitmapText.getFont(), false);
  365.                         inputCursorBitmapText.setSize(bitmapText.getFont().getCharSet().getRenderedSize());
  366.                         inputCursorBitmapText.setColor(bitmapText.getColor());
  367.                         Rectangle rectangle = new Rectangle(0, 0, quad.getWidth() - textInset, quad.getHeight() - textInset);
  368.                         inputCursorBitmapText.setBox(rectangle);
  369.                         inputCursorBitmapText.setVerticalAlignment(bitmapText.getVerticalAlignment());
  370.                         inputCursorBitmapText.setAlignment(bitmapText.getAlignment());
  371.                         attachChild(inputCursorBitmapText);
  372.                 }
  373.                 setEditFocus(false);
  374.  
  375.         }
  376.  
  377.         @Override
  378.         public void updateLogicalState(float tpf) {
  379.                 super.updateLogicalState(tpf);
  380.  
  381.                 // This should all really be in a control. but i need the setTransformRefresh() hack anyway.
  382.  
  383.                 if (!rawInputListenersAdded) {
  384.                         setInputListenerAdded(true);
  385.                 }
  386.  
  387.                 if (hasEditFocus()) {
  388.                         updateCursorLocation();
  389.                         inputCursorBlinkDuration -= tpf;
  390.                         if (inputCursorBlinkDuration < 0) {
  391.                                 if (inputCursorBitmapText.getText().isEmpty()) {
  392.                                         inputCursorBitmapText.setText("|");
  393.                                         this.inputCursorBlinkDuration = 0.5f;
  394.                                 } else {
  395.                                         inputCursorBitmapText.setText("");
  396.                                         this.inputCursorBlinkDuration = 0.4f;
  397.                                 }
  398.                         }
  399.                 }
  400.  
  401.         }
  402.  
  403.         private void updateCursorLocation() {
  404.  
  405.                 float x = bitmapText.getFont().getLineWidth(bitmapText.getText());
  406.                 float xAddend = bitmapText.getFont().getLineWidth("|");
  407.                 //float y = bitmapText.getLineHeight() * (bitmapText.getLineCount() - 1);
  408.                 //TODO: doesnt properly support multi-line text field
  409.  
  410.                 switch (bitmapText.getAlignment()) {
  411.                         case Left:
  412.                                 inputCursorBitmapText.setLocalTranslation((x) + (xAddend / 2f), quad.getHeight() - (textInset / 2f), 0);
  413.                                 break;
  414.                         case Center:
  415.                                 inputCursorBitmapText.setLocalTranslation((x / 2f) + (xAddend / 2f), quad.getHeight() - (textInset / 2f), 0);
  416.                                 break;
  417.                         case Right:
  418.                                 inputCursorBitmapText.setLocalTranslation((0) + (xAddend / 2f), quad.getHeight() - (textInset / 2f), 0);
  419.                                 break;
  420.                         default:
  421.                                 throw new AssertionError(bitmapText.getAlignment().name());
  422.  
  423.                 }
  424.  
  425.  
  426.         }
  427.  
  428.         /**
  429.          * does nothing if isEditable() == false
  430.          *
  431.          * sets the state of the element such that the user can start typing as if he or she clicked on it.
  432.          *
  433.          * @param editFocus
  434.          */
  435.         public void setEditFocus(boolean editFocus) {
  436.                 this.editFocus = editFocus;
  437.                 if (inputCursorBitmapText != null) {
  438.                         if (editFocus) {
  439.                                 updateCursorLocation();
  440.                                 inputCursorBitmapText.setText("|");
  441.                                 this.inputCursorBlinkDuration = 0.5f;
  442.                         }
  443.                         inputCursorBitmapText.setCullHint(hasEditFocus() ? CullHint.Never : CullHint.Always);
  444.                 }
  445.                 validateIdleState();
  446.  
  447.         }
  448.  
  449.         /**
  450.          * always returns false if isEditable() == false
  451.          *
  452.          * determines if the user is currently entering text in to the gui elemnt.
  453.          *
  454.          * @return
  455.          */
  456.         public boolean hasEditFocus() {
  457.                 return editable && editFocus;
  458.         }
  459.  
  460.         private void validateIdleState() {
  461.                 if (!hovered && !pressed) {
  462.                         geom.setMaterial(getIdleMaterial());
  463.                 }
  464.         }
  465.  
  466.         /**
  467.          * centers the button within the provided viewport
  468.          *
  469.          * TODO: this assumes guiNode is origined at the bottom left corner of the screen. this code should center the button in accordance to its world translation
  470.          *
  471.          * @return
  472.          */
  473.         @Override
  474.         public GuiElement center() {
  475.                 setLocalTranslation((guiViewport.getCamera().getWidth() / 2f) - (quad.getWidth() / 2f), (guiViewport.getCamera().getHeight() / 2f) - (quad.getHeight() / 2f), 0);
  476.                 return this;
  477.         }
  478.  
  479.         /**
  480.          * centers the button within the provided viewport
  481.          *
  482.          * TODO: this assumes guiNode is origined at the bottom left corner of the screen. this code should center the button in accordance to its world translation
  483.          *
  484.          * @param offsetX after centering the button it will be moved by this amount
  485.          * @param offsetY after centering the button it will be moved by this amount
  486.          * @return
  487.          */
  488.         public GuiElement center(float offsetX, float offsetY) {
  489.                 setLocalTranslation((guiViewport.getCamera().getWidth() / 2f) - (quad.getWidth() / 2f) + offsetX, (guiViewport.getCamera().getHeight() / 2f) - (quad.getHeight() / 2f) + offsetY, 0);
  490.                 return this;
  491.         }
  492.  
  493.         public Spatial move(float x, float y) {
  494.                 return super.move(x, y, 0);
  495.         }
  496.  
  497.         public Spatial move(Vector2f offset) {
  498.                 return super.move(offset.x, offset.y, 0);
  499.         }
  500.  
  501.         /**
  502.          * determines if this spatial is attached to a scene in the provided viewport. (eg "in the scene graph")
  503.          *
  504.          * this is used for automatically removing the raw input listener.
  505.          *
  506.          * @return
  507.          */
  508.         private boolean isInViewport() {
  509.                 List<Spatial> scenes = this.guiViewport.getScenes();
  510.                 for (Spatial rootScene : scenes) {
  511.                         //UtLog.info.log(getName() + " has ancestor? " + rootScene.getName());
  512.                         Node current = this;
  513.  
  514.                         while (current.getParent() != null) {
  515.                                 current = current.getParent();
  516.                                 if (current == rootScene) {
  517.                                         //UtLog.info.log("yes");
  518.                                         return true;
  519.                                 }
  520.                         }
  521.                 }
  522.  
  523.                 //UtLog.info.log("no");
  524.                 return false;
  525.  
  526.  
  527.         }
  528.  
  529.         private void setInputListenerAdded(boolean added) {
  530.                 if (added == rawInputListenersAdded) {
  531.                         return;
  532.                 }
  533.                 if (added) {
  534.                         //if (!isInViewport()) {
  535.                         //        UtLog.warning.log("not in viewport");
  536.                         //}
  537.                         rawInputListenersAdded = true;
  538.                         if (inputManager != null) {
  539.                                 if (rawInputListener == null) {
  540.                                         rawInputListener = new GeRawInputListener();
  541.                                 }
  542.  
  543.                                 inputManager.addRawInputListener(rawInputListener);
  544.                         }
  545.                 } else {
  546.                         rawInputListenersAdded = false;
  547.                         inputManager.removeRawInputListener(rawInputListener);
  548.                 }
  549.         }
  550.  
  551.         @Override
  552.         protected void setTransformRefresh() {
  553.                 super.setTransformRefresh();
  554.                 // This hack removes removes the raw input listener if its been added., it is automatically added inside of updateLogicalState. (this is the workaround i found to automatically discover adding and removing spatials from the scene graph)
  555.  
  556.  
  557.                 if (rawInputListenersAdded == true && !isInViewport()) {
  558.                         setInputListenerAdded(false);
  559.                 }
  560.  
  561.         }
  562.  
  563.         /**
  564.          * determines if mouse is on top of the quad that represents the button
  565.          *
  566.          * @return
  567.          */
  568.         public boolean isMouseOverlappingButton() {
  569.                 Vector2f mouse = inputManager.getCursorPosition();
  570.                 return isMouseOverlappingButton(mouse.x, mouse.y);
  571.         }
  572.  
  573.         private boolean isMouseOverlappingButton(float mouseX, float mouseY) {
  574.  
  575.                 if (!enabled) {
  576.                         return false;
  577.                 }
  578.  
  579.                 Vector3f limit = new Vector3f();
  580.                 BoundingBox buttonBoundingBox = (BoundingBox) geom.getWorldBound();
  581.  
  582.                 buttonBoundingBox.getMin(limit);
  583.  
  584.                 if (mouseX < limit.x || mouseY < limit.y) {
  585.                         return false;
  586.                 }
  587.  
  588.                 buttonBoundingBox.getMax(limit);
  589.  
  590.                 if (mouseX > limit.x || mouseY > limit.y) {
  591.                         return false;
  592.                 }
  593.  
  594.                 return true;
  595.  
  596.  
  597.         }
  598.  
  599.         /**
  600.          * returns either mat or clickedMat depending on if the button is toggled or not.
  601.          *
  602.          * @return
  603.          */
  604.         private Material getIdleMaterial() {
  605.                 if ((toggleable && toggled) || (editable && editFocus)) {
  606.                         return clickedMat;
  607.                 }
  608.                 return mat;
  609.  
  610.         }
  611.  
  612.         private class GeRawInputListener implements RawInputListener {
  613.  
  614.                 public void beginInput() {
  615.                 }
  616.  
  617.                 public void endInput() {
  618.                 }
  619.  
  620.                 public void onJoyAxisEvent(JoyAxisEvent evt) {
  621.                 }
  622.  
  623.                 public void onJoyButtonEvent(JoyButtonEvent evt) {
  624.                 }
  625.  
  626.                 public void onMouseMotionEvent(MouseMotionEvent evt) {
  627.                         if (evt.isConsumed() || pressed || !enabled) {
  628.                                 return;
  629.                         }
  630.  
  631.                         if (isMouseOverlappingButton(evt.getX(), evt.getY())) {
  632.                                 geom.setMaterial(hoverMat);
  633.                                 if (!hovered) {
  634.                                         hovered = true;
  635.                                         if (guiElementListener != null) {
  636.                                                 guiElementListener.onHover(GuiElement.this);
  637.                                         }
  638.                                 }
  639.                         } else {
  640.                                 geom.setMaterial(getIdleMaterial());
  641.                                 if (hovered) {
  642.                                         hovered = false;
  643.                                         if (guiElementListener != null) {
  644.                                                 guiElementListener.onHoverExit(GuiElement.this);
  645.                                         }
  646.  
  647.                                 }
  648.  
  649.                         }
  650.                 }
  651.  
  652.                 public void onMouseButtonEvent(MouseButtonEvent evt) {
  653.                         if (evt.isConsumed() || !enabled) {
  654.                                 return;
  655.                         }
  656.                         if (!pressed && evt.getButtonIndex() == MouseInput.BUTTON_LEFT && evt.isPressed()) {
  657.                                 if (isMouseOverlappingButton(evt.getX(), evt.getY())) {
  658.                                         pressed = true;
  659.                                         geom.setMaterial(clickedMat);
  660.                                         evt.setConsumed();
  661.                                         if (guiElementListener != null) {
  662.                                                 guiElementListener.onPressed(GuiElement.this);
  663.                                         }
  664.                                         if (isEditable()) {
  665.                                                 setEditFocus(true);
  666.                                         }
  667.                                 } else {
  668.                                         if (hasEditFocus()) {
  669.                                                 evt.setConsumed();
  670.                                                 setEditFocus(false); // material is changed through validateIdleState in this method.
  671.                                                 if (guiElementListener != null) {
  672.                                                         guiElementListener.onTextInput(GuiElement.this);
  673.                                                 }
  674.                                         }
  675.                                 }
  676.                         } else if (pressed && evt.getButtonIndex() == MouseInput.BUTTON_LEFT && evt.isReleased()) {
  677.                                 toggled = !toggled;
  678.                                 pressed = false;
  679.                                 if (isMouseOverlappingButton(evt.getX(), evt.getY())) {
  680.                                         geom.setMaterial(hoverMat);
  681.                                         hovered = true;
  682.                                         if (guiElementListener != null) {
  683.                                                 guiElementListener.onReleased(GuiElement.this);
  684.                                         }
  685.  
  686.                                 } else {
  687.                                         geom.setMaterial(getIdleMaterial());
  688.                                         hovered = false;
  689.                                         if (guiElementListener != null) {
  690.                                                 guiElementListener.onReleased(GuiElement.this);
  691.                                                 guiElementListener.onHoverExit(GuiElement.this);
  692.                                         }
  693.                                 }
  694.                         }
  695.  
  696.  
  697.                 }
  698.  
  699.                 public void onKeyEvent(KeyInputEvent evt) {
  700.                         if (!hasEditFocus() || evt.isConsumed()) {
  701.                                 return;
  702.                         }
  703.  
  704.                         evt.setConsumed();
  705.  
  706.                         if (evt.isReleased()) {
  707.                                 return;
  708.                         }
  709.  
  710.                         switch (evt.getKeyCode()) {
  711.                                 case KeyInput.KEY_ESCAPE:
  712.                                         setEditFocus(false);
  713.                                         if (guiElementListener != null) {
  714.                                                 guiElementListener.onTextInput(GuiElement.this);
  715.                                         }
  716.                                         break;
  717.                                 case KeyInput.KEY_BACK:
  718.                                         appendTextBackspace();
  719.                                         break;
  720.                                 case KeyInput.KEY_RETURN:
  721.                                         setEditFocus(false);
  722.                                         if (guiElementListener != null) {
  723.                                                 guiElementListener.onTextInput(GuiElement.this);
  724.                                         }
  725.                                         break;
  726.                                 default:
  727.                                         char keyChar = evt.getKeyChar();
  728.                                         if (keyChar != 0) {
  729.                                                 appendText(String.valueOf(keyChar));
  730.                                         }
  731.                                         break;
  732.                         }
  733.  
  734.  
  735.  
  736.                 }
  737.  
  738.                 public void onTouchEvent(TouchEvent evt) {
  739.                 }
  740.  
  741.         }
  742.  
  743.         /**
  744.          * A convenient class that can save valuable code space
  745.          */
  746.         public static class GuiElementAdapter implements GuiElementListener {
  747.  
  748.                 @Override
  749.                 public void onHover(GuiElement guiElement) {
  750.                 }
  751.  
  752.                 @Override
  753.                 public void onHoverExit(GuiElement guiElement) {
  754.                 }
  755.  
  756.                 @Override
  757.                 public void onReleased(GuiElement guiElement) {
  758.                 }
  759.  
  760.                 @Override
  761.                 public void onPressed(GuiElement guiElement) {
  762.                 }
  763.  
  764.                 @Override
  765.                 public void onTextInput(GuiElement guiElement) {
  766.                 }
  767.  
  768.         }
  769.  
  770.         public interface GuiElementListener {
  771.  
  772.                 /**
  773.                  * mouse enters button click space
  774.                  *
  775.                  * @param guiElement
  776.                  */
  777.                 public void onHover(GuiElement guiElement);
  778.  
  779.                 /**
  780.                  * mouse leaves the button click space
  781.                  *
  782.                  * @param guiElement
  783.                  */
  784.                 public void onHoverExit(GuiElement guiElement);
  785.  
  786.                 /**
  787.                  * mouse button is released after being pressed
  788.                  *
  789.                  * NOTE: If you wish to check for the toggle state of the button it should be done in onReleased rather than onPressed()
  790.                  *
  791.                  * @param guiElement
  792.                  */
  793.                 public void onReleased(GuiElement guiElement);
  794.  
  795.                 /**
  796.                  * mouse button is pressed (as opposed to being released)
  797.                  *
  798.                  * NOTE: If you wish to check for the toggle state of the button it should be done in onReleased rather than onPressed()
  799.                  *
  800.                  * @param guiElement
  801.                  */
  802.                 public void onPressed(GuiElement guiElement);
  803.  
  804.                 /**
  805.                  * called when the element is editable and the text is changed by the user.
  806.                  *
  807.                  * not called until the user dismisses the focus (eg presses enter, escape, or clicks outside the element)
  808.                  *
  809.                  * @param guiElement
  810.                  */
  811.                 public void onTextInput(GuiElement guiElement);
  812.  
  813.         }
  814.  
  815.         private static Material makeMat(AssetManager assetManager, ColorRGBA color) {
  816.                 Material mat = new Material(assetManager, "Common/MatDefs/Misc/Unshaded.j3md");
  817.                 mat.setColor("Color", color);
  818.                 mat.getAdditionalRenderState().setBlendMode(RenderState.BlendMode.Alpha);
  819.                 return mat;
  820.         }
  821.  
  822.         private static Material darkGrayMat(AssetManager assetManager) {
  823.                 return makeMat(assetManager, new ColorRGBA(0, 0, 0, 0.2f));
  824.         }
  825.  
  826.         private static Material lightGrayMat(AssetManager assetManager) {
  827.                 return makeMat(assetManager, new ColorRGBA(0.2f, 0.2f, 0.2f, 0.7f));
  828.         }
  829.  
  830.         private static Material blueMat(AssetManager assetManager) {
  831.                 return makeMat(assetManager, new ColorRGBA(0.1f, 0.1f, 0.7f, 0.9f));
  832.         }
  833.  
  834.         public static GuiElement makeLabel(Application app, String text, float width, float height) {
  835.                 return makeLabel(app.getGuiViewPort(), app.getInputManager(), app.getAssetManager(), text, width, height);
  836.         }
  837.  
  838.         public static GuiElement makeLabel(ViewPort guiViewport, InputManager inputManager, AssetManager assetManager, String text, float width, float height) {
  839.  
  840.                 BitmapFont font = assetManager.loadFont("Interface/Fonts/Default.fnt");
  841.                 ColorRGBA textColor = ColorRGBA.Gray.mult(2);
  842.  
  843.                 GuiElement element = new GuiElement(guiViewport, inputManager, text, width, height, darkGrayMat(assetManager), lightGrayMat(assetManager), blueMat(assetManager), font, textColor);
  844.                 element.setEnabled(false);
  845.  
  846.                 return element;
  847.         }
  848.  
  849.         public static GuiElement makeButton(Application app, String text, float width, float height) {
  850.                 return makeButton(app.getGuiViewPort(), app.getInputManager(), app.getAssetManager(), text, width, height);
  851.         }
  852.  
  853.         public static GuiElement makeButton(ViewPort guiViewport, InputManager inputManager, AssetManager assetManager, String text, float width, float height) {
  854.  
  855.                 BitmapFont font = assetManager.loadFont("Interface/Fonts/Default.fnt");
  856.                 ColorRGBA textColor = ColorRGBA.Gray.mult(2);
  857.  
  858.                 return new GuiElement(guiViewport, inputManager, text, width, height, darkGrayMat(assetManager), lightGrayMat(assetManager), blueMat(assetManager), font, textColor);
  859.         }
  860.  
  861.         public static GuiElement makeToggleButton(Application app, String text, float width, float height) {
  862.                 return makeToggleButton(app.getGuiViewPort(), app.getInputManager(), app.getAssetManager(), text, width, height);
  863.         }
  864.  
  865.         public static GuiElement makeToggleButton(ViewPort guiViewport, InputManager inputManager, AssetManager assetManager, String text, float width, float height) {
  866.  
  867.                 BitmapFont font = assetManager.loadFont("Interface/Fonts/Default.fnt");
  868.                 ColorRGBA textColor = ColorRGBA.Gray.mult(2);
  869.  
  870.                 GuiElement element = new GuiElement(guiViewport, inputManager, text, width, height, darkGrayMat(assetManager), lightGrayMat(assetManager), blueMat(assetManager), font, textColor);
  871.                 element.setToggleable(true);
  872.                 return element;
  873.         }
  874.  
  875.         public static GuiElement makeTextField(Application app, String text, float width, float height) {
  876.                 return makeTextField(app.getGuiViewPort(), app.getInputManager(), app.getAssetManager(), text, width, height);
  877.         }
  878.  
  879.         public static GuiElement makeTextField(ViewPort guiViewport, InputManager inputManager, AssetManager assetManager, String text, float width, float height) {
  880.                 BitmapFont font = assetManager.loadFont("Interface/Fonts/Default.fnt");
  881.                 ColorRGBA textColor = ColorRGBA.Gray.mult(2);
  882.  
  883.                 GuiElement element = new GuiElement(guiViewport, inputManager, text, width, height, darkGrayMat(assetManager), lightGrayMat(assetManager), blueMat(assetManager), font, textColor);
  884.                 element.setEditable(true);
  885.                 return element;
  886.         }
  887.  
  888. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement