-
-
Notifications
You must be signed in to change notification settings - Fork 21.4k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add rotary input support for Android platform #88130
Add rotary input support for Android platform #88130
Conversation
platform/android/java/lib/src/org/godotengine/godot/input/GodotInputHandler.java
Outdated
Show resolved
Hide resolved
Assuming the implementation will be accepted by the @godotengine/android team, one step prior to merging would be to squash the commits. See PR workflow for instructions. |
Here is an issue in proposal repo godotengine/godot-proposals#9062 |
ade7b8c
to
53608d1
Compare
if (event.isFromSource(InputDevice.SOURCE_ROTARY_ENCODER)) { | ||
// If event came from RotaryEncoder (Bezel or Crown rotate event on Wear OS smart watches), | ||
// convert it to vertical mouse wheel event. | ||
verticalFactor = event.getAxisValue(MotionEvent.AXIS_SCROLL); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The documentation you linked to has additional logic that is not replicated here; is there a reason to leave that logic out?
You should also provide the ability for users to select whether this should be converted to a vertical event or to a horizontal event using project settings.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thank you for review. Yes you are right I need to make negation for axis value. All other logic in this documentation connected with getting some settings from configuration, like getting scroll velocity and applying RotaryInput to UI control.
You should also provide the ability for users to select whether this should be converted to a vertical event or to a horizontal event using project settings.
I have concerns about ability to change direction of this input from vertical to horizontal through project settings. As I understand we should convert some specific inputs to another more general inputs. So here I conver RotaryInput to mouse wheel input(most of miсe have only one wheel for vertical scrolling). If I added such settings It would be very disappointed, because in the same game running on PC mouse wheel would cause vertical scrolling but on smart watches crown wheel or bezel wheel would cause horizontal scrolling. Anyway In the same game such event can cause as vertical as horizontal scrolling in different scenes. So how to handle this events and which axis should be chaned by this event should be defined in specific places(inside controls or scene or other object scripts) in my opinion.
Considering fact that if developer wants to handle this events as horizaontal scrolling he can override it with a couple lines of script such configuration option contradicts this rule:
- Can the feature be worked around in script with a few lines?
If the feature is only intended to save users a few lines of code it is unlikely to be accepted.
So if I have not convinced you, let me know and I will add this setting.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
For a cross-platform game/app, I'd agree that consistency is key and for that reason the default value for the project setting should be set to vertical to simulate similar interaction on other platforms.
However a developer can also decide to target wear os devices only and as such should not be restricted by other platforms conventions. For that reason, we should provide the option to override how the rotary input is interpreted.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Added option to change RotaryInpur axis through project settings.
0a8db8c
to
f55f612
Compare
f55f612
to
7afc512
Compare
main/main.cpp
Outdated
@@ -2857,6 +2857,7 @@ Error Main::setup2() { | |||
|
|||
GLOBAL_DEF_BASIC("input_devices/pointing/android/enable_long_press_as_right_click", false); | |||
GLOBAL_DEF_BASIC("input_devices/pointing/android/enable_pan_and_scale_gestures", false); | |||
GLOBAL_DEF_RST_NOVAL(PropertyInfo(Variant::STRING, "input_devices/pointing/android/rotary_input_scroll_axis", PROPERTY_HINT_ENUM, "Y,X"), "Y"); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I personally suggest switching the order here as X is conventionally the first axis.
GLOBAL_DEF_RST_NOVAL(PropertyInfo(Variant::STRING, "input_devices/pointing/android/rotary_input_scroll_axis", PROPERTY_HINT_ENUM, "Y,X"), "Y"); | |
GLOBAL_DEF_RST_NOVAL(PropertyInfo(Variant::STRING, "input_devices/pointing/android/rotary_input_scroll_axis", PROPERTY_HINT_ENUM, "X,Y"), "Y"); |
But, is it appropriate to use a string for this setting? Could it also not be a numerical value or a boolean (0 or 1), instead?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I agree the axis value should be an int
instead of a string
. This matches the pattern used in the codebase.
As for the labels, I think using Horizontal, Vertical
would be more clear.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Horizontal,Vertical
. No spacing, it is not trimmed when visualized. Notably, though, there's really going to ever be just two options so the setting could also be reworked into a toggle. Unless for some reason other mouse button combinations are considered.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for the correction!
I think it's okay to keep both options since it's consistent with what we usually do for axes, and it provides more clarity to the end user.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Fixed
doc/classes/ProjectSettings.xml
Outdated
@@ -1358,6 +1358,9 @@ | |||
<member name="input_devices/pointing/android/enable_pan_and_scale_gestures" type="bool" setter="" getter="" default="false"> | |||
If [code]true[/code], multi-touch pan and scale gestures are enabled on Android devices. | |||
</member> | |||
<member name="input_devices/pointing/android/rotary_input_scroll_axis" type="String" setter="" getter="" default="Y"> | |||
Defines which axis of mouse wheel RotaryInput will be mapped on Wear OS devices. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Defines which axis of mouse wheel RotaryInput will be mapped on Wear OS devices. | |
On Wear OS devices, defines which axis of the mouse wheel rotary input is mapped to. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Fixed
main/main.cpp
Outdated
@@ -2857,6 +2857,7 @@ Error Main::setup2() { | |||
|
|||
GLOBAL_DEF_BASIC("input_devices/pointing/android/enable_long_press_as_right_click", false); | |||
GLOBAL_DEF_BASIC("input_devices/pointing/android/enable_pan_and_scale_gestures", false); | |||
GLOBAL_DEF_RST_NOVAL(PropertyInfo(Variant::STRING, "input_devices/pointing/android/rotary_input_scroll_axis", PROPERTY_HINT_ENUM, "Y,X"), "Y"); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I agree the axis value should be an int
instead of a string
. This matches the pattern used in the codebase.
As for the labels, I think using Horizontal, Vertical
would be more clear.
/** | ||
* Define which axis of mouse wheel event will be used for mapping RotaryInput. | ||
*/ | ||
protected open fun setRotaryInputAxis() = |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This should be getRotaryInputAxis()
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Fixed
@@ -70,6 +73,8 @@ public class GodotInputHandler implements InputManager.InputDeviceListener { | |||
* Used to decide whether mouse capture can be enabled. | |||
*/ | |||
private int lastSeenToolType = MotionEvent.TOOL_TYPE_UNKNOWN; | |||
|
|||
private static String rotaryInputAxis = AXIS_Y; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You can remove static
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
No I can not. This property is used in handleMouseEvent
function which is static.
// convert it to vertical mouse wheel event. | ||
if (event.isFromSource(InputDevice.SOURCE_ROTARY_ENCODER)) { | ||
if (rotaryInputAxis.equals(AXIS_X)) { | ||
horizontalFactor = event.getAxisValue(MotionEvent.AXIS_SCROLL); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The negation should be applied here as well.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
fixed
f7f5b14
to
db5a8b2
Compare
@@ -101,6 +106,13 @@ public void enableLongPress(boolean enable) { | |||
public void enablePanningAndScalingGestures(boolean enable) { | |||
this.godotGestureHandler.setPanningAndScalingEnabled(enable); | |||
} | |||
|
|||
/** | |||
* Set RotaryInput axis. This is Y by default. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This javadoc should be updated to match the added documentation.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Fixed.
float horizontalFactor = 0; | ||
|
||
// If event came from RotaryEncoder (Bezel or Crown rotate event on Wear OS smart watches), | ||
// convert it to vertical mouse wheel event. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The vertical
in this sentence can be removed.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Fixed.
@@ -272,6 +273,11 @@ open class GodotEditor : GodotActivity() { | |||
*/ | |||
protected open fun enablePanAndScaleGestures() = | |||
java.lang.Boolean.parseBoolean(GodotLib.getEditorSetting("interface/touchscreen/enable_pan_and_scale_gestures")) | |||
/** | |||
* Define which axis of mouse wheel event will be used for mapping RotaryInput. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The javadoc should be updated to match the added documentation.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Fixed.
doc/classes/ProjectSettings.xml
Outdated
@@ -1358,6 +1358,9 @@ | |||
<member name="input_devices/pointing/android/enable_pan_and_scale_gestures" type="bool" setter="" getter="" default="false"> | |||
If [code]true[/code], multi-touch pan and scale gestures are enabled on Android devices. | |||
</member> | |||
<member name="input_devices/pointing/android/rotary_input_scroll_axis" type="int" setter="" getter="" default="Vertical"> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The value for default
should be 1
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Fixed.
@@ -110,6 +110,7 @@ open class GodotEditor : GodotActivity() { | |||
super.onGodotSetupCompleted() | |||
val longPressEnabled = enableLongPressGestures() | |||
val panScaleEnabled = enablePanAndScaleGestures() | |||
val rotaryInputAxis = getRotaryInputAxis() |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The rotaryInputAxis
value needs to be passed to the GodotInputHandler
below on line 121.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Fixed.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actually, I made a mistake; the changes in the GodotEditor
class are not needed because the editor just used the Godot
object which applies the setting for it.
So you should be able to revert the changes in this file.
* Define which axis of mouse wheel event will be used for mapping RotaryInput. | ||
*/ | ||
protected open fun getRotaryInputAxis() = | ||
GodotLib.getEditorSetting("input_devices/pointing/android/rotary_input_scroll_axis") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
GodotLib.getEditorSetting(...)
returns a String
, so you need to use Integer.parseInt(...)
to parse it to an int
value.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Fixed.
private static final int VERTICAL_AXIS = 1; | ||
private static final int HORIZONTAL_AXIS = 0; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Let's update these constants to ROTARY_INPUT_VERTICAL_AXIS
and ROTARY_INPUT_HORIZONTAL_AXIS
for clarity.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Fixed.
rotaryInputAxis = axis; | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks like there is an issue with indentation here.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Fixed. And All others indentation errors.
db5a8b2
to
387b706
Compare
main/main.cpp
Outdated
@@ -2857,7 +2857,7 @@ Error Main::setup2() { | |||
|
|||
GLOBAL_DEF_BASIC("input_devices/pointing/android/enable_long_press_as_right_click", false); | |||
GLOBAL_DEF_BASIC("input_devices/pointing/android/enable_pan_and_scale_gestures", false); | |||
|
|||
GLOBAL_DEF_BASIC(PropertyInfo(Variant::INT, "input_devices/pointing/android/rotary_input_scroll_axis", PROPERTY_HINT_ENUM, "Horizontal,Vertical"), "1"); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
GLOBAL_DEF_BASIC(PropertyInfo(Variant::INT, "input_devices/pointing/android/rotary_input_scroll_axis", PROPERTY_HINT_ENUM, "Horizontal,Vertical"), "1"); | |
GLOBAL_DEF_BASIC(PropertyInfo(Variant::INT, "input_devices/pointing/android/rotary_input_scroll_axis", PROPERTY_HINT_ENUM, "Horizontal,Vertical"), 1); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thank you. Fixed
387b706
to
3641437
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks great!
There is one set of changes that need to be reverted then it'll be good to merge!
@@ -110,6 +110,7 @@ open class GodotEditor : GodotActivity() { | |||
super.onGodotSetupCompleted() | |||
val longPressEnabled = enableLongPressGestures() | |||
val panScaleEnabled = enablePanAndScaleGestures() | |||
val rotaryInputAxis = getRotaryInputAxis() |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actually, I made a mistake; the changes in the GodotEditor
class are not needed because the editor just used the Godot
object which applies the setting for it.
So you should be able to revert the changes in this file.
3641437
to
4098933
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@@ -118,6 +118,7 @@ open class GodotEditor : GodotActivity() { | |||
godotFragment?.godot?.renderView?.inputHandler?.apply { | |||
enableLongPress(longPressEnabled) | |||
enablePanningAndScalingGestures(panScaleEnabled) | |||
setRotaryInputAxis(rotaryInputAxis) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You can also revert this change for the GodotEditor
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
fixed
* On Wear OS devices, defines which axis of the mouse wheel rotary input is mapped to. | ||
*/ | ||
protected open fun getRotaryInputAxis() = | ||
Integer.parseInt(GodotLib.getEditorSetting("input_devices/pointing/android/rotary_input_scroll_axis")) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You can also revert this change for the GodotEditor
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
fixed
4098933
to
8b198d9
Compare
platform/android/java/lib/src/org/godotengine/godot/input/GodotInputHandler.java
Outdated
Show resolved
Hide resolved
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks great!
8b198d9
to
d5c2a64
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks! And congrats for your first merged Godot contribution 🎉 |
This PR adds Rotary input support for wear os devices. It converts RotaryInput to vertical mouse wheel event. Without it Godot does not recognise this event at all.