summaryrefslogtreecommitdiffstats
path: root/src/widget/wnumberpos.cpp
blob: 748ef5006fe716af5eb0115b3a7797c0a80faef8 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
// Tue Haste Andersen <haste@diku.dk>, (C) 2003

#include <QTime>

#include "widget/wnumberpos.h"
#include "controlobject.h"
#include "controlobjectthread.h"
#include "util/math.h"
#include "util/time.h"

WNumberPos::WNumberPos(const char* group, QWidget* parent)
        : WNumber(parent),
          m_dOldValue(0.0),
          m_dTrackSamples(0.0),
          m_dTrackSampleRate(0.0),
          m_bRemain(false) {
    m_qsText = "";

    m_pShowTrackTimeRemaining = new ControlObjectThread(
            "[Controls]", "ShowDurationRemaining");
    m_pShowTrackTimeRemaining->connectValueChanged(
            this, SLOT(slotSetRemain(double)));
    slotSetRemain(m_pShowTrackTimeRemaining->get());

    // We use the engine's playposition value directly because the parameter
    // normalization done by the widget system used to be unusable for this
    // because the range of playposition was -0.14 to 1.14 in 1.11.x. As a
    // result, the <Connection> parameter is no longer necessary in skin
    // definitions, but leaving it in is harmless.
    m_pVisualPlaypos = new ControlObjectThread(group, "playposition");
    m_pVisualPlaypos->connectValueChanged(this, SLOT(slotSetValue(double)));

    m_pTrackSamples = new ControlObjectThread(
            group, "track_samples");
    m_pTrackSamples->connectValueChanged(
            this, SLOT(slotSetTrackSamples(double)));

    // Tell the CO to re-emit its value since we could be created after it was
    // set to a valid value.
    m_pTrackSamples->emitValueChanged();

    m_pTrackSampleRate = new ControlObjectThread(
            group, "track_samplerate");
    m_pTrackSampleRate->connectValueChanged(
            this, SLOT(slotSetTrackSampleRate(double)));

    // Tell the CO to re-emit its value since we could be created after it was
    // set to a valid value.
    m_pTrackSampleRate->emitValueChanged();

    slotSetValue(m_pVisualPlaypos->get());
}

WNumberPos::~WNumberPos() {
    delete m_pTrackSampleRate;
    delete m_pTrackSamples;
    delete m_pVisualPlaypos;
    delete m_pShowTrackTimeRemaining;
}

void WNumberPos::mousePressEvent(QMouseEvent* pEvent) {
    bool leftClick = pEvent->buttons() & Qt::LeftButton;

    if (leftClick) {
        setRemain(!m_bRemain);
        m_pShowTrackTimeRemaining->slotSet(m_bRemain ? 1.0 : 0.0);
    }
}

void WNumberPos::slotSetTrackSamples(double dSamples) {
    m_dTrackSamples = dSamples;
    slotSetValue(m_dOldValue);
}

void WNumberPos::slotSetTrackSampleRate(double dSampleRate) {
    m_dTrackSampleRate = dSampleRate;
    slotSetValue(m_dOldValue);
}

void WNumberPos::setValue(double dValue) {
    // Ignore midi-scaled signals from the skin connection.
    Q_UNUSED(dValue);
    // Update our value with the old value.
    slotSetValue(m_dOldValue);
}

void WNumberPos::slotSetValue(double dValue) {
    m_dOldValue = dValue;

    double valueMillis = 0.0;
    if (m_dTrackSamples > 0 && m_dTrackSampleRate > 0) {
        double dDuration = m_dTrackSamples / m_dTrackSampleRate / 2.0;
        valueMillis = dValue * 500.0 * m_dTrackSamples / m_dTrackSampleRate;
        double durationMillis = dDuration * Time::kMillisPerSecond;
        if (m_bRemain)
            valueMillis = math_max(durationMillis - valueMillis, 0.0);
    }

    QString valueString;
    if (valueMillis >= 0) {
        valueString = m_qsText % Time::formatSeconds(
                valueMillis / Time::kMillisPerSecond, true);
    } else {
        valueString = m_qsText % QLatin1String("-") % Time::formatSeconds(
                -valueMillis / Time::kMillisPerSecond, true);
    }
    setText(valueString);
}

void WNumberPos::slotSetRemain(double remain) {
    setRemain(remain > 0.0);
}

void WNumberPos::setRemain(bool bRemain)
{
    m_bRemain = bRemain;

    // Shift display state between showing position and remaining
    if (m_bRemain)
        m_qsText = "-";
    else
        m_qsText = "";

    // Have the widget redraw itself with its current value.
    slotSetValue(m_dOldValue);
}