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

History | View | Annotate | Download (7.65 KB)

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

    
3
/*
4
    Sonic Lineup
5
    Comparative visualisation and alignment of related audio recordings
6
    Centre for Digital Music, Queen Mary, University of London.
7
    
8
    This program is free software; you can redistribute it and/or
9
    modify it under the terms of the GNU General Public License as
10
    published by the Free Software Foundation; either version 2 of the
11
    License, or (at your option) any later version.  See the file
12
    COPYING included with this distribution for more information.
13
*/
14

    
15
#include "IntroDialog.h"
16

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

    
29
#include "widgets/IconLoader.h"
30

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

    
34
using namespace std;
35

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

    
45
    QDialog d(parent, Qt::SplashScreen);
46
    d.setWindowTitle(d.tr("Welcome!"));
47
    
48
    vector<pair<QString, QString>> texts {
49
        { d.tr("Welcome!"),
50
          d.tr("<p>The first thing is to open some audio files. The Open button<br>"
51
               "is on the toolbar up here.</p>"
52
               "<p>(But please read these introductory notes first!)</p>"
53
               "<p>If you have more than one recording of the same thing,<br>"
54
               "such as multiple performances, takes, or even cover versions,"
55
               "<br>try opening them all in one go.</p>"
56
               "<p>Comparative visualisation is what this app is designed for.</p>"
57
               "<p>You can also record a new track directly from the "
58
               "microphone.</p>")
59
        },
60
        { d.tr("Scroll, zoom, and play"),
61
          d.tr("<p>Your audio files will all appear in this main pane.</p>"
62
               "<p>Drag left and right to move through time, and use<br>"
63
               "two-finger scroll-drag, or a scroll wheel, to zoom.</p>"
64
               "<p>You can also move using the left and right cursor keys,<br>"
65
               "and zoom using the up and down keys.</p>"
66
               "<p>%1 will try to align the audio files, so as to<br>"
67
               "ensure they scroll together in terms of musical material.<br>"
68
               "You can toggle or control alignment in the Playback menu.</p>"
69
              ).arg(QApplication::applicationName())
70
        },
71
        { d.tr("Change your view"),
72
          d.tr("<p>Use the buttons along the bottom to change the current view.</p>"
73
               "<p>There are two waveform views: \"Outline\" for a simplified<br>"
74
               "overview, or a more typical waveform for detail. And two<br>"
75
               "spectrograms with different frequency and colour profiles.</p>"
76
               "<p>The \"Sung pitch\" view shows pitch profiles, in the case of<br>"
77
               "solo singing or similar music; \"Key\" is a key-likelihood plot;<br>"
78
               "and \"Stereo azimuth\" gives a stereo-plan decomposition.</p>"
79
               "<p>See the documentation in the Help menu for more details.</p>"
80
               "</ul>"
81
              )
82
        }
83
    };
84

    
85
    QGridLayout *outerLayout = new QGridLayout;
86
    d.setLayout(outerLayout);
87
    QFrame *outerFrame = new QFrame;
88
#ifdef Q_OS_WIN32
89
    outerFrame->setFrameStyle(QFrame::Panel | QFrame::Raised);
90
#endif
91
    outerLayout->addWidget(outerFrame, 0, 0);
92
    
93
    QGridLayout *layout = new QGridLayout;
94
    outerFrame->setLayout(layout);
95
    layout->setRowStretch(0, 10);
96
    layout->setRowStretch(1, 20);
97
    layout->setRowStretch(2, 10);
98
    layout->setRowStretch(3, 0);
99
    layout->setColumnStretch(0, 0);
100
    layout->setColumnStretch(1, 0);
101
    layout->setColumnStretch(2, 20);
102

    
103
    int page = 1;
104

    
105
    vector<QString> arrowFiles {
106
        ":icons/scalable/arrow-above-white.svg",
107
        ":icons/scalable/arrow-left-white.svg",
108
        ":icons/scalable/arrow-below-white.svg"
109
    };
110

    
111
    int dpratio = d.devicePixelRatio();
112
    int sz = dpratio * int(round(parent->height() * 0.1));
113

    
114
    vector<QPixmap> arrowPixmaps {
115
        QPixmap(sz, sz),
116
        QPixmap(sz, (sz * 6) / 10),
117
        QPixmap(sz, sz)
118
    };
119

    
120
    for (int i = 0; i < int(arrowFiles.size()); ++i) {
121
        arrowPixmaps[i].fill(Qt::transparent);
122
        QPainter painter(&arrowPixmaps[i]);
123
        QSvgRenderer renderer(arrowFiles[i]);
124
        renderer.render(&painter);
125
        arrowPixmaps[i].setDevicePixelRatio(dpratio);
126
    }
127

    
128
    vector<QLabel *> arrowLabels;
129

    
130
    for (auto p: arrowPixmaps) {
131
        QLabel *arrowLabel = new QLabel;
132
        arrowLabel->setPixmap(p);
133
        arrowLabel->setVisible(arrowLabels.empty());
134
        arrowLabels.push_back(arrowLabel);
135
    }
136
        
137
    layout->addWidget(arrowLabels[0], 0, 0);
138
    layout->addWidget(arrowLabels[1], 1, 0, 1, 1, Qt::AlignTop);
139
    layout->addWidget(arrowLabels[2], 1, 0, 1, 1, Qt::AlignBottom);
140

    
141
    QFont smallerFont(d.font());
142
#ifdef Q_OS_WIN32
143
    if (smallerFont.pixelSize() > 0) {
144
        smallerFont.setPixelSize(int(ceil(smallerFont.pixelSize() * 1.1)));
145
    } else {
146
        smallerFont.setPointSize(int(ceil(smallerFont.pointSize() * 1.1)));
147
    }
148
#endif
149
    
150
    QFont biggerFont(d.font());
151
    if (biggerFont.pixelSize() > 0) {
152
        biggerFont.setPixelSize(int(ceil(biggerFont.pixelSize() * 1.4)));
153
    } else {
154
        biggerFont.setPointSize(int(ceil(biggerFont.pointSize() * 1.4)));
155
    }
156
    
157
    QLabel *numberLabel = new QLabel;
158
    numberLabel->setText(d.tr("%1.").arg(page));
159
    layout->addWidget(numberLabel, 0, 1, 1, 1,
160
                      Qt::AlignRight | Qt::AlignBottom);
161
    numberLabel->setFont(biggerFont);
162

    
163
    QLabel *titleLabel = new QLabel;
164
    titleLabel->setText(texts[page-1].first);
165
    titleLabel->setFont(biggerFont);
166
    layout->addWidget(titleLabel, 0, 2, 1, 1,
167
                      Qt::AlignLeft | Qt::AlignBottom);
168

    
169
    QLabel *bodyLabel = new QLabel;
170
    bodyLabel->setWordWrap(false);
171
    bodyLabel->setText(texts[page-1].second);
172
    bodyLabel->setFont(smallerFont);
173
    layout->addWidget(bodyLabel, 1, 2);
174
        
175
    QDialogButtonBox *bb = new QDialogButtonBox;
176

    
177
    QPushButton *prev = bb->addButton
178
        (d.tr("&Prev"), QDialogButtonBox::ActionRole);
179
    prev->setIcon(IconLoader().load("rewind"));
180
    prev->setEnabled(false);
181

    
182
    QPushButton *next = bb->addButton
183
        (d.tr("&Next"), QDialogButtonBox::ActionRole);
184
    next->setIcon(IconLoader().load("ffwd"));
185
    
186
    QPushButton *close = bb->addButton(QDialogButtonBox::Close);
187
    QObject::connect(close, SIGNAL(clicked()), &d, SLOT(accept()));
188
    close->setIcon(IconLoader().load("cross"));
189
    close->setEnabled(false);
190
    layout->addWidget(bb, 3, 0, 1, 3);
191

    
192
    auto repage =
193
        [&](int step)
194
        {
195
            arrowLabels[page-1]->hide();
196

    
197
            int npages = int(texts.size());
198
            page += step;
199

    
200
            prev->setEnabled(page > 1);
201

    
202
            next->setEnabled(page < npages);
203
            next->setDefault(page < npages);
204

    
205
            close->setEnabled(page == npages);
206
            close->setDefault(page == npages);
207

    
208
            numberLabel->setText(d.tr("%1.").arg(page));
209
            titleLabel->setText(texts[page-1].first);
210
            bodyLabel->setText(texts[page-1].second);
211

    
212
            arrowLabels[page-1]->show();
213
        };
214

    
215
    QObject::connect(next, &QPushButton::clicked, [&]() { repage(1); });
216
    QObject::connect(prev, &QPushButton::clicked, [&]() { repage(-1); });
217
    
218
    d.setMinimumSize(QSize(int(ceil(parent->width() * 0.4)),
219
                           int(ceil(parent->height() * 0.6))));
220
    d.setModal(false);
221
    d.exec();
222
    
223
    settings.setValue("shown", true);
224
}
225