diff --git a/data/mainwindow.css b/data/mainwindow.css index 8b40c8f35..ce65827cc 100644 --- a/data/mainwindow.css +++ b/data/mainwindow.css @@ -12,7 +12,7 @@ darwin QMenu { } -#playlist[background_enabled = "true"] { +#playlist[default_background_enabled = "true"] { background-image: url(:logo.png); background-attachment: fixed; background-position: bottom right; diff --git a/src/musicbrainz/chromaprinter.h b/src/musicbrainz/chromaprinter.h index 1362579b1..a9c32265f 100644 --- a/src/musicbrainz/chromaprinter.h +++ b/src/musicbrainz/chromaprinter.h @@ -1,5 +1,5 @@ /* This file is part of Clementine. - Copyright 2010, David Sansome + Copyright 2012, David Sansome Clementine is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff --git a/src/playlist/playlistview.cpp b/src/playlist/playlistview.cpp index 6b087ec8d..181cb4ef0 100644 --- a/src/playlist/playlistview.cpp +++ b/src/playlist/playlistview.cpp @@ -41,6 +41,12 @@ const int PlaylistView::kGlowIntensitySteps = 24; const int PlaylistView::kAutoscrollGraceTimeout = 60; // seconds const int PlaylistView::kDropIndicatorWidth = 2; const int PlaylistView::kDropIndicatorGradientWidth = 5; +// Opacity value used by all background images but the default clementine one +// (because it is already opaque and load through the mainwindow.css file) +const qreal PlaylistView::kBackgroundOpacity = 0.3; + +const char* PlaylistView::kSettingBackgroundImageType = "playlistview_background_type"; +const char* PlaylistView::kSettingBackgroundImageFilename = "playlistview_background_image_file"; PlaylistProxyStyle::PlaylistProxyStyle(QStyle* base) @@ -91,6 +97,9 @@ PlaylistView::PlaylistView(QWidget *parent) upgrading_from_qheaderview_(false), read_only_settings_(true), upgrading_from_version_(-1), + background_image_type_(Default), + last_height_(-1), + last_width_(-1), glow_enabled_(true), currently_glowing_(false), glow_intensity_step_(0), @@ -775,13 +784,33 @@ void PlaylistView::JumpToLastPlayedTrack() { } void PlaylistView::paintEvent(QPaintEvent* event) { - // Reimplemented to draw the drop indicator + // Reimplemented to draw the background image. + // Reimplemented also to draw the drop indicator // When the user is dragging some stuff over the playlist paintEvent gets // called for the entire viewport every time the user moves the mouse. // The drawTree is kinda expensive, so we cache the result and draw from the // cache while the user is dragging. The cached pixmap gets invalidated in // dragLeaveEvent, dropEvent and scrollContentsBy. + // Draw background + if (background_image_type_ == Custom) { + if (!background_image_.isNull()) { + QPainter background_painter(viewport()); + if (height() != last_height_ || width() != last_width_) { + cached_scaled_background_image_ = background_image_.scaled( + width(), height(), + Qt::KeepAspectRatioByExpanding, + Qt::SmoothTransformation); + last_height_ = height(); + last_width_ = width(); + } + background_painter.setOpacity(kBackgroundOpacity); + background_painter.drawPixmap((width() - cached_scaled_background_image_.width()) / 2, + (height() - cached_scaled_background_image_.height()) / 2, + cached_scaled_background_image_); + } + } + QPainter p(viewport()); if (drop_indicator_row_ != -1) { @@ -882,7 +911,20 @@ void PlaylistView::ReloadSettings() { QSettings s; s.beginGroup(Playlist::kSettingsGroup); glow_enabled_ = s.value("glow_effect", true).toBool(); - background_enabled_ = s.value("bg_enabled", true).toBool(); + + QVariant playlistview_background_type = s.value(kSettingBackgroundImageType); + // bg_enabled should also be checked for backward compatibility (in releases + // <= 1.0, there was just a boolean to activate/deactivate the background) + QVariant bg_enabled = s.value("bg_enabled"); + if (playlistview_background_type.isValid()) { + background_image_type_ = static_cast(playlistview_background_type.toInt()); + } else if (bg_enabled.isValid()) { + if (bg_enabled.toBool()) { + background_image_type_ = Default; + } else { + background_image_type_ = None; + } + } if (setting_initial_header_layout_ || upgrading_from_qheaderview_) { header_->SetStretchEnabled(s.value("stretch", true).toBool()); @@ -894,7 +936,8 @@ void PlaylistView::ReloadSettings() { if (!glow_enabled_) StopGlowing(); - setProperty("background_enabled", background_enabled_); + setProperty("default_background_enabled", background_image_type_ == Default); + emit BackgroundPropertyChanged(); if (setting_initial_header_layout_) { header_->SetColumnWidth(Playlist::Column_Length, 0.06); @@ -914,6 +957,11 @@ void PlaylistView::ReloadSettings() { column_alignment_ = DefaultColumnAlignment(); } + QString background_image_filename = s.value(kSettingBackgroundImageFilename).toString(); + if (!background_image_filename.isEmpty()) { + background_image_ = QPixmap(background_image_filename); + } + emit ColumnAlignmentChanged(column_alignment_); } @@ -925,7 +973,7 @@ void PlaylistView::SaveSettings() { s.beginGroup(Playlist::kSettingsGroup); s.setValue("glow_effect", glow_enabled_); s.setValue("column_alignments", QVariant::fromValue(column_alignment_)); - s.setValue("bg_enabled", background_enabled_); + s.setValue(kSettingBackgroundImageType, background_image_type_); } void PlaylistView::StretchChanged(bool stretch) { diff --git a/src/playlist/playlistview.h b/src/playlist/playlistview.h index 45ff59baa..f0a3022ae 100644 --- a/src/playlist/playlistview.h +++ b/src/playlist/playlistview.h @@ -57,14 +57,20 @@ private: class PlaylistView : public QTreeView { Q_OBJECT - Q_PROPERTY(bool background_enabled - READ background_enabled - WRITE set_background_enabled - NOTIFY BackgroundPropertyChanged) public: + + enum BackgroundImageType { + Default, + None, + Custom, + }; + PlaylistView(QWidget* parent = 0); static const int kStateVersion; + // Constants for settings: are persistent, values should not be changed + static const char* kSettingBackgroundImageType; + static const char* kSettingBackgroundImageFilename; static ColumnAlignmentMap DefaultColumnAlignment(); @@ -76,7 +82,7 @@ class PlaylistView : public QTreeView { void SetPlayer(Player* player) { player_ = player; } Playlist* playlist() const { return playlist_; } - bool background_enabled() const { return background_enabled_; } + BackgroundImageType background_image_type() const { return background_image_type_; } Qt::Alignment column_alignment(int section) const; // QTreeView @@ -150,13 +156,14 @@ class PlaylistView : public QTreeView { void UpdateCachedCurrentRowPixmap(QStyleOptionViewItemV4 option, const QModelIndex& index); - inline void set_background_enabled(bool bg) { background_enabled_ = bg; emit BackgroundPropertyChanged(); } + void set_background_image_type(BackgroundImageType bg) { background_image_type_ = bg; emit BackgroundPropertyChanged(); } private: static const int kGlowIntensitySteps; static const int kAutoscrollGraceTimeout; static const int kDropIndicatorWidth; static const int kDropIndicatorGradientWidth; + static const qreal kBackgroundOpacity; QList GetEditableColumns(); QModelIndex NextEditableIndex(const QModelIndex& current); @@ -172,7 +179,11 @@ class PlaylistView : public QTreeView { bool read_only_settings_; int upgrading_from_version_; - bool background_enabled_; + BackgroundImageType background_image_type_; + QPixmap background_image_; + QPixmap cached_scaled_background_image_; + int last_height_; + int last_width_; bool glow_enabled_; bool currently_glowing_; diff --git a/src/ui/albumcoverchoicecontroller.h b/src/ui/albumcoverchoicecontroller.h index 74a6972ab..a320da6fd 100644 --- a/src/ui/albumcoverchoicecontroller.h +++ b/src/ui/albumcoverchoicecontroller.h @@ -36,6 +36,10 @@ class AlbumCoverChoiceController : public QWidget { Q_OBJECT public: + static const char* kLoadImageFileFilter; + static const char* kSaveImageFileFilter; + static const char* kAllFilesFilter; + AlbumCoverChoiceController(QWidget* parent = 0); ~AlbumCoverChoiceController(); @@ -108,10 +112,6 @@ private: QString GetInitialPathForFileDialog(const Song& song, const QString& filename); - static const char* kLoadImageFileFilter; - static const char* kSaveImageFileFilter; - static const char* kAllFilesFilter; - static bool IsKnownImageExtension(const QString& suffix); static QSet* sImageExtensions; diff --git a/src/ui/appearancesettingspage.cpp b/src/ui/appearancesettingspage.cpp index cd6f1e065..e73b22269 100644 --- a/src/ui/appearancesettingspage.cpp +++ b/src/ui/appearancesettingspage.cpp @@ -19,18 +19,23 @@ #include #include +#include #include #include "iconloader.h" +#include "mainwindow.h" #include "settingsdialog.h" #include "ui_appearancesettingspage.h" #include "core/appearance.h" #include "core/logging.h" +#include "playlist/playlistview.h" +#include "ui/albumcoverchoicecontroller.h" AppearanceSettingsPage::AppearanceSettingsPage(SettingsDialog* dialog) : SettingsPage(dialog), ui_(new Ui_AppearanceSettingsPage), - original_use_a_custom_color_set_(false) + original_use_a_custom_color_set_(false), + playlist_view_background_image_type_(PlaylistView::Default) { ui_->setupUi(this); setWindowIcon(IconLoader::Load("view-media-visualization")); @@ -43,6 +48,25 @@ AppearanceSettingsPage::AppearanceSettingsPage(SettingsDialog* dialog) connect(ui_->select_foreground_color, SIGNAL(pressed()), SLOT(SelectForegroundColor())); connect(ui_->select_background_color, SIGNAL(pressed()), SLOT(SelectBackgroundColor())); connect(ui_->use_a_custom_color_set, SIGNAL(toggled(bool)), SLOT(UseCustomColorSetOptionChanged(bool))); + + connect(ui_->select_background_image_filename_button, SIGNAL(pressed()), SLOT(SelectBackgroundImage())); + connect(ui_->use_custom_background_image, SIGNAL(toggled(bool)), + ui_->background_image_filename, SLOT(setEnabled(bool))); + connect(ui_->use_custom_background_image, SIGNAL(toggled(bool)), + ui_->select_background_image_filename_button, SLOT(setEnabled(bool))); + + switch (playlist_view_background_image_type_) { + case PlaylistView::None: + ui_->use_no_background->setChecked(true); + break; + case PlaylistView::Custom: + ui_->use_custom_background_image->setChecked(true); + break; + case PlaylistView::Default: + default: + ui_->use_default_background->setChecked(true); + } + ui_->background_image_filename->setText(playlist_view_background_image_filename_); } AppearanceSettingsPage::~AppearanceSettingsPage() { @@ -67,6 +91,14 @@ void AppearanceSettingsPage::Load() { current_background_color_ = original_background_color_; InitColorSelectorsColors(); + + QSettings playlist_settings; + playlist_settings.beginGroup(Playlist::kSettingsGroup); + playlist_view_background_image_type_ = + static_cast( + playlist_settings.value(PlaylistView::kSettingBackgroundImageType).toInt()); + playlist_view_background_image_filename_ = + playlist_settings.value(PlaylistView::kSettingBackgroundImageFilename).toString(); } void AppearanceSettingsPage::Save() { @@ -80,6 +112,21 @@ void AppearanceSettingsPage::Save() { } else { dialog()->appearance()->ResetToSystemDefaultTheme(); } + + QSettings playlist_settings; + playlist_settings.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; + } else if (ui_->use_default_background->isChecked()) { + 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, + playlist_view_background_image_filename_); + } + playlist_settings.setValue(PlaylistView::kSettingBackgroundImageType, + playlist_view_background_image_type_); } void AppearanceSettingsPage::Cancel() { @@ -134,3 +181,15 @@ void AppearanceSettingsPage::UpdateColorSelectorColor(QWidget* color_selector, c .arg(color.blue()); color_selector->setStyleSheet(css); } + +void AppearanceSettingsPage::SelectBackgroundImage() { + QString selected_filename = + QFileDialog::getOpenFileName(this, tr("Select background image"), + playlist_view_background_image_filename_, + tr(AlbumCoverChoiceController::kLoadImageFileFilter) + ";;" + + tr(AlbumCoverChoiceController::kAllFilesFilter)); + if (selected_filename.isEmpty()) + return; + playlist_view_background_image_filename_ = selected_filename; + ui_->background_image_filename->setText(playlist_view_background_image_filename_); +} diff --git a/src/ui/appearancesettingspage.h b/src/ui/appearancesettingspage.h index 37f419328..4be3caa0d 100644 --- a/src/ui/appearancesettingspage.h +++ b/src/ui/appearancesettingspage.h @@ -20,6 +20,8 @@ #include "settingspage.h" +#include "playlist/playlistview.h" + class QWidget; class Ui_AppearanceSettingsPage; @@ -39,6 +41,7 @@ private slots: void SelectForegroundColor(); void SelectBackgroundColor(); void UseCustomColorSetOptionChanged(bool); + void SelectBackgroundImage(); private: // Set the widget's background to new_color @@ -52,6 +55,8 @@ private: QColor original_background_color_; QColor current_foreground_color_; QColor current_background_color_; + PlaylistView::BackgroundImageType playlist_view_background_image_type_; + QString playlist_view_background_image_filename_; }; #endif // APPEARANCESETTINGSPAGE_H diff --git a/src/ui/appearancesettingspage.ui b/src/ui/appearancesettingspage.ui index ff27f2265..c979acdd8 100644 --- a/src/ui/appearancesettingspage.ui +++ b/src/ui/appearancesettingspage.ui @@ -7,7 +7,7 @@ 0 0 596 - 199 + 397 @@ -82,6 +82,65 @@ + + + + + + + Background image + + + + + + + + Default background image + + + + + + + + + + + No background image + + + + + + + + + + + Custom image: + + + + + + + false + + + + + + + false + + + Browse... + + + + + diff --git a/src/ui/behavioursettingspage.cpp b/src/ui/behavioursettingspage.cpp index 084fd1a80..f656af1e3 100644 --- a/src/ui/behavioursettingspage.cpp +++ b/src/ui/behavioursettingspage.cpp @@ -111,7 +111,6 @@ void BehaviourSettingsPage::Load() { s.beginGroup(Playlist::kSettingsGroup); ui_->b_grey_out_deleted_->setChecked(s.value("greyoutdeleted", false).toBool()); - ui_->b_enable_background_img_->setChecked(s.value("bg_enabled", true).toBool()); s.endGroup(); } @@ -146,7 +145,6 @@ void BehaviourSettingsPage::Save() { s.beginGroup(Playlist::kSettingsGroup); s.setValue("greyoutdeleted", ui_->b_grey_out_deleted_->isChecked()); - s.setValue("bg_enabled", ui_->b_enable_background_img_->isChecked()); s.endGroup(); } diff --git a/src/ui/behavioursettingspage.ui b/src/ui/behavioursettingspage.ui index d17c21b20..8ad56eb1c 100644 --- a/src/ui/behavioursettingspage.ui +++ b/src/ui/behavioursettingspage.ui @@ -6,7 +6,7 @@ 0 0 - 497 + 516 516 @@ -31,16 +31,6 @@ - - - - Enable playlist background image - - - true - - -