iOS: don't show popup on call to setVisible
It turns out that setting visibility means whether or not the menu should appear visible in a parent menu, and not to actually show or hide the popup. This means that the only way to show a popup is to call showPopup, which also makes it simpler since we then always get a parent window as argument that we can activate and get a focus object from. Change-Id: Ie3866b5664294f9aa4d694fa422e8116e9c75ced Reviewed-by: Tor Arne Vestbø <tor.arne.vestbo@digia.com>
This commit is contained in:
parent
4dffab4c39
commit
ee31bc59be
@ -126,7 +126,6 @@ private:
|
|||||||
quintptr m_tag;
|
quintptr m_tag;
|
||||||
bool m_enabled;
|
bool m_enabled;
|
||||||
bool m_visible;
|
bool m_visible;
|
||||||
bool m_effectiveVisible;
|
|
||||||
QString m_text;
|
QString m_text;
|
||||||
MenuType m_menuType;
|
MenuType m_menuType;
|
||||||
MenuType m_effectiveMenuType;
|
MenuType m_effectiveMenuType;
|
||||||
@ -140,11 +139,10 @@ private:
|
|||||||
static QIOSMenu *m_currentMenu;
|
static QIOSMenu *m_currentMenu;
|
||||||
|
|
||||||
void updateVisibility();
|
void updateVisibility();
|
||||||
void updateVisibilityUsingUIMenuController();
|
void toggleShowUsingUIMenuController(bool show);
|
||||||
void updateVisibilityUsingUIPickerView();
|
void toggleShowUsingUIPickerView(bool show);
|
||||||
QIOSMenuItemList visibleMenuItems() const;
|
QIOSMenuItemList visibleMenuItems() const;
|
||||||
void repositionMenu();
|
void repositionMenu();
|
||||||
void hide() { setVisible(false); }
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // QIOSMENU_H
|
#endif // QIOSMENU_H
|
||||||
|
@ -195,12 +195,12 @@ static NSString *const kSelectorPrefix = @"_qtMenuItem_";
|
|||||||
if (!m_visibleMenuItems.isEmpty())
|
if (!m_visibleMenuItems.isEmpty())
|
||||||
QIOSMenu::currentMenu()->handleItemSelected(m_visibleMenuItems.at(m_selectedRow));
|
QIOSMenu::currentMenu()->handleItemSelected(m_visibleMenuItems.at(m_selectedRow));
|
||||||
else
|
else
|
||||||
QIOSMenu::currentMenu()->setVisible(false);
|
QIOSMenu::currentMenu()->dismiss();
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void)cancelMenu
|
- (void)cancelMenu
|
||||||
{
|
{
|
||||||
QIOSMenu::currentMenu()->setVisible(false);
|
QIOSMenu::currentMenu()->dismiss();
|
||||||
}
|
}
|
||||||
|
|
||||||
@end
|
@end
|
||||||
@ -299,8 +299,7 @@ QIOSMenu::QIOSMenu()
|
|||||||
: QPlatformMenu()
|
: QPlatformMenu()
|
||||||
, m_tag(0)
|
, m_tag(0)
|
||||||
, m_enabled(true)
|
, m_enabled(true)
|
||||||
, m_visible(false)
|
, m_visible(true)
|
||||||
, m_effectiveVisible(false)
|
|
||||||
, m_text(QString())
|
, m_text(QString())
|
||||||
, m_menuType(DefaultMenu)
|
, m_menuType(DefaultMenu)
|
||||||
, m_effectiveMenuType(DefaultMenu)
|
, m_effectiveMenuType(DefaultMenu)
|
||||||
@ -348,96 +347,12 @@ void QIOSMenu::setText(const QString &text)
|
|||||||
|
|
||||||
void QIOSMenu::setEnabled(bool enabled)
|
void QIOSMenu::setEnabled(bool enabled)
|
||||||
{
|
{
|
||||||
if (m_enabled == enabled)
|
|
||||||
return;
|
|
||||||
|
|
||||||
m_enabled = enabled;
|
m_enabled = enabled;
|
||||||
updateVisibility();
|
|
||||||
}
|
|
||||||
|
|
||||||
void QIOSMenu::showPopup(const QWindow *parentWindow, const QRect &targetRect, const QPlatformMenuItem *item)
|
|
||||||
{
|
|
||||||
m_parentWindow = const_cast<QWindow *>(parentWindow);
|
|
||||||
m_targetRect = targetRect;
|
|
||||||
m_targetItem = static_cast<const QIOSMenuItem *>(item);
|
|
||||||
|
|
||||||
if (m_parentWindow && !m_parentWindow->isActive())
|
|
||||||
m_parentWindow->requestActivate();
|
|
||||||
|
|
||||||
setVisible(true);
|
|
||||||
}
|
|
||||||
|
|
||||||
void QIOSMenu::handleItemSelected(QIOSMenuItem *menuItem)
|
|
||||||
{
|
|
||||||
emit menuItem->activated();
|
|
||||||
setVisible(false);
|
|
||||||
|
|
||||||
if (QIOSMenu *menu = menuItem->m_menu) {
|
|
||||||
menu->setMenuType(m_effectiveMenuType);
|
|
||||||
menu->showPopup(m_parentWindow, m_targetRect, 0);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void QIOSMenu::dismiss()
|
|
||||||
{
|
|
||||||
setVisible(false);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void QIOSMenu::setVisible(bool visible)
|
void QIOSMenu::setVisible(bool visible)
|
||||||
{
|
{
|
||||||
if (m_visible == visible)
|
|
||||||
return;
|
|
||||||
|
|
||||||
m_visible = visible;
|
m_visible = visible;
|
||||||
updateVisibility();
|
|
||||||
}
|
|
||||||
|
|
||||||
void QIOSMenu::updateVisibility()
|
|
||||||
{
|
|
||||||
bool visibleAndEnabled = m_visible && m_enabled;
|
|
||||||
if ((visibleAndEnabled && m_effectiveVisible) || (!visibleAndEnabled && m_currentMenu != this))
|
|
||||||
return;
|
|
||||||
|
|
||||||
if (visibleAndEnabled && !qApp->focusObject()) {
|
|
||||||
// Since the menus depend on communicating with a focus object, a focus object is required to show
|
|
||||||
// the menu. Note that QIOSMenu::showPopup() will activate the parent window (and set a focus object)
|
|
||||||
// before this function is called, so this should normally be the case. Not having a focus object is only
|
|
||||||
// expected in a hybrid environment where the first responder can be something else than a QUIView (then
|
|
||||||
// no QWindow will be active). If the focus object changes while the menu is visible, the menu will hide.
|
|
||||||
qWarning() << "QIOSMenu: cannot open menu without any active QWindows!";
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
m_effectiveVisible = visibleAndEnabled;
|
|
||||||
|
|
||||||
if (m_effectiveVisible) {
|
|
||||||
Q_ASSERT(m_currentMenu != this);
|
|
||||||
if (m_currentMenu) {
|
|
||||||
// The current implementation allow only one visible
|
|
||||||
// menu at a time, so close the one currently showing.
|
|
||||||
m_currentMenu->setVisible(false);
|
|
||||||
}
|
|
||||||
|
|
||||||
m_currentMenu = this;
|
|
||||||
m_effectiveMenuType = m_menuType;
|
|
||||||
connect(qGuiApp, &QGuiApplication::focusObjectChanged, this, &QIOSMenu::hide);
|
|
||||||
} else {
|
|
||||||
disconnect(qGuiApp, &QGuiApplication::focusObjectChanged, this, &QIOSMenu::hide);
|
|
||||||
m_currentMenu = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
switch (m_effectiveMenuType) {
|
|
||||||
case EditMenu:
|
|
||||||
updateVisibilityUsingUIMenuController();
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
updateVisibilityUsingUIPickerView();
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Emit the signal after the fact in case a
|
|
||||||
// receiver opens a new menu when receiving it.
|
|
||||||
emit (m_effectiveVisible ? aboutToShow() : aboutToHide());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void QIOSMenu::setMenuType(QPlatformMenu::MenuType type)
|
void QIOSMenu::setMenuType(QPlatformMenu::MenuType type)
|
||||||
@ -445,9 +360,72 @@ void QIOSMenu::setMenuType(QPlatformMenu::MenuType type)
|
|||||||
m_menuType = type;
|
m_menuType = type;
|
||||||
}
|
}
|
||||||
|
|
||||||
void QIOSMenu::updateVisibilityUsingUIMenuController()
|
void QIOSMenu::handleItemSelected(QIOSMenuItem *menuItem)
|
||||||
{
|
{
|
||||||
if (m_effectiveVisible) {
|
emit menuItem->activated();
|
||||||
|
dismiss();
|
||||||
|
|
||||||
|
if (QIOSMenu *menu = menuItem->m_menu) {
|
||||||
|
menu->setMenuType(m_effectiveMenuType);
|
||||||
|
menu->showPopup(m_parentWindow, m_targetRect, 0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void QIOSMenu::showPopup(const QWindow *parentWindow, const QRect &targetRect, const QPlatformMenuItem *item)
|
||||||
|
{
|
||||||
|
if (m_currentMenu == this || !m_visible || !m_enabled || !parentWindow)
|
||||||
|
return;
|
||||||
|
|
||||||
|
emit aboutToShow();
|
||||||
|
|
||||||
|
m_parentWindow = const_cast<QWindow *>(parentWindow);
|
||||||
|
m_targetRect = targetRect;
|
||||||
|
m_targetItem = static_cast<const QIOSMenuItem *>(item);
|
||||||
|
|
||||||
|
if (!m_parentWindow->isActive())
|
||||||
|
m_parentWindow->requestActivate();
|
||||||
|
|
||||||
|
if (m_currentMenu && m_currentMenu != this)
|
||||||
|
m_currentMenu->dismiss();
|
||||||
|
|
||||||
|
m_currentMenu = this;
|
||||||
|
m_effectiveMenuType = m_menuType;
|
||||||
|
connect(qGuiApp, &QGuiApplication::focusObjectChanged, this, &QIOSMenu::dismiss);
|
||||||
|
|
||||||
|
switch (m_effectiveMenuType) {
|
||||||
|
case EditMenu:
|
||||||
|
toggleShowUsingUIMenuController(true);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
toggleShowUsingUIPickerView(true);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void QIOSMenu::dismiss()
|
||||||
|
{
|
||||||
|
if (m_currentMenu != this)
|
||||||
|
return;
|
||||||
|
|
||||||
|
emit aboutToHide();
|
||||||
|
|
||||||
|
disconnect(qGuiApp, &QGuiApplication::focusObjectChanged, this, &QIOSMenu::dismiss);
|
||||||
|
|
||||||
|
switch (m_effectiveMenuType) {
|
||||||
|
case EditMenu:
|
||||||
|
toggleShowUsingUIMenuController(false);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
toggleShowUsingUIPickerView(false);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
m_currentMenu = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void QIOSMenu::toggleShowUsingUIMenuController(bool show)
|
||||||
|
{
|
||||||
|
if (show) {
|
||||||
Q_ASSERT(!m_menuController);
|
Q_ASSERT(!m_menuController);
|
||||||
m_menuController = [[QUIMenuController alloc] initWithVisibleMenuItems:visibleMenuItems()];
|
m_menuController = [[QUIMenuController alloc] initWithVisibleMenuItems:visibleMenuItems()];
|
||||||
repositionMenu();
|
repositionMenu();
|
||||||
@ -462,11 +440,11 @@ void QIOSMenu::updateVisibilityUsingUIMenuController()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void QIOSMenu::updateVisibilityUsingUIPickerView()
|
void QIOSMenu::toggleShowUsingUIPickerView(bool show)
|
||||||
{
|
{
|
||||||
static QObject *focusObjectWithPickerView = 0;
|
static QObject *focusObjectWithPickerView = 0;
|
||||||
|
|
||||||
if (m_effectiveVisible) {
|
if (show) {
|
||||||
Q_ASSERT(!m_pickerView);
|
Q_ASSERT(!m_pickerView);
|
||||||
m_pickerView = [[QUIPickerView alloc] initWithVisibleMenuItems:visibleMenuItems() selectItem:m_targetItem];
|
m_pickerView = [[QUIPickerView alloc] initWithVisibleMenuItems:visibleMenuItems() selectItem:m_targetItem];
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user