From db8d6e54a190e1799e26e3e5998320fce8bd6ca6 Mon Sep 17 00:00:00 2001 From: Roman Pudashkin Date: Tue, 19 May 2026 12:58:25 +0300 Subject: [PATCH 1/2] Add StyledPopupLoader --- .../qml/Muse/UiComponents/CMakeLists.txt | 1 + .../Muse/UiComponents/StyledPopupLoader.qml | 98 +++++++++++++++++++ 2 files changed, 99 insertions(+) create mode 100644 framework/uicomponents/qml/Muse/UiComponents/StyledPopupLoader.qml diff --git a/framework/uicomponents/qml/Muse/UiComponents/CMakeLists.txt b/framework/uicomponents/qml/Muse/UiComponents/CMakeLists.txt index 3ed6bb5d1b..05d342281c 100644 --- a/framework/uicomponents/qml/Muse/UiComponents/CMakeLists.txt +++ b/framework/uicomponents/qml/Muse/UiComponents/CMakeLists.txt @@ -143,6 +143,7 @@ qt_add_qml_module(muse_uicomponents_qml StyledListView.qml StyledMenuLoader.qml StyledPopupView.qml + StyledPopupLoader.qml StyledScrollBar.qml StyledSlider.qml StyledTabBar.qml diff --git a/framework/uicomponents/qml/Muse/UiComponents/StyledPopupLoader.qml b/framework/uicomponents/qml/Muse/UiComponents/StyledPopupLoader.qml new file mode 100644 index 0000000000..aacf2e7fde --- /dev/null +++ b/framework/uicomponents/qml/Muse/UiComponents/StyledPopupLoader.qml @@ -0,0 +1,98 @@ +/* + * SPDX-License-Identifier: GPL-3.0-only + * MuseScore-CLA-applies + * + * MuseScore + * Music Composition & Notation + * + * Copyright (C) 2026 MuseScore Limited 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 . + */ +pragma ComponentBehavior: Bound + +import QtQuick + +import Muse.UiComponents + +Loader { + id: loader + + property StyledPopupView popup: loader.item as StyledPopupView + property Item popupAnchorItem: null + + readonly property bool isOpened: Boolean(loader.popup) && loader.popup.isOpened + + signal opened() + signal closed() + + function open() { + if (loader.status === Loader.Ready) { + loader.popup.open() + } else { + prv.pendingOpen = true + loader.active = true + } + } + + function toggleOpened() { + if (loader.isOpened || prv.pendingOpen) { + close() + return + } + + open() + } + + function close() { + prv.pendingOpen = false + + if (loader.isOpened) { + loader.popup.close() + } + } + + QtObject { + id: prv + + property bool pendingOpen: false + + function unloadPopup() { + if (loader.popup && loader.popup.isOpened) { + return + } + + loader.active = false + Qt.callLater(loader.closed) + } + } + + active: false + + onLoaded: { + var popup = loader.popup + popup.parent = loader.parent + + if (loader.popupAnchorItem) { + popup.anchorItem = loader.popupAnchorItem + } + + popup.opened.connect(function() { Qt.callLater(loader.opened) }) + popup.closed.connect(function() { Qt.callLater(prv.unloadPopup) }) + + if (prv.pendingOpen) { + prv.pendingOpen = false + popup.open() + } + } +} From 481b97acb5bde2dfebf4089c9f874de7776eff0a Mon Sep 17 00:00:00 2001 From: Roman Pudashkin Date: Tue, 19 May 2026 13:50:04 +0300 Subject: [PATCH 2/2] Add PopupButton --- .../qml/Muse/UiComponents/CMakeLists.txt | 1 + .../qml/Muse/UiComponents/PopupButton.qml | 53 +++++++++++++++++++ 2 files changed, 54 insertions(+) create mode 100644 framework/uicomponents/qml/Muse/UiComponents/PopupButton.qml diff --git a/framework/uicomponents/qml/Muse/UiComponents/CMakeLists.txt b/framework/uicomponents/qml/Muse/UiComponents/CMakeLists.txt index 05d342281c..471a4a7b76 100644 --- a/framework/uicomponents/qml/Muse/UiComponents/CMakeLists.txt +++ b/framework/uicomponents/qml/Muse/UiComponents/CMakeLists.txt @@ -123,6 +123,7 @@ qt_add_qml_module(muse_uicomponents_qml NumberInputField.qml PageIndicator.qml PageTabButton.qml + PopupButton.qml PopupPanel.qml ProgressBar.qml ProgressButton.qml diff --git a/framework/uicomponents/qml/Muse/UiComponents/PopupButton.qml b/framework/uicomponents/qml/Muse/UiComponents/PopupButton.qml new file mode 100644 index 0000000000..8846a02190 --- /dev/null +++ b/framework/uicomponents/qml/Muse/UiComponents/PopupButton.qml @@ -0,0 +1,53 @@ +/* + * SPDX-License-Identifier: GPL-3.0-only + * MuseScore-CLA-applies + * + * MuseScore + * Music Composition & Notation + * + * Copyright (C) 2026 MuseScore Limited 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 + +import Muse.UiComponents + +FlatButton { + id: root + + property alias popupAnchorItem: popupLoader.popupAnchorItem + property alias popupComponent: popupLoader.sourceComponent + + property alias isPopupOpened: popupLoader.isOpened + + signal popupOpened() + signal popupClosed() + + function close() { + popupLoader.close() + } + + accentButton: root.isPopupOpened + + StyledPopupLoader { + id: popupLoader + + onOpened: root.popupOpened() + onClosed: root.popupClosed() + } + + onClicked: { + popupLoader.toggleOpened() + } +}