-
Notifications
You must be signed in to change notification settings - Fork 2.7k
Actions
Actions
are intentions that are sent from the view (or from somewhere else) to the model. The model (by actions controller) processes the action, changes its state and sends a notification of changes. See interact workflow.
Action consists of a code, that's all
namespace mu::actions {
using ActionCode = std::string;
}
All actions are processed by some specific modules, there are no global actions or actions that do not belong to anyone. Each module can have an action controller to handle the actions associated with that module. Also, some actions can handle the view models of the module (for example, changing the zoom).
Actions can be without arguments (most) and with arguments.
Basically, to add a new action, we just need to register its handler with the action dispatcher.
For example, registering an action:
dispatcher()->reg(this, "do-something", [this]() { ... });
To send actions, use the Action Dispatcher
.
At the moment, we can use the dispatcher only in C++ code and we do not plan to add the ability to use the dispatcher in Qml directly. If you want to send an action, when a button is clicked in Qml, then there must be a cpp model, the method of which is called when the button is clicked and an action is dispatched in the method implementation.
Adding a dispatcher dependency:
...
#include "modularity/ioc.h"
#include "actions/iactionsdispatcher.h"
...
class NotationToolBarModel
{
INJECT(notation_scene, actions::IActionsDispatcher, dispatcher)
...
}
Submit Actions
// without arguments
dispatcher()->dispatch("note-input");
// with arguments
dispatcher()->dispatch("put-note", ActionData::make_arg3<QPoint, bool, bool>(logicPos, replace, insert));
Usually, a module that can handle some kind of actions, have the actions controller.
Controller registers action handlers
void NotationActionController::init()
{
// without arguments
dispatcher()->reg("pad-note-4", [this]() { padNote(Pad::NOTE4); });
dispatcher()->reg("note-input", this, &NotationActionController::toggleNoteInput);
...
// with argumens
dispatcher()->reg("put-note", [this](const ActionData& args) { ... });
dispatcher()->reg("put-note", this, &NotationActionController::putNote);
...
// there are also other possible registration signatures, see IActionsDispatcher
}
// Where
void NotationActionController::putNote(const actions::ActionData& data)
{
...
QPoint pos = data.arg<QPoint>(0);
bool replace = data.arg<bool>(1);
bool insert = data.arg<bool>(2);
notation->putNote(pos, replace, insert);
}
For a class to register in dispatcher, it must inherit from actions::Actionable
...
#include "actions/actionable.h"
...
class NotationActionController : public actions::Actionable
{
...
};
Also, the controller must determine if it is technically possible to handle the action now.
For example, if the action depends on the selected notation element, and now nothing is selected, then the action cannot be processed.
To do this, the controller must implement the canReceiveAction
method
For example:
bool NotationActionController::canReceiveAction(const actions::ActionCode& code) const
{
//! NOTE If the notation is not loaded, we cannot process anything.
if (!currentNotation()) {
return false;
}
//! NOTE At the moment, if we are in the text editing mode, we can only process the escape
if (isTextEditting()) {
return code == ESCAPE_ACTION_CODE;
}
if (code == UNDO_ACTION_CODE) {
return canUndo();
}
if (code == REDO_ACTION_CODE) {
return canRedo();
}
...
return true;
}
View models can also be action controllers for actions that are associated with these view models (for example, changing the zoom)
Testing
- Manual testing
- Automatic testing
Translation
Compilation
- Set up developer environment
- Install Qt and Qt Creator
- Get MuseScore's source code
- Install dependencies
- Compile on the command line
- Compile in Qt Creator
Beyond compiling
Misc. development
Architecture general
- Architecture overview
- AppShell
- Modularity
- Interact workflow
- Channels and Notifications
- Settings and Configuration
- Error handling
- Launcher and Interactive
- Keyboard Navigation
Audio
Engraving
- Style settings
- Working with style files
- Style parameter changes for 4.0
- Style parameter changes for 4.1
- Style parameter changes for 4.2
- Style parameter changes for 4.3
- Style parameter changes for 4.4
Extensions
- Extensions overview
- Manifest
- Forms
- Macros
- Api
- Legacy plugin API
Google Summer of Code
References