[DocumentPlugin]functional version fixing https://codeberg.org/bugui/score/issues/1

This commit is contained in:
thibaud keller 2024-10-06 15:16:11 +01:00
parent 42f28e2b2f
commit b1c9378732
11 changed files with 305 additions and 207 deletions

View file

@ -13,29 +13,29 @@ endif()
score_common_setup()
set(HDRS
# "Hardware/Hardware.hpp"
# "Hardware/Controller.hpp"
# "Hardware/MidiController.hpp"
"Hardware/Controller.hpp"
"Hardware/MidiController.hpp"
"Hardware/Settings/Model.hpp"
"Hardware/Settings/Presenter.hpp"
"Hardware/Settings/View.hpp"
"Hardware/Settings/Factory.hpp"
"Hardware/DocumentPlugin.hpp"
"Hardware/ApplicationPlugin.hpp"
"score_addon_hardware.hpp"
)
set(SRCS
# "${CMAKE_CURRENT_SOURCE_DIR}/Hardware/Hardware.cpp"
# "${CMAKE_CURRENT_SOURCE_DIR}/Hardware/Controller.cpp"
# "${CMAKE_CURRENT_SOURCE_DIR}/Hardware/MidiController.cpp"
"${CMAKE_CURRENT_SOURCE_DIR}/Hardware/Controller.cpp"
"${CMAKE_CURRENT_SOURCE_DIR}/Hardware/MidiController.cpp"
# "${CMAKE_CURRENT_SOURCE_DIR}/Hardware/Settings/Model.cpp"
# "${CMAKE_CURRENT_SOURCE_DIR}/Hardware/Settings/Presenter.cpp"
# "${CMAKE_CURRENT_SOURCE_DIR}/Hardware/Settings/View.cpp"
"${CMAKE_CURRENT_SOURCE_DIR}/Hardware/Settings/Model.cpp"
"${CMAKE_CURRENT_SOURCE_DIR}/Hardware/Settings/Presenter.cpp"
"${CMAKE_CURRENT_SOURCE_DIR}/Hardware/Settings/View.cpp"
"${CMAKE_CURRENT_SOURCE_DIR}/Hardware/DocumentPlugin.cpp"
"${CMAKE_CURRENT_SOURCE_DIR}/Hardware/ApplicationPlugin.cpp"
"${CMAKE_CURRENT_SOURCE_DIR}/score_addon_hardware.cpp"

View file

@ -1,10 +1,20 @@
#include <score/tools/IdentifierGeneration.hpp>
#include <core/document/Document.hpp>
#include <core/document/DocumentModel.hpp>
#include <Hardware/ApplicationPlugin.hpp>
#include <Hardware/DocumentPlugin.hpp>
namespace Hardware
{
ApplicationPlugin::ApplicationPlugin(const score::GUIApplicationContext& app)
: GUIApplicationPlugin{app}
{ }
void ApplicationPlugin::on_createdDocument(score::Document& doc)
{
doc.model().addPluginModel(new DocumentPlugin{doc.context(), &doc.model()});
}
}

View file

@ -8,5 +8,8 @@ class ApplicationPlugin final : public score::GUIApplicationPlugin
{
public:
ApplicationPlugin(const score::GUIApplicationContext& app);
protected:
void on_createdDocument(score::Document& doc) override;
};
}

View file

@ -1,2 +1,145 @@
#include <wobjectimpl.h>
#include <score/application/ApplicationContext.hpp>
#include <score/actions/ActionManager.hpp>
#include <Scenario/Application/ScenarioActions.hpp>
#include "MidiController.hpp"
#include "Controller.hpp"
namespace Hardware
{
Controller::Controller(const score::DocumentContext& doc)
: h_ofset{0.} // initial horizontal ofset
, v_ofset{0.} // initial verticalal ofset
, h_zoom{.125} // initial horizontal zoom
, v_zoom{1.1} // initial verticalal zoom
{
commandCallback = [&doc, this](Controller::Commands com, const bool& shift) {
switch (com)
{
case Controller::Play:
if (shift)
doc.app.actions.action<Actions::PlayGlobal>().action()->trigger();
else
doc.app.actions.action<Actions::Play>().action()->trigger();
break;
case Controller::Stop:
if (shift)
doc.app.actions.action<Actions::Reinitialize>().action()->trigger();
else
doc.app.actions.action<Actions::Stop>().action()->trigger();
break;
case Controller::Up:
if (shift)
{
v_zoom += .2;
draw_intervals();
}
else
{
v_ofset += .02;
draw_intervals();
}
break;
case Controller::Down:
if (shift)
{
if (v_zoom > .2)
{
v_zoom -= .2;
draw_intervals();
}
}
else
{
v_ofset -= .02;
draw_intervals();
}
break;
case Controller::Left:
if (shift)
{
if (h_zoom > .02)
{
h_zoom -= .02;
draw_intervals();
}
}
else
{
if (h_ofset > 0)
{
h_ofset -= .02;
draw_intervals();
}
}
break;
case Controller::Right:
if (shift)
{
h_zoom += .02;
draw_intervals();
}
else
{
h_ofset += .02;
draw_intervals();
}
break;
default:
break;
}
// qDebug() << "v_ofset: " << v_ofset;
// qDebug() << "v_zoom: " << v_zoom;
// qDebug() << "h_ofset: " << h_ofset;
// qDebug() << "h_zoom: " << h_ofset;
};
}
void Controller::setup()
{
ctl = new MidiController{};
ctl->on_command = commandCallback;
ctl->setup();
}
void Controller::setup_scenario(Scenario::ProcessModel* s)
{
scenar = s;
// Connet interval signals
// adapted from
// src/plugins/score-plugin-scenario/Scenario/Process/MiniScenarioView.cpp#18
scenar->intervals.added.connect<&Controller::on_interval_changed>(this);
scenar->intervals.removed.connect<&Controller::on_interval_changed>(this);
connect(scenar,
&Scenario::ProcessModel::intervalMoved,
[this] { draw_intervals(); });
}
void Controller::on_interval_changed(const Scenario::IntervalModel &)
{
draw_intervals();
}
void Controller::draw_intervals()
{
if (!ctl || !scenar) return;
for(const Scenario::IntervalModel& c : scenar->intervals)
{
auto def = c.duration.defaultDuration().sec() * h_zoom;
auto st = (c.date().sec() * h_zoom) - h_ofset;
auto y = (c.heightPercentage() * v_zoom) + v_ofset;
ctl->draw_line({st, y}, {st + def, y});
}
ctl->update_grid();
}
}
W_OBJECT_IMPL(Hardware::Controller)

View file

@ -1,12 +1,21 @@
#ifndef CONTROLLER_HPP
#define CONTROLLER_HPP
#pragma once
#include <score_addon_hardware_export.h>
#include <Scenario/Document/Interval/IntervalModel.hpp>
#include <Scenario/Process/ScenarioModel.hpp>
namespace Hardware
{
class MidiController;
struct Controller
class SCORE_ADDON_HARDWARE_EXPORT Controller
: public QObject
{
Controller() = default;
W_OBJECT(Controller)
public:
explicit Controller(const score::DocumentContext& doc);
enum Commands
{
@ -17,8 +26,23 @@ struct Controller
Up,
Down
};
};
void setup();
void setup_scenario(Scenario::ProcessModel* s);
void draw_intervals();
private:
double h_ofset;
double v_ofset;
double h_zoom;
double v_zoom;
MidiController* ctl;
Scenario::ProcessModel* scenar;
std::function<void(Controller::Commands, const bool&)> commandCallback;
void on_interval_changed(const Scenario::IntervalModel &);
};
}
#endif // CONTROLLER_HPP

View file

@ -0,0 +1,77 @@
#include <Scenario/Application/ScenarioActions.hpp>
#include <Scenario/Application/ScenarioApplicationPlugin.hpp>
#include <Scenario/Document/BaseScenario/BaseScenario.hpp>
#include <score/actions/Action.hpp>
#include <score/actions/ActionManager.hpp>
#include <score/document/DocumentInterface.hpp>
#include <score/model/path/PathSerialization.hpp>
#include <score/model/tree/TreeNodeSerialization.hpp>
#include <score/serialization/VisitorCommon.hpp>
#include <score/tools/Bind.hpp>
#include <core/document/Document.hpp>
#include <core/document/DocumentModel.hpp>
#include <QBuffer>
#include <Hardware/Settings/Model.hpp>
#include "DocumentPlugin.hpp"
namespace Hardware
{
using namespace std::literals;
DocumentPlugin::DocumentPlugin(const score::DocumentContext& doc, QObject* parent)
: score::DocumentPlugin{doc, "Hardware::DocumentPlugin", parent}
, hardware{doc}
{
auto& set = m_context.app.settings<Settings::Model>();
if(set.getEnabled())
{
create();
}
con(
set, &Settings::Model::EnabledChanged, this,
[this](bool b) {
if(b)
create();
else
cleanup();
},
Qt::QueuedConnection);
}
DocumentPlugin::~DocumentPlugin() { }
void DocumentPlugin::on_documentClosing()
{
cleanup();
}
void DocumentPlugin::create()
{
if(cstr)
cleanup();
auto& doc = m_context.document.model().modelDelegate();
auto scenar = safe_cast<Scenario::ScenarioDocumentModel*>(&doc);
cstr = &scenar->baseScenario().interval();
hardware.setup();
// Get Scenario::processModel
// adapted from
// src/plugins/score-plugin-scenario/Scenario/Document/ScenarioDocument/ScenarioDocumentModel.cpp#67
hardware.setup_scenario(qobject_cast<Scenario::ProcessModel*>(&*cstr->processes.begin()));
}
void DocumentPlugin::cleanup()
{
if(!cstr)
return;
cstr = nullptr;
}
}

View file

@ -0,0 +1,32 @@
#pragma once
#include <score/plugins/documentdelegate/plugin/DocumentPlugin.hpp>
#include <nano_observer.hpp>
#include <score_addon_hardware_export.h>
#include "Controller.hpp"
namespace Scenario
{
class IntervalModel;
}
namespace Hardware
{
class SCORE_ADDON_HARDWARE_EXPORT DocumentPlugin : public score::DocumentPlugin
{
public:
DocumentPlugin(const score::DocumentContext& doc, QObject* parent);
~DocumentPlugin();
void on_documentClosing() override;
Controller hardware;
private:
void create();
void cleanup();
Scenario::IntervalModel* cstr{nullptr};
};
}

View file

@ -1,145 +0,0 @@
#include <wobjectimpl.h>
#include <score/application/ApplicationContext.hpp>
#include <Explorer/DocumentPlugin/DeviceDocumentPlugin.hpp>
#include <score/actions/ActionManager.hpp>
#include <Scenario/Application/ScenarioActions.hpp>
#include "Hardware.hpp"
namespace Hardware
{
Hardware::Hardware(const score::DocumentContext& doc)
: m_dev{doc.plugin<Explorer::DeviceDocumentPlugin>()}
, h_ofset{0.} // initial horizontal ofset
, v_ofset{0.} // initial verticalal ofset
, h_zoom{.125} // initial horizontal zoom
, v_zoom{1.1} // initial verticalal zoom
{
commandCallback = [&doc, this](Controller::Commands com, const bool& shift) {
switch (com)
{
case Controller::Play:
if (shift)
doc.app.actions.action<Actions::PlayGlobal>().action()->trigger();
else
doc.app.actions.action<Actions::Play>().action()->trigger();
break;
case Controller::Stop:
if (shift)
doc.app.actions.action<Actions::Reinitialize>().action()->trigger();
else
doc.app.actions.action<Actions::Stop>().action()->trigger();
break;
case Controller::Up:
if (shift)
{
v_zoom += .2;
draw_intervals();
}
else
{
v_ofset += .02;
draw_intervals();
}
break;
case Controller::Down:
if (shift)
{
if (v_zoom > .2)
{
v_zoom -= .2;
draw_intervals();
}
}
else
{
v_ofset -= .02;
draw_intervals();
}
break;
case Controller::Left:
if (shift)
{
if (h_zoom > .02)
{
h_zoom -= .02;
draw_intervals();
}
}
else
{
if (h_ofset > 0)
{
h_ofset -= .02;
draw_intervals();
}
}
break;
case Controller::Right:
if (shift)
{
h_zoom += .02;
draw_intervals();
}
else
{
h_ofset += .02;
draw_intervals();
}
break;
default:
break;
}
// qDebug() << "v_ofset: " << v_ofset;
// qDebug() << "v_zoom: " << v_zoom;
// qDebug() << "h_ofset: " << h_ofset;
// qDebug() << "h_zoom: " << h_ofset;
};
}
void Hardware::setupController()
{
ctl = new MidiController{};
ctl->on_command = commandCallback;
ctl->setup();
}
void Hardware::setup_scenario(Scenario::ProcessModel* s)
{
scenar = s;
// Connet interval signals
// adapted from
// src/plugins/score-plugin-scenario/Scenario/Process/MiniScenarioView.cpp#18
scenar->intervals.added.connect<&Hardware::on_interval_changed>(this);
scenar->intervals.removed.connect<&Hardware::on_interval_changed>(this);
connect(scenar,
&Scenario::ProcessModel::intervalMoved,
[this] { draw_intervals(); });
}
void Hardware::on_interval_changed(const Scenario::IntervalModel &)
{
draw_intervals();
}
void Hardware::draw_intervals()
{
if (!ctl || !scenar) return;
for(const Scenario::IntervalModel& c : scenar->intervals)
{
auto def = c.duration.defaultDuration().sec() * h_zoom;
auto st = (c.date().sec() * h_zoom) - h_ofset;
auto y = (c.heightPercentage() * v_zoom) + v_ofset;
ctl->draw_line({st, y}, {st + def, y});
}
ctl->update_grid();
}
}
W_OBJECT_IMPL(Hardware::Hardware)

View file

@ -1,39 +0,0 @@
#pragma once
// #include <score_addon_hardware_export.h>
#include <Scenario/Document/Interval/IntervalModel.hpp>
#include <Scenario/Process/ScenarioModel.hpp>
#include "MidiController.hpp"
namespace Hardware
{
class /*SCORE_PLUGIN_HARDWARE_EXPORT*/ Hardware
: public QObject
{
W_OBJECT(Hardware)
public:
explicit Hardware(const score::DocumentContext& doc);
void setupController();
void setup_scenario(Scenario::ProcessModel* s);
void draw_intervals();
private:
double h_ofset;
double v_ofset;
double h_zoom;
double v_zoom;
MidiController* ctl;
Explorer::DeviceDocumentPlugin& m_dev;
Scenario::ProcessModel* scenar;
std::function<void(Controller::Commands, const bool&)> commandCallback;
void on_interval_changed(const Scenario::IntervalModel &);
};
}

View file

@ -39,14 +39,9 @@
#define MAX_ROW_INDEX 7
#define MAX_COLUMN_INDEX 7
namespace Explorer
{
class DeviceDocumentPlugin;
}
namespace Hardware
{
class MidiController : public Controller
class MidiController
{
public:
MidiController();

View file

@ -3,8 +3,6 @@
#include <score_addon_hardware_export.h>
#include <tuple>
namespace Hardware
{
namespace Settings