dtkVisualizationWidgetsVideoControls.cpp 10 KB
Newer Older
1 2
#include "dtkVisualizationWidgetsVideoControls.h"

KLOCZKO Thibaud's avatar
KLOCZKO Thibaud committed
3
#include <dtkFonts/dtkFontAwesome>
4

KLOCZKO Thibaud's avatar
KLOCZKO Thibaud committed
5
#include <QtWidgets>
6

KLOCZKO Thibaud's avatar
KLOCZKO Thibaud committed
7 8 9 10 11
// ///////////////////////////////////////////////////////////////////
// dtkVisualizationWidgetsVideoControlsItem
// ///////////////////////////////////////////////////////////////////

class dtkVisualizationWidgetsVideoControlsItem : public QFrame
12 13 14 15
{
    Q_OBJECT

public:
KLOCZKO Thibaud's avatar
KLOCZKO Thibaud committed
16 17 18
    dtkVisualizationWidgetsVideoControlsItem(fa::icon icon, int icon_size, QWidget *parent = nullptr);

    void setIcon(fa::icon icon);
19 20 21 22 23 24 25 26 27

signals:
    void clicked(void);

protected:
    QLabel *label = nullptr;
    int m_icon_size = 0;

protected:
KLOCZKO Thibaud's avatar
KLOCZKO Thibaud committed
28
    void mousePressEvent(QMouseEvent *);
29 30
};

KLOCZKO Thibaud's avatar
KLOCZKO Thibaud committed
31 32 33 34 35 36 37 38 39 40 41 42
// ///////////////////////////////////////////////////////////////////

dtkVisualizationWidgetsVideoControlsItem::dtkVisualizationWidgetsVideoControlsItem(fa::icon icon, int icon_size, QWidget *parent) : QFrame(parent)
{
    m_icon_size = icon_size;

    label = new QLabel(this);
    label->setFixedSize(QSize(icon_size,icon_size));
    label->setPixmap(dtkFontAwesome::instance()->icon(icon).pixmap(icon_size, icon_size));
    label->setAttribute(Qt::WA_TranslucentBackground);
    label->setAttribute(Qt::WA_NoSystemBackground);
    label->setVisible(true);
43

KLOCZKO Thibaud's avatar
KLOCZKO Thibaud committed
44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66
    QHBoxLayout *layout = new QHBoxLayout;
    layout->setContentsMargins(0, 0, 0, 0);
    layout->setAlignment(Qt::AlignHCenter | Qt::AlignVCenter);
    layout->addWidget(label);
    this->setLayout(layout);
    this->setMouseTracking(true);
};

void dtkVisualizationWidgetsVideoControlsItem::setIcon(fa::icon icon)
{
    label->setPixmap(dtkFontAwesome::instance()->icon(icon).pixmap(m_icon_size, m_icon_size));
};

void dtkVisualizationWidgetsVideoControlsItem::mousePressEvent(QMouseEvent *)
{
    emit clicked();
}

// ///////////////////////////////////////////////////////////////////
// dtkVisualizationWidgetsVideoControlsPrivate
// ///////////////////////////////////////////////////////////////////

class dtkVisualizationWidgetsVideoControlsPrivate : public QObject
67 68 69
{
    Q_OBJECT

70 71 72
public:
    dtkVisualizationWidgetsVideoControlsItem *status_item = nullptr;
    dtkVisualizationWidgetsVideoControlsItem *rewind      = nullptr;
73
    dtkVisualizationWidgetsVideoControlsItem *fullscreen  = nullptr;
74

KLOCZKO Thibaud's avatar
KLOCZKO Thibaud committed
75
    dtkVisualizationWidgetsVideoControls::State state = dtkVisualizationWidgetsVideoControls::State::StoppedState;
76

77 78 79
public slots:
    void updateDurationInfo(qint64 currentInfo);

80 81
public:
    QProgressBar *progress_bar = nullptr;
82
    QProgressBar *progress_bar_buffered = nullptr;
83 84
    QLabel *label_duration = nullptr;
    bool is_fullscreen = false;
85 86
};

KLOCZKO Thibaud's avatar
KLOCZKO Thibaud committed
87 88
// ///////////////////////////////////////////////////////////////////

89 90 91 92 93 94 95 96 97 98 99 100 101 102 103
void dtkVisualizationWidgetsVideoControlsPrivate::updateDurationInfo(qint64 currentInfo)
{
    QString tStr;
    int duration = this->progress_bar->maximum() / 1000;
    if (currentInfo || duration) {
        QTime currentTime((currentInfo / 3600) % 60, (currentInfo / 60) % 60,
            currentInfo % 60, (currentInfo * 1000) % 1000);
        QTime totalTime((duration / 3600) % 60, (duration / 60) % 60,
            duration % 60, (duration * 1000) % 1000);
        QString format = "mm:ss";
        if (duration > 3600)
            format = "hh:mm:ss";
        tStr = currentTime.toString(format) + " / " + totalTime.toString(format);
    }
    this->label_duration->setText(tStr);
104 105
    //TODO: do not hard code color, but this requiress VTK background to use dtkThemes
    this->label_duration->setStyleSheet("font: 14pt; color: #bbbbbb;");
106 107
}

KLOCZKO Thibaud's avatar
KLOCZKO Thibaud committed
108 109 110 111 112
// ///////////////////////////////////////////////////////////////////
// dtkVisualizationWidgetsVideoControls
// ///////////////////////////////////////////////////////////////////

dtkVisualizationWidgetsVideoControls::dtkVisualizationWidgetsVideoControls(QWidget *parent) : QFrame(parent), d(new dtkVisualizationWidgetsVideoControlsPrivate)
113
{
114 115 116
    this->setAttribute(Qt::WA_NoSystemBackground);
    this->setAttribute(Qt::WA_TranslucentBackground);

117
    dtkFontAwesome::instance()->initFontAwesome();
118
    dtkFontAwesome::instance()->setDefaultOption("color", QColor(Qt::white));
119

120 121 122
    d->status_item = new dtkVisualizationWidgetsVideoControlsItem(fa::play, 24, parent);
    d->rewind      = new dtkVisualizationWidgetsVideoControlsItem(fa::stepbackward, 24, parent);
    d->fullscreen  = new dtkVisualizationWidgetsVideoControlsItem(fa::arrowsalt, 24, parent);
NICLAUSSE Nicolas's avatar
NICLAUSSE Nicolas committed
123
    connect(d->status_item, &dtkVisualizationWidgetsVideoControlsItem::clicked, this, &dtkVisualizationWidgetsVideoControls::toggle);
124 125 126 127 128 129 130 131 132
    connect(d->fullscreen, &dtkVisualizationWidgetsVideoControlsItem::clicked, [=]() {
            if (d->is_fullscreen) // was fullscreen
                d->fullscreen->setIcon(fa::arrowsalt);
            else
                d->fullscreen->setIcon(fa::compress);

            d->is_fullscreen = !d->is_fullscreen;
            emit fullscreen(d->is_fullscreen);
        });
133
    connect(d->rewind, &dtkVisualizationWidgetsVideoControlsItem::clicked, [=]() {
KLOCZKO Thibaud's avatar
KLOCZKO Thibaud committed
134
            d->state = State::StoppedState;
135 136 137 138 139 140 141 142
            d->status_item->setIcon(fa::play);
            d->progress_bar->reset();
            emit restart();
        });

    d->progress_bar = new QProgressBar(parent);
    d->progress_bar->setOrientation(Qt::Horizontal);
    d->progress_bar->setTextVisible(true);
143
    d->progress_bar->setFixedHeight(10);
144

145 146 147 148 149 150
    d->progress_bar_buffered = new QProgressBar(parent);
    d->progress_bar_buffered->setOrientation(Qt::Horizontal);
    d->progress_bar_buffered->setTextVisible(true);
    d->progress_bar_buffered->setFixedHeight(10);
    d->progress_bar_buffered->setVisible(false);

151
    QString style_bar = "QProgressBar{ border: 1px solid transparent; text-align: center; color:rgba(0,0,0,100); border-radius: 5px; background-color: qlineargradient(spread:pad, x1:0, y1:0, x2:1, y2:1, stop:0 rgba(182, 182, 182, 100), stop:1 rgba(209, 209, 209, 100)); } QProgressBar::chunk{ background-color: rgba(253,26,30,100); }";
152
    QString style_bar_buffered = "QProgressBar{ border: 1px solid transparent; text-align: center; color:rgba(0,0,0,100); border-radius: 5px; background-color: qlineargradient(spread:pad, x1:0, y1:0, x2:1, y2:1, stop:0 rgba(222, 222, 222, 100), stop:1 rgba(249, 249, 249, 100)); } QProgressBar::chunk{ background-color: rgba(253,156,170,100); }";
153 154

    d->progress_bar->setStyleSheet(style_bar);
155
    d->progress_bar_buffered->setStyleSheet(style_bar_buffered);
156

157 158 159 160 161 162 163 164
    d->label_duration = new QLabel(this);
    d->label_duration->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);

    QVBoxLayout *vlayout =  new QVBoxLayout(this);
    vlayout->setContentsMargins(32, 0, 32, 0);
    vlayout->setAlignment(Qt::AlignLeft);

    QHBoxLayout *layout =  new QHBoxLayout;
165 166 167
    layout->setContentsMargins(0, 0, 0, 0);

    layout->addWidget(d->status_item);
168 169 170 171
    layout->addWidget(d->rewind);
    layout->addWidget(d->label_duration);
    layout->addWidget(d->fullscreen);

172
    this->setMouseTracking(true);
173

174
    vlayout->addWidget(d->progress_bar);
175
    vlayout->addWidget(d->progress_bar_buffered);
176 177
    vlayout->addLayout(layout);

178

179
    this->setLayout(vlayout);
180 181
}

KLOCZKO Thibaud's avatar
KLOCZKO Thibaud committed
182 183 184 185
dtkVisualizationWidgetsVideoControls::~dtkVisualizationWidgetsVideoControls(void)
{
    delete d;
}
186

187 188
void dtkVisualizationWidgetsVideoControls::reset(void)
{
KLOCZKO Thibaud's avatar
KLOCZKO Thibaud committed
189
    d->state = State::StoppedState;
190
    dtkFontAwesome::instance()->setDefaultOption("color", QColor(Qt::white));
191 192 193
    d->status_item->setIcon(fa::play);
}

194 195 196 197 198
void dtkVisualizationWidgetsVideoControls::setBufferVisible(bool b)
{
    d->progress_bar_buffered->setVisible(b);
}

KLOCZKO Thibaud's avatar
KLOCZKO Thibaud committed
199
dtkVisualizationWidgetsVideoControls::State dtkVisualizationWidgetsVideoControls::state(void) const
200 201 202 203 204 205 206 207 208
{
    return d->state;
}

void dtkVisualizationWidgetsVideoControls::setFrameNumber(qlonglong count)
{
    d->progress_bar->setRange(1, count);
    d->progress_bar->setValue(1);
    d->progress_bar->reset();
209 210 211 212

    d->progress_bar_buffered->setRange(1, count);
    d->progress_bar_buffered->setValue(1);
    d->progress_bar_buffered->reset();
213 214
}

215 216 217
void dtkVisualizationWidgetsVideoControls::setDuration(qlonglong duration)
{
    d->progress_bar->setRange(0, duration);
218 219
    d->progress_bar_buffered->setRange(0, duration);
    d->updateDurationInfo(0);
220 221 222 223 224
}

void dtkVisualizationWidgetsVideoControls::setPosition(qlonglong pos)
{
    d->progress_bar->setValue(pos);
225
    d->updateDurationInfo(pos / 1000);
226 227
}

228 229 230 231 232
void dtkVisualizationWidgetsVideoControls::setBufferPosition(qlonglong pos)
{
    d->progress_bar_buffered->setValue(pos);
}

NICLAUSSE Nicolas's avatar
NICLAUSSE Nicolas committed
233 234
void dtkVisualizationWidgetsVideoControls::toggle(void)
{
KLOCZKO Thibaud's avatar
KLOCZKO Thibaud committed
235 236
    if (d->state == State::StoppedState || d->state == State::PausedState) {
        d->state = State::PlayingState;
237
        dtkFontAwesome::instance()->setDefaultOption("color", QColor(Qt::white));
NICLAUSSE Nicolas's avatar
NICLAUSSE Nicolas committed
238 239
        d->status_item->setIcon(fa::pause);
        emit play();
KLOCZKO Thibaud's avatar
KLOCZKO Thibaud committed
240

NICLAUSSE Nicolas's avatar
NICLAUSSE Nicolas committed
241
    } else {
KLOCZKO Thibaud's avatar
KLOCZKO Thibaud committed
242
        d->state = State::PausedState;
243
        dtkFontAwesome::instance()->setDefaultOption("color", QColor(Qt::white));
NICLAUSSE Nicolas's avatar
NICLAUSSE Nicolas committed
244 245 246 247 248
        d->status_item->setIcon(fa::play);
        emit pause();
    }
}

249 250 251 252 253
void dtkVisualizationWidgetsVideoControls::setCurrentFrame(qlonglong count)
{
    d->progress_bar->setValue(count);
}

254 255 256 257 258
void dtkVisualizationWidgetsVideoControls::setCurrentBufferFrame(qlonglong count)
{
    d->progress_bar_buffered->setValue(count);
}

259 260
void dtkVisualizationWidgetsVideoControls::mouseMoveEvent(QMouseEvent *event)
{
261 262 263 264 265 266 267 268 269 270 271 272
    int size = d->progress_bar->width();
    double percent = (event->pos().x() - d->progress_bar->x())/ (double)size ;
    int frame_index = percent * d->progress_bar->maximum() / 1000.0 ;

    QTime currentTime((frame_index / 3600) % 60, (frame_index / 60) % 60,
                      frame_index % 60, (frame_index * 1000) % 1000);

    QString format = "mm:ss";
    if (frame_index > 3600)
        format = "hh:mm:ss";

    d->progress_bar->setToolTip(currentTime.toString(format));
273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289
    event->ignore();

    QFrame::mouseMoveEvent(event);
}

void dtkVisualizationWidgetsVideoControls::mousePressEvent(QMouseEvent *event)
{
    int size = d->progress_bar->width();
    double percent = (event->pos().x() - d->progress_bar->x())/ (double)size ;
    int frame_index = percent * d->progress_bar->maximum();
    emit seekTo(frame_index);
    event->ignore();

    QFrame::mousePressEvent(event);
}

#include "dtkVisualizationWidgetsVideoControls.moc"