implemented FocusListener for resetting focus after clicking on another UI item

This commit is contained in:
Roman Pudashkin 2021-09-02 18:19:14 +02:00
parent a1b06af098
commit d4f2811df9
5 changed files with 143 additions and 1 deletions

View file

@ -122,6 +122,8 @@ set(MODULE_SRC
${CMAKE_CURRENT_LIST_DIR}/view/widgetview.h
${CMAKE_CURRENT_LIST_DIR}/view/mainwindowprovider.cpp
${CMAKE_CURRENT_LIST_DIR}/view/mainwindowprovider.h
${CMAKE_CURRENT_LIST_DIR}/view/focuslistener.cpp
${CMAKE_CURRENT_LIST_DIR}/view/focuslistener.h
${CMAKE_CURRENT_LIST_DIR}/dev/interactivetestsmodel.cpp
${CMAKE_CURRENT_LIST_DIR}/dev/interactivetestsmodel.h

View file

@ -52,6 +52,7 @@
#include "view/navigationcontrol.h"
#include "view/navigationevent.h"
#include "view/qmlaccessible.h"
#include "view/focuslistener.h"
#include "dev/interactivetestsmodel.h"
#include "dev/testdialog.h"
@ -132,6 +133,8 @@ void UiModule::registerUiTypes()
qmlRegisterType<AccessibleItem>("MuseScore.Ui", 1, 0, "AccessibleItem");
qmlRegisterUncreatableType<MUAccessible>("MuseScore.Ui", 1, 0, "MUAccessible", "Cannot create a enum type");
qmlRegisterType<FocusListener>("MuseScore.Ui", 1, 0, "FocusListener");
#ifdef Q_OS_MAC
qmlRegisterType<MacOSMainWindowProvider>("MuseScore.Ui", 1, 0, "MainWindowProvider");
#else

View file

@ -0,0 +1,80 @@
/*
* SPDX-License-Identifier: GPL-3.0-only
* MuseScore-CLA-applies
*
* MuseScore
* Music Composition & Notation
*
* Copyright (C) 2021 MuseScore BVBA and others
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 3 as
* published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
#include "focuslistener.h"
#include <QApplication>
using namespace mu::ui;
FocusListener::FocusListener(QObject* parent)
: QObject(parent)
{
}
QQuickItem* FocusListener::item() const
{
return m_item;
}
void FocusListener::setItem(QQuickItem* item)
{
if (m_item == item) {
return;
}
m_item = item;
listenFocusChanged();
emit itemChanged();
}
void FocusListener::listenFocusChanged()
{
if (!m_item) {
return;
}
connect(m_item, &QQuickItem::activeFocusChanged, this, [this](bool hasActiveFocus) {
if (hasActiveFocus) {
qApp->installEventFilter(this);
} else {
qApp->removeEventFilter(this);
}
});
}
bool FocusListener::eventFilter(QObject* watched, QEvent* event)
{
if (m_item && watched && m_item->hasActiveFocus() && event->type() == QEvent::MouseButtonPress) {
QMouseEvent* mouseEvent = static_cast<QMouseEvent*>(event);
QPointF globalItemPos = m_item->mapToGlobal(QPoint(0, 0));
QRect globalItemGeometry = QRect(globalItemPos.x(), globalItemPos.y(), m_item->width(), m_item->height());
bool needResetFocus = !globalItemGeometry.contains(mouseEvent->globalPos());
if (needResetFocus) {
m_item->setFocus(false);
}
}
return QObject::eventFilter(watched, event);
}

View file

@ -0,0 +1,54 @@
/*
* SPDX-License-Identifier: GPL-3.0-only
* MuseScore-CLA-applies
*
* MuseScore
* Music Composition & Notation
*
* Copyright (C) 2021 MuseScore BVBA and others
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 3 as
* published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
#ifndef MU_UI_FOCUSLISTENER_H
#define MU_UI_FOCUSLISTENER_H
#include <QQuickItem>
namespace mu::ui {
class FocusListener : public QObject
{
Q_OBJECT
Q_PROPERTY(QQuickItem* item READ item WRITE setItem NOTIFY itemChanged)
public:
explicit FocusListener(QObject* parent = nullptr);
QQuickItem* item() const;
signals:
void itemChanged();
public slots:
void setItem(QQuickItem* item);
private:
void listenFocusChanged();
bool eventFilter(QObject* watched, QEvent* event);
QQuickItem* m_item = nullptr;
};
}
#endif // MU_UI_FOCUSLISTENER_H

View file

@ -78,6 +78,9 @@ FocusScope {
opacity: root.enabled ? 1.0 : ui.theme.itemOpacityDisabled
FocusListener {
item: root
}
NavigationControl {
id: navCtrl
@ -105,7 +108,7 @@ FocusScope {
border.color: ui.theme.strokeColor
border.width: ui.theme.borderWidth
}
}
RowLayout {
anchors.fill: parent