Visualisation overlay

This commit is contained in:
David Sansome 2010-06-06 18:18:06 +00:00
parent 994d6d9c20
commit c541f242c5
33 changed files with 622 additions and 52 deletions

View File

@ -1212,6 +1212,9 @@ msgstr ""
msgid "Clementine Visualisation"
msgstr ""
msgid "Visualisations Settings"
msgstr ""
msgid "Copy to library..."
msgstr ""

View File

@ -1218,6 +1218,9 @@ msgstr "Vyber barvu..."
msgid "Clementine Visualisation"
msgstr ""
msgid "Visualisations Settings"
msgstr ""
msgid "Copy to library..."
msgstr "Zkopírovat do knihovny..."

View File

@ -1221,6 +1221,9 @@ msgstr "Vælg farve..."
msgid "Clementine Visualisation"
msgstr ""
msgid "Visualisations Settings"
msgstr ""
msgid "Copy to library..."
msgstr "Kopiér til bibliotek..."

View File

@ -1221,6 +1221,9 @@ msgstr "Farbe wählen..."
msgid "Clementine Visualisation"
msgstr ""
msgid "Visualisations Settings"
msgstr ""
msgid "Copy to library..."
msgstr "In die Musiksammlung kopieren..."

View File

@ -1222,6 +1222,9 @@ msgstr "Επέλεξε χρώμα..."
msgid "Clementine Visualisation"
msgstr ""
msgid "Visualisations Settings"
msgstr ""
msgid "Copy to library..."
msgstr "Αντιγραφή στην βιβλιοθήκη..."

View File

@ -1216,6 +1216,9 @@ msgstr "Choose colour..."
msgid "Clementine Visualisation"
msgstr ""
msgid "Visualisations Settings"
msgstr ""
msgid "Copy to library..."
msgstr "Copy to library..."

View File

@ -1228,6 +1228,9 @@ msgstr "Elegir color..."
msgid "Clementine Visualisation"
msgstr ""
msgid "Visualisations Settings"
msgstr ""
msgid "Copy to library..."
msgstr "Copiar a la colección..."

View File

@ -1212,6 +1212,9 @@ msgstr ""
msgid "Clementine Visualisation"
msgstr ""
msgid "Visualisations Settings"
msgstr ""
msgid "Copy to library..."
msgstr "Kopioi kirjastoon"

View File

@ -1226,6 +1226,9 @@ msgstr "Choisir une couleur..."
msgid "Clementine Visualisation"
msgstr ""
msgid "Visualisations Settings"
msgstr ""
msgid "Copy to library..."
msgstr "Copier dans la bilbiothèque..."

View File

@ -1214,6 +1214,9 @@ msgstr ""
msgid "Clementine Visualisation"
msgstr ""
msgid "Visualisations Settings"
msgstr ""
msgid "Copy to library..."
msgstr "Copiar para a biblioteca"

View File

@ -1225,6 +1225,9 @@ msgstr "Scegli colore..."
msgid "Clementine Visualisation"
msgstr ""
msgid "Visualisations Settings"
msgstr ""
msgid "Copy to library..."
msgstr "Copia nella raccolta..."

View File

@ -1214,6 +1214,9 @@ msgstr ""
msgid "Clementine Visualisation"
msgstr ""
msgid "Visualisations Settings"
msgstr ""
msgid "Copy to library..."
msgstr ""

View File

@ -1218,6 +1218,9 @@ msgstr "Velg farge..."
msgid "Clementine Visualisation"
msgstr ""
msgid "Visualisations Settings"
msgstr ""
msgid "Copy to library..."
msgstr "Kopier til bibliotek..."

View File

@ -1212,6 +1212,9 @@ msgstr ""
msgid "Clementine Visualisation"
msgstr ""
msgid "Visualisations Settings"
msgstr ""
msgid "Copy to library..."
msgstr ""

View File

@ -1216,6 +1216,9 @@ msgstr "Wybierz kolor..."
msgid "Clementine Visualisation"
msgstr ""
msgid "Visualisations Settings"
msgstr ""
msgid "Copy to library..."
msgstr "Skopiuj do biblioteki..."

View File

@ -1219,6 +1219,9 @@ msgstr "Escolher a cor.."
msgid "Clementine Visualisation"
msgstr ""
msgid "Visualisations Settings"
msgstr ""
msgid "Copy to library..."
msgstr "Copiar para a biblioteca"

View File

@ -1212,6 +1212,9 @@ msgstr ""
msgid "Clementine Visualisation"
msgstr ""
msgid "Visualisations Settings"
msgstr ""
msgid "Copy to library..."
msgstr ""

View File

@ -1213,6 +1213,9 @@ msgstr "Alege culoare..."
msgid "Clementine Visualisation"
msgstr ""
msgid "Visualisations Settings"
msgstr ""
msgid "Copy to library..."
msgstr "Copiază în bibliotecă..."

View File

@ -1219,6 +1219,9 @@ msgstr "Выберете цвет"
msgid "Clementine Visualisation"
msgstr ""
msgid "Visualisations Settings"
msgstr ""
msgid "Copy to library..."
msgstr "Копировать в коллекцию..."

View File

@ -1220,6 +1220,9 @@ msgstr "Vybrať farbu..."
msgid "Clementine Visualisation"
msgstr ""
msgid "Visualisations Settings"
msgstr ""
msgid "Copy to library..."
msgstr "Skopírovať do zbierky..."

View File

@ -1221,6 +1221,9 @@ msgstr "Välj färg..."
msgid "Clementine Visualisation"
msgstr ""
msgid "Visualisations Settings"
msgstr ""
msgid "Copy to library..."
msgstr "Kopiera till bibliotek..."

View File

@ -1212,6 +1212,9 @@ msgstr ""
msgid "Clementine Visualisation"
msgstr ""
msgid "Visualisations Settings"
msgstr ""
msgid "Copy to library..."
msgstr ""

View File

@ -1203,6 +1203,9 @@ msgstr ""
msgid "Clementine Visualisation"
msgstr ""
msgid "Visualisations Settings"
msgstr ""
msgid "Copy to library..."
msgstr ""

View File

@ -1212,6 +1212,9 @@ msgstr ""
msgid "Clementine Visualisation"
msgstr ""
msgid "Visualisations Settings"
msgstr ""
msgid "Copy to library..."
msgstr ""

View File

@ -249,6 +249,8 @@ MainWindow::MainWindow(NetworkAccessManager* network, Engine::Type engine, QWidg
ui_->clear_playlist_button->setDefaultAction(ui_->action_clear_playlist);
ui_->playlist->SetActions(ui_->action_new_playlist, ui_->action_save_playlist,
ui_->action_load_playlist);
visualisation_->SetActions(ui_->action_previous_track, ui_->action_play_pause,
ui_->action_stop, ui_->action_next_track);
// Add the shuffle and repeat action groups to the menu
ui_->action_shuffle_mode->setMenu(playlist_sequence_->shuffle_menu());
@ -281,12 +283,15 @@ MainWindow::MainWindow(NetworkAccessManager* network, Engine::Type engine, QWidg
connect(player_, SIGNAL(Paused()), osd_, SLOT(Paused()));
connect(player_, SIGNAL(Stopped()), osd_, SLOT(Stopped()));
connect(player_, SIGNAL(Stopped()), visualisation_.get(), SLOT(Stopped()));
connect(player_, SIGNAL(PlaylistFinished()), osd_, SLOT(PlaylistFinished()));
connect(player_, SIGNAL(VolumeChanged(int)), osd_, SLOT(VolumeChanged(int)));
connect(player_, SIGNAL(VolumeChanged(int)), ui_->volume, SLOT(setValue(int)));
connect(player_, SIGNAL(ForceShowOSD(Song)), SLOT(ForceShowOSD(Song)));
connect(player_, SIGNAL(ForceShowOSD(Song)), visualisation_.get(), SLOT(SongMetadataChanged(Song)));
connect(playlists_, SIGNAL(CurrentSongChanged(Song)), osd_, SLOT(SongChanged(Song)));
connect(playlists_, SIGNAL(CurrentSongChanged(Song)), player_, SLOT(CurrentMetadataChanged(Song)));
connect(playlists_, SIGNAL(CurrentSongChanged(Song)), visualisation_.get(), SLOT(SongMetadataChanged(Song)));
connect(playlists_, SIGNAL(PlaylistChanged()), player_, SLOT(PlaylistChanged()));
connect(playlists_, SIGNAL(EditingFinished(QModelIndex)), SLOT(PlaylistEditFinished(QModelIndex)));
connect(playlists_, SIGNAL(Error(QString)), error_dialog_.get(), SLOT(ShowMessage(QString)));

View File

@ -6,18 +6,26 @@ include_directories(${PROJECTM_INCLUDE_DIRS})
set(SOURCES
projectmvisualisation.cpp
visualisationcontainer.cpp
visualisationoverlay.cpp
)
set(HEADERS
projectmvisualisation.h
visualisationcontainer.h
visualisationoverlay.h
)
set(UI
visualisationoverlay.ui
)
qt4_wrap_cpp(MOC ${HEADERS})
qt4_wrap_ui(UIC ${UI})
add_library(clementine_visualisations
${SOURCES}
${MOC}
${UIC}
)
target_link_libraries(clementine_visualisations
@ -26,4 +34,4 @@ target_link_libraries(clementine_visualisations
${PROJECTM_LIBRARIES}
)
add_translation_source(visualisations ${SOURCES} ${MOC})
add_translation_source(visualisations ${SOURCES} ${MOC} ${UIC})

View File

@ -17,51 +17,48 @@
#include "projectmvisualisation.h"
#include <QTimerEvent>
#include <QPainter>
#include <QPaintEngine>
#include <QtDebug>
#include <QGLWidget>
#include <QGraphicsView>
#include <libprojectM/projectM.hpp>
#include <GL/gl.h>
ProjectMVisualisation::ProjectMVisualisation(QWidget *parent)
: QGLWidget(parent),
ProjectMVisualisation::ProjectMVisualisation(QObject *parent)
: QGraphicsScene(parent),
projectm_(NULL)
{
connect(this, SIGNAL(sceneRectChanged(QRectF)), SLOT(SceneRectChanged(QRectF)));
}
ProjectMVisualisation::~ProjectMVisualisation() {
}
void ProjectMVisualisation::showEvent(QShowEvent *) {
redraw_timer_.start(1000/25, this);
}
void ProjectMVisualisation::drawBackground(QPainter* p, const QRectF&) {
p->beginNativePainting();
void ProjectMVisualisation::hideEvent(QHideEvent *) {
redraw_timer_.stop();
}
if (!projectm_) {
projectm_.reset(new projectM("/usr/share/projectM/config.inp"));
}
void ProjectMVisualisation::timerEvent(QTimerEvent* e) {
if (e->timerId() == redraw_timer_.timerId())
update();
}
void ProjectMVisualisation::initializeGL() {
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
projectm_.reset(new projectM("/usr/share/projectM/config.inp"));
projectm_->selectPreset(100);
}
void ProjectMVisualisation::paintGL() {
projectm_->projectM_resetGL(sceneRect().width(), sceneRect().height());
projectm_->renderFrame();
p->endNativePainting();
}
void ProjectMVisualisation::resizeGL(int w, int h) {
projectm_->projectM_resetGL(w, h);
void ProjectMVisualisation::SceneRectChanged(const QRectF &rect) {
if (projectm_)
projectm_->projectM_resetGL(rect.width(), rect.height());
}
void ProjectMVisualisation::ConsumeBuffer(GstBuffer *buffer, GstEnginePipeline*) {
const int samples = GST_BUFFER_SIZE(buffer) / sizeof(short);
const short* data = reinterpret_cast<short*>(GST_BUFFER_DATA(buffer));
projectm_->pcm()->addPCM16Data(data, samples);
if (projectm_)
projectm_->pcm()->addPCM16Data(data, samples);
gst_buffer_unref(buffer);
}

View File

@ -17,7 +17,7 @@
#ifndef PROJECTMVISUALISATION_H
#define PROJECTMVISUALISATION_H
#include <QGLWidget>
#include <QGraphicsScene>
#include <QBasicTimer>
#include <boost/scoped_ptr.hpp>
@ -26,29 +26,24 @@
class projectM;
class ProjectMVisualisation : public QGLWidget, public BufferConsumer {
class ProjectMVisualisation : public QGraphicsScene, public BufferConsumer {
Q_OBJECT
public:
ProjectMVisualisation(QWidget *parent = 0);
ProjectMVisualisation(QObject *parent = 0);
~ProjectMVisualisation();
// QGLWidget
void paintGL();
void resizeGL(int w, int h);
void initializeGL();
// BufferConsumer
void ConsumeBuffer(GstBuffer *buffer, GstEnginePipeline*);
protected:
// QWidget
void hideEvent(QHideEvent *);
void showEvent(QShowEvent *);
void timerEvent(QTimerEvent *);
// QGraphicsScene
void drawBackground(QPainter *painter, const QRectF &rect);
private slots:
void SceneRectChanged(const QRectF& rect);
private:
boost::scoped_ptr<projectM> projectm_;
QBasicTimer redraw_timer_;
};
#endif // PROJECTMVISUALISATION_H

View File

@ -14,35 +14,55 @@
along with Clementine. If not, see <http://www.gnu.org/licenses/>.
*/
#include "visualisationcontainer.h"
#include "projectmvisualisation.h"
#include "visualisationcontainer.h"
#include "visualisationoverlay.h"
#include "engines/gstengine.h"
#include <QHBoxLayout>
#include <QSettings>
#include <QGLWidget>
#include <QtDebug>
#include <QGraphicsProxyWidget>
#include <QLabel>
const char* VisualisationContainer::kSettingsGroup = "Visualisations";
const int VisualisationContainer::kDefaultWidth = 828;
const int VisualisationContainer::kDefaultHeight = 512;
const int VisualisationContainer::kDefaultFps = 35;
VisualisationContainer::VisualisationContainer(QWidget *parent)
: QWidget(parent),
: QGraphicsView(parent),
engine_(NULL),
vis_(new ProjectMVisualisation(this))
vis_(new ProjectMVisualisation(this)),
overlay_(new VisualisationOverlay),
fps_(kDefaultFps)
{
setWindowTitle(tr("Clementine Visualisation"));
QHBoxLayout* layout = new QHBoxLayout(this);
layout->setMargin(0);
layout->setSpacing(0);
layout->addWidget(vis_);
setLayout(layout);
// Set up the graphics view
setScene(vis_);
setViewport(new QGLWidget(QGLFormat(QGL::SampleBuffers)));
setViewportUpdateMode(QGraphicsView::FullViewportUpdate);
setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
// Add the overlay
overlay_proxy_ = scene()->addWidget(overlay_);
connect(overlay_, SIGNAL(OpacityChanged(qreal)), SLOT(ChangeOverlayOpacity(qreal)));
ChangeOverlayOpacity(0.0);
// Load settings
QSettings s;
s.beginGroup(kSettingsGroup);
if (!restoreGeometry(s.value("geometry").toByteArray())) {
resize(kDefaultWidth, kDefaultHeight);
}
fps_ = s.value("fps", kDefaultFps).toInt();
SizeChanged();
show();
}
void VisualisationContainer::SetEngine(GstEngine* engine) {
@ -51,18 +71,71 @@ void VisualisationContainer::SetEngine(GstEngine* engine) {
engine_->AddBufferConsumer(vis_);
}
void VisualisationContainer::showEvent(QShowEvent*) {
void VisualisationContainer::showEvent(QShowEvent* e) {
QGraphicsView::showEvent(e);
update_timer_.start(1000 / fps_, this);
if (engine_)
engine_->AddBufferConsumer(vis_);
}
void VisualisationContainer::hideEvent(QHideEvent*) {
void VisualisationContainer::hideEvent(QHideEvent* e) {
QGraphicsView::hideEvent(e);
update_timer_.stop();
if (engine_)
engine_->RemoveBufferConsumer(vis_);
}
void VisualisationContainer::resizeEvent(QResizeEvent *) {
void VisualisationContainer::resizeEvent(QResizeEvent* e) {
QGraphicsView::resizeEvent(e);
SizeChanged();
}
void VisualisationContainer::SizeChanged() {
// Save the geometry
QSettings s;
s.beginGroup(kSettingsGroup);
s.setValue("geometry", saveGeometry());
// Resize the scene
if (scene())
scene()->setSceneRect(QRect(QPoint(0, 0), size()));
// Resize the overlay
overlay_->resize(size());
}
void VisualisationContainer::timerEvent(QTimerEvent* e) {
if (e->timerId() == update_timer_.timerId())
scene()->update();
}
void VisualisationContainer::SetActions(QAction *previous, QAction *play_pause,
QAction *stop, QAction *next) {
overlay_->SetActions(previous, play_pause, stop, next);
}
void VisualisationContainer::SongMetadataChanged(const Song &metadata) {
overlay_->SetSongTitle(QString("%1 - %2").arg(metadata.artist(), metadata.title()));
}
void VisualisationContainer::Stopped() {
overlay_->SetSongTitle(tr("Clementine"));
}
void VisualisationContainer::ChangeOverlayOpacity(qreal value) {
overlay_proxy_->setOpacity(value);
}
void VisualisationContainer::enterEvent(QEvent *) {
overlay_->SetVisible(true);
}
void VisualisationContainer::leaveEvent(QEvent *) {
overlay_->SetVisible(false);
}
void VisualisationContainer::mouseMoveEvent(QMouseEvent *) {
overlay_->SetVisible(true);
}

View File

@ -17,12 +17,16 @@
#ifndef VISUALISATIONCONTAINER_H
#define VISUALISATIONCONTAINER_H
#include <QWidget>
#include <QGraphicsView>
#include <QBasicTimer>
#include "core/song.h"
class ProjectMVisualisation;
class GstEngine;
class ProjectMVisualisation;
class VisualisationOverlay;
class VisualisationContainer : public QWidget {
class VisualisationContainer : public QGraphicsView {
Q_OBJECT
public:
@ -31,18 +35,41 @@ public:
static const char* kSettingsGroup;
static const int kDefaultWidth;
static const int kDefaultHeight;
static const int kDefaultFps;
void SetEngine(GstEngine* engine);
void SetActions(QAction* previous, QAction* play_pause,
QAction* stop, QAction* next);
public slots:
void SongMetadataChanged(const Song& metadata);
void Stopped();
protected:
// QWidget
void showEvent(QShowEvent*);
void hideEvent(QHideEvent*);
void resizeEvent(QResizeEvent *);
void timerEvent(QTimerEvent *);
void mouseMoveEvent(QMouseEvent *event);
void enterEvent(QEvent *);
void leaveEvent(QEvent *);
private:
void SizeChanged();
private slots:
void ChangeOverlayOpacity(qreal value);
private:
GstEngine* engine_;
ProjectMVisualisation* vis_;
VisualisationOverlay* overlay_;
QBasicTimer update_timer_;
QGraphicsProxyWidget* overlay_proxy_;
int fps_;
};
#endif // VISUALISATIONCONTAINER_H

View File

@ -0,0 +1,99 @@
/* This file is part of Clementine.
Clementine is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
Clementine is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with Clementine. If not, see <http://www.gnu.org/licenses/>.
*/
#include "visualisationoverlay.h"
#include "ui_visualisationoverlay.h"
#include "ui/iconloader.h"
#include <QMouseEvent>
#include <QtDebug>
#include <QTimerEvent>
#include <QTimeLine>
#include <QGraphicsProxyWidget>
const int VisualisationOverlay::kFadeDuration = 500;
const int VisualisationOverlay::kFadeTimeout = 5000;
VisualisationOverlay::VisualisationOverlay(QWidget *parent)
: QWidget(parent),
ui_(new Ui_VisualisationOverlay),
fade_timeline_(new QTimeLine(kFadeDuration, this)),
visible_(false)
{
ui_->setupUi(this);
setAttribute(Qt::WA_TranslucentBackground);
setMouseTracking(true);
ui_->settings->setIcon(IconLoader::Load("configure"));
connect(ui_->settings, SIGNAL(clicked()), SLOT(ShowSettingsMenu()));
connect(fade_timeline_, SIGNAL(valueChanged(qreal)), SIGNAL(OpacityChanged(qreal)));
}
VisualisationOverlay::~VisualisationOverlay() {
delete ui_;
}
QGraphicsProxyWidget* VisualisationOverlay::title(QGraphicsProxyWidget* proxy) const {
return proxy->createProxyForChildWidget(ui_->song_title);
}
void VisualisationOverlay::SetActions(QAction* previous, QAction* play_pause,
QAction* stop, QAction* next) {
ui_->previous->setDefaultAction(previous);
ui_->play_pause->setDefaultAction(play_pause);
ui_->stop->setDefaultAction(stop);
ui_->next->setDefaultAction(next);
}
void VisualisationOverlay::ShowSettingsMenu() {
}
void VisualisationOverlay::timerEvent(QTimerEvent* e) {
QWidget::timerEvent(e);
if (e->timerId() == fade_out_timeout_.timerId()) {
SetVisible(false);
}
}
void VisualisationOverlay::SetVisible(bool visible) {
fade_out_timeout_.stop();
if (visible)
fade_out_timeout_.start(kFadeTimeout, this);
if (visible == visible_)
return;
visible_ = visible;
// If there's already another fader running then start from the same time
// that one was already at.
int start_time = visible ? 0 : fade_timeline_->duration();
if (fade_timeline_->state() == QTimeLine::Running)
start_time = fade_timeline_->currentTime();
fade_timeline_->stop();
fade_timeline_->setDirection(visible ? QTimeLine::Forward : QTimeLine::Backward);
fade_timeline_->setCurrentTime(start_time);
fade_timeline_->resume();
}
void VisualisationOverlay::SetSongTitle(const QString &title) {
ui_->song_title->setText(title);
SetVisible(true);
}

View File

@ -0,0 +1,64 @@
/* This file is part of Clementine.
Clementine is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
Clementine is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with Clementine. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef VISUALISATIONOVERLAY_H
#define VISUALISATIONOVERLAY_H
#include <QWidget>
#include <QBasicTimer>
class Ui_VisualisationOverlay;
class QTimeLine;
class VisualisationOverlay : public QWidget {
Q_OBJECT
public:
VisualisationOverlay(QWidget* parent = 0);
~VisualisationOverlay();
static const int kFadeDuration;
static const int kFadeTimeout;
QGraphicsProxyWidget* title(QGraphicsProxyWidget* proxy) const;
void SetActions(QAction* previous, QAction* play_pause,
QAction* stop, QAction* next);
void SetSongTitle(const QString& title);
public slots:
void SetVisible(bool visible);
signals:
void OpacityChanged(qreal value);
protected:
// QWidget
void timerEvent(QTimerEvent *);
private slots:
void ShowSettingsMenu();
private:
Ui_VisualisationOverlay* ui_;
QTimeLine* fade_timeline_;
QBasicTimer fade_out_timeout_;
bool visible_;
};
#endif // VISUALISATIONOVERLAY_H

View File

@ -0,0 +1,230 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>VisualisationOverlay</class>
<widget class="QWidget" name="VisualisationOverlay">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>523</width>
<height>302</height>
</rect>
</property>
<property name="windowTitle">
<string>Form</string>
</property>
<property name="styleSheet">
<string notr="true">#frame {
background-color: rgba(96, 59, 25, 70%);
border-top-left-radius: 10px;
border-top-right-radius: 10px;
border-color: rgba(145, 89, 38, 100%);
border-width: 4px 4px 0px 4px;
border-style: solid;
}
#song_title {
font-weight: bold;
font-size: 20px;
color: #feae65;
}
QToolButton {
background: transparent;
border: none;
}</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout_2">
<property name="margin">
<number>0</number>
</property>
<item>
<spacer name="verticalSpacer">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>210</height>
</size>
</property>
</spacer>
</item>
<item>
<layout class="QHBoxLayout" name="horizontalLayout_3">
<item>
<spacer name="horizontalSpacer">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
<item>
<widget class="QFrame" name="frame">
<property name="frameShape">
<enum>QFrame::StyledPanel</enum>
</property>
<property name="frameShadow">
<enum>QFrame::Raised</enum>
</property>
<layout class="QVBoxLayout" name="verticalLayout">
<item>
<widget class="QLabel" name="song_title">
<property name="text">
<string>Clementine</string>
</property>
<property name="alignment">
<set>Qt::AlignCenter</set>
</property>
</widget>
</item>
<item>
<layout class="QHBoxLayout" name="horizontalLayout_2">
<item>
<spacer name="horizontalSpacer_5">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeType">
<enum>QSizePolicy::Preferred</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
<item>
<widget class="QWidget" name="widget" native="true">
<property name="sizePolicy">
<sizepolicy hsizetype="Maximum" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<layout class="QHBoxLayout" name="horizontalLayout">
<property name="margin">
<number>0</number>
</property>
<item>
<widget class="QToolButton" name="previous">
<property name="iconSize">
<size>
<width>24</width>
<height>24</height>
</size>
</property>
</widget>
</item>
<item>
<widget class="QToolButton" name="play_pause">
<property name="iconSize">
<size>
<width>24</width>
<height>24</height>
</size>
</property>
</widget>
</item>
<item>
<widget class="QToolButton" name="stop">
<property name="iconSize">
<size>
<width>24</width>
<height>24</height>
</size>
</property>
</widget>
</item>
<item>
<widget class="QToolButton" name="next">
<property name="iconSize">
<size>
<width>24</width>
<height>24</height>
</size>
</property>
</widget>
</item>
<item>
<spacer name="horizontalSpacer_3">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeType">
<enum>QSizePolicy::Fixed</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>13</height>
</size>
</property>
</spacer>
</item>
<item>
<widget class="QToolButton" name="settings">
<property name="toolTip">
<string>Visualisations Settings</string>
</property>
<property name="iconSize">
<size>
<width>24</width>
<height>24</height>
</size>
</property>
</widget>
</item>
</layout>
</widget>
</item>
<item>
<spacer name="horizontalSpacer_4">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeType">
<enum>QSizePolicy::Preferred</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
</layout>
</item>
</layout>
</widget>
</item>
<item>
<spacer name="horizontalSpacer_2">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
</layout>
</item>
</layout>
</widget>
<resources/>
<connections/>
</ui>