Skip to content

Commit efaefe5

Browse files
authored
Merge 6327b2b into fe5a6e5
2 parents fe5a6e5 + 6327b2b commit efaefe5

27 files changed

+387
-334
lines changed

src/appshell/qml/platform/AppMenuBar.qml

Lines changed: 36 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -43,17 +43,15 @@ ListView {
4343
id: appMenuModel
4444

4545
appMenuAreaRect: Qt.rect(root.x, root.y, root.width, root.height)
46-
openedMenuAreaRect: Boolean(prv.openedMenu) ? Qt.rect(prv.openedMenu.x, prv.openedMenu.y, prv.openedMenu.width, prv.openedMenu.height)
47-
: Qt.rect(0, 0, 0, 0)
46+
openedMenuAreaRect: Boolean(menuLoader.isMenuOpened) ? Qt.rect(menuLoader.menu.x, menuLoader.menu.y, menuLoader.menu.width, menuLoader.menu.height)
47+
: Qt.rect(0, 0, 0, 0)
4848

4949
onOpenMenuRequested: {
5050
prv.openMenu(menuId)
5151
}
5252

5353
onCloseOpenedMenuRequested: {
54-
if (Boolean(prv.openedMenu)) {
55-
prv.openedMenu.close()
56-
}
54+
menuLoader.close()
5755
}
5856
}
5957

@@ -68,14 +66,23 @@ ListView {
6866
property bool needRestoreNavigationAfterClose: false
6967
property string lastOpenedMenuId: ""
7068

71-
function openMenu(menuId) {
69+
function openMenu(menuId, byHover) {
7270
for (var i = 0; i < root.count; ++i) {
7371
var item = root.itemAtIndex(i)
7472
if (Boolean(item) && item.menuId === menuId) {
7573
needRestoreNavigationAfterClose = true
7674
lastOpenedMenuId = menuId
7775

78-
item.toggleMenuOpened()
76+
if (!byHover) {
77+
if (menuLoader.isMenuOpened && menuLoader.parent === item) {
78+
menuLoader.close()
79+
return
80+
}
81+
}
82+
83+
menuLoader.menuId = menuId
84+
menuLoader.parent = item
85+
menuLoader.open(item.item.subitems)
7986

8087
return
8188
}
@@ -94,6 +101,8 @@ ListView {
94101
property string menuId: Boolean(item) ? item.id : ""
95102
property string title: Boolean(item) ? item.title : ""
96103

104+
property bool isMenuOpened: menuLoader.isMenuOpened && menuLoader.parent === this
105+
97106
property bool highlight: appMenuModel.highlightedMenuId === menuId
98107
onHighlightChanged: {
99108
if (highlight) {
@@ -108,8 +117,8 @@ ListView {
108117
margins: 8
109118
drawFocusBorderInsideRect: true
110119

111-
transparent: !menuLoader.isMenuOpened
112-
accentButton: menuLoader.isMenuOpened
120+
transparent: !isMenuOpened
121+
accentButton: isMenuOpened
113122

114123
contentItem: StyledTextLabel {
115124
id: textLabel
@@ -155,42 +164,36 @@ ListView {
155164
Accessible.role: Accessible.Button
156165
Accessible.name: Utils.removeAmpersands(title)
157166

158-
mouseArea.onContainsMouseChanged: {
159-
if (!mouseArea.containsMouse || !prv.openedMenu || prv.openedMenu == menuLoader.menu) {
167+
mouseArea.onHoveredChanged: {
168+
if (!mouseArea.containsMouse) {
160169
return
161170
}
162171

163-
appMenuModel.openMenu(radioButtonDelegate.menuId)
172+
if (menuLoader.isMenuOpened && menuLoader.parent !== this) {
173+
appMenuModel.openMenu(radioButtonDelegate.menuId, true)
174+
}
164175
}
165176

166177
onClicked: {
167-
appMenuModel.openMenu(radioButtonDelegate.menuId)
178+
appMenuModel.openMenu(radioButtonDelegate.menuId, false)
168179
}
180+
}
169181

170-
function toggleMenuOpened() {
171-
if (prv.openedMenu && prv.openedMenu != menuLoader.menu) {
172-
prv.openedMenu.close()
173-
}
182+
StyledMenuLoader {
183+
id: menuLoader
174184

175-
Qt.callLater(menuLoader.toggleOpened, item.subitems)
176-
}
185+
property string menuId: ""
177186

178-
StyledMenuLoader {
179-
id: menuLoader
180-
181-
onHandleMenuItem: {
182-
Qt.callLater(appMenuModel.handleMenuItem, itemId)
183-
}
187+
onHandleMenuItem: {
188+
Qt.callLater(appMenuModel.handleMenuItem, itemId)
189+
}
184190

185-
onOpened: {
186-
prv.openedMenu = menu
187-
appMenuModel.openedMenuId = radioButtonDelegate.menuId
188-
}
191+
onOpened: {
192+
appMenuModel.openedMenuId = menuLoader.menuId
193+
}
189194

190-
onClosed: {
191-
prv.openedMenu = null
192-
appMenuModel.openedMenuId = ""
193-
}
195+
onClosed: {
196+
appMenuModel.openedMenuId = ""
194197
}
195198
}
196199
}

src/appshell/view/navigableappmenumodel.cpp

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -76,15 +76,15 @@ void NavigableAppMenuModel::load()
7676
qApp->installEventFilter(this);
7777
}
7878

79-
void NavigableAppMenuModel::openMenu(const QString& menuId)
79+
void NavigableAppMenuModel::openMenu(const QString& menuId, bool byHover)
8080
{
8181
if (isNavigationStarted() || !isMenuOpened()) {
8282
saveMUNavigationSystemState();
8383
} else {
8484
restoreMUNavigationSystemState();
8585
}
8686

87-
emit openMenuRequested(menuId);
87+
emit openMenuRequested(menuId, byHover);
8888
}
8989

9090
bool NavigableAppMenuModel::isNavigationStarted() const
@@ -463,7 +463,7 @@ void NavigableAppMenuModel::restoreMUNavigationSystemState()
463463

464464
void NavigableAppMenuModel::activateHighlightedMenu()
465465
{
466-
emit openMenuRequested(m_highlightedMenuId);
466+
emit openMenuRequested(m_highlightedMenuId, false);
467467
}
468468

469469
QString NavigableAppMenuModel::highlightedMenuId() const

src/appshell/view/navigableappmenumodel.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,7 @@ class NavigableAppMenuModel : public AppMenuModel
4444
explicit NavigableAppMenuModel(QObject* parent = nullptr);
4545

4646
Q_INVOKABLE void load() override;
47-
Q_INVOKABLE void openMenu(const QString& menuId);
47+
Q_INVOKABLE void openMenu(const QString& menuId, bool byHover);
4848

4949
bool isNavigationStarted() const;
5050
bool isMenuOpened() const;
@@ -62,7 +62,7 @@ public slots:
6262
void setOpenedMenuAreaRect(QRect openedMenuAreaRect);
6363

6464
signals:
65-
void openMenuRequested(const QString& menuId);
65+
void openMenuRequested(const QString& menuId, bool byHover);
6666
void closeOpenedMenuRequested();
6767
void highlightedMenuIdChanged(QString highlightedMenuId);
6868
void openedMenuIdChanged(QString openedMenuId);

src/framework/ui/internal/navigationcontroller.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -247,7 +247,7 @@ template<class T>
247247
static T* findByName(const std::set<T*>& set, const QString& name)
248248
{
249249
auto it = std::find_if(set.cbegin(), set.cend(), [name](const T* s) {
250-
return s->name() == name && s->enabled();
250+
return s->name() == name;
251251
});
252252

253253
if (it != set.cend()) {

src/framework/ui/qml/MuseScore/Ui/ToolTipProvider.qml

Lines changed: 47 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -25,49 +25,74 @@ import MuseScore.Ui 1.0
2525
import MuseScore.UiComponents 1.0
2626

2727
Item {
28-
2928
id: root
3029

3130
property var provider: ui.tooltip
3231

3332
anchors.fill: parent
3433

35-
QtObject {
36-
id: prv
34+
Loader {
35+
id: toolTipLoader
3736

38-
property var showedToolTip: null
39-
}
37+
active: false
4038

41-
Component {
42-
id: toolTipComp
39+
sourceComponent: StyledToolTip {
40+
onClosed: {
41+
Qt.callLater(unloadToolTip)
42+
}
43+
}
4344

44-
StyledToolTip {}
45-
}
45+
function loadToolTip() {
46+
toolTipLoader.active = true
47+
}
4648

47-
Connections {
48-
target: root.provider
49+
function unloadToolTip() {
50+
toolTipLoader.active = false
51+
}
4952

50-
function onShowToolTip(parent, title, description, shortcut) {
53+
function open(parent, title, description, shortcut) {
54+
loadToolTip()
55+
56+
update(parent, title, description, shortcut)
57+
58+
var toolTip = toolTipLoader.item
59+
toolTip.open()
60+
}
61+
62+
function close() {
63+
var toolTip = toolTipLoader.item
64+
if (!Boolean(toolTip)) {
65+
return
66+
}
5167

52-
onHideToolTip()
68+
toolTip.close()
69+
}
70+
71+
function update(parent, title, description, shortcut) {
72+
var toolTip = toolTipLoader.item
73+
if (!Boolean(toolTip)) {
74+
return
75+
}
5376

54-
var toolTip = toolTipComp.createObject(parent)
77+
toolTip.parent = parent
5578
toolTip.title = title
5679
toolTip.description = description
5780
toolTip.shortcut = shortcut
5881

59-
toolTip.closed.connect(function() {
60-
prv.showedToolTip.destroy()
61-
prv.showedToolTip = null
62-
})
82+
toolTip.calculateSize()
83+
}
84+
}
85+
86+
Connections {
87+
target: root.provider
6388

64-
prv.showedToolTip = toolTip
65-
toolTip.toggleOpened()
89+
function onShowToolTip(parent, title, description, shortcut) {
90+
toolTipLoader.open(parent, title, description, shortcut)
6691
}
6792

6893
function onHideToolTip() {
69-
if (prv.showedToolTip) {
70-
prv.showedToolTip.close()
94+
if (toolTipLoader.active) {
95+
toolTipLoader.close()
7196
}
7297
}
7398
}

src/framework/ui/tests/navigationcontroller_tests.cpp

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -297,6 +297,39 @@ TEST_F(NavigationControllerTests, FirstActiveOnNextSectionOnFocusedWindow)
297297
delete sect2;
298298
}
299299

300+
TEST_F(NavigationControllerTests, FirstActiveOnNextSectionExclusive)
301+
{
302+
//! CASE Nothing active, and we call next section (F6)
303+
304+
//! [GIVEN] Two section, not active
305+
Section* sect1 = make_section(1, 2, 3);
306+
Section* sect2 = make_section(2, 2, 3);
307+
308+
m_controller->reg(sect1->section);
309+
m_controller->reg(sect2->section);
310+
311+
//! [GIVEN] Section 2 is exclusive, not on focus window
312+
//! we have this behavior for menus and dropdowns
313+
sect2->section->setType(NavigationSection::Exclusive);
314+
315+
QQuickWindow* newFocusWindow = new QQuickWindow();
316+
ON_CALL(*m_applicationMock, focusWindow()).WillByDefault(Return(newFocusWindow));
317+
318+
//! [WHEN] Send action `nav-next-section` (usually F6)
319+
m_dispatcher->dispatch("nav-next-section");
320+
321+
//! [THEN] The second section, the first panel, the first control must be activated
322+
EXPECT_TRUE(sect2->section->active());
323+
EXPECT_TRUE(sect2->panels[0]->panel->active());
324+
EXPECT_TRUE(sect2->panels[0]->controls[0]->control->active());
325+
326+
//! [THEN] The second section must not be activated
327+
EXPECT_FALSE(sect1->section->active());
328+
329+
delete sect1;
330+
delete sect2;
331+
}
332+
300333
TEST_F(NavigationControllerTests, FirstActiveOnNextSectionNonMainWindow)
301334
{
302335
//! CASE Nothing active, and we call next section (F6)

src/framework/ui/view/navigationsection.cpp

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -21,8 +21,6 @@
2121
*/
2222
#include "navigationsection.h"
2323

24-
#include <algorithm>
25-
2624
#include <QQuickWindow>
2725
#include <QApplication>
2826

@@ -79,7 +77,7 @@ bool NavigationSection::enabled() const
7977
QWindow* topWindow = application()->focusWindow();
8078

8179
if (sectionWindow && (topWindow != sectionWindow)) {
82-
return false;
80+
return type() == INavigationSection::Type::Exclusive;
8381
}
8482

8583
bool enbl = false;

src/framework/ui/view/navigationsection.h

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,6 @@
3030

3131
#include "modularity/ioc.h"
3232
#include "global/iapplication.h"
33-
#include "../iinteractiveprovider.h"
3433

3534
#include "../inavigationcontroller.h"
3635

@@ -41,7 +40,6 @@ class NavigationSection : public AbstractNavigation, public INavigationSection
4140
Q_PROPERTY(QmlType type READ type_property WRITE setType NOTIFY typeChanged)
4241

4342
INJECT(ui, framework::IApplication, application)
44-
INJECT(ui, IInteractiveProvider, interactiveProvider)
4543
INJECT(ui, INavigationController, navigationController)
4644

4745
public:

0 commit comments

Comments
 (0)