ModalPopupHandler.cpp 3.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142
  1. /*
  2. * Copyright (c) Contributors to the Open 3D Engine Project.
  3. * For complete copyright and license terms please see the LICENSE at the root of this distribution.
  4. *
  5. * SPDX-License-Identifier: Apache-2.0 OR MIT
  6. *
  7. */
  8. #include "Tests/UI/ModalPopupHandler.h"
  9. #include "Tests/UI/UIFixture.h"
  10. #include <QApplication>
  11. #include <QTimer>
  12. #include <QMenu>
  13. #include <QObject>
  14. #include <QtTest>
  15. namespace EMotionFX
  16. {
  17. ModalPopupHandler::ModalPopupHandler(QObject* pParent)
  18. : QObject(pParent)
  19. {
  20. }
  21. void ModalPopupHandler::ShowContextMenuAndTriggerAction(QWidget* widget, const QString& actionName, int timeout, ActionCompletionCallback completionCallback)
  22. {
  23. MenuActiveCallback menuCallback = [=](QMenu* menu)
  24. {
  25. ASSERT_TRUE(menu) << "Failed to find context menu.";
  26. m_seenTargetWidget = true;
  27. QAction* action = menu->findChild<QAction*>(actionName);
  28. ASSERT_TRUE(action) << "Unable to find context menu action " << actionName.toUtf8().data();
  29. action->trigger();
  30. menu->close();
  31. if (m_actionCompletionCallback)
  32. {
  33. m_actionCompletionCallback(actionName);
  34. }
  35. };
  36. m_totalTime = 0;
  37. m_actionCompletionCallback = completionCallback;
  38. m_menuActiveCallback = menuCallback;
  39. m_timeout = timeout;
  40. // Kick a timer off to check whether the menu is open.
  41. QTimer::singleShot(WaitTickTime, this, SLOT(CheckForContextMenu()));
  42. // Open the modal menu.
  43. UIFixture::BringUpContextMenu(widget, QPoint(10, 10), widget->mapToGlobal(QPoint(10, 10)));
  44. }
  45. void ModalPopupHandler::CheckForContextMenu()
  46. {
  47. m_totalTime += WaitTickTime;
  48. if (m_totalTime >= m_timeout)
  49. {
  50. if (m_actionCompletionCallback)
  51. {
  52. m_actionCompletionCallback("");
  53. return;
  54. }
  55. }
  56. // Check for the active widget being a popup widget.
  57. QWidget* qpop = QApplication::activePopupWidget();
  58. if (!qpop)
  59. {
  60. QTimer::singleShot(WaitTickTime, this, SLOT(CheckForContextMenu()));
  61. return;
  62. }
  63. // If the active widget is not a menu, keep waiting.
  64. QMenu* menu = qobject_cast<QMenu*>(qpop);
  65. if (!menu)
  66. {
  67. QTimer::singleShot(WaitTickTime, this, SLOT(CheckForContextMenu()));
  68. return;
  69. }
  70. // The menu is now active, inform the calling object.
  71. m_menuActiveCallback(menu);
  72. }
  73. void ModalPopupHandler::CheckForPopupWidget()
  74. {
  75. m_totalTime += WaitTickTime;
  76. if (m_totalTime >= m_timeout)
  77. {
  78. if (m_actionCompletionCallback)
  79. {
  80. m_actionCompletionCallback("");
  81. m_complete = true;
  82. return;
  83. }
  84. }
  85. // Check for the active widget being a popup widget.
  86. QWidget* modalWidget = QApplication::activeModalWidget();
  87. if (!modalWidget)
  88. {
  89. QTimer::singleShot(WaitTickTime, this, &ModalPopupHandler::CheckForPopupWidget);
  90. return;
  91. }
  92. m_seenTargetWidget = true;
  93. // Inform the calling object.
  94. m_widgetActiveCallback(modalWidget);
  95. }
  96. bool ModalPopupHandler::GetSeenTargetWidget()
  97. {
  98. return m_seenTargetWidget;
  99. }
  100. void ModalPopupHandler::ResetSeenTargetWidget()
  101. {
  102. m_seenTargetWidget = false;
  103. }
  104. bool ModalPopupHandler::GetIsComplete()
  105. {
  106. return m_complete;
  107. }
  108. void ModalPopupHandler::WaitForCompletion(const int timeout)
  109. {
  110. static_cast<void>(QTest::qWaitFor([&]() {
  111. return m_complete;
  112. }, timeout));
  113. }
  114. } // namespace EMotionFX
  115. #include <Tests/UI/moc_ModalPopupHandler.cpp>