Skip to content

Commit 87e428e

Browse files
committed
feat(nui-libgdx): replace touch pointer removal logic with configurable stickiness
1 parent 2b530a4 commit 87e428e

File tree

1 file changed

+29
-11
lines changed

1 file changed

+29
-11
lines changed

nui-libgdx/src/main/java/org/terasology/nui/backends/libgdx/LibGDXMouseDevice.java

Lines changed: 29 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,13 @@ public class LibGDXMouseDevice implements MouseDevice {
3131
// The maximum number of touches that LibGDX supports on Android is 20.
3232
// See https://github.com/libgdx/libgdx/blob/5eac848925d6e1f24070f887cbfaf99bb8bc4a63/backends/gdx-backend-android/src/com/badlogic/gdx/backends/android/AndroidInput.java#L99
3333
private static final int MAX_POINTERS = 20;
34+
// The default value has been calibrated by trial and error, mostly. You can set your own stickiness in the constructor.
35+
private static final int DEFAULT_POINTER_STICKINESS = 4;
36+
/**
37+
* Defines how "sticky" a pointer is, meaning how many updates it should be retained for after the touch is released.
38+
* This value can be fine-tuned based on the desired general responsiveness of the UI.
39+
*/
40+
private final int pointerStickiness;
3441
/**
3542
* Flags a pointer for "removal" when it is no longer present on the screen.
3643
*
@@ -43,11 +50,20 @@ public class LibGDXMouseDevice implements MouseDevice {
4350
* The removePointer variable is used to delay this removal by a single update, so that UI widgets have time
4451
* to register the removal first (e.g. for button de-presses).
4552
*/
46-
private boolean[] removePointer;
53+
private final int[] pointerCooldowns;
4754

4855
public LibGDXMouseDevice() {
56+
this(DEFAULT_POINTER_STICKINESS);
57+
}
58+
59+
/**
60+
* @param pointerStickiness Defines how "sticky" a pointer is,
61+
* meaning how many updates it should be retained for after the touch is released.
62+
*/
63+
public LibGDXMouseDevice(int pointerStickiness) {
4964
NUIInputProcessor.init();
50-
removePointer = new boolean[MAX_POINTERS];
65+
this.pointerStickiness = pointerStickiness;
66+
pointerCooldowns = new int[MAX_POINTERS];
5167
}
5268

5369
@Override
@@ -72,15 +88,12 @@ public Vector2i getPosition(int pointer) {
7288

7389
if (Gdx.app.getType() == Application.ApplicationType.Android) {
7490
if (Gdx.input.isTouched(pointer)) {
75-
removePointer[pointer] = false;
76-
} else {
77-
if (removePointer[pointer]) {
78-
// Since touches are mapped to pointers on Android, reset the pointer when not currently touching.
79-
// Set the pointer to an off-screen location, so it acts as if it were not present.
80-
return new Vector2i(Integer.MAX_VALUE, Integer.MAX_VALUE);
81-
} else {
82-
removePointer[pointer] = true;
83-
}
91+
pointerCooldowns[pointer] = pointerStickiness;
92+
} else if (pointerCooldowns[pointer] <= 0) {
93+
pointerCooldowns[pointer] = 0;
94+
// Since touches are mapped to pointers on Android, reset the pointer when not currently touching.
95+
// Set the pointer to an off-screen location, so it acts as if it were not present.
96+
return new Vector2i(Integer.MAX_VALUE, Integer.MAX_VALUE);
8497
}
8598
}
8699

@@ -106,6 +119,11 @@ public boolean isButtonDown(int button) {
106119

107120
@Override
108121
public void update() {
122+
for (int pointer = 0; pointer < MAX_POINTERS; pointer++) {
123+
if (pointerCooldowns[pointer] > 0) {
124+
pointerCooldowns[pointer]--;
125+
}
126+
}
109127
}
110128

111129
/**

0 commit comments

Comments
 (0)