Android: Implement context menu backend interface
Implements interface for context menu in QtActivityDelegate and QtEmbeddedDelegate. Task-number: QTBUG-118874 Change-Id: I799ad1aca4beb789b87830b720abf0963ca09274 Reviewed-by: Tinja Paavoseppä <tinja.paavoseppa@qt.io>
This commit is contained in:
parent
2322c71cc7
commit
9319576a59
@ -43,6 +43,7 @@ set(java_sources
|
|||||||
src/org/qtproject/qt/android/BackendRegister.java
|
src/org/qtproject/qt/android/BackendRegister.java
|
||||||
src/org/qtproject/qt/android/QtWindowInterface.java
|
src/org/qtproject/qt/android/QtWindowInterface.java
|
||||||
src/org/qtproject/qt/android/QtAccessibilityInterface.java
|
src/org/qtproject/qt/android/QtAccessibilityInterface.java
|
||||||
|
src/org/qtproject/qt/android/QtMenuInterface.java
|
||||||
)
|
)
|
||||||
|
|
||||||
qt_internal_add_jar(Qt${QtBase_VERSION_MAJOR}Android
|
qt_internal_add_jar(Qt${QtBase_VERSION_MAJOR}Android
|
||||||
|
@ -31,8 +31,8 @@ import android.widget.PopupMenu;
|
|||||||
|
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
|
|
||||||
class QtActivityDelegate
|
class QtActivityDelegate extends QtActivityDelegateBase
|
||||||
extends QtActivityDelegateBase implements QtWindowInterface, QtAccessibilityInterface
|
implements QtWindowInterface, QtAccessibilityInterface, QtMenuInterface
|
||||||
{
|
{
|
||||||
private static final String QtTAG = "QtActivityDelegate";
|
private static final String QtTAG = "QtActivityDelegate";
|
||||||
|
|
||||||
@ -61,6 +61,8 @@ class QtActivityDelegate
|
|||||||
(QtWindowInterface)QtActivityDelegate.this);
|
(QtWindowInterface)QtActivityDelegate.this);
|
||||||
BackendRegister.registerBackend(QtAccessibilityInterface.class,
|
BackendRegister.registerBackend(QtAccessibilityInterface.class,
|
||||||
(QtAccessibilityInterface)QtActivityDelegate.this);
|
(QtAccessibilityInterface)QtActivityDelegate.this);
|
||||||
|
BackendRegister.registerBackend(QtMenuInterface.class,
|
||||||
|
(QtMenuInterface)QtActivityDelegate.this);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -70,6 +72,7 @@ class QtActivityDelegate
|
|||||||
m_backendsRegistered = false;
|
m_backendsRegistered = false;
|
||||||
BackendRegister.unregisterBackend(QtWindowInterface.class);
|
BackendRegister.unregisterBackend(QtWindowInterface.class);
|
||||||
BackendRegister.unregisterBackend(QtAccessibilityInterface.class);
|
BackendRegister.unregisterBackend(QtAccessibilityInterface.class);
|
||||||
|
BackendRegister.unregisterBackend(QtMenuInterface.class);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -290,27 +293,25 @@ class QtActivityDelegate
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@UsedFromNativeCode
|
// QtMenuInterface implementation begin
|
||||||
|
@Override
|
||||||
public void resetOptionsMenu()
|
public void resetOptionsMenu()
|
||||||
{
|
{
|
||||||
QtNative.runAction(() -> m_activity.invalidateOptionsMenu());
|
QtNative.runAction(() -> m_activity.invalidateOptionsMenu());
|
||||||
}
|
}
|
||||||
|
|
||||||
@UsedFromNativeCode
|
@Override
|
||||||
public void openOptionsMenu()
|
public void openOptionsMenu()
|
||||||
{
|
{
|
||||||
QtNative.runAction(() -> m_activity.openOptionsMenu());
|
QtNative.runAction(() -> m_activity.openOptionsMenu());
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean m_contextMenuVisible = false;
|
@Override
|
||||||
|
public void closeContextMenu()
|
||||||
public void onCreatePopupMenu(Menu menu)
|
|
||||||
{
|
{
|
||||||
QtNative.fillContextMenu(menu);
|
QtNative.runAction(() -> m_activity.closeContextMenu());
|
||||||
m_contextMenuVisible = true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@UsedFromNativeCode
|
|
||||||
@Override
|
@Override
|
||||||
public void openContextMenu(final int x, final int y, final int w, final int h)
|
public void openContextMenu(final int x, final int y, final int w, final int h)
|
||||||
{
|
{
|
||||||
@ -330,11 +331,14 @@ class QtActivityDelegate
|
|||||||
popup.show();
|
popup.show();
|
||||||
}, 100);
|
}, 100);
|
||||||
}
|
}
|
||||||
|
// QtMenuInterface implementation end
|
||||||
|
|
||||||
@UsedFromNativeCode
|
private boolean m_contextMenuVisible = false;
|
||||||
public void closeContextMenu()
|
|
||||||
|
public void onCreatePopupMenu(Menu menu)
|
||||||
{
|
{
|
||||||
QtNative.runAction(() -> m_activity.closeContextMenu());
|
QtNative.fillContextMenu(menu);
|
||||||
|
m_contextMenuVisible = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -15,15 +15,19 @@ import android.os.Handler;
|
|||||||
import android.os.Looper;
|
import android.os.Looper;
|
||||||
import android.util.DisplayMetrics;
|
import android.util.DisplayMetrics;
|
||||||
import android.util.Log;
|
import android.util.Log;
|
||||||
|
import android.view.Menu;
|
||||||
import android.view.View;
|
import android.view.View;
|
||||||
import android.view.ViewGroup;
|
import android.view.ViewGroup;
|
||||||
|
import android.widget.PopupMenu;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
|
|
||||||
class QtEmbeddedDelegate extends QtActivityDelegateBase
|
class QtEmbeddedDelegate extends QtActivityDelegateBase
|
||||||
implements QtNative.AppStateDetailsListener, QtEmbeddedViewInterface, QtWindowInterface
|
implements QtNative.AppStateDetailsListener, QtEmbeddedViewInterface, QtWindowInterface,
|
||||||
|
QtMenuInterface
|
||||||
{
|
{
|
||||||
|
private static final String QtTAG = "QtEmbeddedDelegate";
|
||||||
// TODO simplistic implementation with one QtView, expand to support multiple views QTBUG-117649
|
// TODO simplistic implementation with one QtView, expand to support multiple views QTBUG-117649
|
||||||
private QtView m_view;
|
private QtView m_view;
|
||||||
private QtNative.ApplicationStateDetails m_stateDetails;
|
private QtNative.ApplicationStateDetails m_stateDetails;
|
||||||
@ -93,9 +97,11 @@ class QtEmbeddedDelegate extends QtActivityDelegateBase
|
|||||||
if (details.isStarted && !m_backendsRegistered) {
|
if (details.isStarted && !m_backendsRegistered) {
|
||||||
m_backendsRegistered = true;
|
m_backendsRegistered = true;
|
||||||
BackendRegister.registerBackend(QtWindowInterface.class, (QtWindowInterface)this);
|
BackendRegister.registerBackend(QtWindowInterface.class, (QtWindowInterface)this);
|
||||||
|
BackendRegister.registerBackend(QtMenuInterface.class, (QtMenuInterface)this);
|
||||||
} else if (!details.isStarted && m_backendsRegistered) {
|
} else if (!details.isStarted && m_backendsRegistered) {
|
||||||
m_backendsRegistered = false;
|
m_backendsRegistered = false;
|
||||||
BackendRegister.unregisterBackend(QtWindowInterface.class);
|
BackendRegister.unregisterBackend(QtWindowInterface.class);
|
||||||
|
BackendRegister.unregisterBackend(QtMenuInterface.class);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -175,4 +181,36 @@ class QtEmbeddedDelegate extends QtActivityDelegateBase
|
|||||||
m_windowLoaded = true;
|
m_windowLoaded = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// QtMenuInterface implementation begin
|
||||||
|
@Override
|
||||||
|
public void resetOptionsMenu() { QtNative.runAction(() -> m_activity.invalidateOptionsMenu()); }
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void openOptionsMenu() { QtNative.runAction(() -> m_activity.openOptionsMenu()); }
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void closeContextMenu() { QtNative.runAction(() -> m_activity.closeContextMenu()); }
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void openContextMenu(final int x, final int y, final int w, final int h)
|
||||||
|
{
|
||||||
|
QtLayout layout = getQtLayout();
|
||||||
|
layout.postDelayed(() -> {
|
||||||
|
final QtEditText focusedEditText = m_inputDelegate.getCurrentQtEditText();
|
||||||
|
if (focusedEditText == null) {
|
||||||
|
Log.w(QtTAG, "No focused view when trying to open context menu");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
layout.setLayoutParams(focusedEditText, new QtLayout.LayoutParams(w, h, x, y), false);
|
||||||
|
PopupMenu popup = new PopupMenu(m_activity, focusedEditText);
|
||||||
|
QtNative.fillContextMenu(popup.getMenu());
|
||||||
|
popup.setOnMenuItemClickListener(menuItem ->
|
||||||
|
m_activity.onContextItemSelected(menuItem));
|
||||||
|
popup.setOnDismissListener(popupMenu ->
|
||||||
|
m_activity.onContextMenuClosed(popupMenu.getMenu()));
|
||||||
|
popup.show();
|
||||||
|
}, 100);
|
||||||
|
}
|
||||||
|
// QtMenuInterface implementation end
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,11 @@
|
|||||||
|
// Copyright (C) 2024 The Qt Company Ltd.
|
||||||
|
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
|
||||||
|
package org.qtproject.qt.android;
|
||||||
|
|
||||||
|
@UsedFromNativeCode
|
||||||
|
interface QtMenuInterface {
|
||||||
|
void resetOptionsMenu();
|
||||||
|
void openOptionsMenu();
|
||||||
|
void closeContextMenu();
|
||||||
|
void openContextMenu(final int x, final int y, final int w, final int h);
|
||||||
|
}
|
@ -20,6 +20,8 @@ QT_BEGIN_NAMESPACE
|
|||||||
|
|
||||||
using namespace QtAndroid;
|
using namespace QtAndroid;
|
||||||
|
|
||||||
|
Q_DECLARE_JNI_CLASS(QtMenuInterface, "org/qtproject/qt/android/QtMenuInterface");
|
||||||
|
|
||||||
namespace QtAndroidMenu
|
namespace QtAndroidMenu
|
||||||
{
|
{
|
||||||
static QList<QAndroidPlatformMenu *> pendingContextMenus;
|
static QList<QAndroidPlatformMenu *> pendingContextMenus;
|
||||||
@ -44,12 +46,14 @@ namespace QtAndroidMenu
|
|||||||
|
|
||||||
void resetMenuBar()
|
void resetMenuBar()
|
||||||
{
|
{
|
||||||
qtActivityDelegate().callMethod<void>("resetOptionsMenu");
|
AndroidBackendRegister *reg = QtAndroid::backendRegister();
|
||||||
|
reg->callInterface<QtJniTypes::QtMenuInterface, void>("resetOptionsMenu");
|
||||||
}
|
}
|
||||||
|
|
||||||
void openOptionsMenu()
|
void openOptionsMenu()
|
||||||
{
|
{
|
||||||
qtActivityDelegate().callMethod<void>("openOptionsMenu");
|
AndroidBackendRegister *reg = QtAndroid::backendRegister();
|
||||||
|
reg->callInterface<QtJniTypes::QtMenuInterface, void>("openOptionsMenu");
|
||||||
}
|
}
|
||||||
|
|
||||||
void showContextMenu(QAndroidPlatformMenu *menu, const QRect &anchorRect)
|
void showContextMenu(QAndroidPlatformMenu *menu, const QRect &anchorRect)
|
||||||
@ -59,16 +63,18 @@ namespace QtAndroidMenu
|
|||||||
pendingContextMenus.append(visibleMenu);
|
pendingContextMenus.append(visibleMenu);
|
||||||
visibleMenu = menu;
|
visibleMenu = menu;
|
||||||
menu->aboutToShow();
|
menu->aboutToShow();
|
||||||
qtActivityDelegate().callMethod<void>("openContextMenu",
|
AndroidBackendRegister *reg = QtAndroid::backendRegister();
|
||||||
anchorRect.x(), anchorRect.y(),
|
reg->callInterface<QtJniTypes::QtMenuInterface, void>("openContextMenu", anchorRect.x(),
|
||||||
anchorRect.width(), anchorRect.height());
|
anchorRect.y(), anchorRect.width(),
|
||||||
|
anchorRect.height());
|
||||||
}
|
}
|
||||||
|
|
||||||
void hideContextMenu(QAndroidPlatformMenu *menu)
|
void hideContextMenu(QAndroidPlatformMenu *menu)
|
||||||
{
|
{
|
||||||
QMutexLocker lock(&visibleMenuMutex);
|
QMutexLocker lock(&visibleMenuMutex);
|
||||||
if (visibleMenu == menu) {
|
if (visibleMenu == menu) {
|
||||||
qtActivityDelegate().callMethod<void>("closeContextMenu");
|
AndroidBackendRegister *reg = QtAndroid::backendRegister();
|
||||||
|
reg->callInterface<QtJniTypes::QtMenuInterface, void>("closeContextMenu");
|
||||||
pendingContextMenus.clear();
|
pendingContextMenus.clear();
|
||||||
} else {
|
} else {
|
||||||
pendingContextMenus.removeOne(menu);
|
pendingContextMenus.removeOne(menu);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user