Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

render duration of intro & outro ranges on overview waveforms #2089

Merged
merged 8 commits into from
May 5, 2019
2 changes: 2 additions & 0 deletions res/skins/Deere/deck_overview.xml
Original file line number Diff line number Diff line change
Expand Up @@ -41,12 +41,14 @@
<EndControl>intro_end_position</EndControl>
<Color>#0000FF</Color>
<VisibilityControl>[Skin],show_intro_outro_cues</VisibilityControl>
<DurationTextColor>#ffffff</DurationTextColor>
</MarkRange>
<MarkRange>
<StartControl>outro_start_position</StartControl>
<EndControl>outro_end_position</EndControl>
<Color>#0000FF</Color>
<VisibilityControl>[Skin],show_intro_outro_cues</VisibilityControl>
<DurationTextColor>#ffffff</DurationTextColor>
</MarkRange>
<Mark>
<Control>intro_start_position</Control>
Expand Down
2 changes: 2 additions & 0 deletions res/skins/LateNight/deck_overview.xml
Original file line number Diff line number Diff line change
Expand Up @@ -46,12 +46,14 @@
<EndControl>intro_end_position</EndControl>
<Color>#0000FF</Color>
<VisibilityControl>[Skin],show_intro_outro_cues</VisibilityControl>
<DurationTextColor>#ffffff</DurationTextColor>
</MarkRange>
<MarkRange>
<StartControl>outro_start_position</StartControl>
<EndControl>outro_end_position</EndControl>
<Color>#0000FF</Color>
<VisibilityControl>[Skin],show_intro_outro_cues</VisibilityControl>
<DurationTextColor>#ffffff</DurationTextColor>
</MarkRange>
<Mark>
<Control>intro_start_position</Control>
Expand Down
2 changes: 2 additions & 0 deletions res/skins/Shade/deck_overview.xml
Original file line number Diff line number Diff line change
Expand Up @@ -32,12 +32,14 @@
<EndControl>intro_end_position</EndControl>
<Color>#0000FF</Color>
<VisibilityControl>[Skin],show_intro_outro_cues</VisibilityControl>
<DurationTextColor>#ffffff</DurationTextColor>
</MarkRange>
<MarkRange>
<StartControl>outro_start_position</StartControl>
<EndControl>outro_end_position</EndControl>
<Color>#0000FF</Color>
<VisibilityControl>[Skin],show_intro_outro_cues</VisibilityControl>
<DurationTextColor>#ffffff</DurationTextColor>
</MarkRange>
<Mark>
<Control>intro_start_position</Control>
Expand Down
2 changes: 2 additions & 0 deletions res/skins/Tango/deck_overview.xml
Original file line number Diff line number Diff line change
Expand Up @@ -56,12 +56,14 @@ Variables:
<EndControl>intro_end_position</EndControl>
<Color>#0000FF</Color>
<VisibilityControl>[Skin],show_intro_outro_cues</VisibilityControl>
<DurationTextColor>#ffffff</DurationTextColor>
</MarkRange>
<MarkRange>
<StartControl>outro_start_position</StartControl>
<EndControl>outro_end_position</EndControl>
<Color>#0000FF</Color>
<VisibilityControl>[Skin],show_intro_outro_cues</VisibilityControl>
<DurationTextColor>#ffffff</DurationTextColor>
</MarkRange>
<Mark>
<Control>intro_start_position</Control>
Expand Down
7 changes: 6 additions & 1 deletion src/waveform/renderers/waveformmarkrange.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,8 @@ WaveformMarkRange::WaveformMarkRange(
const SkinContext& context,
const WaveformSignalColors& signalColors)
: m_activeColor(context.selectString(node, "Color")),
m_disabledColor(context.selectString(node, "DisabledColor")) {
m_disabledColor(context.selectString(node, "DisabledColor")),
m_durationTextColor(context.selectString(node, "DurationTextColor")) {
if (!m_activeColor.isValid()) {
//vRince kind of legacy fallback ...
// As a fallback, grab the mark color from the parent's MarkerColor
Expand Down Expand Up @@ -87,6 +88,10 @@ double WaveformMarkRange::end() const {
return end;
}

bool WaveformMarkRange::showDuration() const {
return m_durationTextColor.isValid() && start() != end() && start() != -1 && end() != -1;
}

void WaveformMarkRange::generateImage(int weidth, int height) {
m_activeImage = QImage(weidth, height, QImage::Format_ARGB32_Premultiplied);
m_disabledImage = QImage(weidth, height, QImage::Format_ARGB32_Premultiplied);
Expand Down
3 changes: 3 additions & 0 deletions src/waveform/renderers/waveformmarkrange.h
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,8 @@ class WaveformMarkRange {
// Returns end value or -1 if the end control doesn't exist.
double end() const;

bool showDuration() const;

private:
void generateImage(int weidth, int height);

Expand All @@ -46,6 +48,7 @@ class WaveformMarkRange {

QColor m_activeColor;
QColor m_disabledColor;
QColor m_durationTextColor;

QImage m_activeImage;
QImage m_disabledImage;
Expand Down
115 changes: 71 additions & 44 deletions src/widget/woverview.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@
#include "track/track.h"
#include "analyzer/analyzerprogress.h"
#include "util/color/color.h"
#include "util/duration.h"
#include "util/math.h"
#include "util/timer.h"
#include "util/dnd.h"
Expand Down Expand Up @@ -59,6 +60,13 @@ WOverview::WOverview(
m_endOfTrackControl = new ControlProxy(
m_group, "end_of_track", this);
m_endOfTrackControl->connectValueChanged(this, &WOverview::onEndOfTrackChange);
m_pRateDirControl = new ControlProxy(m_group, "rate_dir", this);
m_pRateRangeControl = new ControlProxy(m_group, "rateRange", this);
m_pRateSliderControl = new ControlProxy(m_group, "rate", this);
// Needed to recalculate range durations when rate slider is moved without the deck playing
// TODO: connect to rate_ratio instead in PR #1765
m_pRateSliderControl->connectValueChanged(this, &WOverview::onRateSliderChange);
m_trackSampleRateControl = new ControlProxy(m_group, "track_samplerate", this);
m_trackSamplesControl =
new ControlProxy(m_group, "track_samples", this);
setAcceptDrops(true);
Expand Down Expand Up @@ -271,6 +279,10 @@ void WOverview::onMarkRangeChange(double /*v*/) {
update();
}

void WOverview::onRateSliderChange(double /*v*/) {
update();
}

// currently only updates the mark color but it could be easily extended.
void WOverview::updateCues(const QList<CuePointer> &loadedCues) {
for (CuePointer currentCue: loadedCues) {
Expand Down Expand Up @@ -434,50 +446,6 @@ void WOverview::paintEvent(QPaintEvent * /*unused*/) {
const float offset = 1.0f;
const float gain = static_cast<float>(length() - 2) / trackSamples;

// Draw range (loop)
Be-ing marked this conversation as resolved.
Show resolved Hide resolved
for (auto&& markRange: m_markRanges) {
// If the mark range is not active we should not draw it.
if (!markRange.active()) {
continue;
}

// If the mark range is not visible we should not draw it.
if (!markRange.visible()) {
continue;
}

// Active mark ranges by definition have starts/ends that are not
// disabled.
const double startValue = markRange.start();
const double endValue = markRange.end();

const float startPosition = offset + startValue * gain;
const float endPosition = offset + endValue * gain;

if (startPosition < 0.0 && endPosition < 0.0) {
continue;
}

if (markRange.enabled()) {
painter.setOpacity(0.4);
painter.setPen(markRange.m_activeColor);
painter.setBrush(markRange.m_activeColor);
} else {
painter.setOpacity(0.2);
painter.setPen(markRange.m_disabledColor);
painter.setBrush(markRange.m_disabledColor);
}

// let top and bottom of the rect out of the widget
if (m_orientation == Qt::Horizontal) {
painter.drawRect(QRectF(QPointF(startPosition, -2.0),
QPointF(endPosition, height() + 1.0)));
} else {
painter.drawRect(QRectF(QPointF(-2.0, startPosition),
QPointF(width() + 1.0, endPosition)));
}
}

// Draw markers (Cue & hotcues)
QFont markerFont = painter.font();
markerFont.setPixelSize(10 * m_scaleFactor);
Expand Down Expand Up @@ -565,6 +533,65 @@ void WOverview::paintEvent(QPaintEvent * /*unused*/) {
}
}

// Draw range (loop)
for (auto&& markRange: m_markRanges) {
if (!markRange.active() || !markRange.visible()) {
continue;
}

// Active mark ranges by definition have starts/ends that are not
// disabled.
const double startValue = markRange.start();
const double endValue = markRange.end();

const float startPosition = offset + startValue * gain;
const float endPosition = offset + endValue * gain;

if (startPosition < 0.0 && endPosition < 0.0) {
continue;
}

if (markRange.enabled()) {
painter.setOpacity(0.4);
painter.setPen(markRange.m_activeColor);
painter.setBrush(markRange.m_activeColor);
} else {
painter.setOpacity(0.2);
painter.setPen(markRange.m_disabledColor);
painter.setBrush(markRange.m_disabledColor);
}

// let top and bottom of the rect out of the widget
if (m_orientation == Qt::Horizontal) {
painter.drawRect(QRectF(QPointF(startPosition, -2.0),
QPointF(endPosition, height() + 1.0)));
} else {
painter.drawRect(QRectF(QPointF(-2.0, startPosition),
QPointF(width() + 1.0, endPosition)));
}

// draw duration of range
if (markRange.showDuration()) {
// TODO: replace with rate_ratio in PR #1765
double rateRatio = 1.0 + m_pRateDirControl->get() * m_pRateRangeControl->get() * m_pRateSliderControl->get();
QString duration = mixxx::Duration::formatTime((endValue - startValue)
/ m_trackSampleRateControl->get() / 2 / rateRatio);
Be-ing marked this conversation as resolved.
Show resolved Hide resolved

// Ensure the right end of the text does not get cut off by
// the end of the track
QFontMetrics fm(painter.font());
int textWidth = fm.width(duration);
float x = startPosition;
if (startPosition + textWidth > width()) {
x = width() - textWidth;
}

painter.setOpacity(1.0);
painter.setPen(markRange.m_durationTextColor);
painter.drawText(QPointF(x, height() - 2.0), duration);
}
}

if (m_orientation == Qt::Vertical) {
painter.setTransform(QTransform(0, 1, 1, 0, 0, 0));
}
Expand Down
5 changes: 5 additions & 0 deletions src/widget/woverview.h
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,7 @@ class WOverview : public WWidget, public TrackDropTarget {

void onMarkChanged(double v);
void onMarkRangeChange(double v);
void onRateSliderChange(double v);
void receiveCuesUpdated();

void slotWaveformSummaryUpdated();
Expand All @@ -113,6 +114,10 @@ class WOverview : public WWidget, public TrackDropTarget {
UserSettingsPointer m_pConfig;
ControlProxy* m_endOfTrackControl;
bool m_endOfTrack;
ControlProxy* m_pRateDirControl;
ControlProxy* m_pRateRangeControl;
ControlProxy* m_pRateSliderControl;
ControlProxy* m_trackSampleRateControl;
ControlProxy* m_trackSamplesControl;

// Current active track
Expand Down