[Scummvm-git-logs] scummvm master -> bbcdda6c7fc0a78b7e6ad0ae5f844de42755d7a4

antoniou79 noreply at scummvm.org
Mon Jun 13 21:08:08 UTC 2022


This automated email contains information about 2 new commits which have been
pushed to the 'scummvm' repo located at https://github.com/scummvm/scummvm .

Summary:
57e27dcf12 ANDROID: Let user customize its preferred touch modes
bbcdda6c7f ANDROID: Merge touch mode and toggle keyboard buttons


Commit: 57e27dcf121dfbc54c40faa69db35b0c3c5d2c64
    https://github.com/scummvm/scummvm/commit/57e27dcf121dfbc54c40faa69db35b0c3c5d2c64
Author: Le Philousophe (lephilousophe at users.noreply.github.com)
Date: 2022-06-14T00:08:04+03:00

Commit Message:
ANDROID: Let user customize its preferred touch modes

There are 3 settings: in menus, in 2D games, in 3D games

Changed paths:
  A dists/android/res/drawable/ic_action_touchpad.xml
    backends/graphics/android/android-graphics.cpp
    backends/graphics/android/android-graphics.h
    backends/graphics3d/android/android-graphics3d.cpp
    backends/graphics3d/android/android-graphics3d.h
    backends/platform/android/android.cpp
    backends/platform/android/android.h
    backends/platform/android/events.cpp
    backends/platform/android/jni-android.cpp
    backends/platform/android/jni-android.h
    backends/platform/android/options.cpp
    backends/platform/android/org/scummvm/scummvm/ScummVM.java
    backends/platform/android/org/scummvm/scummvm/ScummVMActivity.java
    backends/platform/android/org/scummvm/scummvm/ScummVMEventsBase.java


diff --git a/backends/graphics/android/android-graphics.cpp b/backends/graphics/android/android-graphics.cpp
index 410dd94f182..f2e22de5543 100644
--- a/backends/graphics/android/android-graphics.cpp
+++ b/backends/graphics/android/android-graphics.cpp
@@ -66,7 +66,8 @@ static void loadBuiltinTexture(JNI::BitmapResources resource, OpenGL::Surface *s
 // AndroidGraphicsManager
 //
 AndroidGraphicsManager::AndroidGraphicsManager() :
-	_touchcontrols(nullptr) {
+	_touchcontrols(nullptr),
+	_old_touch_mode(OSystem_Android::TOUCH_MODE_TOUCHPAD) {
 	ENTER();
 
 	// Initialize our OpenGL ES context.
@@ -76,8 +77,8 @@ AndroidGraphicsManager::AndroidGraphicsManager() :
 	loadBuiltinTexture(JNI::BitmapResources::TOUCH_ARROWS_BITMAP, _touchcontrols);
 	_touchcontrols->updateGLTexture();
 
-	// In 2D we always fallback to standard 2D mode
-	JNI::setTouch3DMode(false);
+	// not in 3D, not in overlay
+	dynamic_cast<OSystem_Android *>(g_system)->applyTouchSettings(false, false);
 }
 
 AndroidGraphicsManager::~AndroidGraphicsManager() {
@@ -150,23 +151,13 @@ void AndroidGraphicsManager::displayMessageOnOSD(const Common::U32String &msg) {
 	JNI::displayMessageOnOSD(msg);
 }
 
-bool AndroidGraphicsManager::showMouse(bool visible) {
-	bool last = OpenGL::OpenGLGraphicsManager::showMouse(visible);
-
-	if (visible && last != visible) {
-		// We just displayed a mouse cursor, disable the 3D mode if user enabled it
-		JNI::setTouch3DMode(false);
-	}
-
-	return last;
-}
-
 void AndroidGraphicsManager::showOverlay() {
 	if (_overlayVisible)
 		return;
 
-	_old_touch_3d_mode = JNI::getTouch3DMode();
-	JNI::setTouch3DMode(false);
+	_old_touch_mode = JNI::getTouchMode();
+	// not in 3D, in overlay
+	dynamic_cast<OSystem_Android *>(g_system)->applyTouchSettings(false, true);
 
 	OpenGL::OpenGLGraphicsManager::showOverlay();
 }
@@ -175,7 +166,8 @@ void AndroidGraphicsManager::hideOverlay() {
 	if (!_overlayVisible)
 		return;
 
-	JNI::setTouch3DMode(_old_touch_3d_mode);
+	// Restore touch mode active before overlay was shown
+	JNI::setTouchMode(_old_touch_mode);
 
 	OpenGL::OpenGLGraphicsManager::hideOverlay();
 }
diff --git a/backends/graphics/android/android-graphics.h b/backends/graphics/android/android-graphics.h
index beb0a58ae58..74a3c6311e4 100644
--- a/backends/graphics/android/android-graphics.h
+++ b/backends/graphics/android/android-graphics.h
@@ -89,7 +89,6 @@ public:
 
 protected:
 	void setSystemMousePosition(const int x, const int y) override {}
-	bool showMouse(bool visible) override;
 
 	void showOverlay() override;
 	void hideOverlay() override;
@@ -103,7 +102,7 @@ protected:
 
 private:
 	OpenGL::Surface *_touchcontrols;
-	bool _old_touch_3d_mode;
+	int _old_touch_mode;
 };
 
 #endif
diff --git a/backends/graphics3d/android/android-graphics3d.cpp b/backends/graphics3d/android/android-graphics3d.cpp
index ea78e61b755..9203401ea51 100644
--- a/backends/graphics3d/android/android-graphics3d.cpp
+++ b/backends/graphics3d/android/android-graphics3d.cpp
@@ -93,7 +93,7 @@ AndroidGraphics3dManager::AndroidGraphics3dManager() :
 	_mouse_dont_scale(false),
 	_show_mouse(false),
 	_touchcontrols_texture(nullptr),
-	_old_touch_3d_mode(false) {
+	_old_touch_mode(OSystem_Android::TOUCH_MODE_TOUCHPAD) {
 
 	if (JNI::egl_bits_per_pixel == 16) {
 		// We default to RGB565 and RGBA5551 which is closest to what we setup in Java side
@@ -113,7 +113,9 @@ AndroidGraphics3dManager::AndroidGraphics3dManager() :
 	_touchcontrols_texture = loadBuiltinTexture(JNI::BitmapResources::TOUCH_ARROWS_BITMAP);
 
 	initSurface();
-	JNI::setTouch3DMode(true);
+
+	// in 3D, not in overlay
+	dynamic_cast<OSystem_Android *>(g_system)->applyTouchSettings(true, false);
 }
 
 AndroidGraphics3dManager::~AndroidGraphics3dManager() {
@@ -124,8 +126,6 @@ AndroidGraphics3dManager::~AndroidGraphics3dManager() {
 	glBindRenderbuffer(GL_RENDERBUFFER, 0);
 	glUseProgram(0);
 
-	JNI::setTouch3DMode(false);
-
 	deinitSurface();
 
 	delete _frame_buffer;
@@ -457,8 +457,9 @@ void AndroidGraphics3dManager::showOverlay() {
 		return;
 	}
 
-	_old_touch_3d_mode = JNI::getTouch3DMode();
-	JNI::setTouch3DMode(false);
+	_old_touch_mode = JNI::getTouchMode();
+	// in 3D, in overlay
+	dynamic_cast<OSystem_Android *>(g_system)->applyTouchSettings(true, true);
 
 	_show_overlay = true;
 	_force_redraw = true;
@@ -504,7 +505,8 @@ void AndroidGraphics3dManager::hideOverlay() {
 
 	_overlay_background->release();
 
-	JNI::setTouch3DMode(_old_touch_3d_mode);
+	// Restore touch mode active before overlay was shown
+	JNI::setTouchMode(_old_touch_mode);
 
 	warpMouse(_game_texture->width() / 2, _game_texture->height() / 2);
 
diff --git a/backends/graphics3d/android/android-graphics3d.h b/backends/graphics3d/android/android-graphics3d.h
index 0e1d3b942f1..846f0b1a5d3 100644
--- a/backends/graphics3d/android/android-graphics3d.h
+++ b/backends/graphics3d/android/android-graphics3d.h
@@ -183,7 +183,7 @@ private:
 
 	// Touch controls layer
 	GLESTexture *_touchcontrols_texture;
-	bool _old_touch_3d_mode;
+	int _old_touch_mode;
 };
 
 #endif
diff --git a/backends/platform/android/android.cpp b/backends/platform/android/android.cpp
index 007cb5c7b67..a8532969706 100644
--- a/backends/platform/android/android.cpp
+++ b/backends/platform/android/android.cpp
@@ -139,7 +139,7 @@ OSystem_Android::OSystem_Android(int audio_sample_rate, int audio_buffer_size) :
 	_eventScaleX(100),
 	_eventScaleY(100),
 	// TODO put these values in some option dlg?
-	_touchpad_mode(true),
+	_touch_mode(TOUCH_MODE_TOUCHPAD),
 	_touchpad_scale(66),
 	_dpad_scale(4),
 //	_fingersDown(0),
diff --git a/backends/platform/android/android.h b/backends/platform/android/android.h
index 35a5a66cebc..4b83e05ebd0 100644
--- a/backends/platform/android/android.h
+++ b/backends/platform/android/android.h
@@ -121,6 +121,13 @@ private:
 	Common::String getSystemProperty(const char *name) const;
 
 public:
+	enum {
+		TOUCH_MODE_TOUCHPAD = 0,
+		TOUCH_MODE_MOUSE = 1,
+		TOUCH_MODE_GAMEPAD = 2,
+		TOUCH_MODE_MAX = 3
+	};
+
 	OSystem_Android(int audio_sample_rate, int audio_buffer_size);
 	virtual ~OSystem_Android();
 
@@ -136,6 +143,8 @@ public:
 	void pushEvent(const Common::Event &event1, const Common::Event &event2);
 
 	TouchControls &getTouchControls() { return _touchControls; }
+	void applyTouchSettings(bool _3dMode, bool overlayShown);
+	void setupTouchMode(int oldValue, int newValue);
 
 private:
 	Common::Queue<Common::Event> _event_queue;
@@ -146,7 +155,7 @@ private:
 	Common::Point _touch_pt_down, _touch_pt_scroll, _touch_pt_dt, _touch_pt_multi;
 	int _eventScaleX;
 	int _eventScaleY;
-	bool _touchpad_mode;
+	int _touch_mode;
 	int _touchpad_scale;
 	int _trackball_scale;
 	int _dpad_scale;
diff --git a/backends/platform/android/events.cpp b/backends/platform/android/events.cpp
index b26f7fd8174..bd4351886cb 100644
--- a/backends/platform/android/events.cpp
+++ b/backends/platform/android/events.cpp
@@ -618,7 +618,7 @@ void OSystem_Android::pushEvent(int type, int arg1, int arg2, int arg3,
 //		LOGD("JE_SCROLL");
 		e.type = Common::EVENT_MOUSEMOVE;
 
-		if (_touchpad_mode) {
+		if (_touch_mode == TOUCH_MODE_TOUCHPAD) {
 			if (_touch_pt_scroll.x == -1 && _touch_pt_scroll.y == -1) {
 				_touch_pt_scroll.x = arg3;
 				_touch_pt_scroll.y = arg4;
@@ -647,7 +647,7 @@ void OSystem_Android::pushEvent(int type, int arg1, int arg2, int arg3,
 
 		e.type = Common::EVENT_MOUSEMOVE;
 
-		if (_touchpad_mode) {
+		if (_touch_mode == TOUCH_MODE_TOUCHPAD) {
 			e.mouse = dynamic_cast<AndroidCommonGraphics *>(_graphicsManager)->getMousePosition();
 		} else {
 			e.mouse.x = arg1;
@@ -695,7 +695,7 @@ void OSystem_Android::pushEvent(int type, int arg1, int arg2, int arg3,
 				_event_queue.push(_queuedEvent);
 			}
 
-			if (!_touchpad_mode) {
+			if (_touch_mode != TOUCH_MODE_TOUCHPAD) {
 				// In this case the mouse move is done in "direct mode"
 				// ie. the cursor jumps to where the tap occured
 				// so we don't have relMouse coordinates to set for the event
@@ -722,7 +722,7 @@ void OSystem_Android::pushEvent(int type, int arg1, int arg2, int arg3,
 
 		e.type = Common::EVENT_MOUSEMOVE;
 
-		if (_touchpad_mode) {
+		if (_touch_mode == TOUCH_MODE_TOUCHPAD) {
 			e.mouse = dynamic_cast<AndroidCommonGraphics *>(_graphicsManager)->getMousePosition();
 		} else {
 			e.mouse.x = arg1;
@@ -753,7 +753,7 @@ void OSystem_Android::pushEvent(int type, int arg1, int arg2, int arg3,
 
 				dptype = Common::EVENT_MOUSEMOVE;
 
-				if (_touchpad_mode) {
+				if (_touch_mode == TOUCH_MODE_TOUCHPAD) {
 					e.mouse.x = (arg1 - _touch_pt_dt.x) * 100 / _touchpad_scale;
 					e.mouse.y = (arg2 - _touch_pt_dt.y) * 100 / _touchpad_scale;
 					e.mouse += _touch_pt_down;
@@ -791,7 +791,7 @@ void OSystem_Android::pushEvent(int type, int arg1, int arg2, int arg3,
 
 		e.type = Common::EVENT_MOUSEMOVE;
 
-		if (_touchpad_mode) {
+		if (_touch_mode == TOUCH_MODE_TOUCHPAD) {
 			e.mouse = dynamic_cast<AndroidCommonGraphics *>(_graphicsManager)->getMousePosition();
 		} else {
 			e.mouse.x = arg3;
@@ -918,7 +918,7 @@ void OSystem_Android::pushEvent(int type, int arg1, int arg2, int arg3,
 				multitype = Common::EVENT_MOUSEMOVE;
 
 				// TODO TO TEST for non-touchpad mode too!
-				if (_touchpad_mode) {
+				if (_touch_mode == TOUCH_MODE_TOUCHPAD) {
 					e.mouse.x = (arg3 - _touch_pt_multi.x) * 100 / _touchpad_scale;
 					e.mouse.y = (arg4 - _touch_pt_multi.y) * 100 / _touchpad_scale;
 					e.mouse += _touch_pt_down; // TODO maybe we need another reference point???
@@ -1309,4 +1309,15 @@ void OSystem_Android::pushEvent(const Common::Event &event1, const Common::Event
 	_event_queue_lock->unlock();
 }
 
+void OSystem_Android::setupTouchMode(int oldValue, int newValue) {
+	_touch_mode = newValue;
+
+	if (newValue == TOUCH_MODE_TOUCHPAD) {
+		// Make sure we have a proper touch point if we switch to touchpad mode with finger down
+		_touch_pt_down = dynamic_cast<AndroidCommonGraphics *>(_graphicsManager)->getMousePosition();
+		_touch_pt_scroll.x = -1;
+		_touch_pt_scroll.y = -1;
+	}
+}
+
 #endif
diff --git a/backends/platform/android/jni-android.cpp b/backends/platform/android/jni-android.cpp
index 2140e881b68..de6472deda5 100644
--- a/backends/platform/android/jni-android.cpp
+++ b/backends/platform/android/jni-android.cpp
@@ -88,8 +88,8 @@ jmethodID JNI::_MID_setWindowCaption = 0;
 jmethodID JNI::_MID_showVirtualKeyboard = 0;
 jmethodID JNI::_MID_showKeyboardControl = 0;
 jmethodID JNI::_MID_getBitmapResource = 0;
-jmethodID JNI::_MID_setTouch3DMode = 0;
-jmethodID JNI::_MID_getTouch3DMode = 0;
+jmethodID JNI::_MID_setTouchMode = 0;
+jmethodID JNI::_MID_getTouchMode = 0;
 jmethodID JNI::_MID_showSAFRevokePermsControl = 0;
 jmethodID JNI::_MID_getSysArchives = 0;
 jmethodID JNI::_MID_getAllStorageLocations = 0;
@@ -126,6 +126,8 @@ const JNINativeMethod JNI::_natives[] = {
 		(void *)JNI::pushEvent },
 	{ "updateTouch", "(IIII)V",
 		(void *)JNI::updateTouch },
+	{ "setupTouchMode", "(II)V",
+		(void *)JNI::setupTouchMode },
 	{ "setPause", "(Z)V",
 		(void *)JNI::setPause },
 	{ "getNativeVersionInfo", "()Ljava/lang/String;",
@@ -455,10 +457,10 @@ Graphics::Surface *JNI::getBitmapResource(BitmapResources resource) {
 	return ret;
 }
 
-void JNI::setTouch3DMode(bool touch3DMode) {
+void JNI::setTouchMode(int touchMode) {
 	JNIEnv *env = JNI::getEnv();
 
-	env->CallVoidMethod(_jobj, _MID_setTouch3DMode, touch3DMode);
+	env->CallVoidMethod(_jobj, _MID_setTouchMode, touchMode);
 
 	if (env->ExceptionCheck()) {
 		LOGE("Error trying to set touch controls mode");
@@ -468,10 +470,10 @@ void JNI::setTouch3DMode(bool touch3DMode) {
 	}
 }
 
-bool JNI::getTouch3DMode() {
+int JNI::getTouchMode() {
 	JNIEnv *env = JNI::getEnv();
 
-	bool enabled = env->CallBooleanMethod(_jobj, _MID_getTouch3DMode);
+	int mode = env->CallIntMethod(_jobj, _MID_getTouchMode);
 
 	if (env->ExceptionCheck()) {
 		LOGE("Error trying to get touch controls status");
@@ -480,7 +482,7 @@ bool JNI::getTouch3DMode() {
 		env->ExceptionClear();
 	}
 
-	return enabled;
+	return mode;
 }
 
 void JNI::showSAFRevokePermsControl(bool enable) {
@@ -667,8 +669,8 @@ void JNI::create(JNIEnv *env, jobject self, jobject asset_manager,
 	FIND_METHOD(, showVirtualKeyboard, "(Z)V");
 	FIND_METHOD(, showKeyboardControl, "(Z)V");
 	FIND_METHOD(, getBitmapResource, "(I)Landroid/graphics/Bitmap;");
-	FIND_METHOD(, setTouch3DMode, "(Z)V");
-	FIND_METHOD(, getTouch3DMode, "()Z");
+	FIND_METHOD(, setTouchMode, "(I)V");
+	FIND_METHOD(, getTouchMode, "()I");
 	FIND_METHOD(, getSysArchives, "()[Ljava/lang/String;");
 	FIND_METHOD(, getAllStorageLocations, "()[Ljava/lang/String;");
 	FIND_METHOD(, initSurface, "()Ljavax/microedition/khronos/egl/EGLSurface;");
@@ -822,6 +824,13 @@ void JNI::updateTouch(JNIEnv *env, jobject self, int action, int ptr, int x, int
 	_system->getTouchControls().update((TouchControls::Action) action, ptr, x, y);
 }
 
+void JNI::setupTouchMode(JNIEnv *env, jobject self, jint oldValue, jint newValue) {
+	if (!_system)
+		return;
+
+	_system->setupTouchMode(oldValue, newValue);
+}
+
 void JNI::setPause(JNIEnv *env, jobject self, jboolean value) {
 	if (!_system)
 		return;
diff --git a/backends/platform/android/jni-android.h b/backends/platform/android/jni-android.h
index d3afb71f2e7..7b69e2a4211 100644
--- a/backends/platform/android/jni-android.h
+++ b/backends/platform/android/jni-android.h
@@ -77,8 +77,8 @@ public:
 	static void showVirtualKeyboard(bool enable);
 	static void showKeyboardControl(bool enable);
 	static Graphics::Surface *getBitmapResource(BitmapResources resource);
-	static void setTouch3DMode(bool touch3DMode);
-	static bool getTouch3DMode();
+	static void setTouchMode(int touchMode);
+	static int getTouchMode();
 	static void showSAFRevokePermsControl(bool enable);
 	static void addSysArchivesToSearchSet(Common::SearchSet &s, int priority);
 
@@ -126,8 +126,8 @@ private:
 	static jmethodID _MID_showVirtualKeyboard;
 	static jmethodID _MID_showKeyboardControl;
 	static jmethodID _MID_getBitmapResource;
-	static jmethodID _MID_setTouch3DMode;
-	static jmethodID _MID_getTouch3DMode;
+	static jmethodID _MID_setTouchMode;
+	static jmethodID _MID_getTouchMode;
 	static jmethodID _MID_showSAFRevokePermsControl;
 	static jmethodID _MID_getSysArchives;
 	static jmethodID _MID_getAllStorageLocations;
@@ -164,6 +164,7 @@ private:
 	static void pushEvent(JNIEnv *env, jobject self, int type, int arg1,
 							int arg2, int arg3, int arg4, int arg5, int arg6);
 	static void updateTouch(JNIEnv *env, jobject self, int action, int ptr, int x, int y);
+	static void setupTouchMode(JNIEnv *env, jobject self, jint oldValue, jint newValue);
 	static void setPause(JNIEnv *env, jobject self, jboolean value);
 
 	static jstring getNativeVersionInfo(JNIEnv *env, jobject self);
diff --git a/backends/platform/android/options.cpp b/backends/platform/android/options.cpp
index aff4b02dec9..8edb0e6e094 100644
--- a/backends/platform/android/options.cpp
+++ b/backends/platform/android/options.cpp
@@ -39,8 +39,10 @@
 #include "backends/platform/android/android.h"
 #include "backends/platform/android/jni-android.h"
 
+#include "gui/gui-manager.h"
 #include "gui/ThemeEval.h"
 #include "gui/widget.h"
+#include "gui/widgets/popup.h"
 
 #include "common/translation.h"
 
@@ -60,17 +62,67 @@ private:
 	void defineLayout(GUI::ThemeEval &layouts, const Common::String &layoutName, const Common::String &overlayedLayout) const override;
 
 	GUI::CheckboxWidget *_onscreenCheckbox;
-	GUI::CheckboxWidget *_touchpadCheckbox;
+	GUI::StaticTextWidget *_preferredTouchModeDesc;
+	GUI::StaticTextWidget *_preferredTMMenusDesc;
+	GUI::PopUpWidget *_preferredTMMenusPopUp;
+	GUI::StaticTextWidget *_preferredTM2DGamesDesc;
+	GUI::PopUpWidget *_preferredTM2DGamesPopUp;
+	GUI::StaticTextWidget *_preferredTM3DGamesDesc;
+	GUI::PopUpWidget *_preferredTM3DGamesPopUp;
 	GUI::CheckboxWidget *_onscreenSAFRevokeCheckbox;
 
 	bool _enabled;
+
+
+	uint32 loadTouchMode(const Common::String &setting, bool acceptDefault, uint32 defaultValue);
+	void saveTouchMode(const Common::String &setting, uint32 touchMode);
+};
+
+enum {
+	kTouchModeDefault = -1,
+	kTouchModeTouchpad = 0,
+	kTouchModeMouse,
+	kTouchModeGamepad,
 };
 
 AndroidOptionsWidget::AndroidOptionsWidget(GuiObject *boss, const Common::String &name, const Common::String &domain) :
 		OptionsContainerWidget(boss, name, "AndroidOptionsDialog", false, domain), _enabled(true) {
+
+	const bool inAppDomain = domain.equalsIgnoreCase(Common::ConfigManager::kApplicationDomain);;
+
 	_onscreenCheckbox = new GUI::CheckboxWidget(widgetsBoss(), "AndroidOptionsDialog.OnScreenControl", _("Show On-screen control"));
-	_touchpadCheckbox = new GUI::CheckboxWidget(widgetsBoss(), "AndroidOptionsDialog.TouchpadMode", _("Touchpad mouse mode"));
-	if (domain.equalsIgnoreCase(Common::ConfigManager::kApplicationDomain)) {
+	_preferredTouchModeDesc = new GUI::StaticTextWidget(widgetsBoss(), "AndroidOptionsDialog.PreferredTouchModeText", _("Choose the preferred touch mode:"));
+	if (inAppDomain) {
+		_preferredTMMenusDesc = new GUI::StaticTextWidget(widgetsBoss(), "AndroidOptionsDialog.TMMenusText", _("In menus"));
+		_preferredTMMenusPopUp = new GUI::PopUpWidget(widgetsBoss(), "AndroidOptionsDialog.TMMenus");
+		_preferredTMMenusPopUp->appendEntry(_("Touchpad emulation"), kTouchModeTouchpad);
+		_preferredTMMenusPopUp->appendEntry(_("Direct mouse"), kTouchModeMouse); // TODO: Find a better name
+		_preferredTMMenusPopUp->appendEntry(_("Gamepad emulation"), kTouchModeGamepad);
+	} else {
+		_preferredTMMenusDesc = nullptr;
+		_preferredTMMenusPopUp = nullptr;
+	}
+
+	_preferredTM2DGamesDesc = new GUI::StaticTextWidget(widgetsBoss(), "AndroidOptionsDialog.TM2DGamesText", _("In 2D games"));
+	_preferredTM2DGamesPopUp = new GUI::PopUpWidget(widgetsBoss(), "AndroidOptionsDialog.TM2DGames");
+	_preferredTM3DGamesDesc = new GUI::StaticTextWidget(widgetsBoss(), "AndroidOptionsDialog.TM3DGamesText", _("In 3D games"));
+	_preferredTM3DGamesPopUp = new GUI::PopUpWidget(widgetsBoss(), "AndroidOptionsDialog.TM3DGames");
+
+	if (!inAppDomain) {
+		_preferredTM2DGamesPopUp->appendEntry(_("<default>"), kTouchModeDefault);
+		_preferredTM3DGamesPopUp->appendEntry(_("<default>"), kTouchModeDefault);
+	}
+
+	_preferredTM2DGamesPopUp->appendEntry(_("Touchpad emulation"), kTouchModeTouchpad);
+	_preferredTM3DGamesPopUp->appendEntry(_("Touchpad emulation"), kTouchModeTouchpad);
+
+	_preferredTM2DGamesPopUp->appendEntry(_("Direct mouse"), kTouchModeMouse); // TODO: Find a better name
+	_preferredTM3DGamesPopUp->appendEntry(_("Direct mouse"), kTouchModeMouse);
+
+	_preferredTM2DGamesPopUp->appendEntry(_("Gamepad emulation"), kTouchModeGamepad);
+	_preferredTM3DGamesPopUp->appendEntry(_("Gamepad emulation"), kTouchModeGamepad);
+
+	if (inAppDomain) {
 		// Only show this checkbox in Options (via Options... in the launcher), and not at game domain level (via Edit Game...)
 		// I18N: Show a button to revoke Storage Access Framework permissions for Android
 		_onscreenSAFRevokeCheckbox = new GUI::CheckboxWidget(widgetsBoss(), "AndroidOptionsDialog.SAFRevokePermsControl", _("Show SAF revoke permissions overlay button"));
@@ -81,37 +133,115 @@ AndroidOptionsWidget::~AndroidOptionsWidget() {
 }
 
 void AndroidOptionsWidget::defineLayout(GUI::ThemeEval &layouts, const Common::String &layoutName, const Common::String &overlayedLayout) const {
+	const bool inAppDomain = _domain.equalsIgnoreCase(Common::ConfigManager::kApplicationDomain);;
+
 	layouts.addDialog(layoutName, overlayedLayout)
 	        .addLayout(GUI::ThemeLayout::kLayoutVertical)
 	            .addPadding(0, 0, 0, 0)
 	            .addWidget("OnScreenControl", "Checkbox")
-	            .addWidget("TouchpadMode", "Checkbox");
-	if (_domain.equalsIgnoreCase(Common::ConfigManager::kApplicationDomain)) {
+				.addWidget("PreferredTouchModeText", "", -1, layouts.getVar("Globals.Line.Height"));
+
+	if (inAppDomain) {
+		layouts.addLayout(GUI::ThemeLayout::kLayoutHorizontal)
+			.addPadding(0, 0, 0, 0)
+			.addWidget("TMMenusText", "OptionsLabel")
+			.addWidget("TMMenus", "PopUp")
+		.closeLayout();
+	}
+	layouts.addLayout(GUI::ThemeLayout::kLayoutHorizontal)
+			.addPadding(0, 0, 0, 0)
+			.addWidget("TM2DGamesText", "OptionsLabel")
+			.addWidget("TM2DGames", "PopUp")
+		.closeLayout()
+		.addLayout(GUI::ThemeLayout::kLayoutHorizontal)
+			.addPadding(0, 0, 0, 0)
+			.addWidget("TM3DGamesText", "OptionsLabel")
+			.addWidget("TM3DGames", "PopUp")
+		.closeLayout();
+	if (inAppDomain) {
 		layouts.addWidget("SAFRevokePermsControl", "Checkbox");
 	}
 	layouts.closeLayout()
 	    .closeDialog();
 }
 
+uint32 AndroidOptionsWidget::loadTouchMode(const Common::String &setting, bool acceptDefault, uint32 defaultValue) {
+	if (!acceptDefault || ConfMan.hasKey(setting, _domain)) {
+		Common::String preferredTouchMode = ConfMan.get(setting, _domain);
+		if (preferredTouchMode == "mouse") {
+			return kTouchModeMouse;
+		} else if (preferredTouchMode == "gamepad") {
+			return kTouchModeGamepad;
+		} else if (preferredTouchMode == "touchpad") {
+			return kTouchModeTouchpad;
+		} else {
+			return defaultValue;
+		}
+	} else {
+		return kTouchModeDefault;
+	}
+}
+
 void AndroidOptionsWidget::load() {
+	const bool inAppDomain = _domain.equalsIgnoreCase(Common::ConfigManager::kApplicationDomain);
+
 	_onscreenCheckbox->setState(ConfMan.getBool("onscreen_control", _domain));
-	_touchpadCheckbox->setState(ConfMan.getBool("touchpad_mouse_mode", _domain));
-	if (_domain.equalsIgnoreCase(Common::ConfigManager::kApplicationDomain)) {
+
+	// When in application domain, we don't have default entry so we must have a value
+	if (inAppDomain) {
+		_preferredTMMenusPopUp->setSelectedTag(loadTouchMode("touch_mode_menus", !inAppDomain, kTouchModeMouse));
+	}
+	_preferredTM2DGamesPopUp->setSelectedTag(loadTouchMode("touch_mode_2d_games", !inAppDomain, kTouchModeTouchpad));
+	_preferredTM3DGamesPopUp->setSelectedTag(loadTouchMode("touch_mode_3d_games", !inAppDomain, kTouchModeGamepad));
+
+	if (inAppDomain) {
 		_onscreenSAFRevokeCheckbox->setState(ConfMan.getBool("onscreen_saf_revoke_btn", _domain));
 	}
 }
 
+void AndroidOptionsWidget::saveTouchMode(const Common::String &setting, uint32 touchMode) {
+	switch (touchMode) {
+	case kTouchModeTouchpad:
+		ConfMan.set(setting, "touchpad", _domain);
+		break;
+	case kTouchModeMouse:
+		ConfMan.set(setting, "mouse", _domain);
+		break;
+	case kTouchModeGamepad:
+		ConfMan.set(setting, "gamepad", _domain);
+		break;
+	default:
+		// default
+		ConfMan.removeKey(setting, _domain);
+		break;
+	}
+}
+
 bool AndroidOptionsWidget::save() {
+	const bool inAppDomain = _domain.equalsIgnoreCase(Common::ConfigManager::kApplicationDomain);
+
 	if (_enabled) {
 		ConfMan.setBool("onscreen_control", _onscreenCheckbox->getState(), _domain);
-		ConfMan.setBool("touchpad_mouse_mode", _touchpadCheckbox->getState(), _domain);
-		if (_domain.equalsIgnoreCase(Common::ConfigManager::kApplicationDomain)) {
+
+		if (inAppDomain) {
+			saveTouchMode("touch_mode_menus", _preferredTMMenusPopUp->getSelectedTag());
+		}
+		saveTouchMode("touch_mode_2d_games", _preferredTM2DGamesPopUp->getSelectedTag());
+		saveTouchMode("touch_mode_3d_games", _preferredTM3DGamesPopUp->getSelectedTag());
+
+		if (inAppDomain) {
 			ConfMan.setBool("onscreen_saf_revoke_btn", _onscreenSAFRevokeCheckbox->getState(), _domain);
 		}
 	} else {
 		ConfMan.removeKey("onscreen_control", _domain);
-		ConfMan.removeKey("touchpad_mouse_mode", _domain);
-		if (_domain.equalsIgnoreCase(Common::ConfigManager::kApplicationDomain)) {
+
+		if (inAppDomain) {
+			ConfMan.removeKey("touch_mode_menus", _domain);
+		}
+		ConfMan.removeKey("touch_mode_2d_games", _domain);
+		ConfMan.removeKey("touch_mode_3d_games", _domain);
+
+		if (inAppDomain) {
 			ConfMan.removeKey("onscreen_saf_revoke_btn", _domain);
 		}
 	}
@@ -121,16 +251,29 @@ bool AndroidOptionsWidget::save() {
 
 bool AndroidOptionsWidget::hasKeys() {
 	return ConfMan.hasKey("onscreen_control", _domain) ||
-	       ConfMan.hasKey("touchpad_mouse_mode", _domain) ||
+	       (_domain.equalsIgnoreCase(Common::ConfigManager::kApplicationDomain) && ConfMan.hasKey("touch_mode_menus", _domain)) ||
+	       ConfMan.hasKey("touch_mode_2d_games", _domain) ||
+	       ConfMan.hasKey("touch_mode_3d_games", _domain) ||
 	       (_domain.equalsIgnoreCase(Common::ConfigManager::kApplicationDomain) && ConfMan.hasKey("onscreen_saf_revoke_btn", _domain));
 }
 
 void AndroidOptionsWidget::setEnabled(bool e) {
+	const bool inAppDomain = _domain.equalsIgnoreCase(Common::ConfigManager::kApplicationDomain);
+
 	_enabled = e;
 
 	_onscreenCheckbox->setEnabled(e);
-	_touchpadCheckbox->setEnabled(e);
-	if (_domain.equalsIgnoreCase(Common::ConfigManager::kApplicationDomain)) {
+
+	if (inAppDomain) {
+		_preferredTMMenusDesc->setEnabled(e);
+		_preferredTMMenusPopUp->setEnabled(e);
+	}
+	_preferredTM2DGamesDesc->setEnabled(e);
+	_preferredTM2DGamesPopUp->setEnabled(e);
+	_preferredTM3DGamesDesc->setEnabled(e);
+	_preferredTM3DGamesPopUp->setEnabled(e);
+
+	if (inAppDomain) {
 		_onscreenSAFRevokeCheckbox->setEnabled(e);
 	}
 }
@@ -142,12 +285,40 @@ GUI::OptionsContainerWidget *OSystem_Android::buildBackendOptionsWidget(GUI::Gui
 
 void OSystem_Android::registerDefaultSettings(const Common::String &target) const {
 	ConfMan.registerDefault("onscreen_control", true);
-	ConfMan.registerDefault("touchpad_mouse_mode", true);
+	ConfMan.registerDefault("touch_mode_menus", "mouse");
+	ConfMan.registerDefault("touch_mode_2d_games", "touchpad");
+	ConfMan.registerDefault("touch_mode_3d_games", "gamepad");
 	ConfMan.registerDefault("onscreen_saf_revoke_btn", false);
 }
 
+void OSystem_Android::applyTouchSettings(bool _3dMode, bool overlayShown) {
+	Common::String setting;
+	int defaultMode;
+
+	if (overlayShown) {
+		setting = "touch_mode_menus";
+		defaultMode = TOUCH_MODE_MOUSE;
+	} else if (_3dMode) {
+		setting = "touch_mode_3d_games";
+		defaultMode = TOUCH_MODE_GAMEPAD;
+	} else {
+		setting = "touch_mode_2d_games";
+		defaultMode = TOUCH_MODE_TOUCHPAD;
+	}
+
+	Common::String preferredTouchMode = ConfMan.get(setting);
+	if (preferredTouchMode == "mouse") {
+		JNI::setTouchMode(TOUCH_MODE_MOUSE);
+	} else if (preferredTouchMode == "gamepad") {
+		JNI::setTouchMode(TOUCH_MODE_GAMEPAD);
+	} else if (preferredTouchMode == "touchpad") {
+		JNI::setTouchMode(TOUCH_MODE_TOUCHPAD);
+	} else {
+		JNI::setTouchMode(defaultMode);
+	}
+}
+
 void OSystem_Android::applyBackendSettings() {
 	JNI::showKeyboardControl(ConfMan.getBool("onscreen_control"));
 	JNI::showSAFRevokePermsControl(ConfMan.getBool("onscreen_saf_revoke_btn"));
-	_touchpad_mode = ConfMan.getBool("touchpad_mouse_mode");
 }
diff --git a/backends/platform/android/org/scummvm/scummvm/ScummVM.java b/backends/platform/android/org/scummvm/scummvm/ScummVM.java
index 1ff62d65f42..83b30c7f7cd 100644
--- a/backends/platform/android/org/scummvm/scummvm/ScummVM.java
+++ b/backends/platform/android/org/scummvm/scummvm/ScummVM.java
@@ -58,6 +58,7 @@ public abstract class ScummVM implements SurfaceHolder.Callback, Runnable {
 	final public native void pushEvent(int type, int arg1, int arg2, int arg3,
 										int arg4, int arg5, int arg6);
 	// Update the 3D touch controls
+	final public native void setupTouchMode(int oldValue, int newValue);
 	final public native void updateTouch(int action, int ptr, int x, int y);
 
 	final public native String getNativeVersionInfo();
@@ -74,8 +75,8 @@ public abstract class ScummVM implements SurfaceHolder.Callback, Runnable {
 	abstract protected void showVirtualKeyboard(boolean enable);
 	abstract protected void showKeyboardControl(boolean enable);
 	abstract protected Bitmap getBitmapResource(int resource);
-	abstract protected void setTouch3DMode(boolean touch3DMode);
-	abstract protected boolean getTouch3DMode();
+	abstract protected void setTouchMode(int touchMode);
+	abstract protected int getTouchMode();
 	abstract protected void showSAFRevokePermsControl(boolean enable);
 	abstract protected String[] getSysArchives();
 	abstract protected String[] getAllStorageLocations();
diff --git a/backends/platform/android/org/scummvm/scummvm/ScummVMActivity.java b/backends/platform/android/org/scummvm/scummvm/ScummVMActivity.java
index 18b537643ee..9e21ba67058 100644
--- a/backends/platform/android/org/scummvm/scummvm/ScummVMActivity.java
+++ b/backends/platform/android/org/scummvm/scummvm/ScummVMActivity.java
@@ -118,7 +118,7 @@ public class ScummVMActivity extends Activity implements OnKeyboardVisibilityLis
 	FrameLayout _videoLayout = null;
 
 	private EditableSurfaceView _main_surface = null;
-	private ImageView _toggleGamepadBtnIcon = null;
+	private ImageView _toggleTouchModeBtnIcon = null;
 	private ImageView _toggleKeyboardBtnIcon = null;
 	private ImageView _openMenuBtnIcon = null;
 	private ImageView _revokeSafPermissionsBtnIcon = null;
@@ -570,14 +570,33 @@ public class ScummVMActivity extends Activity implements OnKeyboardVisibilityLis
 	// ---------------------------------------------------------------------------------------------------------------------------
 	//
 
-	public final View.OnClickListener gamepadBtnOnClickListener = new View.OnClickListener() {
+	protected void setupTouchModeBtn(final int touchMode) {
+		int resId;
+
+		switch(touchMode) {
+		case ScummVMEventsBase.TOUCH_MODE_TOUCHPAD:
+			resId = R.drawable.ic_action_touchpad;
+			break;
+		case ScummVMEventsBase.TOUCH_MODE_MOUSE:
+			resId = R.drawable.ic_action_mouse;
+			break;
+		case ScummVMEventsBase.TOUCH_MODE_GAMEPAD:
+			resId = R.drawable.ic_action_gamepad;
+			break;
+		default:
+			throw new IllegalArgumentException("Invalid touchMode");
+		}
+
+		_toggleTouchModeBtnIcon.setImageResource(resId);
+	}
+
+	public final View.OnClickListener touchModeBtnOnClickListener = new View.OnClickListener() {
 		@Override
 		public void onClick(View v) {
 			runOnUiThread(new Runnable() {
 				public void run() {
-					boolean touch3DMode = !_events.getTouch3DMode();
-					_events.setTouch3DMode(touch3DMode);
-					_toggleGamepadBtnIcon.setImageResource(touch3DMode ? R.drawable.ic_action_mouse : R.drawable.ic_action_gamepad);
+					int newTouchMode = _events.nextTouchMode();
+					setupTouchModeBtn(newTouchMode);
 				}
 			});
 		}
@@ -739,21 +758,21 @@ public class ScummVMActivity extends Activity implements OnKeyboardVisibilityLis
 		}
 
 		@Override
-		protected void setTouch3DMode(final boolean touch3DMode) {
-			if (_events.getTouch3DMode() == touch3DMode) {
+		protected void setTouchMode(final int touchMode) {
+			if (_events.getTouchMode() == touchMode) {
 				return;
 			}
 			runOnUiThread(new Runnable() {
 				public void run() {
-					_events.setTouch3DMode(touch3DMode);
-					_toggleGamepadBtnIcon.setImageResource(touch3DMode ? R.drawable.ic_action_mouse : R.drawable.ic_action_gamepad);
+					_events.setTouchMode(touchMode);
+					setupTouchModeBtn(touchMode);
 				}
 			});
 		}
 
 		@Override
-		protected boolean getTouch3DMode() {
-			return _events.getTouch3DMode();
+		protected int getTouchMode() {
+			return _events.getTouchMode();
 		}
 
 		@Override
@@ -1009,10 +1028,9 @@ public class ScummVMActivity extends Activity implements OnKeyboardVisibilityLis
 		_videoLayout.addView(buttonLayout, buttonLayoutParams);
 		_videoLayout.bringChildToFront(buttonLayout);
 
-		_toggleGamepadBtnIcon = new ImageView(this);
-		_toggleGamepadBtnIcon.setImageResource(R.drawable.ic_action_gamepad);
-		buttonLayout.addView(_toggleGamepadBtnIcon, new FrameLayout.LayoutParams(FrameLayout.LayoutParams.WRAP_CONTENT, FrameLayout.LayoutParams.WRAP_CONTENT));
-		buttonLayout.bringChildToFront(_toggleGamepadBtnIcon);
+		_toggleTouchModeBtnIcon = new ImageView(this);
+		buttonLayout.addView(_toggleTouchModeBtnIcon, new FrameLayout.LayoutParams(FrameLayout.LayoutParams.WRAP_CONTENT, FrameLayout.LayoutParams.WRAP_CONTENT));
+		buttonLayout.bringChildToFront(_toggleTouchModeBtnIcon);
 
 		_toggleKeyboardBtnIcon = new ImageView(this);
 		_toggleKeyboardBtnIcon.setImageResource(R.drawable.ic_action_keyboard);
@@ -1121,9 +1139,11 @@ public class ScummVMActivity extends Activity implements OnKeyboardVisibilityLis
 				_events = new ScummVMEventsBase(this, _scummvm, _mouseHelper);
 			}
 
+			setupTouchModeBtn(_events.getTouchMode());
+
 			// On screen button listener
 			//findViewById(R.id.show_keyboard).setOnClickListener(keyboardBtnOnClickListener);
-			_toggleGamepadBtnIcon.setOnClickListener(gamepadBtnOnClickListener);
+			_toggleTouchModeBtnIcon.setOnClickListener(touchModeBtnOnClickListener);
 			_toggleKeyboardBtnIcon.setOnClickListener(keyboardBtnOnClickListener);
 			_openMenuBtnIcon.setOnClickListener(menuBtnOnClickListener);
 			_revokeSafPermissionsBtnIcon.setOnClickListener(revokeSafPermissionsBtnOnClickListener);
@@ -1391,8 +1411,8 @@ public class ScummVMActivity extends Activity implements OnKeyboardVisibilityLis
 			_openMenuBtnIcon.setVisibility(show ? View.VISIBLE : View.GONE);
 		}
 
-		if (_toggleGamepadBtnIcon != null ) {
-			_toggleGamepadBtnIcon.setVisibility(show ? View.VISIBLE : View.GONE);
+		if (_toggleTouchModeBtnIcon != null ) {
+			_toggleTouchModeBtnIcon.setVisibility(show ? View.VISIBLE : View.GONE);
 		}
 	}
 
diff --git a/backends/platform/android/org/scummvm/scummvm/ScummVMEventsBase.java b/backends/platform/android/org/scummvm/scummvm/ScummVMEventsBase.java
index d1dba19c3af..ffbe79496a1 100644
--- a/backends/platform/android/org/scummvm/scummvm/ScummVMEventsBase.java
+++ b/backends/platform/android/org/scummvm/scummvm/ScummVMEventsBase.java
@@ -55,6 +55,11 @@ public class ScummVMEventsBase implements
 	public static final int JACTION_UP = 2;
 	public static final int JACTION_CANCEL = 3;
 
+	public static final int TOUCH_MODE_TOUCHPAD = 0;
+	public static final int TOUCH_MODE_MOUSE = 1;
+	public static final int TOUCH_MODE_GAMEPAD = 2;
+	public static final int TOUCH_MODE_MAX = 3;
+
 	final protected Context _context;
 	final protected ScummVM _scummvm;
 	final protected GestureDetector _gd;
@@ -62,7 +67,7 @@ public class ScummVMEventsBase implements
 	final protected MouseHelper _mouseHelper;
 	final protected MultitouchHelper _multitouchHelper;
 
-	protected boolean _touch3DMode;
+	protected int _touchMode;
 
 	// Custom handler code (to avoid mem leaks, see warning "This Handler Class Should Be Static Or Leaks Might Occur”) based on:
 	// https://stackoverflow.com/a/27826094
@@ -142,15 +147,36 @@ public class ScummVMEventsBase implements
 		}
 	}
 
-	final public boolean getTouch3DMode() {
-		return _touch3DMode;
+	final public int getTouchMode() {
+		return _touchMode;
 	}
 
-	final public void setTouch3DMode(boolean touch3DMode) {
-		if (_touch3DMode != touch3DMode && !touch3DMode) {
+	final public void setTouchMode(int touchMode) {
+		assert (touchMode >= 0) && (touchMode < TOUCH_MODE_MAX);
+
+		if (_touchMode == touchMode) {
+			return;
+		}
+
+		if (_touchMode == TOUCH_MODE_GAMEPAD) {
+			// We were in gamepad mode and we leave it
 			_scummvm.updateTouch(JACTION_CANCEL, 0, 0, 0);
 		}
-		_touch3DMode = touch3DMode;
+		int oldTouchMode = _touchMode;
+		_touchMode = touchMode;
+		_scummvm.setupTouchMode(oldTouchMode, _touchMode);
+	}
+
+	final public int nextTouchMode() {
+		if (_touchMode == TOUCH_MODE_GAMEPAD) {
+			// We leave gamepad mode
+			_scummvm.updateTouch(JACTION_CANCEL, 0, 0, 0);
+		}
+		int oldTouchMode = _touchMode;
+		_touchMode = (_touchMode + 1) % TOUCH_MODE_MAX;
+		_scummvm.setupTouchMode(oldTouchMode, _touchMode);
+
+		return _touchMode;
 	}
 
 	public void clearEventHandler() {
@@ -477,7 +503,7 @@ public class ScummVMEventsBase implements
 			}
 		}
 
-		if (_touch3DMode) {
+		if (_touchMode == TOUCH_MODE_GAMEPAD) {
 			switch (event.getActionMasked()) {
 				case MotionEvent.ACTION_DOWN:
 				case MotionEvent.ACTION_POINTER_DOWN: {
@@ -528,7 +554,7 @@ public class ScummVMEventsBase implements
 	@Override
 	final public boolean onDown(MotionEvent e) {
 //		Log.d(ScummVM.LOG_TAG, "SCUMMV-EVENTS-BASE - onDOWN MotionEvent");
-		if (!_touch3DMode) {
+		if (_touchMode != TOUCH_MODE_GAMEPAD) {
 			_scummvm.pushEvent(JE_DOWN, (int)e.getX(), (int)e.getY(), 0, 0, 0, 0);
 		}
 		return true;
@@ -553,7 +579,7 @@ public class ScummVMEventsBase implements
 	final public boolean onScroll(MotionEvent e1, MotionEvent e2,
 									float distanceX, float distanceY) {
 //		Log.d(ScummVM.LOG_TAG, "onScroll");
-		if (!_touch3DMode) {
+		if (_touchMode != TOUCH_MODE_GAMEPAD) {
 			// typical use:
 			// - move mouse cursor around (most traditional point and click games)
 			// - mouse look (eg. Myst 3)
@@ -570,7 +596,7 @@ public class ScummVMEventsBase implements
 	@Override
 	final public boolean onSingleTapUp(MotionEvent e) {
 //		Log.d(ScummVM.LOG_TAG, "onSingleTapUp");
-		if (!_touch3DMode) {
+		if (_touchMode != TOUCH_MODE_GAMEPAD) {
 			_scummvm.pushEvent(JE_TAP, (int)e.getX(), (int)e.getY(),
 							(int)(e.getEventTime() - e.getDownTime()), 0, 0, 0);
 		}
@@ -598,7 +624,7 @@ public class ScummVMEventsBase implements
 //		} else {
 //			Log.d(ScummVM.LOG_TAG, "onDoubleTapEvent UNKNOWN!!!!");
 //		}
-		if (!_touch3DMode) {
+		if (_touchMode != TOUCH_MODE_GAMEPAD) {
 			_scummvm.pushEvent(JE_DOUBLE_TAP, (int)e.getX(), (int)e.getY(), e.getAction(), 0, 0, 0);
 		}
 		return true;
diff --git a/dists/android/res/drawable/ic_action_touchpad.xml b/dists/android/res/drawable/ic_action_touchpad.xml
new file mode 100644
index 00000000000..3959ccb6f8e
--- /dev/null
+++ b/dists/android/res/drawable/ic_action_touchpad.xml
@@ -0,0 +1,17 @@
+<vector
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    android:name="vector"
+    android:width="48dp"
+    android:height="48dp"
+    android:viewportWidth="48"
+    android:viewportHeight="48"
+    android:alpha="0.5">
+  <path
+      android:fillColor="#ffffff"
+      android:pathData="M37.78,29.5l-8.18,-4.08c-0.56,-0.28 -1.16,-0.42 -1.78,-0.42H26.0v-12.0C26.0,11.34 24.66,10.0 23.0,10.0S20.0,11.34 20.0,13.0v21.48L13.5,33.0c-0.66,-0.14 -1.36,0.06 -1.84,0.56L10.0,35.24l9.08,9.58C19.84,45.58 21.36,46.0 22.42,46.0h12.32c2.0,0.0 3.68,-1.46 3.96,-3.44l1.26,-8.92C40.2,31.94 39.32,30.28 37.78,29.5z"
+	  android:strokeWidth="1"/>
+  <path
+      android:fillColor="#ffffff"
+      android:pathData="M40.26,7.74C37.38,4.34 31.2,2.0 24.0,2.0S10.62,4.34 7.74,7.74L4.0,4.0v10.0h10.0L9.86,9.86c2.0,-2.58 7.4,-4.86 14.14,-4.86s12.14,2.28 14.14,4.86L34.0,14.0h10.0V4.0L40.26,7.74z"
+	  android:strokeWidth="1"/>
+</vector>


Commit: bbcdda6c7fc0a78b7e6ad0ae5f844de42755d7a4
    https://github.com/scummvm/scummvm/commit/bbcdda6c7fc0a78b7e6ad0ae5f844de42755d7a4
Author: Le Philousophe (lephilousophe at users.noreply.github.com)
Date: 2022-06-14T00:08:04+03:00

Commit Message:
ANDROID: Merge touch mode and toggle keyboard buttons

A long press on the button shows the keyboard

Changed paths:
    backends/platform/android/org/scummvm/scummvm/ScummVMActivity.java


diff --git a/backends/platform/android/org/scummvm/scummvm/ScummVMActivity.java b/backends/platform/android/org/scummvm/scummvm/ScummVMActivity.java
index 9e21ba67058..88cfae76437 100644
--- a/backends/platform/android/org/scummvm/scummvm/ScummVMActivity.java
+++ b/backends/platform/android/org/scummvm/scummvm/ScummVMActivity.java
@@ -118,8 +118,7 @@ public class ScummVMActivity extends Activity implements OnKeyboardVisibilityLis
 	FrameLayout _videoLayout = null;
 
 	private EditableSurfaceView _main_surface = null;
-	private ImageView _toggleTouchModeBtnIcon = null;
-	private ImageView _toggleKeyboardBtnIcon = null;
+	private ImageView _toggleTouchModeKeyboardBtnIcon = null;
 	private ImageView _openMenuBtnIcon = null;
 	private ImageView _revokeSafPermissionsBtnIcon = null;
 
@@ -142,7 +141,6 @@ public class ScummVMActivity extends Activity implements OnKeyboardVisibilityLis
 		super.onConfigurationChanged(newConfig);
 
 		final boolean hwKeyboard = isHWKeyboardConnected();
-		_toggleKeyboardBtnIcon.setVisibility(hwKeyboard ? View.GONE : View.VISIBLE);
 		if (hwKeyboard) {
 			hideScreenKeyboard();
 		}
@@ -520,6 +518,7 @@ public class ScummVMActivity extends Activity implements OnKeyboardVisibilityLis
 				//Log.d(ScummVM.LOG_TAG, "showScreenKeyboard - captureMouse(false)");
 				_main_surface.captureMouse(false);
 				//_main_surface.showSystemMouseCursor(true);
+				setupTouchModeBtn(_events.getTouchMode());
 				return;
 			}
 			//Log.d(ScummVM.LOG_TAG, "showScreenKeyboard: YOU SHOULD NOT SEE ME!!!");
@@ -541,6 +540,7 @@ public class ScummVMActivity extends Activity implements OnKeyboardVisibilityLis
 				//Log.d(ScummVM.LOG_TAG, "hideScreenKeyboard - captureMouse(true)");
 				_main_surface.captureMouse(true);
 				//_main_surface.showSystemMouseCursor(false);
+				setupTouchModeBtn(_events.getTouchMode());
 			}
 		}
 	}
@@ -573,43 +573,55 @@ public class ScummVMActivity extends Activity implements OnKeyboardVisibilityLis
 	protected void setupTouchModeBtn(final int touchMode) {
 		int resId;
 
-		switch(touchMode) {
-		case ScummVMEventsBase.TOUCH_MODE_TOUCHPAD:
-			resId = R.drawable.ic_action_touchpad;
-			break;
-		case ScummVMEventsBase.TOUCH_MODE_MOUSE:
-			resId = R.drawable.ic_action_mouse;
-			break;
-		case ScummVMEventsBase.TOUCH_MODE_GAMEPAD:
-			resId = R.drawable.ic_action_gamepad;
-			break;
-		default:
-			throw new IllegalArgumentException("Invalid touchMode");
-		}
-
-		_toggleTouchModeBtnIcon.setImageResource(resId);
+		if (isScreenKeyboardShown()) {
+			resId = R.drawable.ic_action_keyboard;
+		} else {
+			switch(touchMode) {
+			case ScummVMEventsBase.TOUCH_MODE_TOUCHPAD:
+				resId = R.drawable.ic_action_touchpad;
+				break;
+			case ScummVMEventsBase.TOUCH_MODE_MOUSE:
+				resId = R.drawable.ic_action_mouse;
+				break;
+			case ScummVMEventsBase.TOUCH_MODE_GAMEPAD:
+				resId = R.drawable.ic_action_gamepad;
+				break;
+			default:
+				throw new IllegalArgumentException("Invalid touchMode");
+			}
+		}
+
+		_toggleTouchModeKeyboardBtnIcon.setImageResource(resId);
 	}
 
-	public final View.OnClickListener touchModeBtnOnClickListener = new View.OnClickListener() {
+	public final View.OnClickListener touchModeKeyboardBtnOnClickListener = new View.OnClickListener() {
 		@Override
 		public void onClick(View v) {
 			runOnUiThread(new Runnable() {
 				public void run() {
-					int newTouchMode = _events.nextTouchMode();
-					setupTouchModeBtn(newTouchMode);
+					// On normal click, hide keyboard if it is shown
+					// Else, change touch mode
+					if (isScreenKeyboardShown()) {
+						hideScreenKeyboard();
+					} else {
+						int newTouchMode = _events.nextTouchMode();
+						setupTouchModeBtn(newTouchMode);
+					}
 				}
 			});
 		}
 	};
 
-	public final View.OnClickListener keyboardBtnOnClickListener = new View.OnClickListener() {
+	public final View.OnLongClickListener touchModeKeyboardBtnOnLongClickListener = new View.OnLongClickListener() {
 		@Override
-		public void onClick(View v) {
+		public boolean onLongClick(View v) {
 			runOnUiThread(new Runnable() {
 				public void run() {
+					// On long click, toggle screen keyboard (if there isn't any HW)
 					toggleScreenKeyboard();
 				}
 			});
+			return true;
 		}
 	};
 
@@ -1028,14 +1040,9 @@ public class ScummVMActivity extends Activity implements OnKeyboardVisibilityLis
 		_videoLayout.addView(buttonLayout, buttonLayoutParams);
 		_videoLayout.bringChildToFront(buttonLayout);
 
-		_toggleTouchModeBtnIcon = new ImageView(this);
-		buttonLayout.addView(_toggleTouchModeBtnIcon, new FrameLayout.LayoutParams(FrameLayout.LayoutParams.WRAP_CONTENT, FrameLayout.LayoutParams.WRAP_CONTENT));
-		buttonLayout.bringChildToFront(_toggleTouchModeBtnIcon);
-
-		_toggleKeyboardBtnIcon = new ImageView(this);
-		_toggleKeyboardBtnIcon.setImageResource(R.drawable.ic_action_keyboard);
-		buttonLayout.addView(_toggleKeyboardBtnIcon, new FrameLayout.LayoutParams(FrameLayout.LayoutParams.WRAP_CONTENT, FrameLayout.LayoutParams.WRAP_CONTENT));
-		buttonLayout.bringChildToFront(_toggleKeyboardBtnIcon);
+		_toggleTouchModeKeyboardBtnIcon = new ImageView(this);
+		buttonLayout.addView(_toggleTouchModeKeyboardBtnIcon, new FrameLayout.LayoutParams(FrameLayout.LayoutParams.WRAP_CONTENT, FrameLayout.LayoutParams.WRAP_CONTENT));
+		buttonLayout.bringChildToFront(_toggleTouchModeKeyboardBtnIcon);
 
 		_openMenuBtnIcon = new ImageView(this);
 		_openMenuBtnIcon.setImageResource(R.drawable.ic_action_menu);
@@ -1143,8 +1150,8 @@ public class ScummVMActivity extends Activity implements OnKeyboardVisibilityLis
 
 			// On screen button listener
 			//findViewById(R.id.show_keyboard).setOnClickListener(keyboardBtnOnClickListener);
-			_toggleTouchModeBtnIcon.setOnClickListener(touchModeBtnOnClickListener);
-			_toggleKeyboardBtnIcon.setOnClickListener(keyboardBtnOnClickListener);
+			_toggleTouchModeKeyboardBtnIcon.setOnClickListener(touchModeKeyboardBtnOnClickListener);
+			_toggleTouchModeKeyboardBtnIcon.setOnLongClickListener(touchModeKeyboardBtnOnLongClickListener);
 			_openMenuBtnIcon.setOnClickListener(menuBtnOnClickListener);
 			_revokeSafPermissionsBtnIcon.setOnClickListener(revokeSafPermissionsBtnOnClickListener);
 
@@ -1398,21 +1405,12 @@ public class ScummVMActivity extends Activity implements OnKeyboardVisibilityLis
 	// Show or hide the semi-transparent onscreen controls
 	// Called by the override of showKeyboardControl()
 	private void showToggleKeyboardBtnIcon(boolean show) {
-		//ImageView keyboardBtn = findViewById(R.id.show_keyboard);
-		if (_toggleKeyboardBtnIcon != null ) {
-			if (show && !isHWKeyboardConnected()) {
-				_toggleKeyboardBtnIcon.setVisibility(View.VISIBLE);
-			} else {
-				_toggleKeyboardBtnIcon.setVisibility(View.GONE);
-			}
-		}
-
 		if (_openMenuBtnIcon != null ) {
 			_openMenuBtnIcon.setVisibility(show ? View.VISIBLE : View.GONE);
 		}
 
-		if (_toggleTouchModeBtnIcon != null ) {
-			_toggleTouchModeBtnIcon.setVisibility(show ? View.VISIBLE : View.GONE);
+		if (_toggleTouchModeKeyboardBtnIcon != null ) {
+			_toggleTouchModeKeyboardBtnIcon.setVisibility(show ? View.VISIBLE : View.GONE);
 		}
 	}
 




More information about the Scummvm-git-logs mailing list