Line data Source code
1 : /*
2 : * SPDX-License-Identifier: GPL-3.0-only
3 : * MuseScore-Studio-CLA-applies
4 : *
5 : * MuseScore Studio
6 : * Music Composition & Notation
7 : *
8 : * Copyright (C) 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 "appshellcommandsstate.h"
24 :
25 : #include "appshelltypes.h"
26 : #include "global/containers.h"
27 :
28 : #include "dockwindow/idockwindow.h"
29 :
30 : #include "../appshellcommands.h"
31 : #include <vector>
32 :
33 : using namespace muse;
34 : using namespace muse::rcommand;
35 : using namespace muse::dock;
36 : using namespace mu::appshell;
37 :
38 : static const muse::Uri PROJECT_PAGE_URI("musescore://notation");
39 :
40 : static const std::vector<Command> PROJECT_PAGE_COMMANDS = {
41 : DOCK_TOGGLE_PLAYBACK_COMMAND,
42 : DOCK_TOGGLE_NOTEINPUT_COMMAND,
43 : DOCK_TOGGLE_PALETTES_COMMAND,
44 : DOCK_TOGGLE_INSTRUMENTS_COMMAND,
45 : DOCK_TOGGLE_PROPERTIES_COMMAND,
46 : DOCK_TOGGLE_SELECTION_FILTER_COMMAND,
47 : DOCK_TOGGLE_UNDO_HISTORY_COMMAND,
48 : DOCK_TOGGLE_NAVIGATOR_COMMAND,
49 : DOCK_TOGGLE_BRAILLE_COMMAND,
50 : DOCK_TOGGLE_TIMELINE_COMMAND,
51 : DOCK_TOGGLE_MIXER_COMMAND,
52 : DOCK_TOGGLE_PIANO_KEYBOARD_COMMAND,
53 : DOCK_TOGGLE_PERCUSSION_COMMAND,
54 : DOCK_TOGGLE_STATUSBAR_COMMAND,
55 : };
56 :
57 0 : std::string AppshellCommandsState::moduleName() const
58 : {
59 0 : return "appshell";
60 : }
61 :
62 0 : void AppshellCommandsState::init()
63 : {
64 0 : m_moduleRegister = commandsRegister()->moduleRegister(moduleName());
65 0 : IF_ASSERT_FAILED(m_moduleRegister) {
66 0 : return;
67 : }
68 :
69 0 : mainWindow()->isFullScreenChanged().onNotify(this, [this]() {
70 0 : updateCommandStates({ APP_FULLSCREEN_COMMAND });
71 0 : });
72 :
73 0 : appShellState()->isNotationNavigatorVisibleChanged().onNotify(this, [this]() {
74 0 : updateCommandStates({ DOCK_TOGGLE_NAVIGATOR_COMMAND });
75 0 : });
76 :
77 0 : brailleConfiguration()->braillePanelEnabledChanged().onNotify(this, [this]() {
78 0 : updateCommandStates({ DOCK_TOGGLE_BRAILLE_COMMAND });
79 0 : });
80 :
81 0 : dockWindowProvider()->windowChanged().onNotify(this, [this]() {
82 0 : const IDockWindow* window = dockWindowProvider()->window();
83 0 : if (!window) {
84 0 : return;
85 : }
86 :
87 0 : window->docksOpenStatusChanged().onReceive(this, [this](const QStringList& dockNames) {
88 0 : std::vector<Command> commands;
89 0 : commands.reserve(dockNames.size());
90 0 : for (const QString& dockName : dockNames) {
91 0 : Command cmd = commandsController()->dockToggleCommand(dockName);
92 0 : if (cmd.isValid()) {
93 0 : commands.push_back(std::move(cmd));
94 : }
95 0 : }
96 :
97 0 : updateCommandStates({ commands });
98 0 : });
99 : });
100 :
101 0 : interactive()->currentUri().ch.onReceive(this, [this](const muse::Uri&) {
102 0 : updateCommandStates(PROJECT_PAGE_COMMANDS);
103 0 : });
104 :
105 0 : updateCommandStates();
106 : }
107 :
108 0 : void AppshellCommandsState::deinit()
109 : {
110 0 : mainWindow()->isFullScreenChanged().disconnect(this);
111 0 : }
112 :
113 0 : void AppshellCommandsState::updateCommandStates(const std::vector<Command>& commands)
114 : {
115 0 : IF_ASSERT_FAILED(m_moduleRegister) {
116 0 : return;
117 : }
118 :
119 0 : const auto& commandList = commands.empty() ? m_moduleRegister->commandList() : commands;
120 :
121 0 : for (const auto& command : commandList) {
122 0 : CommandState newState = commandState(command);
123 0 : if (m_commandStates[command] != newState) {
124 0 : m_commandStates[command] = newState;
125 0 : m_commandStateChanged.send(command, newState);
126 : }
127 : }
128 : }
129 :
130 0 : CommandState AppshellCommandsState::commandState(const Command& command) const
131 : {
132 0 : if (command == APP_FULLSCREEN_COMMAND) {
133 0 : return CommandState(true, mainWindow()->isFullScreen());
134 : }
135 :
136 0 : if (muse::contains(PROJECT_PAGE_COMMANDS, command)) {
137 0 : if (!isProjectPage()) {
138 0 : return CommandState(false, false);
139 : }
140 : }
141 :
142 0 : if (command == DOCK_TOGGLE_NAVIGATOR_COMMAND) {
143 0 : return CommandState(true, appShellState()->isNotationNavigatorVisible());
144 : }
145 :
146 0 : if (command == DOCK_TOGGLE_BRAILLE_COMMAND) {
147 0 : return CommandState(true, brailleConfiguration()->braillePanelEnabled());
148 : }
149 :
150 0 : const DockName dockName = commandsController()->commandDockName(command);
151 0 : if (!dockName.isEmpty()) {
152 0 : const IDockWindow* window = dockWindowProvider()->window();
153 0 : bool opened = window ? window->isDockOpen(dockName) : false;
154 0 : return CommandState(true, opened);
155 : }
156 :
157 0 : return CommandState(true, false);
158 0 : }
159 :
160 0 : async::Channel<Command, CommandState> AppshellCommandsState::commandStateChanged() const
161 : {
162 0 : return m_commandStateChanged;
163 : }
164 :
165 0 : bool AppshellCommandsState::isProjectPage() const
166 : {
167 0 : if (!interactive()) {
168 0 : return false;
169 : }
170 :
171 0 : return interactive()->isOpened(PROJECT_PAGE_URI).val;
172 : }
|