File: waveformshaper.cpp

package info (click to toggle)
tiatracker 1.3-5
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid, trixie
  • size: 6,664 kB
  • sloc: cpp: 8,875; asm: 664; makefile: 8
file content (158 lines) | stat: -rw-r--r-- 5,519 bytes parent folder | download | duplicates (2)
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
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
/* TIATracker, (c) 2016 Andre "Kylearan" Wichmann.
 * Website: https://bitbucket.org/kylearan/tiatracker
 * Email: andre.wichmann@gmx.de
 * See the file "license.txt" for information on usage and redistribution
 * of this file.
 */

#include "waveformshaper.h"
#include <QPainter>
#include "mainwindow.h"
#include "percussiontab.h"
#include <cassert>
#include <QMouseEvent>
#include "tiasound/tiasound.h"
#include <QWheelEvent>
#include "instrumentstab.h"


WaveformShaper::WaveformShaper(QWidget *parent) : QWidget(parent)
{
    valueFont.setPixelSize(valueFontSize);
    QFontMetrics fontMetrics(valueFont);
    valueFontHeight = fontMetrics.height();
    valueAreaHeight = valueFontHeight + 2*valueAreaMargin;
    setFixedWidth(calcWidth());
    setFixedHeight(valueAreaHeight + legendCellSize);

    // Create context menu
    foreach (TiaSound::Distortion dist, PercussionTab::availableWaveforms) {
        contextMenu.addAction(TiaSound::getDistortionName(dist));
    }
    QObject::connect(&contextMenu, SIGNAL(triggered(QAction*)), this, SLOT(setWaveform(QAction*)));
}

/*************************************************************************/

void WaveformShaper::registerPercussion(Track::Percussion *newPercussion) {
    pPercussion = newPercussion;

}

/*************************************************************************/

void WaveformShaper::updateSize() {
    setFixedWidth(calcWidth());
}

/*************************************************************************/

QList<TiaSound::Distortion> *WaveformShaper::getValues() {
    return values;
}

void WaveformShaper::setValues(QList<TiaSound::Distortion> *newValues) {
    values = newValues;
    updateSize();
}

/*************************************************************************/

void WaveformShaper::setWaveform(QAction *action) {
    // Get distortion of selected waveform and set pen to it
    foreach (TiaSound::Distortion dist, PercussionTab::availableWaveforms) {
        if (TiaSound::getDistortionName(dist) == action->text()) {
            distortionPen = dist;
            break;
        }
    }
    // Set distortion column
    (*values)[waveformColumn] = distortionPen;
    update();
}

/*************************************************************************/

void WaveformShaper::paintEvent(QPaintEvent *) {
    QPainter painter(this);

    const int envelopeLength = pPercussion->getEnvelopeLength();

    // Left side
    painter.fillRect(0, 0, legendCellSize, valueAreaHeight+legendCellSize, MainWindow::lightHighlighted);
    // Bottom
    painter.fillRect(legendCellSize, valueAreaHeight, envelopeLength*cellWidth, legendCellSize, MainWindow::lightHighlighted);
    // Value area
    painter.fillRect(legendCellSize, 0, envelopeLength*cellWidth, valueAreaHeight, MainWindow::dark);
    // Frame numbers
    painter.setFont(valueFont);
    painter.setPen(MainWindow::contentDarker);
    for (int frame = 0; frame < envelopeLength; ++frame) {
        int xPos = legendCellSize + frame*cellWidth;
        painter.drawText(xPos, valueAreaHeight, cellWidth, legendCellSize, Qt::AlignCenter, QString::number(frame + 1));
    }
    // Values
    painter.setPen(MainWindow::contentLight);
    for (int iValue = 0; iValue < envelopeLength; ++iValue) {
        TiaSound::Distortion value = (*values)[iValue];
        int intValue = TiaSound::getDistortionInt(value);
        painter.drawText(legendCellSize + iValue*cellWidth, valueAreaMargin, cellWidth, valueFontHeight, Qt::AlignCenter, QString::number(intValue));
    }

}

/*************************************************************************/

void WaveformShaper::contextMenuEvent(QContextMenuEvent *event) {
    if (event->x() >= legendCellSize && event->y() < valueAreaHeight) {
        waveformColumn = (event->x() - legendCellSize)/cellWidth;
        contextMenu.exec(event->globalPos());
    }
}

/*************************************************************************/

void WaveformShaper::mousePressEvent(QMouseEvent *event) {
    if (event->button() == Qt::LeftButton) {
        if (event->x() >= legendCellSize && event->y() < valueAreaHeight) {
           int column = (event->x() - legendCellSize)/cellWidth;
           (*values)[column] = distortionPen;
           update();
        }
    }
}

/*************************************************************************/

void WaveformShaper::wheelEvent(QWheelEvent *event) {
    if (event->x() >= legendCellSize && event->y() < valueAreaHeight) {
        int column = (event->x() - legendCellSize)/cellWidth;
        int delta = event->delta()/100;
        // Get index of current waveform
        TiaSound::Distortion oldDist = (*values)[column];
        int oldIndex = PercussionTab::availableWaveforms.indexOf(oldDist);
        int newIndex = oldIndex + delta;
        newIndex = std::max(newIndex, 0);
        newIndex = std::min(newIndex, PercussionTab::availableWaveforms.size() - 1);
        (*values)[column] = PercussionTab::availableWaveforms[newIndex];
        update();
    }
}

/*************************************************************************/

int WaveformShaper::calcWidth() {
    int envelopeLength = 21;
    // During init, no percussion is registered yet
    if (pPercussion != nullptr) {
        envelopeLength = pPercussion->getEnvelopeLength();
    }
    int width = legendCellSize;
    if (values != nullptr) {
        width += envelopeLength*cellWidth;
    }
    return width;
}

/*************************************************************************/