Skip to content

Commit

Permalink
progress with marks
Browse files Browse the repository at this point in the history
  • Loading branch information
acolombier committed Oct 19, 2024
1 parent 1d14354 commit d751248
Show file tree
Hide file tree
Showing 25 changed files with 1,070 additions and 154 deletions.
4 changes: 4 additions & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -2797,6 +2797,7 @@ if(QML)
src/waveform/renderers/allshader/waveformrenderbeat.cpp
src/waveform/renderers/allshader/waveformrenderer.cpp
src/waveform/renderers/allshader/waveformrendererendoftrack.cpp
# FIXME depends on rendergraph/openglnode.h
# src/waveform/renderers/allshader/waveformrendererslipmode.cpp
# src/waveform/renderers/allshader/waveformrendererfiltered.cpp
# src/waveform/renderers/allshader/waveformrendererhsv.cpp
Expand Down Expand Up @@ -3498,6 +3499,8 @@ if (STEM)
if(QML)
target_compile_definitions(mixxx-qml-lib PUBLIC __STEM__)
target_sources(mixxx-qml-lib PRIVATE
# FIXME depends on rendergraph/openglnode.h
# src/waveform/renderers/allshader/waveformrendererstem.cpp
src/qml/qmlstemsmodel.cpp
)
endif()
Expand Down Expand Up @@ -3832,6 +3835,7 @@ add_subdirectory(src/rendergraph/opengl)
add_subdirectory(res/shaders/rendergraph)
target_link_libraries(mixxx-lib PUBLIC rendergraph_gl)
target_compile_definitions(mixxx-lib PRIVATE rendergraph=rendergraph_gl)
target_compile_definitions(mixxx-lib PRIVATE __RENDERGRAPH_OPENGL__)
target_compile_definitions(mixxx-lib PRIVATE allshader=allshader_gl)
if(QML)
add_subdirectory(src/rendergraph/scenegraph)
Expand Down
205 changes: 204 additions & 1 deletion res/qml/WaveformDisplay.qml
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,12 @@ Item {

required property string group

enum MouseStatus {
Normal,
Bending,
Scratching
}

MixxxControls.WaveformDisplay {
anchors.fill: parent
group: root.group
Expand All @@ -21,8 +27,41 @@ Item {
color: 'red'
}

// // Mixxx.WaveformRendererMarkRange {
// // // <!-- Loop -->
// // Mixxx.WaveformMarkRange {
// // startControl: "loop_start_position"
// // endControl: "loop_end_position"
// // enabledControl: "loop_enabled"
// // color: 'LoopColor'
// // opacity: 0.7
// // disabledColor: '#FFFFFF'
// // disabledOpacity: 0.6
// // }
// // // <!-- Intro -->
// // Mixxx.WaveformMarkRange {
// // startControl: "intro_start_position"
// // endControl: "intro_end_position"
// // // visibilityControl: '[Skin],show_intro_outro_cues'
// // color: 'IntroOutroColor'
// // opacity: 0.6
// // durationTextColor: '#ffffff'
// // durationTextLocation: 'after'
// // }
// // // <!-- Outro -->
// // Mixxx.WaveformMarkRange {
// // startControl: "outro_start_position"
// // endControl: "outro_end_position"
// // // visibilityControl: '[Skin],show_intro_outro_cues'
// // color: 'IntroOutroColor'
// // opacity: 0.6
// // durationTextColor: '#ffffff'
// // durationTextLocation: 'before'
// // }
// // }

Mixxx.WaveformRendererRGB {
axesColor: 'white'
axesColor: 'yellow'
lowColor: 'red'
midColor: 'green'
highColor: 'blue'
Expand All @@ -31,5 +70,169 @@ Item {
Mixxx.WaveformRendererBeat {
color: 'green'
}

Mixxx.WaveformRendererMark {
playMarkerColor: 'cyan'
playMarkerBackground: 'orange'
defaultMark: Mixxx.WaveformMark {
align: "bottom|right"
color: "#FF0000"
textColor: "#FFFFFF"
text: " %1 "
}
Mixxx.WaveformMark {
control: "cue_point"
text: 'C'
align: 'top|right'
color: 'red'
textColor: '#FFFFFF'
}
Mixxx.WaveformMark {
control: "loop_start_position"
text: '&#8635;'
align: 'top|left'
color: 'green'
textColor: '#FFFFFF'
}
Mixxx.WaveformMark {
control: "loop_end_position"
// visibilityControl: '<Variable name="'
// <!--Text>OUT</Text-->
align: 'bottom|right'
color: 'green'
textColor: '#FFFFFF'
// visibilityControl: '<Variable name="'
}
Mixxx.WaveformMark {
control: "intro_start_position"
// visibilityControl: '[Skin],show_intro_outro_cues'
align: 'top|right'
color: 'blue'
textColor: '#FFFFFF'
}
Mixxx.WaveformMark {
control: "intro_end_position"
// visibilityControl: '[Skin],show_intro_outro_cues'
text: '&#9698;'
align: 'top|left'
color: 'blue'
textColor: '#FFFFFF'
}
Mixxx.WaveformMark {
control: "outro_start_position"
// visibilityControl: '[Skin],show_intro_outro_cues'
text: '&#9699;'
align: 'top|right'
color: 'blue'
textColor: '#FFFFFF'
}
Mixxx.WaveformMark {
control: "outro_end_position"
// visibilityControl: '[Skin],show_intro_outro_cues'
align: 'top|left'
color: 'blue'
textColor: '#FFFFFF'
}
}
}

Mixxx.ControlProxy {
id: scratchPositionEnableControl

group: root.group
key: "scratch_position_enable"
}

Mixxx.ControlProxy {
id: scratchPositionControl

group: root.group
key: "scratch_position"
}

Mixxx.ControlProxy {
id: wheelControl

group: root.group
key: "wheel"
}

Mixxx.ControlProxy {
id: rateRatioControl

group: root.group
key: "rate_ratio"
}

Mixxx.ControlProxy {
id: zoomControl

group: root.group
key: "waveform_zoom"
}
readonly property real effectiveZoomFactor: (1 / rateRatioControl.value) * (100 / zoomControl.value)

MouseArea {
property int mouseStatus: WaveformDisplay.MouseStatus.Normal
property point mouseAnchor: Qt.point(0, 0)

anchors.fill: parent
acceptedButtons: Qt.LeftButton | Qt.RightButton
onPressed: {
mouseAnchor = Qt.point(mouse.x, mouse.y);
if (mouse.button == Qt.LeftButton) {
if (mouseStatus == WaveformDisplay.MouseStatus.Bending)
wheelControl.parameter = 0.5;

mouseStatus = WaveformDisplay.MouseStatus.Scratching;
scratchPositionEnableControl.value = 1;
// TODO: Calculate position properly
scratchPositionControl.value = -mouse.x * 2 * zoomControl.value;
console.log(mouse.x);
} else {
if (mouseStatus == WaveformDisplay.MouseStatus.Scratching)
scratchPositionEnableControl.value = 0;

wheelControl.parameter = 0.5;
mouseStatus = WaveformDisplay.MouseStatus.Bending;
}
}
onPositionChanged: {
switch (mouseStatus) {
case WaveformDisplay.MouseStatus.Bending: {
const diff = mouse.x - mouseAnchor.x;
// Start at the middle of [0.0, 1.0], and emit values based on how far
// the mouse has traveled horizontally. Note, for legacy (MIDI) reasons,
// this is tuned to 127.
const v = 0.5 + (diff / 1270);
// clamp to [0.0, 1.0]
wheelControl.parameter = Mixxx.MathUtils.clamp(v, 0, 1);
break;
};
case WaveformDisplay.MouseStatus.Scratching:
// TODO: Calculate position properly
scratchPositionControl.value = -mouse.x * zoomControl.value * 2 * 10;
break;
}
}
onReleased: {
switch (mouseStatus) {
case WaveformDisplay.MouseStatus.Bending:
wheelControl.parameter = 0.5;
break;
case WaveformDisplay.MouseStatus.Scratching:
scratchPositionEnableControl.value = 0;
break;
}
mouseStatus = WaveformDisplay.MouseStatus.Normal;
}

onWheel: {
if (wheel.angleDelta.y < 0 && zoomControl.value > 1) {
zoomControl.value -= 1;
} else if (wheel.angleDelta.y > 0 && zoomControl.value < 10.0) {
zoomControl.value += 1;
}
}
}
}
48 changes: 47 additions & 1 deletion src/qml/qmlwaveformdisplay.cpp
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
#include "qml/qmlwaveformdisplay.h"

#include <qnamespace.h>

#include <QQuickWindow>
#include <QSGFlatColorMaterial>
#include <QSGSimpleRectNode>
Expand All @@ -10,6 +12,7 @@
#include <QtQuick/QSGTexture>
#include <QtQuick/QSGTextureProvider>
#include <cmath>
#include <memory>

#include "mixer/basetrackplayer.h"
#include "moc_qmlwaveformdisplay.cpp"
Expand Down Expand Up @@ -41,10 +44,19 @@ namespace qml {
QmlWaveformDisplay::QmlWaveformDisplay(QQuickItem* parent)
: QQuickItem(parent),
WaveformWidgetRenderer("[Channel1]"),
m_pPlayer(nullptr) {
m_pPlayer(nullptr),
m_pWaveformRenderMark(nullptr),
m_pWaveformRenderMarkRange(nullptr),
m_pZoom(std::make_unique<ControlProxy>(getGroup(),
"waveform_zoom",
this,
ControlFlag::NoAssertIfMissing)) {
setFlag(QQuickItem::ItemHasContents, true);

connect(this, &QmlWaveformDisplay::windowChanged, this, &QmlWaveformDisplay::slotWindowChanged);
m_pZoom->connectValueChanged(this, [this](double zoom) {
setZoom(zoom);
});
}

QmlWaveformDisplay::~QmlWaveformDisplay() {
Expand Down Expand Up @@ -137,6 +149,8 @@ QSGNode* QmlWaveformDisplay::updatePaintNode(QSGNode* node, UpdatePaintNodeData*

if (!bgNode || m_dirtyFlag.testFlag(DirtyFlag::Window)) {
if (bgNode) {
m_pWaveformRenderMark = nullptr;
m_pWaveformRenderMarkRange = nullptr;
delete bgNode;
m_dirtyFlag.setFlag(DirtyFlag::Window, false);
}
Expand All @@ -153,6 +167,21 @@ QSGNode* QmlWaveformDisplay::updatePaintNode(QSGNode* node, UpdatePaintNodeData*
addRenderer(renderer.renderer);
// appendChildTo(pOpacityNode, renderer.node);
pTopNode->appendChildNode(std::unique_ptr<rendergraph::TreeNode>(renderer.node));

auto* pWaveformRenderMark = dynamic_cast<allshader::WaveformRenderMark*>(renderer.node);
if (pWaveformRenderMark != nullptr) {
DEBUG_ASSERT(m_pWaveformRenderMark == nullptr);
m_pWaveformRenderMark = pWaveformRenderMark;
continue;
}

auto* pWaveformRenderMarkRange =
dynamic_cast<allshader::WaveformRenderMarkRange*>(
renderer.node);
if (pWaveformRenderMarkRange != nullptr) {
DEBUG_ASSERT(m_pWaveformRenderMarkRange == nullptr);
m_pWaveformRenderMarkRange = pWaveformRenderMarkRange;
}
}

// pTopNode->appendChildNode(std::move(pOpacityNode));
Expand All @@ -175,8 +204,20 @@ QSGNode* QmlWaveformDisplay::updatePaintNode(QSGNode* node, UpdatePaintNodeData*
qDebug() << "RECT" << window()->size();
m_pEngine->resize(boundingRect());
bgNode->setRect(boundingRect());

auto rect = QRectF(boundingRect().x() +

Check warning on line 208 in src/qml/qmlwaveformdisplay.cpp

View workflow job for this annotation

GitHub Actions / clazy

unused QRectF [-Wclazy-unused-non-trivial-variable]
boundingRect().width() * m_playMarkerPosition - 1.0,
boundingRect().y(),
2.0,
boundingRect().height());
}

if (m_pWaveformRenderMark != nullptr) {
m_pWaveformRenderMark->update();
}
if (m_pWaveformRenderMarkRange != nullptr) {
m_pWaveformRenderMarkRange->update();
}
onPreRender(this);
bgNode->markDirty(QSGNode::DirtyForceUpdate);

Expand Down Expand Up @@ -225,6 +266,11 @@ void QmlWaveformDisplay::setGroup(const QString& group) {
}

WaveformWidgetRenderer::setGroup(group);
m_pZoom = std::make_unique<ControlProxy>(
getGroup(), "waveform_zoom", this, ControlFlag::NoAssertIfMissing);
m_pZoom->connectValueChanged(this, [this](double zoom) {
setZoom(zoom);
});
emit groupChanged(group);

// TODO m0dB unique_ptr ?
Expand Down
7 changes: 7 additions & 0 deletions src/qml/qmlwaveformdisplay.h
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,9 @@
#include <QQuickItem>
#include <QQuickWindow>
#include <QSGNode>
#include <QSGSimpleRectNode>
#include <QtQml>
#include <memory>

#include "qml/qmlplayerproxy.h"
#include "qml/qmlwaveformrenderer.h"
Expand Down Expand Up @@ -95,6 +97,11 @@ class QmlWaveformDisplay : public QQuickItem, ISyncTimeProvider, public Waveform
DirtyFlags m_dirtyFlag{DirtyFlag::None};
std::unique_ptr<rendergraph::Engine> m_pEngine;
QList<QmlWaveformRendererFactory*> m_waveformRenderers;

allshader::WaveformRenderMark* m_pWaveformRenderMark;
allshader::WaveformRenderMarkRange* m_pWaveformRenderMarkRange;

std::unique_ptr<ControlProxy> m_pZoom;
};

} // namespace qml
Expand Down
Loading

0 comments on commit d751248

Please sign in to comment.