Line data Source code
1 : /*
2 : * SPDX-License-Identifier: GPL-3.0-only
3 : * MuseScore-CLA-applies
4 : *
5 : * MuseScore Studio
6 : * Music Composition & Notation
7 : *
8 : * Copyright (C) 2021 MuseScore Limited and others
9 : *
10 : * This program is free software: you can redistribute it and/or modify
11 : * it under the terms of the GNU General Public License version 3 as
12 : * published by the Free Software Foundation.
13 : *
14 : * This program is distributed in the hope that it will be useful,
15 : * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 : * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 : * GNU General Public License for more details.
18 : *
19 : * You should have received a copy of the GNU General Public License
20 : * along with this program. If not, see <https://www.gnu.org/licenses/>.
21 : */
22 :
23 : #include "buttonboxmodel.h"
24 :
25 : #include "containers.h"
26 :
27 : #include "log.h"
28 :
29 : using namespace muse::uicomponents;
30 :
31 0 : ButtonBoxModel::ButtonBoxModel(QObject* parent)
32 0 : : QObject(parent), m_buttonsItems(this)
33 : {
34 0 : }
35 :
36 0 : QList<int> ButtonBoxModel::load()
37 : {
38 0 : QList<int> result;
39 0 : std::unordered_map <int, std::vector <LayoutButton*> > sortedButtons;
40 0 : int maxCustomRole = static_cast<int>(ButtonRole::CustomRole);
41 :
42 0 : const QList<QQuickItem*> buttonsItems = m_buttonsItems.list();
43 0 : for (const QQuickItem* item : buttonsItems) {
44 0 : QVariant buttonTypeVar = item->property("buttonId");
45 0 : int type = static_cast<int>(ButtonType::CustomButton);
46 0 : LayoutButton* button = nullptr;
47 0 : if (buttonTypeVar.isValid()) {
48 0 : type = buttonTypeVar.toInt();
49 0 : if (type >= static_cast<int>(ButtonType::CustomButton)) {
50 0 : button = layoutButton(item);
51 : } else {
52 0 : button = m_layoutButtons[static_cast<ButtonType>(type)];
53 : }
54 : } else {
55 0 : button = m_layoutButtons[static_cast<ButtonType>(type)];
56 : }
57 :
58 0 : IF_ASSERT_FAILED(button) {
59 0 : continue;
60 : }
61 :
62 0 : ButtonRole role = button->buttonRole;
63 0 : if (role >= ButtonRole::CustomRole) {
64 0 : maxCustomRole = std::max(maxCustomRole, static_cast<int>(role));
65 : }
66 :
67 0 : sortedButtons[role].push_back(button);
68 0 : }
69 :
70 0 : const std::vector<ButtonRole>& currentLayout = chooseButtonLayoutType();
71 :
72 0 : auto buttonsByRole = [&sortedButtons, maxCustomRole](ButtonRole buttonRole) -> std::vector<LayoutButton*> {
73 0 : bool isCustom = buttonRole == ButtonRole::CustomRole;
74 0 : if (!isCustom) {
75 0 : if (muse::contains(sortedButtons, static_cast<int>(buttonRole))) {
76 0 : return sortedButtons[buttonRole];
77 : }
78 :
79 0 : return {};
80 : }
81 :
82 0 : std::vector<LayoutButton*> buttons;
83 0 : for (int role = static_cast<int>(ButtonRole::CustomRole); role <= maxCustomRole; ++role) {
84 0 : for (LayoutButton* button : sortedButtons[role]) {
85 0 : buttons.push_back(button);
86 : }
87 : }
88 :
89 0 : return buttons;
90 0 : };
91 :
92 0 : for (ButtonRole buttonRole : currentLayout) {
93 0 : std::vector<LayoutButton*> buttons = buttonsByRole(buttonRole);
94 :
95 0 : for (LayoutButton* button : buttons) {
96 0 : result << button->buttonType;
97 : }
98 0 : }
99 :
100 0 : return result;
101 0 : }
102 :
103 0 : void ButtonBoxModel::setButtons(const QVariantList& buttons)
104 : {
105 0 : for (const QVariant& buttonTypeVar : buttons) {
106 0 : LayoutButton* button = m_layoutButtons[ButtonType(buttonTypeVar.toInt())];
107 0 : emit addButton(button->text, button->buttonType, button->buttonRole, button->isAccent, button->isLeftSide);
108 : }
109 0 : }
110 :
111 0 : const std::vector <ButtonBoxModel::ButtonRole>& ButtonBoxModel::chooseButtonLayoutType()
112 : {
113 0 : size_t index = 0;
114 0 : if (m_buttonLayout != ButtonLayout::UnknownLayout) {
115 0 : index = static_cast<size_t>(m_buttonLayout);
116 : } else {
117 : #if defined (Q_OS_MACOS)
118 : index = 1;
119 : #elif defined (Q_OS_LINUX) || defined (Q_OS_UNIX) || defined(Q_OS_FREEBSD)
120 0 : index = 2;
121 : #endif
122 : }
123 :
124 0 : IF_ASSERT_FAILED(index < buttonRoleLayouts.size()) {
125 0 : index = 0;
126 : }
127 :
128 0 : return buttonRoleLayouts[index];
129 : }
130 :
131 0 : ButtonBoxModel::LayoutButton* ButtonBoxModel::layoutButton(const QQuickItem* item) const
132 : {
133 0 : QString text = item->property("text").toString();
134 0 : ButtonRole role = static_cast<ButtonRole>(item->property("buttonRole").toInt());
135 0 : int type = item->property("buttonId").toInt();
136 0 : bool isAccent = item->property("accentButton").toBool();
137 0 : bool isLeftSide = item->property("isLeftSide").toBool();
138 :
139 0 : return new LayoutButton(text, type, role, isAccent, isLeftSide);
140 0 : }
141 :
142 0 : ButtonBoxModel::ButtonLayout ButtonBoxModel::buttonLayout() const
143 : {
144 0 : return m_buttonLayout;
145 : }
146 :
147 0 : void ButtonBoxModel::setButtonLayout(ButtonLayout newButtonLayout)
148 : {
149 0 : if (m_buttonLayout == newButtonLayout) {
150 0 : return;
151 : }
152 0 : m_buttonLayout = newButtonLayout;
153 0 : emit buttonLayoutChanged();
154 :
155 0 : emit reloadRequested();
156 : }
157 :
158 0 : QQmlListProperty<QQuickItem> ButtonBoxModel::buttonsItems()
159 : {
160 0 : return m_buttonsItems.property();
161 : }
|