Merge pull request #7737 from igorkorsukov/mu4/autobot/draw_diff

[MU4] Added diff painting step
This commit is contained in:
RomanPudashkin 2021-03-18 10:27:51 +02:00 committed by GitHub
commit 210132326e
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
23 changed files with 354 additions and 73 deletions

View file

@ -57,12 +57,14 @@ set(MODULE_SRC
${CMAKE_CURRENT_LIST_DIR}/internal/steps/abscoreclosestep.h
${CMAKE_CURRENT_LIST_DIR}/internal/steps/abscorezoom.cpp
${CMAKE_CURRENT_LIST_DIR}/internal/steps/abscorezoom.h
${CMAKE_CURRENT_LIST_DIR}/internal/steps/abdrawserializationstep.cpp
${CMAKE_CURRENT_LIST_DIR}/internal/steps/abdrawserializationstep.h
${CMAKE_CURRENT_LIST_DIR}/internal/steps/abdrawdeserializationstep.cpp
${CMAKE_CURRENT_LIST_DIR}/internal/steps/abdrawdeserializationstep.h
${CMAKE_CURRENT_LIST_DIR}/internal/steps/abdrawcurrentstep.cpp
${CMAKE_CURRENT_LIST_DIR}/internal/steps/abdrawcurrentstep.h
${CMAKE_CURRENT_LIST_DIR}/internal/steps/abdrawrefstep.cpp
${CMAKE_CURRENT_LIST_DIR}/internal/steps/abdrawrefstep.h
${CMAKE_CURRENT_LIST_DIR}/internal/steps/abdrawcompstep.cpp
${CMAKE_CURRENT_LIST_DIR}/internal/steps/abdrawcompstep.h
${CMAKE_CURRENT_LIST_DIR}/internal/steps/abdiffdrawstep.cpp
${CMAKE_CURRENT_LIST_DIR}/internal/steps/abdiffdrawstep.h
${CMAKE_CURRENT_LIST_DIR}/view/autobotmodel.cpp
${CMAKE_CURRENT_LIST_DIR}/view/autobotmodel.h
)

View file

@ -23,9 +23,10 @@
#include "steps/abscoreloadstep.h"
#include "steps/abscorezoom.h"
#include "steps/abscoreclosestep.h"
#include "steps/abdrawserializationstep.h"
#include "steps/abdrawdeserializationstep.h"
#include "steps/abdrawcurrentstep.h"
#include "steps/abdrawrefstep.h"
#include "steps/abdrawcompstep.h"
#include "steps/abdiffdrawstep.h"
using namespace mu::autobot;
@ -34,11 +35,14 @@ void AbRunner::init()
m_steps = {
Step(new AbScoreLoadStep()),
Step(new AbScoreZoom(100), 10),
Step(new AbDrawSerializationStep(), 0),
Step(new AbDrawDeserializationStep(), 0),
Step(new AbDrawCurrentStep(false), 0),
Step(new AbDrawRefStep(), 0),
Step(new AbDrawCompStep(), 0),
Step(new AbScoreZoom(50), 1000),
Step(new AbScoreZoom(100), 1000),
Step(new AbDiffDrawStep(), 0),
//Step(new AbScoreZoom(50), 1000),
//Step(new AbScoreZoom(100), 1000),
Step(new AbScoreCloseStep(), 1000)
};

View file

@ -19,6 +19,12 @@
#include "abpaintprovider.h"
#include "log.h"
#include "libmscore/draw/painter.h"
static const QColor REMOVED_COLOR("#cc0000");
static const QColor ADDED_COLOR("#009900");
static const std::string NOTATION_DEFAULT_OBJ("notationview_default");
using namespace mu::autobot;
@ -28,16 +34,91 @@ const std::shared_ptr<AbPaintProvider>& AbPaintProvider::instance()
return p;
}
AbPaintProvider::AbPaintProvider()
{
}
void AbPaintProvider::beginTarget(const std::string& name)
{
LOGI() << name;
BufferedPaintProvider::beginTarget(name);
}
void AbPaintProvider::beforeEndTargetHook(draw::Painter* painter)
{
IF_ASSERT_FAILED(painter) {
return;
}
if (!m_isDiffDrawEnabled) {
return;
}
draw::IPaintProviderPtr provider = painter->provider();
if (m_diff.dataRemoved && !m_diff.dataRemoved->objects.empty()) {
paintData(provider, m_diff.dataRemoved, REMOVED_COLOR);
}
if (m_diff.dataAdded && !m_diff.dataAdded->objects.empty()) {
paintData(provider, m_diff.dataAdded, ADDED_COLOR);
}
}
void AbPaintProvider::paintData(draw::IPaintProviderPtr provider, const draw::DrawDataPtr& data, const QColor& overcolor)
{
using namespace mu::draw;
for (const DrawData::Object& obj : data->objects) {
if (obj.name == NOTATION_DEFAULT_OBJ) {
continue;
}
for (const DrawData::Data& d : obj.datas) {
DrawData::State st = d.state;
st.pen.setColor(overcolor);
st.pen.setWidth(10);
st.brush.setColor(overcolor);
provider->setPen(st.pen);
provider->setBrush(st.brush);
provider->setFont(st.font);
provider->setTransform(st.transform);
provider->setAntialiasing(st.isAntialiasing);
provider->setCompositionMode(st.compositionMode);
for (const DrawPath& path : d.paths) {
provider->setPen(path.pen);
provider->setBrush(path.brush);
provider->drawPath(path.path);
}
for (const DrawPolygon& pl : d.polygons) {
if (pl.polygon.empty()) {
continue;
}
provider->drawPolygon(&pl.polygon[0], pl.polygon.size(), pl.mode);
}
for (const DrawText& t : d.texts) {
provider->drawText(t.pos, t.text);
}
for (const DrawRectText& t : d.rectTexts) {
provider->drawText(t.rect, t.flags, t.text);
}
for (const DrawGlyphRun& g : d.glyphs) {
provider->drawGlyphRun(g.pos, g.glyphRun);
}
for (const DrawPixmap& px : d.pixmaps) {
provider->drawPixmap(px.pos, px.pm);
}
for (const DrawTiledPixmap& px : d.tiledPixmap) {
provider->drawTiledPixmap(px.rect, px.pm, px.offset);
}
}
}
}
bool AbPaintProvider::endTarget(bool endDraw)
{
bool ok = BufferedPaintProvider::endTarget(endDraw);
@ -51,3 +132,13 @@ const mu::draw::DrawData& AbPaintProvider::notationViewDrawData() const
{
return m_notationViewDrawData;
}
void AbPaintProvider::setDiff(const draw::Diff& diff)
{
m_diff = diff;
}
void AbPaintProvider::setIsDiffDrawEnabled(bool arg)
{
m_isDiffDrawEnabled = arg;
}

View file

@ -21,6 +21,7 @@
#include <memory>
#include "libmscore/draw/bufferedpaintprovider.h"
#include "libmscore/draw/drawtypes.h"
namespace mu::autobot {
class AbPaintProvider : public draw::BufferedPaintProvider
@ -30,14 +31,23 @@ public:
static const std::shared_ptr<AbPaintProvider>& instance();
void beginTarget(const std::string& name) override;
void beforeEndTargetHook(draw::Painter* painter) override;
bool endTarget(bool endDraw = false) override;
const draw::DrawData& notationViewDrawData() const;
void setDiff(const draw::Diff& diff);
void setIsDiffDrawEnabled(bool arg);
private:
AbPaintProvider();
AbPaintProvider() = default;
void paintData(draw::IPaintProviderPtr provider, const draw::DrawDataPtr& data, const QColor& overcolor);
draw::DrawData m_notationViewDrawData;
draw::Diff m_diff;
bool m_isDiffDrawEnabled = false;
};
}

View file

@ -0,0 +1,36 @@
//=============================================================================
// MuseScore
// Music Composition & Notation
//
// Copyright (C) 2021 MuseScore BVBA 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 2.
//
// 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, write to the Free Software
// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
//=============================================================================
#include "abdiffdrawstep.h"
#include "log.h"
#include "../draw/abpaintprovider.h"
#include "libmscore/draw/drawtypes.h"
#include "libmscore/draw/drawcomp.h"
using namespace mu::autobot;
void AbDiffDrawStep::doRun(AbContext ctx)
{
draw::Diff diff = ctx.val<draw::Diff>(AbContext::Key::DiffDrawData);
AbPaintProvider::instance()->setDiff(diff);
AbPaintProvider::instance()->setIsDiffDrawEnabled(true);
dispatcher()->dispatch("dev-notationview-redraw");
}

View file

@ -0,0 +1,39 @@
//=============================================================================
// MuseScore
// Music Composition & Notation
//
// Copyright (C) 2021 MuseScore BVBA 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 2.
//
// 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, write to the Free Software
// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
//=============================================================================
#ifndef MU_AUTOBOT_ABDIFFDRAWSTEP_H
#define MU_AUTOBOT_ABDIFFDRAWSTEP_H
#include "../abbasestep.h"
#include "modularity/ioc.h"
#include "actions/iactionsdispatcher.h"
namespace mu::autobot {
class AbDiffDrawStep : public AbBaseStep
{
INJECT(autobot, actions::IActionsDispatcher, dispatcher)
public:
AbDiffDrawStep() = default;
protected:
void doRun(AbContext ctx) override;
};
}
#endif // MU_AUTOBOT_ABDIFFDRAWSTEP_H

View file

@ -41,8 +41,8 @@ void AbDrawCompStep::doRun(AbContext ctx)
draw::DrawComp::Tolerance tolerance;
tolerance.base = 0.01;
draw::DrawComp::Diff diff = draw::DrawComp::compare(curBuf, refBuf, tolerance);
ctx.setVal<draw::DrawComp::Diff>(AbContext::Key::DiffDrawData, diff);
draw::Diff diff = draw::DrawComp::compare(curBuf, refBuf, tolerance);
ctx.setVal<draw::Diff>(AbContext::Key::DiffDrawData, diff);
if (diff.empty()) {
LOGI() << "draw data equals";

View file

@ -16,7 +16,7 @@
// along with this program; if not, write to the Free Software
// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
//=============================================================================
#include "abdrawserializationstep.h"
#include "abdrawcurrentstep.h"
#include <QFile>
@ -25,9 +25,23 @@
#include "libmscore/draw/drawjson.h"
using namespace mu::autobot;
using namespace mu::draw;
void AbDrawSerializationStep::doRun(AbContext ctx)
AbDrawCurrentStep::AbDrawCurrentStep(bool isDoSave)
: m_isDoSave(isDoSave)
{
}
void AbDrawCurrentStep::doRun(AbContext ctx)
{
const DrawData& buf = AbPaintProvider::instance()->notationViewDrawData();
ctx.setVal<DrawDataPtr>(AbContext::Key::CurDrawData, std::make_shared<DrawData>(buf));
if (!m_isDoSave) {
doFinish(ctx);
return;
}
io::path drawDataPath = configuration()->drawDataPath();
if (!fileSystem()->exists(drawDataPath)) {
Ret ret = fileSystem()->makePath(drawDataPath);
@ -38,9 +52,6 @@ void AbDrawSerializationStep::doRun(AbContext ctx)
}
}
const draw::DrawData& buf = AbPaintProvider::instance()->notationViewDrawData();
ctx.setVal<draw::DrawDataPtr>(AbContext::Key::CurDrawData, std::make_shared<draw::DrawData>(buf));
QByteArray data = draw::DrawBufferJson::toJson(buf);
io::path scorePath = ctx.val<io::path>(AbContext::Key::ScoreFile);

View file

@ -16,8 +16,8 @@
// along with this program; if not, write to the Free Software
// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
//=============================================================================
#ifndef MU_AUTOBOT_ABDRAWDESERIALIZATIONSTEP_H
#define MU_AUTOBOT_ABDRAWDESERIALIZATIONSTEP_H
#ifndef MU_AUTOBOT_ABDRAWCURRENTSTEP_H
#define MU_AUTOBOT_ABDRAWCURRENTSTEP_H
#include "../abbasestep.h"
#include "modularity/ioc.h"
@ -25,17 +25,21 @@
#include "system/ifilesystem.h"
namespace mu::autobot {
class AbDrawDeserializationStep : public AbBaseStep
class AbDrawCurrentStep : public AbBaseStep
{
INJECT(autobot, IAutobotConfiguration, configuration)
INJECT(autobot, system::IFileSystem, fileSystem)
public:
AbDrawDeserializationStep() = default;
AbDrawCurrentStep(bool isDoSave = false);
protected:
void doRun(AbContext ctx) override;
private:
bool m_isDoSave = false;
};
}
#endif // MU_AUTOBOT_ABDRAWDESERIALIZATIONSTEP_H
#endif // MU_AUTOBOT_ABDRAWCURRENTSTEP_H

View file

@ -16,7 +16,7 @@
// along with this program; if not, write to the Free Software
// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
//=============================================================================
#include "abdrawdeserializationstep.h"
#include "abdrawrefstep.h"
#include "log.h"
#include "io/path.h"
@ -24,7 +24,7 @@
using namespace mu::autobot;
void AbDrawDeserializationStep::doRun(AbContext ctx)
void AbDrawRefStep::doRun(AbContext ctx)
{
io::path scorePath = ctx.val<io::path>(AbContext::Key::ScoreFile);
io::path filePath = configuration()->scoreDrawData(scorePath);

View file

@ -16,8 +16,8 @@
// along with this program; if not, write to the Free Software
// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
//=============================================================================
#ifndef MU_AUTOBOT_ABDRAWSERIALIZATIONSTEP_H
#define MU_AUTOBOT_ABDRAWSERIALIZATIONSTEP_H
#ifndef MU_AUTOBOT_ABDRAWREFSTEP_H
#define MU_AUTOBOT_ABDRAWREFSTEP_H
#include "../abbasestep.h"
#include "modularity/ioc.h"
@ -25,17 +25,17 @@
#include "system/ifilesystem.h"
namespace mu::autobot {
class AbDrawSerializationStep : public AbBaseStep
class AbDrawRefStep : public AbBaseStep
{
INJECT(autobot, IAutobotConfiguration, configuration)
INJECT(autobot, system::IFileSystem, fileSystem)
public:
AbDrawSerializationStep() = default;
AbDrawRefStep() = default;
protected:
void doRun(AbContext ctx) override;
};
}
#endif // MU_AUTOBOT_ABDRAWSERIALIZATIONSTEP_H
#endif // MU_AUTOBOT_ABDRAWREFSTEP_H

View file

@ -45,6 +45,10 @@ void BufferedPaintProvider::beginTarget(const std::string& name)
m_isActive = true;
}
void BufferedPaintProvider::beforeEndTargetHook(Painter*)
{
}
bool BufferedPaintProvider::endTarget(bool endDraw)
{
UNUSED(endDraw);
@ -69,8 +73,16 @@ void BufferedPaintProvider::endObject()
{
TRACEFUNC;
m_drawObjectsLogger.endObject();
// remove last empty state
DrawData::Object& obj = m_currentObjects.top();
if (!obj.datas.empty() && obj.datas.back().empty()) {
obj.datas.pop_back();
}
// move object to buffer
m_buf.objects.push_back(m_currentObjects.top());
m_buf.objects.push_back(obj);
// remove obj
m_currentObjects.pop();
}

View file

@ -40,6 +40,7 @@ public:
bool isActive() const override;
void beginTarget(const std::string& name) override;
void beforeEndTargetHook(Painter* painter) override;
bool endTarget(bool endDraw = false) override;
void beginObject(const std::string& name, const QPointF& pagePos) override;

View file

@ -137,16 +137,48 @@ static bool isEqual(const QFont& f1, const QFont& f2)
return true;
}
static bool isEqual(const QTransform& t1, const QTransform& t2)
static bool isEqual(const QTransform& t1, const QTransform& t2, double tolerance)
{
if (t1 != t2) {
if (!isEqual(t1.m11(), t2.m11(), tolerance)) {
return false;
}
if (!isEqual(t1.m12(), t2.m12(), tolerance)) {
return false;
}
if (!isEqual(t1.m13(), t2.m13(), tolerance)) {
return false;
}
if (!isEqual(t1.m21(), t2.m21(), tolerance)) {
return false;
}
if (!isEqual(t1.m22(), t2.m22(), tolerance)) {
return false;
}
if (!isEqual(t1.m23(), t2.m23(), tolerance)) {
return false;
}
if (!isEqual(t1.m31(), t2.m31(), tolerance)) {
return false;
}
if (!isEqual(t1.m32(), t2.m32(), tolerance)) {
return false;
}
if (!isEqual(t1.m33(), t2.m33(), tolerance)) {
return false;
}
return true;
}
static bool isEqual(const DrawData::State& s1, const DrawData::State& s2, DrawComp::Tolerance /*tolerance*/)
static bool isEqual(const DrawData::State& s1, const DrawData::State& s2, DrawComp::Tolerance tolerance)
{
if (s1.isAntialiasing != s2.isAntialiasing) {
return false;
@ -168,7 +200,7 @@ static bool isEqual(const DrawData::State& s1, const DrawData::State& s2, DrawCo
return false;
}
if (!isEqual(s1.transform, s2.transform)) {
if (!isEqual(s1.transform, s2.transform, tolerance.base)) {
return false;
}
@ -419,7 +451,7 @@ static void difference(std::vector<T>& diff, const std::vector<T>& v1, const std
}
} // mu::draw::comp
DrawComp::Diff DrawComp::compare(const DrawDataPtr& data, const DrawDataPtr& origin, Tolerance tolerance)
Diff DrawComp::compare(const DrawDataPtr& data, const DrawDataPtr& origin, Tolerance tolerance)
{
Diff diff;
IF_ASSERT_FAILED(data) {
@ -436,8 +468,8 @@ DrawComp::Diff DrawComp::compare(const DrawDataPtr& data, const DrawDataPtr& ori
diff.dataRemoved = std::make_shared<DrawData>();
diff.dataRemoved->name = data->name;
comp::difference(diff.dataAdded->objects, data->objects, origin->objects, tolerance);
comp::difference(diff.dataRemoved->objects, origin->objects, data->objects, tolerance);
comp::difference(diff.dataRemoved->objects, data->objects, origin->objects, tolerance);
comp::difference(diff.dataAdded->objects, origin->objects, data->objects, tolerance);
return diff;
}

View file

@ -28,25 +28,6 @@ class DrawComp
{
public:
struct Diff {
DrawDataPtr dataAdded;
DrawDataPtr dataRemoved;
bool empty() const
{
bool ret = true;
if (dataAdded) {
ret = dataAdded->objects.empty();
}
if (ret && dataRemoved) {
ret = dataRemoved->objects.empty();
}
return ret;
}
};
struct Tolerance {
double base = -1.0;
Tolerance() {}

View file

@ -91,21 +91,18 @@ static QJsonArray toArr(const QTransform& t)
{
return QJsonArray({ rtoi(t.m11()), rtoi(t.m12()), rtoi(t.m13()),
rtoi(t.m21()), rtoi(t.m22()), rtoi(t.m23()),
rtoi(t.m31()), rtoi(t.m32()), rtoi(t.m33()),
rtoi(t.dx()), rtoi(t.dy()) });
rtoi(t.m31()), rtoi(t.m32()), rtoi(t.m33()) });
}
static void fromArr(const QJsonArray& arr, QTransform& t)
{
IF_ASSERT_FAILED(arr.size() == 11) {
IF_ASSERT_FAILED(arr.size() == 9) {
return;
}
t.setMatrix(itor(arr.at(0).toInt()), itor(arr.at(1).toInt()), itor(arr.at(2).toInt()),
itor(arr.at(3).toInt()), itor(arr.at(4).toInt()), itor(arr.at(5).toInt()),
itor(arr.at(6).toInt()), itor(arr.at(7).toInt()), itor(arr.at(8).toInt()));
t.translate(itor(arr.at(9).toInt()), itor(arr.at(10).toInt()));
}
static QJsonArray toArr(const QPointF& p)
@ -389,6 +386,10 @@ QByteArray DrawBufferJson::toJson(const DrawData& buf)
objObj["a_pagePos"] = toArr(obj.pagePos);
QJsonArray datasArr;
for (const DrawData::Data& data : obj.datas) {
if (data.empty()) {
continue;
}
QJsonObject dataObj;
dataObj["state"] = toObj(data.state);
dataObj["paths"] = toArr(data.paths);
@ -408,7 +409,7 @@ QByteArray DrawBufferJson::toJson(const DrawData& buf)
root["objects"] = objsArr;
return QJsonDocument(root).toJson(QJsonDocument::Compact);
return QJsonDocument(root).toJson(QJsonDocument::Indented);
}
mu::RetVal<DrawDataPtr> DrawBufferJson::fromJson(const QByteArray& json)

View file

@ -148,5 +148,24 @@ struct DrawData
};
using DrawDataPtr = std::shared_ptr<DrawData>;
struct Diff {
DrawDataPtr dataAdded;
DrawDataPtr dataRemoved;
bool empty() const
{
bool ret = true;
if (dataAdded) {
ret = dataAdded->objects.empty();
}
if (ret && dataRemoved) {
ret = dataRemoved->objects.empty();
}
return ret;
}
};
}
#endif // MU_DRAW_DRAWTYPES_H

View file

@ -31,6 +31,7 @@
#include "drawtypes.h"
namespace mu::draw {
class Painter;
class IPaintProvider
{
public:
@ -41,6 +42,7 @@ public:
virtual bool isActive() const = 0;
virtual void beginTarget(const std::string& name) = 0;
virtual void beforeEndTargetHook(Painter* painter) = 0;
virtual bool endTarget(bool endDraw = false) = 0;
virtual void beginObject(const std::string& name, const QPointF& pagePos) = 0;
virtual void endObject() = 0;

View file

@ -53,10 +53,7 @@ Painter::Painter(QPainter* qp, const std::string& name, bool overship)
Painter::~Painter()
{
m_provider->endTarget();
if (extended) {
extended->endTarget();
}
endTarget(false);
}
void Painter::init()
@ -78,11 +75,26 @@ QPainter* Painter::qpainter() const
return m_provider->qpainter();
}
IPaintProviderPtr Painter::provider() const
{
return m_provider;
}
bool Painter::endDraw()
{
bool ok = m_provider->endTarget(true);
return endTarget(true);
}
bool Painter::endTarget(bool endDraw)
{
m_provider->beforeEndTargetHook(this);
if (extended) {
extended->endTarget(true);
extended->beforeEndTargetHook(this);
}
bool ok = m_provider->endTarget(endDraw);
if (extended) {
extended->endTarget(endDraw);
}
return ok;
}
@ -463,4 +475,7 @@ void Painter::updateMatrix()
}
m_provider->setTransform(st.transform);
if (extended) {
extended->setTransform(st.transform);
}
}

View file

@ -55,6 +55,7 @@ public:
QPaintDevice* device() const;
QPainter* qpainter() const;
IPaintProviderPtr provider() const;
bool isActive() const;
bool endDraw();
@ -172,6 +173,8 @@ private:
QTransform makeViewTransform() const;
void updateMatrix();
bool endTarget(bool endDraw);
IPaintProviderPtr m_provider;
std::string m_name;
std::stack<State> m_states;

View file

@ -59,6 +59,10 @@ void QPainterProvider::beginTarget(const std::string&)
{
}
void QPainterProvider::beforeEndTargetHook(Painter*)
{
}
bool QPainterProvider::endTarget(bool endDraw)
{
if (endDraw) {
@ -147,6 +151,7 @@ void QPainterProvider::restore()
void QPainterProvider::setTransform(const QTransform& transform)
{
m_transform = transform;
m_painter->setTransform(transform);
}

View file

@ -39,6 +39,7 @@ public:
QPainter* qpainter() const override;
void beginTarget(const std::string& name) override;
void beforeEndTargetHook(Painter* painter) override;
bool endTarget(bool endDraw = false) override;
bool isActive() const override;
@ -80,6 +81,8 @@ private:
QPainter* m_painter = nullptr;
bool m_overship = false;
DrawObjectsLogger m_drawObjectsLogger;
QTransform m_transform;
};
}

View file

@ -23,6 +23,7 @@
#include "log.h"
#include "actions/actiontypes.h"
#include "stringutils.h"
using namespace mu::notation;
using namespace mu::uicomponents;
@ -58,6 +59,11 @@ NotationPaintView::NotationPaintView(QQuickItem* parent)
m_loopInMarker = std::make_unique<LoopMarker>(LoopBoundaryType::LoopIn);
m_loopOutMarker = std::make_unique<LoopMarker>(LoopBoundaryType::LoopOut);
//! NOTE For Autobot tests tool
dispatcher()->reg(this, "dev-notationview-redraw", [this]() {
update();
});
}
void NotationPaintView::load()
@ -153,6 +159,10 @@ bool NotationPaintView::canReceiveAction(const actions::ActionCode& actionCode)
return true;
}
if (QString::fromStdString(actionCode).startsWith("dev-")) {
return true;
}
return hasFocus();
}