1 /*
2  * Copyright (c) 2009-2010 jMonkeyEngine
3  * All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions are
7  * met:
8  *
9  * * Redistributions of source code must retain the above copyright
10  *   notice, this list of conditions and the following disclaimer.
11  *
12  * * Redistributions in binary form must reproduce the above copyright
13  *   notice, this list of conditions and the following disclaimer in the
14  *   documentation and/or other materials provided with the distribution.
15  *
16  * * Neither the name of 'jMonkeyEngine' nor the names of its contributors
17  *   may be used to endorse or promote products derived from this software
18  *   without specific prior written permission.
19  *
20  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
21  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
22  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
23  * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
24  * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
25  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
26  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
27  * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
28  * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
29  * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
30  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31  */
32 package com.jme3.niftygui;
33 
34 import com.jme3.input.InputManager;
35 import com.jme3.input.KeyInput;
36 import com.jme3.input.RawInputListener;
37 import com.jme3.input.SoftTextDialogInput;
38 import com.jme3.input.controls.SoftTextDialogInputListener;
39 import com.jme3.input.event.*;
40 import com.jme3.system.JmeSystem;
41 import de.lessvoid.nifty.Nifty;
42 import de.lessvoid.nifty.NiftyInputConsumer;
43 import de.lessvoid.nifty.controls.TextField;
44 import de.lessvoid.nifty.controls.nullobjects.TextFieldNull;
45 import de.lessvoid.nifty.elements.Element;
46 import de.lessvoid.nifty.tools.resourceloader.NiftyResourceLoader;
47 import de.lessvoid.nifty.input.keyboard.KeyboardInputEvent;
48 import de.lessvoid.nifty.spi.input.InputSystem;
49 import java.util.ArrayList;
50 import java.util.logging.Level;
51 import java.util.logging.Logger;
52 
53 public class InputSystemJme implements InputSystem, RawInputListener {
54 
55     private final ArrayList<InputEvent> inputQueue = new ArrayList<InputEvent>();
56     private InputManager inputManager;
57     private boolean isDragging = false, niftyOwnsDragging = false;
58     private boolean pressed = false;
59     private int buttonIndex;
60     private int x, y;
61     private int height;
62     private boolean shiftDown = false;
63     private boolean ctrlDown = false;
64     private Nifty nifty;
65 
InputSystemJme(InputManager inputManager)66     public InputSystemJme(InputManager inputManager) {
67         this.inputManager = inputManager;
68     }
69 
setResourceLoader(NiftyResourceLoader niftyResourceLoader)70     public void setResourceLoader(NiftyResourceLoader niftyResourceLoader) {
71     }
72 
setNifty(Nifty nifty)73     public void setNifty(Nifty nifty) {
74         this.nifty = nifty;
75     }
76 
77     /**
78      * @param height The height of the viewport. Used to convert
79      * buttom-left origin to upper-left origin.
80      */
setHeight(int height)81     public void setHeight(int height) {
82         this.height = height;
83     }
84 
setMousePosition(int x, int y)85     public void setMousePosition(int x, int y) {
86     }
87 
beginInput()88     public void beginInput() {
89     }
90 
endInput()91     public void endInput() {
92         boolean result = nifty.update();
93     }
94 
onTouchEventQueued(TouchEvent evt, NiftyInputConsumer nic)95     private void onTouchEventQueued(TouchEvent evt, NiftyInputConsumer nic) {
96         boolean consumed = false;
97 
98         x = (int) evt.getX();
99         y = (int) (height - evt.getY());
100 
101         if (!inputManager.getSimulateMouse()) {
102             switch (evt.getType()) {
103                 case DOWN:
104                     consumed = nic.processMouseEvent(x, y, 0, 0, true);
105                     isDragging = true;
106                     niftyOwnsDragging = consumed;
107                     if (consumed) {
108                         evt.setConsumed();
109                     }
110 
111                     break;
112 
113                 case UP:
114                     if (niftyOwnsDragging) {
115                         consumed = nic.processMouseEvent(x, y, 0, 0, false);
116                         if (consumed) {
117                             evt.setConsumed();
118                         }
119                     }
120 
121                     isDragging = false;
122                     niftyOwnsDragging = false;
123 
124                     if (consumed) {
125                         processSoftKeyboard();
126                     }
127 
128                     break;
129             }
130         }
131     }
132 
onMouseMotionEventQueued(MouseMotionEvent evt, NiftyInputConsumer nic)133     private void onMouseMotionEventQueued(MouseMotionEvent evt, NiftyInputConsumer nic) {
134         x = evt.getX();
135         y = height - evt.getY();
136         nic.processMouseEvent(x, y, evt.getDeltaWheel(), buttonIndex, pressed);
137 //        if (nic.processMouseEvent(niftyEvt) /*|| nifty.getCurrentScreen().isMouseOverElement()*/){
138         // Do not consume motion events
139         //evt.setConsumed();
140 //        }
141     }
142 
onMouseButtonEventQueued(MouseButtonEvent evt, NiftyInputConsumer nic)143     private void onMouseButtonEventQueued(MouseButtonEvent evt, NiftyInputConsumer nic) {
144         boolean wasPressed = pressed;
145         boolean forwardToNifty = true;
146 
147         buttonIndex = evt.getButtonIndex();
148         pressed = evt.isPressed();
149 
150         // Mouse button raised. End dragging
151         if (wasPressed && !pressed) {
152             if (!niftyOwnsDragging) {
153                 forwardToNifty = false;
154             }
155             isDragging = false;
156             niftyOwnsDragging = false;
157         }
158 
159         boolean consumed = false;
160         if (forwardToNifty) {
161             consumed = nic.processMouseEvent(x, y, 0, buttonIndex, pressed);
162             if (consumed) {
163                 evt.setConsumed();
164             }
165         }
166 
167         // Mouse button pressed. Begin dragging
168         if (!wasPressed && pressed) {
169             isDragging = true;
170             niftyOwnsDragging = consumed;
171         }
172 
173         if (consumed && pressed) {
174             processSoftKeyboard();
175         }
176 
177     }
178 
onKeyEventQueued(KeyInputEvent evt, NiftyInputConsumer nic)179     private void onKeyEventQueued(KeyInputEvent evt, NiftyInputConsumer nic) {
180         int code = evt.getKeyCode();
181 
182         if (code == KeyInput.KEY_LSHIFT || code == KeyInput.KEY_RSHIFT) {
183             shiftDown = evt.isPressed();
184         } else if (code == KeyInput.KEY_LCONTROL || code == KeyInput.KEY_RCONTROL) {
185             ctrlDown = evt.isPressed();
186         }
187 
188         KeyboardInputEvent keyEvt = new KeyboardInputEvent(code,
189                 evt.getKeyChar(),
190                 evt.isPressed(),
191                 shiftDown,
192                 ctrlDown);
193 
194         if (nic.processKeyboardEvent(keyEvt)) {
195             evt.setConsumed();
196         }
197     }
198 
onMouseMotionEvent(MouseMotionEvent evt)199     public void onMouseMotionEvent(MouseMotionEvent evt) {
200         // Only forward the event if there's actual motion involved.
201         if (inputManager.isCursorVisible() && (evt.getDX() != 0
202                 || evt.getDY() != 0
203                 || evt.getDeltaWheel() != 0)) {
204             inputQueue.add(evt);
205         }
206     }
207 
onMouseButtonEvent(MouseButtonEvent evt)208     public void onMouseButtonEvent(MouseButtonEvent evt) {
209         if (inputManager.isCursorVisible() && evt.getButtonIndex() >= 0 && evt.getButtonIndex() <= 2) {
210             inputQueue.add(evt);
211         }
212     }
213 
onJoyAxisEvent(JoyAxisEvent evt)214     public void onJoyAxisEvent(JoyAxisEvent evt) {
215     }
216 
onJoyButtonEvent(JoyButtonEvent evt)217     public void onJoyButtonEvent(JoyButtonEvent evt) {
218     }
219 
onKeyEvent(KeyInputEvent evt)220     public void onKeyEvent(KeyInputEvent evt) {
221         inputQueue.add(evt);
222     }
223 
onTouchEvent(TouchEvent evt)224     public void onTouchEvent(TouchEvent evt) {
225         inputQueue.add(evt);
226     }
227 
forwardEvents(NiftyInputConsumer nic)228     public void forwardEvents(NiftyInputConsumer nic) {
229         int queueSize = inputQueue.size();
230 
231         for (int i = 0; i < queueSize; i++) {
232             InputEvent evt = inputQueue.get(i);
233             if (evt instanceof MouseMotionEvent) {
234                 onMouseMotionEventQueued((MouseMotionEvent) evt, nic);
235             } else if (evt instanceof MouseButtonEvent) {
236                 onMouseButtonEventQueued((MouseButtonEvent) evt, nic);
237             } else if (evt instanceof KeyInputEvent) {
238                 onKeyEventQueued((KeyInputEvent) evt, nic);
239             } else if (evt instanceof TouchEvent) {
240                 onTouchEventQueued((TouchEvent) evt, nic);
241             }
242         }
243 
244         inputQueue.clear();
245     }
246 
processSoftKeyboard()247     private void processSoftKeyboard() {
248         SoftTextDialogInput softTextDialogInput = JmeSystem.getSoftTextDialogInput();
249         if (softTextDialogInput != null) {
250 
251             Element element = nifty.getCurrentScreen().getFocusHandler().getKeyboardFocusElement();
252             if (element != null) {
253                 final TextField textField = element.getNiftyControl(TextField.class);
254                 if (textField != null && !(textField instanceof TextFieldNull)) {
255                     Logger.getLogger(InputSystemJme.class.getName()).log(Level.INFO, "Current TextField: {0}", textField.getId());
256                     String initialValue = textField.getText();
257                     if (initialValue == null) {
258                         initialValue = "";
259                     }
260 
261                     softTextDialogInput.requestDialog(SoftTextDialogInput.TEXT_ENTRY_DIALOG, "Enter Text", initialValue, new SoftTextDialogInputListener() {
262 
263                         public void onSoftText(int action, String text) {
264                             if (action == SoftTextDialogInputListener.COMPLETE) {
265                                 textField.setText(text);
266                             }
267                         }
268                     });
269                 }
270             }
271         }
272 
273     }
274 }
275