Add moodbar settings to the settings dialog

This commit is contained in:
David Sansome 2012-05-27 23:44:49 +01:00
parent 8c33cb91e0
commit abdc6d8844
17 changed files with 257 additions and 37 deletions

View File

@ -343,5 +343,6 @@
<file>providers/mygpo32.png</file>
<file>providers/itunes.png</file>
<file>providers/bbc.png</file>
<file>sample.mood</file>
</qresource>
</RCC>

BIN
data/sample.mood Executable file

Binary file not shown.

View File

@ -96,7 +96,7 @@ Application::Application(QObject* parent)
gpodder_sync_ = new GPodderSync(this, this);
#ifdef HAVE_MOODBAR
moodbar_loader_ = new MoodbarLoader(this);
moodbar_loader_ = new MoodbarLoader(this, this);
moodbar_controller_ = new MoodbarController(this, this);
#endif

View File

@ -26,6 +26,7 @@
#include <QApplication>
#include <QPainter>
#include <QSettings>
#include <QtConcurrentRun>
MoodbarItemDelegate::Data::Data()
@ -35,8 +36,24 @@ MoodbarItemDelegate::Data::Data()
MoodbarItemDelegate::MoodbarItemDelegate(Application* app, QObject* parent)
: QItemDelegate(parent),
app_(app)
app_(app),
style_(MoodbarRenderer::Style_Normal)
{
connect(app_, SIGNAL(SettingsChanged()), SLOT(ReloadSettings()));
ReloadSettings();
}
void MoodbarItemDelegate::ReloadSettings() {
QSettings s;
s.beginGroup("Moodbar");
MoodbarRenderer::MoodbarStyle new_style =
static_cast<MoodbarRenderer::MoodbarStyle>(
s.value("style", MoodbarRenderer::Style_Normal).toInt());
if (new_style != style_) {
style_ = new_style;
ReloadAllColors();
}
}
void MoodbarItemDelegate::paint(
@ -86,6 +103,12 @@ QPixmap MoodbarItemDelegate::PixmapForIndex(
}
// We have to start loading the data from scratch.
StartLoadingData(url, data);
return QPixmap();
}
void MoodbarItemDelegate::StartLoadingData(const QUrl& url, Data* data) {
data->state_ = Data::State_LoadingData;
// Load a mood file for this song and generate some colors from it
@ -108,8 +131,6 @@ QPixmap MoodbarItemDelegate::PixmapForIndex(
url, pipeline);
break;
}
return QPixmap();
}
bool MoodbarItemDelegate::RemoveFromCacheIfIndexesInvalid(const QUrl& url, Data* data) {
@ -123,6 +144,16 @@ bool MoodbarItemDelegate::RemoveFromCacheIfIndexesInvalid(const QUrl& url, Data*
return true;
}
void MoodbarItemDelegate::ReloadAllColors() {
foreach (const QUrl& url, data_.keys()) {
Data* data = data_[url];
if (data->state_ == Data::State_Loaded) {
StartLoadingData(url, data);
}
}
}
void MoodbarItemDelegate::DataLoaded( const QUrl& url, MoodbarPipeline* pipeline) {
Data* data = data_[url];
if (!data) {
@ -152,7 +183,7 @@ void MoodbarItemDelegate::StartLoadingColors(
url, watcher);
QFuture<ColorVector> future = QtConcurrent::run(MoodbarRenderer::Colors,
bytes, MoodbarRenderer::Style_Normal, qApp->palette());
bytes, style_, qApp->palette());
watcher->setFuture(future);
}

View File

@ -40,6 +40,8 @@ public:
const QModelIndex& index) const;
private slots:
void ReloadSettings();
void DataLoaded(const QUrl& url, MoodbarPipeline* pipeline);
void ColorsLoaded(const QUrl& url, QFutureWatcher<ColorVector>* watcher);
void ImageLoaded(const QUrl& url, QFutureWatcher<QImage>* watcher);
@ -67,14 +69,19 @@ private:
private:
QPixmap PixmapForIndex(const QModelIndex& index, const QSize& size);
void StartLoadingData(const QUrl& url, Data* data);
void StartLoadingColors(const QUrl& url, const QByteArray& bytes, Data* data);
void StartLoadingImage(const QUrl& url, Data* data);
bool RemoveFromCacheIfIndexesInvalid(const QUrl& url, Data* data);
void ReloadAllColors();
private:
Application* app_;
QCache<QUrl, Data> data_;
MoodbarRenderer::MoodbarStyle style_;
};
#endif // MOODBARITEMDELEGATE_H

View File

@ -17,6 +17,7 @@
#include "moodbarloader.h"
#include "moodbarpipeline.h"
#include "core/application.h"
#include "core/closure.h"
#include "core/qhash_qurl.h"
#include "core/utilities.h"
@ -31,7 +32,7 @@
#include <boost/scoped_ptr.hpp>
MoodbarLoader::MoodbarLoader(QObject* parent)
MoodbarLoader::MoodbarLoader(Application* app, QObject* parent)
: QObject(parent),
cache_(new QNetworkDiskCache(this)),
thread_(new QThread(this)),
@ -40,6 +41,9 @@ MoodbarLoader::MoodbarLoader(QObject* parent)
{
cache_->setCacheDirectory(Utilities::GetConfigPath(Utilities::Path_MoodbarCache));
cache_->setMaximumCacheSize(10 * 1024 * 1024); // 10MB - enough for 3333 moodbars
connect(app, SIGNAL(SettingsChanged()), SLOT(ReloadSettings()));
ReloadSettings();
}
MoodbarLoader::~MoodbarLoader() {
@ -47,6 +51,12 @@ MoodbarLoader::~MoodbarLoader() {
thread_->wait(1000);
}
void MoodbarLoader::ReloadSettings() {
QSettings s;
s.beginGroup("Moodbar");
save_alongside_originals_ = s.value("save_alongside_originals", false).toBool();
}
QStringList MoodbarLoader::MoodFilenames(const QString& song_filename) {
const QFileInfo file_info(song_filename);
const QString dir_path(file_info.dir().path());

View File

@ -25,13 +25,14 @@
class QNetworkDiskCache;
class QUrl;
class Application;
class MoodbarPipeline;
class MoodbarLoader : public QObject {
Q_OBJECT
public:
MoodbarLoader(QObject* parent = 0);
MoodbarLoader(Application* app, QObject* parent = 0);
~MoodbarLoader();
enum Result {
@ -50,6 +51,8 @@ public:
Result Load(const QUrl& url, QByteArray* data, MoodbarPipeline** async_pipeline);
private slots:
void ReloadSettings();
void RequestFinished(MoodbarPipeline* request, const QUrl& filename);
void MaybeTakeNextRequest();

View File

@ -16,10 +16,12 @@
*/
#include "moodbarproxystyle.h"
#include "core/application.h"
#include "core/logging.h"
#include <QEvent>
#include <QPainter>
#include <QSettings>
#include <QSlider>
#include <QStyleOptionComplex>
#include <QStyleOptionSlider>
@ -30,7 +32,7 @@ const int MoodbarProxyStyle::kBorderSize = 1;
const int MoodbarProxyStyle::kArrowWidth = 17;
const int MoodbarProxyStyle::kArrowHeight = 13;
MoodbarProxyStyle::MoodbarProxyStyle(QSlider* slider)
MoodbarProxyStyle::MoodbarProxyStyle(Application* app, QSlider* slider)
: QProxyStyle(slider->style()),
slider_(slider),
enabled_(true),
@ -44,6 +46,30 @@ MoodbarProxyStyle::MoodbarProxyStyle(QSlider* slider)
slider->installEventFilter(this);
connect(fade_timeline_, SIGNAL(valueChanged(qreal)), SLOT(FaderValueChanged(qreal)));
connect(app, SIGNAL(SettingsChanged()), SLOT(ReloadSettings()));
ReloadSettings();
}
void MoodbarProxyStyle::ReloadSettings() {
QSettings s;
s.beginGroup("Moodbar");
// Get the enabled/disabled setting, and start the timelines if there's a
// change.
enabled_ = s.value("show", true).toBool();
NextState();
// Get the style, and redraw if there's a change.
MoodbarRenderer::MoodbarStyle new_style =
static_cast<MoodbarRenderer::MoodbarStyle>(
s.value("style", MoodbarRenderer::Style_Normal).toInt());
if (new_style != moodbar_style_) {
moodbar_style_ = new_style;
moodbar_colors_dirty_ = true;
slider_->update();
}
}
void MoodbarProxyStyle::SetMoodbarData(const QByteArray& data) {

View File

@ -22,6 +22,8 @@
#include <QProxyStyle>
class Application;
class QSlider;
class QStyleOptionSlider;
class QTimeLine;
@ -30,7 +32,7 @@ class MoodbarProxyStyle : public QProxyStyle {
Q_OBJECT
public:
MoodbarProxyStyle(QSlider* slider);
MoodbarProxyStyle(Application* app, QSlider* slider);
// QProxyStyle
void drawComplexControl(ComplexControl control, const QStyleOptionComplex* option,
@ -73,6 +75,7 @@ private:
const QSize& size, const QPalette& palette);
private slots:
void ReloadSettings();
void FaderValueChanged(qreal value);
private:

View File

@ -33,7 +33,7 @@ ColorVector MoodbarRenderer::Colors(
case Style_Frozen: properties = StyleProperties(samples / 360 * 1, 140, 160, 50, 100); break;
case Style_Happy: properties = StyleProperties(samples / 360 * 2, 0, 359, 150, 250); break;
case Style_Normal: properties = StyleProperties(samples / 360 * 3, 0, 359, 100, 100); break;
case Style_SystemDefault:
case Style_SystemPalette:
default: {
const QColor highlight_color(palette.color(QPalette::Active, QPalette::Highlight));

View File

@ -28,12 +28,14 @@ typedef QVector<QColor> ColorVector;
class MoodbarRenderer {
public:
// These values are persisted. Remember to change appearancesettingspage.ui
// when changing them.
enum MoodbarStyle {
Style_Normal = 0,
Style_Angry,
Style_Frozen,
Style_Happy,
Style_Normal,
Style_SystemDefault
Style_SystemPalette
};
static const int kNumHues;

View File

@ -20,22 +20,33 @@
#include <QApplication>
#include <QColorDialog>
#include <QFileDialog>
#include <QPainter>
#include <QSettings>
#include "config.h"
#include "iconloader.h"
#include "mainwindow.h"
#include "settingsdialog.h"
#include "ui_appearancesettingspage.h"
#include "core/appearance.h"
#include "core/application.h"
#include "core/logging.h"
#include "playlist/playlistview.h"
#include "ui/albumcoverchoicecontroller.h"
#ifdef HAVE_MOODBAR
# include "moodbar/moodbarrenderer.h"
#endif
const int AppearanceSettingsPage::kMoodbarPreviewWidth = 150;
const int AppearanceSettingsPage::kMoodbarPreviewHeight = 18;
AppearanceSettingsPage::AppearanceSettingsPage(SettingsDialog* dialog)
: SettingsPage(dialog),
ui_(new Ui_AppearanceSettingsPage),
original_use_a_custom_color_set_(false),
playlist_view_background_image_type_(PlaylistView::Default)
playlist_view_background_image_type_(PlaylistView::Default),
initialised_moodbar_previews_(false)
{
ui_->setupUi(this);
setWindowIcon(IconLoader::Load("view-media-visualization"));
@ -75,14 +86,15 @@ void AppearanceSettingsPage::Load() {
current_background_color_ = original_background_color_;
InitColorSelectorsColors();
s.endGroup();
QSettings playlist_settings;
playlist_settings.beginGroup(Playlist::kSettingsGroup);
// Playlist settings
s.beginGroup(Playlist::kSettingsGroup);
playlist_view_background_image_type_ =
static_cast<PlaylistView::BackgroundImageType>(
playlist_settings.value(PlaylistView::kSettingBackgroundImageType).toInt());
s.value(PlaylistView::kSettingBackgroundImageType).toInt());
playlist_view_background_image_filename_ =
playlist_settings.value(PlaylistView::kSettingBackgroundImageFilename).toString();
s.value(PlaylistView::kSettingBackgroundImageFilename).toString();
ui_->use_system_color_set->setChecked(!original_use_a_custom_color_set_);
ui_->use_a_custom_color_set->setChecked(original_use_a_custom_color_set_);
@ -102,6 +114,16 @@ void AppearanceSettingsPage::Load() {
ui_->use_default_background->setChecked(true);
}
ui_->background_image_filename->setText(playlist_view_background_image_filename_);
s.endGroup();
// Moodbar settings
s.beginGroup("Moodbar");
ui_->moodbar_show->setChecked(s.value("show", true).toBool());
ui_->moodbar_style->setCurrentIndex(s.value("style", 0).toInt());
ui_->moodbar_save->setChecked(s.value("save_alongside_originals", false).toBool());
s.endGroup();
InitMoodbarPreviews();
}
void AppearanceSettingsPage::Save() {
@ -115,9 +137,10 @@ void AppearanceSettingsPage::Save() {
} else {
dialog()->appearance()->ResetToSystemDefaultTheme();
}
s.endGroup();
QSettings playlist_settings;
playlist_settings.beginGroup(Playlist::kSettingsGroup);
// Playlist settings
s.beginGroup(Playlist::kSettingsGroup);
playlist_view_background_image_filename_ = ui_->background_image_filename->text();
if (ui_->use_no_background->isChecked()) {
playlist_view_background_image_type_ = PlaylistView::None;
@ -127,11 +150,19 @@ void AppearanceSettingsPage::Save() {
playlist_view_background_image_type_ = PlaylistView::Default;
} else if (ui_->use_custom_background_image->isChecked()) {
playlist_view_background_image_type_ = PlaylistView::Custom;
playlist_settings.setValue(PlaylistView::kSettingBackgroundImageFilename,
s.setValue(PlaylistView::kSettingBackgroundImageFilename,
playlist_view_background_image_filename_);
}
playlist_settings.setValue(PlaylistView::kSettingBackgroundImageType,
s.setValue(PlaylistView::kSettingBackgroundImageType,
playlist_view_background_image_type_);
s.endGroup();
// Moodbar settings
s.beginGroup("Moodbar");
s.setValue("show", ui_->moodbar_show->isChecked());
s.setValue("style", ui_->moodbar_style->currentIndex());
s.setValue("save_alongside_originals", ui_->moodbar_save->isChecked());
s.endGroup();
}
void AppearanceSettingsPage::Cancel() {
@ -198,3 +229,37 @@ void AppearanceSettingsPage::SelectBackgroundImage() {
playlist_view_background_image_filename_ = selected_filename;
ui_->background_image_filename->setText(playlist_view_background_image_filename_);
}
void AppearanceSettingsPage::InitMoodbarPreviews() {
#ifdef HAVE_MOODBAR
if (initialised_moodbar_previews_)
return;
initialised_moodbar_previews_ = true;
const QSize preview_size(kMoodbarPreviewWidth, kMoodbarPreviewHeight);
ui_->moodbar_style->setIconSize(preview_size);
// Read the sample data
QFile file(":sample.mood");
if (!file.open(QIODevice::ReadOnly)) {
qLog(Warning) << "Unable to open moodbar sample file";
return;
}
QByteArray data(file.readAll());
// Render and set each preview
for (int i=0 ; i<ui_->moodbar_style->count() ; ++i) {
const ColorVector colors =
MoodbarRenderer::Colors(data, MoodbarRenderer::MoodbarStyle(i), palette());
QPixmap pixmap(preview_size);
QPainter p(&pixmap);
MoodbarRenderer::Render(colors, &p, pixmap.rect());
p.end();
ui_->moodbar_style->setItemData(i, pixmap, Qt::DecorationRole);
}
#else
ui_->moodbar_group->hide();
#endif
}

View File

@ -44,11 +44,16 @@ private slots:
void SelectBackgroundImage();
private:
static const int kMoodbarPreviewWidth;
static const int kMoodbarPreviewHeight;
// Set the widget's background to new_color
void UpdateColorSelectorColor(QWidget* color_selector, const QColor& new_color);
// Init (or refresh) the colorSelectors colors
void InitColorSelectorsColors();
void InitMoodbarPreviews();
Ui_AppearanceSettingsPage* ui_;
bool original_use_a_custom_color_set_;
QColor original_foreground_color_;
@ -57,6 +62,8 @@ private:
QColor current_background_color_;
PlaylistView::BackgroundImageType playlist_view_background_image_type_;
QString playlist_view_background_image_filename_;
bool initialised_moodbar_previews_;
};
#endif // APPEARANCESETTINGSPAGE_H

View File

@ -7,13 +7,13 @@
<x>0</x>
<y>0</y>
<width>596</width>
<height>397</height>
<height>566</height>
</rect>
</property>
<property name="windowTitle">
<string>Appearance</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout_2">
<layout class="QVBoxLayout" name="verticalLayout">
<item>
<widget class="QGroupBox" name="groupBox">
<property name="title">
@ -155,22 +155,81 @@
</item>
</layout>
</item>
<item>
<spacer name="verticalSpacer">
<property name="orientation">
<enum>Qt::Vertical</enum>
</layout>
</widget>
</item>
<item>
<widget class="QGroupBox" name="moodbar_group">
<property name="title">
<string>Moodbars</string>
</property>
<layout class="QFormLayout" name="formLayout">
<item row="0" column="0" colspan="2">
<widget class="QCheckBox" name="moodbar_show">
<property name="text">
<string>Show a moodbar in the track progress bar</string>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>40</height>
</size>
</widget>
</item>
<item row="1" column="0">
<widget class="QLabel" name="label">
<property name="text">
<string>Moodbar style:</string>
</property>
</spacer>
</widget>
</item>
<item row="1" column="1">
<widget class="QComboBox" name="moodbar_style">
<item>
<property name="text">
<string>Normal</string>
</property>
</item>
<item>
<property name="text">
<string>Angry</string>
</property>
</item>
<item>
<property name="text">
<string>Frozen</string>
</property>
</item>
<item>
<property name="text">
<string>Happy</string>
</property>
</item>
<item>
<property name="text">
<string>System colors</string>
</property>
</item>
</widget>
</item>
<item row="2" column="0" colspan="2">
<widget class="QCheckBox" name="moodbar_save">
<property name="text">
<string>Save .mood files in your music library</string>
</property>
</widget>
</item>
</layout>
</widget>
</item>
<item>
<spacer name="verticalSpacer">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>40</height>
</size>
</property>
</spacer>
</item>
</layout>
</widget>
<resources/>

View File

@ -621,6 +621,7 @@ MainWindow::MainWindow(Application* app,
ui_->status_bar_stack->setCurrentWidget(ui_->playlist_summary_page);
connect(ui_->multi_loading_indicator, SIGNAL(TaskCountChange(int)), SLOT(TaskCountChanged(int)));
ui_->track_slider->SetApplication(app);
#ifdef HAVE_MOODBAR
// Moodbar connections
connect(app_->moodbar_controller(), SIGNAL(CurrentMoodbarDataChanged(QByteArray)),

View File

@ -38,10 +38,6 @@ TrackSlider::TrackSlider(QWidget* parent)
{
ui_->setupUi(this);
#ifdef HAVE_MOODBAR
moodbar_style_ = new MoodbarProxyStyle(ui_->slider);
#endif
QFont font("Courier");
ui_->elapsed->setFont(font);
ui_->remaining->setFont(font);
@ -62,6 +58,12 @@ TrackSlider::~TrackSlider() {
delete ui_;
}
void TrackSlider::SetApplication(Application* app) {
#ifdef HAVE_MOODBAR
moodbar_style_ = new MoodbarProxyStyle(app, ui_->slider);
#endif
}
void TrackSlider::UpdateLabelWidth() {
// We set the label's minimum size so it won't resize itself when the user
// is dragging the slider.

View File

@ -22,6 +22,7 @@
class QLabel;
class Application;
class MoodbarProxyStyle;
class Ui_TrackSlider;
@ -32,6 +33,8 @@ class TrackSlider : public QWidget {
TrackSlider(QWidget* parent = 0);
~TrackSlider();
void SetApplication(Application* app);
// QWidget
QSize sizeHint() const;