From 6b26f3e6e6203ccb38f3e0311745c48e27f5ce23 Mon Sep 17 00:00:00 2001 From: James Mizen Date: Thu, 9 Jan 2025 10:37:06 +0000 Subject: [PATCH] Refactor partial tie popup menu --- .../Muse/UiComponents/ContextMenuLoader.qml | 18 ----- .../Muse/UiComponents/StyledMenuLoader.qml | 18 +---- .../Muse/UiComponents/internal/StyledMenu.qml | 7 +- src/notation/notationscene.qrc | 1 + .../internal/PartialTieMenuRowItem.qml | 75 +++++++++++++++++ .../internal/PartialTiePopup.qml | 81 ++++++++++++------- 6 files changed, 132 insertions(+), 68 deletions(-) create mode 100644 src/notation/qml/MuseScore/NotationScene/internal/PartialTieMenuRowItem.qml diff --git a/src/framework/uicomponents/qml/Muse/UiComponents/ContextMenuLoader.qml b/src/framework/uicomponents/qml/Muse/UiComponents/ContextMenuLoader.qml index d5a9b891abfd6..6633c1b116c60 100644 --- a/src/framework/uicomponents/qml/Muse/UiComponents/ContextMenuLoader.qml +++ b/src/framework/uicomponents/qml/Muse/UiComponents/ContextMenuLoader.qml @@ -21,23 +21,12 @@ */ import QtQuick 2.15 -import Muse.Ui 1.0 - Item { id: container // Useful for static context menus property var items: [] - - property NavigationSection notationViewNavigationSection: null - property int navigationOrderStart: 0 - - property alias closeMenuOnSelection: contextMenuLoader.closeMenuOnSelection - property alias opensUpward: contextMenuLoader.opensUpward - property alias focusOnOpened: contextMenuLoader.focusOnOpened - property alias item: contextMenuLoader.item - signal handleMenuItem(string itemId) signal opened() signal closed() @@ -47,13 +36,6 @@ Item { width: 0 height: 0 - onNotationViewNavigationSectionChanged: function() { - contextMenuLoader.item.navigationSectionOverride = container.notationViewNavigationSection - } - onNavigationOrderStartChanged: function() { - contextMenuLoader.item.navigationOrderStart = container.navigationOrderStart - } - function show(position: point, items) { if (!items) { items = container.items diff --git a/src/framework/uicomponents/qml/Muse/UiComponents/StyledMenuLoader.qml b/src/framework/uicomponents/qml/Muse/UiComponents/StyledMenuLoader.qml index 2b0d0fcf8ee20..1622e320e80bf 100644 --- a/src/framework/uicomponents/qml/Muse/UiComponents/StyledMenuLoader.qml +++ b/src/framework/uicomponents/qml/Muse/UiComponents/StyledMenuLoader.qml @@ -21,7 +21,6 @@ */ import QtQuick 2.15 -import Muse.Ui 1.0 import Muse.UiComponents 1.0 import "internal" @@ -38,13 +37,6 @@ Loader { property StyledMenu menu: loader.item as StyledMenu property Item menuAnchorItem: null property bool hasSiblingMenus: false - property bool closeMenuOnSelection: true - property bool focusOnOpened: true - - property NavigationSection notationViewNavigationSection: null - property int navigationOrderStart: 0 - - property bool opensUpward: false property alias isMenuOpened: loader.active @@ -73,9 +65,7 @@ Loader { accessibleName: loader.accessibleName onHandleMenuItem: function(itemId) { - if (loader.closeMenuOnSelection) { - itemMenu.close() - } + itemMenu.close() Qt.callLater(loader.handleMenuItem, itemId) } @@ -92,9 +82,7 @@ Loader { } onOpened: { - if (focusOnOpened) { - focusOnOpenedMenuTimer.start() - } + focusOnOpenedMenuTimer.start() } } @@ -145,8 +133,6 @@ Loader { menu.closeSubMenu() - menu.setOpensUpward(loader.opensUpward) - if (x !== -1) { menu.x = x } diff --git a/src/framework/uicomponents/qml/Muse/UiComponents/internal/StyledMenu.qml b/src/framework/uicomponents/qml/Muse/UiComponents/internal/StyledMenu.qml index cb2b4c8fb5bdc..6262704ad7365 100644 --- a/src/framework/uicomponents/qml/Muse/UiComponents/internal/StyledMenu.qml +++ b/src/framework/uicomponents/qml/Muse/UiComponents/internal/StyledMenu.qml @@ -32,9 +32,6 @@ MenuView { property alias model: view.model - property NavigationSection navigationSectionOverride: null - property int navigationOrderStart: 0 - property int preferredAlign: Qt.AlignRight // Left, HCenter, Right property bool hasSiblingMenus: loader.hasSiblingMenus @@ -137,9 +134,9 @@ MenuView { property NavigationPanel navigationPanel: NavigationPanel { name: "StyledMenu" + section: content.navigationSection direction: NavigationPanel.Vertical - section: root.navigationSectionOverride ?? content.navigationSection - order: root.navigationOrderStart + order: 1 accessible.name: root.accessibleName diff --git a/src/notation/notationscene.qrc b/src/notation/notationscene.qrc index b8f733c499b97..87c61b9b52bf9 100644 --- a/src/notation/notationscene.qrc +++ b/src/notation/notationscene.qrc @@ -68,5 +68,6 @@ qml/MuseScore/NotationScene/internal/EditStyle/IconAndTextButtonSelector.qml qml/MuseScore/NotationScene/PercussionPanelPadSwapDialog.qml qml/MuseScore/NotationScene/internal/PartialTiePopup.qml + qml/MuseScore/NotationScene/internal/PartialTieMenuRowItem.qml diff --git a/src/notation/qml/MuseScore/NotationScene/internal/PartialTieMenuRowItem.qml b/src/notation/qml/MuseScore/NotationScene/internal/PartialTieMenuRowItem.qml new file mode 100644 index 0000000000000..8d6d897f70af8 --- /dev/null +++ b/src/notation/qml/MuseScore/NotationScene/internal/PartialTieMenuRowItem.qml @@ -0,0 +1,75 @@ +/* + * SPDX-License-Identifier: GPL-3.0-only + * MuseScore-CLA-applies + * + * MuseScore + * Music Composition & Notation + * + * Copyright (C) 2025 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 . + */ +import QtQuick 2.15 +import QtQuick.Controls 2.15 +import QtQuick.Layouts 1.15 +import QtQuick.Window 2.15 + +import Muse.Ui 1.0 +import Muse.UiComponents 1.0 +import MuseScore.NotationScene 1.0 + +ListItemBlank { + function calculateWidth() { + let result = 0 + + result += rowLayout.anchors.leftMargin + + result += Math.ceil(checkIcon.Layout.preferredWidth) + result += rowLayout.spacing + + result += Math.ceil(titleLabel.implicitWidth) + result += rowLayout.spacing + result += rowLayout.anchors.rightMargin + + return result + } + + RowLayout { + id: rowLayout + + anchors.verticalCenter: parent.verticalCenter + anchors.left: parent.left + anchors.leftMargin: 12 + anchors.right: parent.right + anchors.rightMargin: 12 + + spacing: 12 + + StyledIconLabel { + id: checkIcon + Layout.alignment: Qt.AlignLeft + Layout.preferredWidth: 16 + iconCode: modelData.checked ? IconCode.TICK_RIGHT_ANGLE : IconCode.NONE + } + + StyledTextLabel { + id: titleLabel + Layout.fillWidth: true + horizontalAlignment: Text.AlignLeft + + text: modelData.title + + textFormat: Text.RichText + } + } +} diff --git a/src/notation/qml/MuseScore/NotationScene/internal/PartialTiePopup.qml b/src/notation/qml/MuseScore/NotationScene/internal/PartialTiePopup.qml index d17f1fe34e0fa..63a8546b116b5 100644 --- a/src/notation/qml/MuseScore/NotationScene/internal/PartialTiePopup.qml +++ b/src/notation/qml/MuseScore/NotationScene/internal/PartialTiePopup.qml @@ -5,7 +5,7 @@ * MuseScore * Music Composition & Notation * - * Copyright (C) 2022 MuseScore BVBA and others + * Copyright (C) 2025 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 @@ -32,6 +32,9 @@ StyledPopupView { id: root margins: 0 + contentWidth: content.width + contentHeight: content.height + property alias notationViewNavigationSection: partialTieNavPanel.section property alias navigationOrderStart: partialTieNavPanel.order readonly property alias navigationOrderEnd: partialTieNavPanel.order @@ -40,12 +43,7 @@ StyledPopupView { showArrow: false - onOpened: { - tieMenuLoader.show(Qt.point(0, 0)) - } - onClosed: { - tieMenuLoader.close() partialTiePopupModel.onClosed() } @@ -53,26 +51,23 @@ StyledPopupView { function updatePosition() { const opensUp = partialTiePopupModel.tieDirection - const popupHeight = tieMenuLoader.item.height + root.margins * 2 + root.padding * 2 + const popupHeight = content.height + root.margins * 2 + root.padding * 2 root.x = partialTiePopupModel.dialogPosition.x - root.parent.x root.y = partialTiePopupModel.dialogPosition.y - root.parent.y - (opensUp ? popupHeight : 0) root.setOpensUpward(opensUp) - } - - contentWidth: tieMenuLoader.width - contentHeight: tieMenuLoader.childrenRect.height - ContextMenuLoader { - id: tieMenuLoader - closeMenuOnSelection: false - focusOnOpened: false - opensUpward: root.opensUpward + tieMenuList.calculateWidth() + } - items: partialTiePopupModel.items + Component.onCompleted: { + partialTiePopupModel.init() + } - onHandleMenuItem: function(itemId) { - partialTiePopupModel.toggleItemChecked(itemId) - } + Column { + id: content + width: tieMenuList.width + height: tieMenuList.height + spacing: 0 PartialTiePopupModel { id: partialTiePopupModel @@ -82,26 +77,54 @@ StyledPopupView { } onItemsChanged: function() { - tieMenuLoader.show(Qt.point(0, 0)) + tieMenuList.model = partialTiePopupModel.items } } - Component.onCompleted: { - partialTiePopupModel.init() - } - NavigationPanel { id: partialTieNavPanel name: "PartialTieMenu" direction: NavigationPanel.Vertical accessible.name: qsTrc("notation", "Partial tie menu items") + } + + StyledListView { + id: tieMenuList + + property int itemHeight: 32 + + implicitWidth: contentItem.childrenRect.width + height: itemHeight * count + + spacing: 0 + arrowControlsAvailable: false - onSectionChanged: function() { - tieMenuLoader.notationViewNavigationSection = section + model: partialTiePopupModel.items + + visible: true + + function calculateWidth() { + var result = 0 + for (var item in tieMenuList.contentItem.children) { + var row = tieMenuList.contentItem.children[item]; + if (!(row instanceof ListItemBlank)) { + continue + } + result = Math.max(result, tieMenuList.contentItem.children[item].calculateWidth()) + } + + tieMenuList.width = result } - onOrderChanged: function() { - tieMenuLoader.navigationOrderStart = order + delegate: PartialTieMenuRowItem { + implicitHeight: tieMenuList.itemHeight + hoverHitColor: ui.theme.accentColor + anchors.left: parent ? parent.left : undefined + anchors.right: parent ? parent.right : undefined + + onClicked: { + partialTiePopupModel.toggleItemChecked(modelData.id) + } } } }