diff --git a/widgets/videowidget.cpp b/widgets/videowidget.cpp index 29e3e80e0..a8ea15ed1 100644 --- a/widgets/videowidget.cpp +++ b/widgets/videowidget.cpp @@ -1,5 +1,5 @@ /* - * Copyright 2008 Aaron Seigo + * Copyright 2009 Marco Martin * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Library General Public License as @@ -19,13 +19,20 @@ #include "videowidget.h" -#include +#include +#include +#include + +#include +#include #include #include #include #include +#include +#include namespace Plasma { @@ -34,6 +41,9 @@ class VideoWidgetPrivate { public: VideoWidgetPrivate() + : ticking(false), + shownControls(VideoWidget::NoControls), + controlsWidget(0) { } @@ -41,11 +51,97 @@ public: { } + void playPause(); + void ticked(qint64 progress); + void totalTimeChanged(qint64 time); + void setPosition(int newProgress); + void setVolume(int value); + void volumeChanged(qreal value); + void showOpenFileDialog(); + void openFile(const QString &path); + void stateChanged(Phonon::State newState, Phonon::State oldState); + + Phonon::VideoWidget *videoWidget; Phonon::AudioOutput *audioOutput; Phonon::MediaObject *media; + + bool ticking; + + //control widgets + VideoWidget::Controls shownControls; + QGraphicsWidget *controlsWidget; + IconWidget *playPauseButton; + Slider *progress; + Slider *volume; + IconWidget *openFileButton; }; +void VideoWidgetPrivate::playPause() +{ + if (media->state() == Phonon::PlayingState) { + media->pause(); + } else { + media->play(); + } +} + +void VideoWidgetPrivate::ticked(qint64 newProgress) +{ + ticking = true; + progress->setValue(newProgress); + ticking = false; +} + +void VideoWidgetPrivate::totalTimeChanged(qint64 time) +{ + ticking = true; + //FIXME: this will break for veeery long stuff, butPhonon::SeekSlider seems to have the same problem + progress->setRange(0, time); + ticking = false; +} + +void VideoWidgetPrivate::setPosition(int progress) +{ + if (!ticking) { + media->seek(progress); + } +} + +void VideoWidgetPrivate::setVolume(int value) +{ + audioOutput->setVolume(qreal(value)/100.0); +} + +void VideoWidgetPrivate::volumeChanged(qreal value) +{ + volume->setValue(value*100); +} + +void VideoWidgetPrivate::showOpenFileDialog() +{ + openFile(KFileDialog::getOpenFileName()); +} + +void VideoWidgetPrivate::openFile(const QString &path) +{ + media->setCurrentSource(Phonon::MediaSource(path)); + media->play(); +} + +void VideoWidgetPrivate::stateChanged(Phonon::State newState, Phonon::State oldState) +{ + Q_UNUSED(oldState) + + if (newState == Phonon::PlayingState) { + playPauseButton->setIcon("media-playback-pause"); + } else { + playPauseButton->setIcon("media-playback-start"); + } +} + + + VideoWidget::VideoWidget(QGraphicsWidget *parent) : QGraphicsProxyWidget(parent), d(new VideoWidgetPrivate) @@ -89,6 +185,81 @@ QString VideoWidget::url() const return d->media->currentSource().url().toString(); } +void VideoWidget::setShownControls(Controls controls) +{ + d->shownControls = controls; + + QGraphicsLinearLayout *controlsLayout; + if (controls != NoControls && d->controlsWidget == 0) { + d->controlsWidget = new QGraphicsWidget(this); + controlsLayout = new QGraphicsLinearLayout(Qt::Horizontal, d->controlsWidget); + d->controlsWidget->setPos(0,0); + d->controlsWidget->show(); + d->controlsWidget->resize(size().width(), d->controlsWidget->size().height()); + //controls == NoControls + } else if (d->controlsWidget != 0) { + d->controlsWidget->deleteLater(); + d->controlsWidget = 0; + + //disconnect all the stuff that wasn't automatically disconnected 'cause widget deaths + disconnect(d->media, SIGNAL(stateChanged(Phonon::State, Phonon::State)), this, SLOT(stateChanged(Phonon::State, Phonon::State))); + disconnect(d->media, SIGNAL(tick(qint64)), this, SLOT(ticked(qint64))); + disconnect(d->media, SIGNAL(totalTimeChanged(qint64)), this, SLOT(totalTimeChanged(qint64))); + disconnect(d->audioOutput, SIGNAL(volumeChanged(qreal)), this, SLOT(volumeChanged(qreal))); + return; + } + + + d->playPauseButton = new IconWidget(d->controlsWidget); + d->playPauseButton->setIcon("media-playback-start"); + controlsLayout->addItem(d->playPauseButton); + connect(d->playPauseButton, SIGNAL(clicked()), this, SLOT(playPause())); + connect(d->media, SIGNAL(stateChanged(Phonon::State, Phonon::State)), this, SLOT(stateChanged(Phonon::State, Phonon::State))); + + d->playPauseButton->setVisible(controls&PlayPause); + + + + d->progress = new Slider(d->controlsWidget); + d->progress->setMinimum(0); + d->progress->setMaximum(100); + d->progress->setOrientation(Qt::Horizontal); + controlsLayout->addItem(d->progress); + controlsLayout->setStretchFactor(d->progress, 4); + + connect(d->media, SIGNAL(tick(qint64)), this, SLOT(ticked(qint64))); + connect(d->media, SIGNAL(totalTimeChanged(qint64)), SLOT(totalTimeChanged(qint64))); + connect(d->progress, SIGNAL(valueChanged(int)), this, SLOT(setPosition(int))); + + d->progress->setVisible(controls&Progress); + + + d->volume = new Slider(d->controlsWidget); + d->volume->setMinimum(0); + d->volume->setMaximum(100); + d->volume->setValue(100); + d->volume->setOrientation(Qt::Horizontal); + controlsLayout->addItem(d->volume); + + connect(d->volume, SIGNAL(valueChanged(int)), SLOT(setVolume(int))); + connect(d->audioOutput, SIGNAL(volumeChanged(qreal)), SLOT(volumeChanged(qreal))); + + d->volume->setVisible(controls&Volume); + + + d->openFileButton = new IconWidget(d->controlsWidget); + d->openFileButton->setIcon(KIcon("document-open")); + connect(d->openFileButton, SIGNAL(clicked()), this, SLOT(showOpenFileDialog())); + controlsLayout->addItem(d->openFileButton); + + d->openFileButton->setVisible(controls&OpenFile); +} + +VideoWidget::Controls VideoWidget::shownControls() const +{ + return d->shownControls; +} + void VideoWidget::play() { d->media->play(); @@ -140,6 +311,16 @@ Phonon::VideoWidget *VideoWidget::nativeWidget() const return d->videoWidget; } + +void VideoWidget::resizeEvent(QGraphicsSceneResizeEvent *event) +{ + QGraphicsProxyWidget::resizeEvent(event); + + if (d->controlsWidget) { + d->controlsWidget->resize(event->newSize().width(), d->controlsWidget->size().height()); + } +} + } // namespace Plasma #include diff --git a/widgets/videowidget.h b/widgets/videowidget.h index 67128391f..df5c24e05 100644 --- a/widgets/videowidget.h +++ b/widgets/videowidget.h @@ -53,9 +53,25 @@ class PLASMA_EXPORT VideoWidget : public QGraphicsProxyWidget Q_PROPERTY(QString currentTime READ currentTime) Q_PROPERTY(QString totalTime READ totalTime) Q_PROPERTY(QString remainingTime READ remainingTime) + Q_PROPERTY(Controls shownControls READ shownControls WRITE setShownControls) Q_PROPERTY(QString styleSheet READ styleSheet WRITE setStyleSheet) public: + enum Control { + NoControls = 0, + Play = 1, + Pause = 2, + Stop = 4, + PlayPause = 8, + Previous = 16, + Next = 32, + Progress = 64, + Volume = 128, + OpenFile = 256, + DefaultControls = PlayPause|Progress|Volume|OpenFile + }; + Q_DECLARE_FLAGS(Controls, Control); + explicit VideoWidget(QGraphicsWidget *parent = 0); ~VideoWidget(); @@ -97,6 +113,20 @@ public: */ qint64 remainingTime() const; + /** + * Set what control widgets to show + * + * @arg controls OR combination of Controls flags + * @see Controls + */ + void setShownControls(Controls controls); + + /** + * @return the video controls that are being show right now + * @see Controls + */ + Controls shownControls() const; + /** * Sets the stylesheet used to control the visual display of this VideoWidget * @@ -148,8 +178,20 @@ Q_SIGNALS: */ void aboutToFinish(); +protected: + void resizeEvent(QGraphicsSceneResizeEvent *event); + private: VideoWidgetPrivate * const d; + + Q_PRIVATE_SLOT(d, void playPause()) + Q_PRIVATE_SLOT(d, void ticked(qint64 progress)) + Q_PRIVATE_SLOT(d, void totalTimeChanged(qint64 time)) + Q_PRIVATE_SLOT(d, void setPosition(int progress)) + Q_PRIVATE_SLOT(d, void setVolume(int value)) + Q_PRIVATE_SLOT(d, void volumeChanged(qreal value)) + Q_PRIVATE_SLOT(d, void showOpenFileDialog()) + Q_PRIVATE_SLOT(d, void stateChanged(Phonon::State newState, Phonon::State oldState)) }; } // namespace Plasma