source: trunk/src/org/expeditee/gio/InputManager.java@ 1415

Last change on this file since 1415 was 1415, checked in by bln4, 5 years ago

Renamed Frame.getItems() to Frame.getSortedItems() to better represent its functionality.

-> org.apollo.ApolloGestureActions
-> org.apollo.ApolloSystem
-> org.expeditee.actions.Actions
-> org.expeditee.actions.Debug
-> org.expeditee.actions.ExploratorySearchActions
-> org.expeditee.actions.JfxBrowserActions
-> org.expeditee.actions.Misc
-> org.expeditee.actions.Navigation
-> org.expeditee.actions.ScriptBase
-> org.expeditee.actions.Simple
-> org.expeditee.agents.ComputeTree
-> org.expeditee.agents.CopyTree
-> org.expeditee.agents.DisplayComet
-> org.expeditee.agents.DisplayTree
-> org.expeditee.agents.DisplayTreeLeaves
-> org.expeditee.agents.GraphFramesetLinks
-> org.expeditee.agents.TreeProcessor
-> org.expeditee.gio.gesture.StandardGestureActions
-> org.expeditee.gui.DisplayController
-> org.expeditee.gui.FrameCreator
-> org.expeditee.gui.FrameIO
-> org.expeditee.io.DefaultTreeWriter
-> org.expeditee.io.JavaWriter
-> org.expeditee.io.PDF2Writer
-> org.expeditee.io.TXTWriter
-> org.expeditee.io.WebParser
-> org.expeditee.io.flowlayout.XGroupItem
-> org.expeditee.items.Dot
-> org.expeditee.items.Item
-> org.expeditee.items.ItemUtils
-> org.expeditee.network.FrameShare
-> org.expeditee.stats.TreeStats


Created ItemsList class to wrap ArrayList<Item>. Frames now use this new class to store its body list (used for display) as well as its primaryBody and surrogateBody.

-> org.expeditee.agents.Format
-> org.expeditee.agents.HFormat
-> org.expeditee.gio.gesture.StandardGestureActions
-> org.expeditee.gui.Frame
-> org.expeditee.gui.FrameUtils


Refactorted Frame.setResort(bool) to Frame.invalidateSorted() to better function how it is intended to with a more accurate name.

-> org.expeditee.agents.Sort


When writing out .exp files and getting attributes to respond to LEFT + RIGHT click, boolean items are by default true. This has always been the case. An ammendment to this is that defaults can now be established.
Also added 'EnterClick' functionality. If cursored over a item with this property and you press enter, it acts as if you have clicked on it instead.

-> org.expeditee.assets.resources-public.framesets.authentication.1.exp to 6.exp
-> org.expeditee.gio.gesture.StandardGestureActions
-> org.expeditee.gio.input.KBMInputEvent
-> org.expeditee.gio.javafx.JavaFXConversions
-> org.expeditee.gio.swing.SwingConversions
-> org.expeditee.gui.AttributeUtils
-> org.expeditee.io.Conversion
-> org.expeditee.io.DefaultFrameWriter
-> org.expeditee.items.Item


Fixed a bug caused by calling Math.abs on Integer.MIN_VALUE returning unexpected result. Due to zero being a thing, you cannot represent Math.abs(Integer.MIN_VALUE) in a Integer object. The solution is to use Integer.MIN_VALUE + 1 instead of Integer.MIN_VALUE.

-> org.expeditee.core.bounds.CombinationBounds
-> org.expeditee.io.flowlayout.DimensionExtent


Recoded the contains function in EllipticalBounds so that intersection tests containing circles work correctly.

-> org.expeditee.core.bounds.EllipticalBounds


Added toString() to PolygonBounds to allow for useful printing during debugging.

-> org.expeditee.core.bounds.PolygonBounds

Implemented Surrogate Mode!

-> org.expeditee.encryption.io.EncryptedExpReader
-> org.expeditee.encryption.io.EncryptedExpWriter
-> org.expeditee.encryption.items.surrogates.EncryptionDetail
-> org.expeditee.encryption.items.surrogates.Label
-> org.expeditee.gui.FrameUtils
-> org.expeditee.gui.ItemsList
-> org.expeditee.items.Item
-> org.expeditee.items.Text


???? Use Integer.MAX_VALUE cast to a float instead of Float.MAX_VALUE. This fixed some bug which I cannot remember.

-> org.expeditee.gio.TextLayoutManager
-> org.expeditee.gio.swing.SwingTextLayoutManager


Improved solution for dealing with the F10 key taking focus away from Expeditee due to it being a assessibility key.

-> org.expeditee.gio.swing.SwingInputManager


Renamed variable visibleItems in FrameGraphics.paintFrame to itemsToPaintCanditates to better represent functional intent.

-> org.expeditee.gui.FrameGraphics


Improved checking for if personal resources exist before recreating them

-> org.expeditee.gui.FrameIO


Repeated messages to message bay now have a visual feedback instead of just a beep. This visual feedback is in the form of a count of the amount of times it has repeated.

-> org.expeditee.gui.MessageBay


Updated comment on the Vector class to explain what vectors are.

-> org.expeditee.gui.Vector


Added constants to represent all of the property keys in DefaultFrameReader and DefaultFrameWriter.

-> org.expeditee.io.DefaultFrameReader
-> org.expeditee.io.DefaultFrameWriter


Updated the KeyList setting to be more heirarcial with how users will store their Secrets.

-> org.expeditee.settings.identity.secrets.KeyList

File size: 11.5 KB
Line 
1package org.expeditee.gio;
2
3import java.util.Collection;
4import java.util.HashMap;
5import java.util.LinkedList;
6import java.util.List;
7import java.util.ListIterator;
8import java.util.Set;
9
10import org.expeditee.core.Point;
11import org.expeditee.gio.TimeoutQueue.TimeoutHandle;
12import org.expeditee.gio.gesture.Gesture;
13import org.expeditee.gio.gesture.GestureListener;
14import org.expeditee.gio.input.InputEvent;
15import org.expeditee.gio.input.InputEvent.InputType;
16import org.expeditee.gio.input.InputEventListener;
17import org.expeditee.gio.input.InputEventToGestureTranslator;
18import org.expeditee.gio.input.TimeoutInputEvent;
19import org.expeditee.items.widgets.Widget;
20
21/**
22 * Receives input events from the system and distributes them within Expeditee.
23 * Abstract as platform-specific implementation must be provided to handle receiving
24 * input events from the system.
25 *
26 * Native Input
27 * |
28 * | /---------\
29 * `------->| Widgets |
30 * ,--------| |
31 * | \---------/
32 * v
33 * /-------------\
34 * | Input |
35 * | Translation |
36 * \-------------/
37 * |
38 * Expeditee Input
39 * |
40 * | /-----------\
41 * `------->| Input |
42 * ,--------| Listeners |
43 * | \-----------/
44 * |
45 * v
46 * /-------------\
47 * Context---->| Gesture |
48 * | Translation |
49 * \-------------/
50 * |
51 * Gestures
52 * | /-----------\
53 * `------->| Gesture |
54 * | Listeners |
55 * \-----------/
56 *
57 * @author cts16
58 */
59public abstract class InputManager {
60
61 protected InputManager()
62 {
63 // Initialise the list of window-event listeners
64 _windowEventListeners = new LinkedList<WindowEventListener>();
65
66 // Initialise the timeout queue
67 _timeoutQueue = new TimeoutQueue();
68
69 // Initialise the list of widgets
70 _widgets = new LinkedList<Widget>();
71
72 // Initialise the list of input event listeners
73 _inputEventListeners = new LinkedList<InputEventListener>();
74
75 // Initialise the map of input-event -> gesture translators
76 _translators = new HashMap<InputType, List<InputEventToGestureTranslator>>(InputType.values().length);
77 for (InputType type : InputType.values()) {
78 _translators.put(type, new LinkedList<InputEventToGestureTranslator>());
79 }
80
81 // Initialise the list of gesture listeners
82 _gestureListeners = new LinkedList<GestureListener>();
83
84 // Initialise the cursor position
85 _cursorPosition = getRealCursorPosition().clone();
86 }
87
88 /*
89 *
90 * Window-specific events.
91 *
92 */
93
94 /** The types of window events that can be listened for. */
95 public enum WindowEventType {
96 WINDOW_RESIZED,
97 WINDOW_CLOSED,
98 MOUSE_EXITED_WINDOW,
99 MOUSE_ENTERED_WINDOW
100 }
101
102 /** The interface window-event listeners must implement to receive events. */
103 public static interface WindowEventListener
104 {
105 public void onWindowEvent(WindowEventType type);
106 }
107
108 /** The list of window-event listeners. */
109 private List<WindowEventListener> _windowEventListeners;
110
111 /** Adds a new window-event listener. */
112 public void addWindowEventListener(WindowEventListener listener)
113 {
114 _windowEventListeners.add(listener);
115 }
116
117 /**
118 * Should be called by platform-specific input managers to
119 * notify listeners of a window event.
120 */
121 protected void distributeWindowEvent(WindowEventType type)
122 {
123 ListIterator<WindowEventListener> it = _windowEventListeners.listIterator(_windowEventListeners.size());
124
125 // Run event handlers in reverse order
126 while (it.hasPrevious()) {
127 it.previous().onWindowEvent(type);
128 }
129 }
130
131 /*
132 *
133 * Cursor-control methods.
134 *
135 */
136
137 /** The position of the mouse cursor. */
138 private Point _cursorPosition;
139
140 /** Gets the current position of the cursor inside the Expeditee window. */
141 public Point getCursorPosition()
142 {
143 return _cursorPosition.clone();
144 }
145
146 /** Gets the position of the cursor (for initialisation purposes). */
147 protected abstract Point getRealCursorPosition();
148
149 /** Should be called by the platform-specific input manager to keep the cursor position up-to-date. */
150 protected void updateCursorPosition(int x, int y)
151 {
152 _cursorPosition.set(x, y);
153 }
154
155 /** Moves the cursor to the given position in the window. */
156 public abstract void setCursorPosition(Point position);
157
158 /** Moves the cursor by the given amount. */
159 public final void moveCursor(int x, int y)
160 {
161 setCursorPosition(getCursorPosition().clone().add(x, y));
162 }
163
164 /*
165 *
166 * Timeout-event handling.
167 *
168 */
169
170 /** TODO: Comment. cts16 */
171 private TimeoutQueue _timeoutQueue;
172
173 /** TODO: Comment. cts16 */
174 public TimeoutHandle addTimeout(int milliseconds)
175 {
176 TimeoutHandle handle = _timeoutQueue.addTimeout(milliseconds);
177
178 Long nextTimeout = _timeoutQueue.getNextTimeout();
179
180 if (nextTimeout != null) {
181 updateTimer(nextTimeout);
182 }
183
184 return handle;
185 }
186
187 /** TODO: Comment. cts16 */
188 public void cancelTimeout(TimeoutHandle handle)
189 {
190 _timeoutQueue.cancelTimeout(handle);
191 }
192
193 /** TODO: Comment. cts16 */
194 protected abstract void updateTimer(long nextTimeout);
195
196 /** TODO: Comment. cts16 */
197 public final void triggerTimeoutEvents()
198 {
199 Set<TimeoutHandle> expiredHandles;
200 while (!(expiredHandles = _timeoutQueue.popExpiredTimeouts()).isEmpty()) {
201 triggerTimeoutEvents(expiredHandles);
202 }
203
204 Long nextTimeout = _timeoutQueue.getNextTimeout();
205
206 if (nextTimeout != null) {
207 updateTimer(nextTimeout);
208 }
209 }
210
211 /** TODO: Comment. cts16 */
212 protected final void triggerTimeoutEvents(Collection<TimeoutHandle> handles)
213 {
214 if (handles == null) {
215 return;
216 }
217
218 for (TimeoutHandle handle : handles) {
219 triggerTimeoutEvent(handle);
220 }
221 }
222
223 /** TODO: Comment. cts16 */
224 protected final void triggerTimeoutEvent(TimeoutHandle handle)
225 {
226 if (handle == null) {
227 return;
228 }
229
230 TimeoutInputEvent event = new TimeoutInputEvent(handle);
231
232 distributeInputEvent(event);
233 }
234
235 /*
236 *
237 * Native-input-layer distribution methods.
238 *
239 */
240
241 /** The widgets enrolled with the input manager. */
242 protected List<Widget> _widgets;
243
244 /** Registers a widget with the manager. */
245 public void addInteractiveWidget(Widget iw)
246 {
247 if (iw == null) {
248 return;
249 }
250
251 if (!_widgets.contains(iw)) {
252 _widgets.add(iw);
253 }
254 }
255
256 /** Unregisters a widget with the manager. */
257 public void removeInteractiveWidget(Widget iw)
258 {
259 if (iw == null) {
260 return;
261 }
262
263 if (_widgets.contains(iw)) {
264 _widgets.remove(iw);
265 }
266 }
267
268 /*
269 *
270 * Expeditee-input-layer distribution methods.
271 *
272 */
273
274 /** The registered input event listeners. */
275 private LinkedList<InputEventListener> _inputEventListeners;
276
277 /**
278 * Registers the given input event listener to intercept input events.
279 * Priority of interception is in order of registration.
280 */
281 public final void registerInputEventListener(InputEventListener listener)
282 {
283 if (listener == null) {
284 return;
285 }
286
287 _inputEventListeners.add(listener);
288 }
289
290 /** Unregisters an input event listener. */
291 public final void removeInputEventListener(InputEventListener listener)
292 {
293 if (listener == null) {
294 return;
295 }
296
297 _inputEventListeners.remove(listener);
298 }
299
300 /**
301 * Lets any registered input-event listeners view/consume input. If none
302 * consume the input, it gets passed to the gesture-translation system. This method
303 * should be called by the implementation-native input system to get input into
304 * Expeditee.
305 */
306 protected final void distributeInputEvent(InputEvent event)
307 {
308// if (event instanceof KBMInputEvent) {
309// KBMInputEvent kEvent = (KBMInputEvent) event;
310// if (kEvent.getKeyDown() != null) {
311// System.err.println("distributeInputEvent:::" + kEvent.toString());
312// }
313// }
314
315 // Allow listeners to optionally consume input before gesture translation
316 for (InputEventListener listener : _inputEventListeners) {
317 if (listener.onInputEvent(event)) {
318 return;
319 }
320 }
321
322 // Get the relevant translators
323 List<InputEventToGestureTranslator> translators = getInputEventToGestureTranslators(event.getInputType());
324
325 // Translate the input event in reverse order, only taking the gestures from the first
326 // translator to respond
327 List<Gesture> gestures = null;
328 ListIterator<InputEventToGestureTranslator> it = translators.listIterator(translators.size());
329 while (it.hasPrevious()) {
330 InputEventToGestureTranslator translator = it.previous();
331 List<Gesture> translatorGestures = translator.onInputEvent(event);
332 if (gestures == null && translatorGestures != null && !translatorGestures.isEmpty()) {
333 gestures = translatorGestures;
334 }
335 }
336
337 // Perform the gestures
338 distributeGestures(gestures, false);
339 }
340
341 /*
342 *
343 * Gesture-layer distribution methods.
344 *
345 */
346
347 /** The registered InputEventToGestureTranslators. */
348 private HashMap<InputType, List<InputEventToGestureTranslator>> _translators;
349
350 /** The registered gesture listeners. */
351 private LinkedList<GestureListener> _gestureListeners;
352
353 /**
354 * Sets the translator to use to generate gestures for a given type of input.
355 * @return True if the input type is supported by this Input Manager, false if not.
356 */
357 public final void addInputEventToGestureTranslator(InputEventToGestureTranslator translator)
358 {
359 if (translator == null) {
360 return;
361 }
362
363 Set<InputType> types = translator.getMonitoredInputTypes();
364
365 for (InputType type : types) {
366 _translators.get(type).add(translator);
367 }
368 }
369
370 /**
371 * Gets the input-event -> gesture translator that was registered with the
372 * given input type.
373 */
374 public final List<InputEventToGestureTranslator> getInputEventToGestureTranslators(InputType type)
375 {
376 if (type == null) {
377 return null;
378 }
379
380 return _translators.get(type);
381 }
382
383 /**
384 * Should return true if the input manager supports the given
385 * type of input and false if not.
386 */
387 protected abstract boolean isInputTypeSupported(InputType type);
388
389 /** Registers a new listener to receive gestures from the input system. */
390 public final void registerGestureListener(GestureListener listener)
391 {
392 if (listener == null) {
393 return;
394 }
395
396 _gestureListeners.add(listener);
397 }
398
399 /** Notifies all gesture listeners of the given gestures. */
400 public void distributeGestures(List<Gesture> gestures)
401 {
402 distributeGestures(gestures, true);
403 }
404
405 /** Notifies all gesture listeners of the given gestures. */
406 protected void distributeGestures(List<Gesture> gestures, boolean robotic)
407 {
408 if (gestures == null) {
409 return;
410 }
411
412 for (Gesture gesture : gestures) {
413 distributeGesture(gesture, robotic);
414 }
415 }
416
417 /** Notifies all gesture listeners of the given gesture. */
418 public void distributeGesture(Gesture gesture)
419 {
420 distributeGesture(gesture, true);
421 }
422
423 /** Notifies all gesture listeners of the given gesture. */
424 protected void distributeGesture(final Gesture gesture, final boolean robotic)
425 {
426 if (gesture == null) {
427 return;
428 }
429
430 // Ensure robotic callers don't try to spoof being non-robotic
431 if (robotic) {
432 gesture.setRobotic(true);
433 }
434
435 final Gesture clone = gesture.clone();
436
437 for(final GestureListener listener : _gestureListeners) {
438 listener.preGesture(clone);
439 }
440
441 for (final GestureListener listener : _gestureListeners) {
442 listener.onGesture(clone);
443 }
444
445 for (final GestureListener listener : _gestureListeners) {
446 listener.postGesture(clone);
447 }
448 }
449
450}
Note: See TracBrowser for help on using the repository browser.