diff options
author | BogDan Vatra <bogdan@kde.org> | 2014-09-29 13:43:35 +0300 |
---|---|---|
committer | BogDan Vatra <bogdan@kde.org> | 2014-10-01 20:10:58 +0200 |
commit | 3b577dfe798bf5065a2bba4d7095709454aa709c (patch) | |
tree | 14172b58fac4e15662c58dbbd53c5790df48681a /src/plugins/platforms | |
parent | 8ee9774e67edf57d891528749a360a0af8f0c6f7 (diff) |
Use PopupMenu when possible.
On API-11+ we are going to use PopupMenu instead of ContextMenu to show
context menus. A PopupMenu displays a Menu in a modal popup window
anchored to a View. The popup will appear below the anchor view if there
is room, or above it if there is not.
Task-number: QTBUG-39736
Change-Id: Ie412ab0935b868348ce5c8bb0bf53571ffefd582
Reviewed-by: J-P Nurmi <jpnurmi@digia.com>
Reviewed-by: Paul Olav Tvete <paul.tvete@digia.com>
Diffstat (limited to 'src/plugins/platforms')
4 files changed, 49 insertions, 25 deletions
diff --git a/src/plugins/platforms/android/androidjnimenu.cpp b/src/plugins/platforms/android/androidjnimenu.cpp index 8f41d411ab..ecd6fcce72 100644 --- a/src/plugins/platforms/android/androidjnimenu.cpp +++ b/src/plugins/platforms/android/androidjnimenu.cpp @@ -38,9 +38,12 @@ #include "qandroidplatformmenuitem.h" #include <QMutex> -#include <QSet> +#include <QPoint> #include <QQueue> +#include <QRect> +#include <QSet> #include <QWindow> +#include <QtCore/private/qjnihelpers_p.h> QT_BEGIN_NAMESPACE @@ -48,7 +51,7 @@ using namespace QtAndroid; namespace QtAndroidMenu { - static QQueue<QAndroidPlatformMenu *> pendingContextMenus; + static QList<QAndroidPlatformMenu *> pendingContextMenus; static QAndroidPlatformMenu *visibleMenu = 0; static QMutex visibleMenuMutex(QMutex::Recursive); @@ -87,21 +90,25 @@ namespace QtAndroidMenu env.jniEnv->CallStaticVoidMethod(applicationClass(), openOptionsMenuMethodID); } - void showContextMenu(QAndroidPlatformMenu *menu, JNIEnv *env) + void showContextMenu(QAndroidPlatformMenu *menu, const QRect &anchorRect, JNIEnv *env) { QMutexLocker lock(&visibleMenuMutex); - if (visibleMenu) { - pendingContextMenus.enqueue(menu); + if (QtAndroidPrivate::androidSdkVersion() > 10 && + QtAndroidPrivate::androidSdkVersion() < 14 && + anchorRect.isValid()) { + pendingContextMenus.clear(); + } else if (visibleMenu) { + pendingContextMenus.append(visibleMenu); + } + + visibleMenu = menu; + menu->aboutToShow(); + if (env) { + env->CallStaticVoidMethod(applicationClass(), openContextMenuMethodID, anchorRect.x(), anchorRect.y(), anchorRect.width(), anchorRect.height()); } else { - visibleMenu = menu; - menu->aboutToShow(); - if (env) { - env->CallStaticVoidMethod(applicationClass(), openContextMenuMethodID); - } else { - AttachedJNIEnv aenv; - if (aenv.jniEnv) - aenv.jniEnv->CallStaticVoidMethod(applicationClass(), openContextMenuMethodID); - } + AttachedJNIEnv aenv; + if (aenv.jniEnv) + aenv.jniEnv->CallStaticVoidMethod(applicationClass(), openContextMenuMethodID, anchorRect.x(), anchorRect.y(), anchorRect.width(), anchorRect.height()); } } @@ -111,7 +118,8 @@ namespace QtAndroidMenu if (visibleMenu == menu) { AttachedJNIEnv env; if (env.jniEnv) - env.jniEnv->CallStaticVoidMethod(applicationClass(), openContextMenuMethodID); + env.jniEnv->CallStaticVoidMethod(applicationClass(), closeContextMenuMethodID); + pendingContextMenus.clear(); } else { pendingContextMenus.removeOne(menu); } @@ -298,7 +306,7 @@ namespace QtAndroidMenu QAndroidPlatformMenuItem *item = static_cast<QAndroidPlatformMenuItem *>(menus.front()->menuItemForTag(menuId)); if (item) { if (item->menu()) { - showContextMenu(item->menu(), env); + showContextMenu(item->menu(), QRect(), env); } else { if (item->isCheckable()) item->setChecked(checked); @@ -308,7 +316,7 @@ namespace QtAndroidMenu } else { QAndroidPlatformMenu *menu = static_cast<QAndroidPlatformMenu *>(visibleMenuBar->menuForTag(menuId)); if (menu) - showContextMenu(menu, env); + showContextMenu(menu, QRect(), env); } return JNI_TRUE; @@ -333,17 +341,30 @@ namespace QtAndroidMenu addAllMenuItemsToMenu(env, menu, visibleMenu); } + static void fillContextMenu(JNIEnv *env, jobject /*thiz*/, jobject menu) + { + env->CallVoidMethod(menu, clearMenuMethodID); + QMutexLocker lock(&visibleMenuMutex); + if (!visibleMenu) + return; + + addAllMenuItemsToMenu(env, menu, visibleMenu); + } + static jboolean onContextItemSelected(JNIEnv *env, jobject /*thiz*/, jint menuId, jboolean checked) { QMutexLocker lock(&visibleMenuMutex); QAndroidPlatformMenuItem * item = static_cast<QAndroidPlatformMenuItem *>(visibleMenu->menuItemForTag(menuId)); if (item) { if (item->menu()) { - showContextMenu(item->menu(), env); + showContextMenu(item->menu(), QRect(), env); } else { if (item->isCheckable()) item->setChecked(checked); item->activated(); + visibleMenu->aboutToHide(); + visibleMenu = 0; + pendingContextMenus.clear(); } } return JNI_TRUE; @@ -354,10 +375,11 @@ namespace QtAndroidMenu QMutexLocker lock(&visibleMenuMutex); if (!visibleMenu) return; + visibleMenu->aboutToHide(); visibleMenu = 0; if (!pendingContextMenus.empty()) - showContextMenu(pendingContextMenus.dequeue(), env); + showContextMenu(pendingContextMenus.takeLast(), QRect(), env); } static JNINativeMethod methods[] = { @@ -365,6 +387,7 @@ namespace QtAndroidMenu {"onOptionsItemSelected", "(IZ)Z", (void *)onOptionsItemSelected}, {"onOptionsMenuClosed", "(Landroid/view/Menu;)V", (void*)onOptionsMenuClosed}, {"onCreateContextMenu", "(Landroid/view/ContextMenu;)V", (void *)onCreateContextMenu}, + {"fillContextMenu", "(Landroid/view/Menu;)V", (void *)fillContextMenu}, {"onContextItemSelected", "(IZ)Z", (void *)onContextItemSelected}, {"onContextMenuClosed", "(Landroid/view/Menu;)V", (void*)onContextMenuClosed}, }; @@ -406,7 +429,7 @@ namespace QtAndroidMenu return false; } - GET_AND_CHECK_STATIC_METHOD(openContextMenuMethodID, appClass, "openContextMenu", "()V"); + GET_AND_CHECK_STATIC_METHOD(openContextMenuMethodID, appClass, "openContextMenu", "(IIII)V"); GET_AND_CHECK_STATIC_METHOD(closeContextMenuMethodID, appClass, "closeContextMenu", "()V"); GET_AND_CHECK_STATIC_METHOD(resetOptionsMenuMethodID, appClass, "resetOptionsMenu", "()V"); GET_AND_CHECK_STATIC_METHOD(openOptionsMenuMethodID, appClass, "openOptionsMenu", "()V"); diff --git a/src/plugins/platforms/android/androidjnimenu.h b/src/plugins/platforms/android/androidjnimenu.h index 161fe004db..c54eb37f37 100644 --- a/src/plugins/platforms/android/androidjnimenu.h +++ b/src/plugins/platforms/android/androidjnimenu.h @@ -43,12 +43,14 @@ class QAndroidPlatformMenuBar; class QAndroidPlatformMenu; class QAndroidPlatformMenuItem; class QWindow; +class QRect; +class QPoint; namespace QtAndroidMenu { // Menu support void openOptionsMenu(); - void showContextMenu(QAndroidPlatformMenu *menu, JNIEnv *env = 0); + void showContextMenu(QAndroidPlatformMenu *menu, const QRect &anchorRect, JNIEnv *env = 0); void hideContextMenu(QAndroidPlatformMenu *menu); void syncMenu(QAndroidPlatformMenu *menu); void androidPlatformMenuDestroyed(QAndroidPlatformMenu *menu); diff --git a/src/plugins/platforms/android/qandroidplatformmenu.cpp b/src/plugins/platforms/android/qandroidplatformmenu.cpp index a282ecd136..f3505fac3c 100644 --- a/src/plugins/platforms/android/qandroidplatformmenu.cpp +++ b/src/plugins/platforms/android/qandroidplatformmenu.cpp @@ -135,13 +135,12 @@ bool QAndroidPlatformMenu::isVisible() const return m_isVisible; } -void QAndroidPlatformMenu::showPopup(const QWindow *parentWindow, QPoint pos, const QPlatformMenuItem *item) +void QAndroidPlatformMenu::showPopup(const QWindow *parentWindow, const QRect &targetRect, const QPlatformMenuItem *item) { Q_UNUSED(parentWindow); - Q_UNUSED(pos); Q_UNUSED(item); setVisible(true); - QtAndroidMenu::showContextMenu(this); + QtAndroidMenu::showContextMenu(this, targetRect); } QPlatformMenuItem *QAndroidPlatformMenu::menuItemAt(int position) const diff --git a/src/plugins/platforms/android/qandroidplatformmenu.h b/src/plugins/platforms/android/qandroidplatformmenu.h index 1499b3b77f..221c7d33f4 100644 --- a/src/plugins/platforms/android/qandroidplatformmenu.h +++ b/src/plugins/platforms/android/qandroidplatformmenu.h @@ -65,7 +65,7 @@ public: bool isEnabled() const; void setVisible(bool visible); bool isVisible() const; - void showPopup(const QWindow *parentWindow, QPoint pos, const QPlatformMenuItem *item); + void showPopup(const QWindow *parentWindow, const QRect &targetRect, const QPlatformMenuItem *item); QPlatformMenuItem *menuItemAt(int position) const; QPlatformMenuItem *menuItemForTag(quintptr tag) const; |