To check out this repository please hg clone the following URL, or open the URL using EasyMercurial or your preferred Mercurial client.

Statistics Download as Zip
| Branch: | Tag: | Revision:

root / main / IntroDialog.cpp @ 312:6394462e0c12

History | View | Annotate | Download (6.47 KB)

1
/* -*- c-basic-offset: 4 indent-tabs-mode: nil -*-  vi:set ts=8 sts=4 sw=4: */
2

    
3
/*
4
    Vect
5
    An experimental audio player for plural recordings of a work
6
    Centre for Digital Music, Queen Mary, University of London.
7
    This file copyright 2006-2019 Chris Cannam and QMUL.
8
    
9
    This program is free software; you can redistribute it and/or
10
    modify it under the terms of the GNU General Public License as
11
    published by the Free Software Foundation; either version 2 of the
12
    License, or (at your option) any later version.  See the file
13
    COPYING included with this distribution for more information.
14
*/
15

    
16
#include "IntroDialog.h"
17

    
18
#include <QSettings>
19
#include <QDialog>
20
#include <QGridLayout>
21
#include <QLabel>
22
#include <QSvgWidget>
23
#include <QSvgRenderer>
24
#include <QPainter>
25
#include <QDialogButtonBox>
26
#include <QPushButton>
27

    
28
#include "widgets/IconLoader.h"
29

    
30
#include <vector>
31
#include <cmath>
32

    
33
using namespace std;
34

    
35
IntroDialog::IntroDialog(QWidget *parent)
36
{
37
    QSettings settings;
38
    settings.beginGroup("IntroDialog");
39
    if (settings.value("shown", false).toBool()) {
40
        return;
41
    }
42

    
43
    QDialog d(parent, Qt::SplashScreen);
44
    d.setWindowTitle(d.tr("Welcome!"));
45

    
46
    vector<pair<QString, QString>> texts {
47
        { d.tr("Open some audio files!"),
48
          d.tr("<p>If you have more than one recording of the same thing,<br>"
49
               "such as multiple performances, takes, or even cover versions,"
50
               "<br>try opening them all in one go.</p>"
51
               "<p>Comparative visualisation is what this app is all about!</p>"
52
               "<p>You can also record a new track directly from the "
53
               "microphone.</p>")
54
        },
55
        { d.tr("Scroll, zoom, and play"),
56
          d.tr("<p>Drag left and right in the main pane to move through time,<br>"
57
               "and use two-finger scroll-drag, or a scroll wheel, to zoom.</p>"
58
               "<p>You can also move using the left and right cursor keys,<br>"
59
               "and zoom using the up and down keys.</p>"
60
               "<p>Sonic Lineup will try to align the audio files so as to<br>"
61
               "ensure they scroll in sync in terms of musical material.<br>"
62
               "You can switch off or control alignment in the Playback menu.</p>"
63
              )
64
        },
65
        { d.tr("Switch view"),
66
          d.tr("<p>Use the buttons along the bottom to change the current view:</p>"
67
               "<ul><li>Outline waveform: simplified waveform on a single axis</li>"
68
               "<li>Waveform: classic audio-editor style waveform</li>"
69
               "<li>Melodic spectrogram: detailed log-frequency spectrogram in limited range</li>"
70
               "<li>Spectrogram: full-range dB spectrogram</li>"
71
               "<li>Sung pitch: pitch contour extracted as if from singing</li>"
72
               "<li>Key: likelihood plot for key within circle-of-fifths</li>"
73
               "<li>Stereo azimuth: left/right decomposition of frequency bins</li>"
74
               "</ul>"
75
              )
76
        }
77
    };
78
    
79
    QGridLayout *layout = new QGridLayout;
80
    d.setLayout(layout);
81
    layout->setRowStretch(0, 10);
82
    layout->setRowStretch(1, 20);
83
    layout->setRowStretch(2, 10);
84
    layout->setRowStretch(3, 0);
85
    layout->setColumnStretch(0, 0);
86
    layout->setColumnStretch(1, 0);
87
    layout->setColumnStretch(2, 20);
88

    
89
    int page = 1;
90

    
91
    vector<QString> arrowFiles {
92
        ":icons/scalable/arrow-above-white.svg",
93
        ":icons/scalable/arrow-left-white.svg",
94
        ":icons/scalable/arrow-below-white.svg"
95
    };
96

    
97
    int sz = int(round(parent->height() * 0.1));
98

    
99
    vector<QPixmap> arrowPixmaps {
100
        QPixmap(sz, sz),
101
        QPixmap(sz, (sz * 6) / 10),
102
        QPixmap(sz, sz)
103
    };
104

    
105
    for (int i = 0; i < int(arrowFiles.size()); ++i) {
106
        arrowPixmaps[i].fill(Qt::transparent);
107
        QPainter painter(&arrowPixmaps[i]);
108
        QSvgRenderer renderer(arrowFiles[i]);
109
        renderer.render(&painter);
110
    }
111

    
112
    vector<QLabel *> arrowLabels;
113

    
114
    for (auto p: arrowPixmaps) {
115
        QLabel *arrowLabel = new QLabel;
116
        arrowLabel->setPixmap(p);
117
        arrowLabel->setVisible(arrowLabels.empty());
118
        arrowLabels.push_back(arrowLabel);
119
    }
120
        
121
    layout->addWidget(arrowLabels[0], 0, 0);
122
    layout->addWidget(arrowLabels[1], 1, 0);
123
    layout->addWidget(arrowLabels[2], 1, 0, 1, 1, Qt::AlignBottom);
124

    
125
    QLabel *numberLabel = new QLabel;
126
    numberLabel->setText(d.tr("%1.").arg(page));
127
    layout->addWidget(numberLabel, 0, 1, 1, 1,
128
                      Qt::AlignRight | Qt::AlignBottom);
129
    QFont f(numberLabel->font());
130
    if (f.pixelSize() > 0) {
131
        f.setPixelSize(int(ceil(f.pixelSize() * 1.4)));
132
    } else {
133
        f.setPointSize(int(ceil(f.pointSize() * 1.4)));
134
    }
135
    numberLabel->setFont(f);
136

    
137
    QLabel *titleLabel = new QLabel;
138
    titleLabel->setText(texts[page-1].first);
139
    titleLabel->setFont(f);
140
    layout->addWidget(titleLabel, 0, 2, 1, 1,
141
                      Qt::AlignLeft | Qt::AlignBottom);
142

    
143
    QLabel *bodyLabel = new QLabel;
144
    bodyLabel->setWordWrap(false);
145
    bodyLabel->setText(texts[page-1].second);
146
    layout->addWidget(bodyLabel, 1, 2);
147
    
148
    d.setMinimumSize(parent->size() * 0.6);
149
        
150
    QDialogButtonBox *bb = new QDialogButtonBox;
151

    
152
    QPushButton *prev = bb->addButton
153
        (d.tr("&Prev"), QDialogButtonBox::ActionRole);
154
    prev->setIcon(IconLoader().load("rewind"));
155
    prev->setEnabled(false);
156

    
157
    QPushButton *next = bb->addButton
158
        (d.tr("&Next"), QDialogButtonBox::ActionRole);
159
    next->setIcon(IconLoader().load("ffwd"));
160
    
161
    QPushButton *close = bb->addButton(QDialogButtonBox::Close);
162
    QObject::connect(close, SIGNAL(clicked()), &d, SLOT(accept()));
163
    close->setEnabled(false);
164
    layout->addWidget(bb, 3, 0);
165

    
166
    auto repage =
167
        [&](int step)
168
        {
169
            arrowLabels[page-1]->hide();
170

    
171
            int npages = int(texts.size());
172
            page += step;
173

    
174
            prev->setEnabled(page > 1);
175

    
176
            next->setEnabled(page < npages);
177
            next->setDefault(page < npages);
178

    
179
            close->setEnabled(page == npages);
180
            close->setDefault(page == npages);
181

    
182
            numberLabel->setText(d.tr("%1.").arg(page));
183
            titleLabel->setText(texts[page-1].first);
184
            bodyLabel->setText(texts[page-1].second);
185

    
186
            arrowLabels[page-1]->show();
187
        };
188

    
189
    QObject::connect(next, &QPushButton::clicked, [&]() { repage(1); });
190
    QObject::connect(prev, &QPushButton::clicked, [&]() { repage(-1); });
191

    
192
    d.exec();
193
    
194
    settings.setValue("shown", true);
195
}
196