2018-02-27 18:06:05 +01:00
|
|
|
/*
|
|
|
|
* Strawberry Music Player
|
|
|
|
* This file was part of Clementine.
|
|
|
|
* Copyright 2010, David Sansome <me@davidsansome.com>
|
|
|
|
*
|
|
|
|
* Strawberry 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.
|
|
|
|
*
|
|
|
|
* Strawberry 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 Strawberry. If not, see <http://www.gnu.org/licenses/>.
|
2018-08-09 18:10:03 +02:00
|
|
|
*
|
2018-02-27 18:06:05 +01:00
|
|
|
*/
|
|
|
|
|
|
|
|
#ifndef PLAYLISTVIEW_H
|
|
|
|
#define PLAYLISTVIEW_H
|
|
|
|
|
|
|
|
#include "config.h"
|
|
|
|
|
|
|
|
#include <memory>
|
2018-05-01 00:41:33 +02:00
|
|
|
#include <stdbool.h>
|
|
|
|
|
|
|
|
#include <QtGlobal>
|
|
|
|
#include <QObject>
|
|
|
|
#include <QWidget>
|
|
|
|
#include <QList>
|
|
|
|
#include <QString>
|
|
|
|
#include <QImage>
|
|
|
|
#include <QPixmap>
|
|
|
|
#include <QRect>
|
|
|
|
#include <QRegion>
|
|
|
|
#include <QStyle>
|
|
|
|
#include <QStyleOption>
|
2018-02-27 18:06:05 +01:00
|
|
|
#include <QProxyStyle>
|
|
|
|
#include <QTreeView>
|
2018-05-01 00:41:33 +02:00
|
|
|
#include <QPoint>
|
|
|
|
#include <QTimer>
|
|
|
|
#include <QBasicTimer>
|
|
|
|
#include <QTimeLine>
|
|
|
|
#include <QCommonStyle>
|
|
|
|
#include <QPainter>
|
|
|
|
#include <QAbstractItemDelegate>
|
|
|
|
#include <QAbstractItemModel>
|
|
|
|
#include <QStyleOptionViewItem>
|
|
|
|
#include <QtEvents>
|
2018-02-27 18:06:05 +01:00
|
|
|
|
2019-07-30 21:32:56 +02:00
|
|
|
#include "core/song.h"
|
2019-03-25 22:00:40 +01:00
|
|
|
#include "settings/appearancesettingspage.h"
|
2018-02-27 18:06:05 +01:00
|
|
|
#include "playlist.h"
|
|
|
|
|
2018-05-01 00:41:33 +02:00
|
|
|
class QEvent;
|
|
|
|
class QShowEvent;
|
|
|
|
class QContextMenuEvent;
|
|
|
|
class QDragEnterEvent;
|
|
|
|
class QDragLeaveEvent;
|
|
|
|
class QDragMoveEvent;
|
|
|
|
class QDropEvent;
|
|
|
|
class QFocusEvent;
|
|
|
|
class QHideEvent;
|
|
|
|
class QKeyEvent;
|
|
|
|
class QMouseEvent;
|
|
|
|
class QPaintEvent;
|
|
|
|
class QTimerEvent;
|
2018-02-27 18:06:05 +01:00
|
|
|
|
|
|
|
class Application;
|
|
|
|
class CollectionBackend;
|
|
|
|
class PlaylistHeader;
|
|
|
|
|
|
|
|
// This proxy style works around a bug/feature introduced in Qt 4.7's QGtkStyle
|
2018-05-01 00:41:33 +02:00
|
|
|
// that uses Gtk to paint row backgrounds, ignoring any custom brush or palette the caller set in the QStyleOption.
|
|
|
|
// That breaks our currently playing track animation, which relies on the background painted by Qt to be transparent.
|
2018-02-27 18:06:05 +01:00
|
|
|
// This proxy style uses QCommonStyle to paint the affected elements.
|
2019-03-09 17:43:20 +01:00
|
|
|
// This class is used by internet search view as well.
|
2018-02-27 18:06:05 +01:00
|
|
|
class PlaylistProxyStyle : public QProxyStyle {
|
|
|
|
public:
|
|
|
|
PlaylistProxyStyle(QStyle *base);
|
2019-07-24 19:16:51 +02:00
|
|
|
|
2018-02-27 18:06:05 +01:00
|
|
|
void drawControl(ControlElement element, const QStyleOption *option, QPainter *painter, const QWidget *widget) const;
|
|
|
|
void drawPrimitive(PrimitiveElement element, const QStyleOption *option, QPainter *painter, const QWidget *widget) const;
|
|
|
|
|
|
|
|
private:
|
|
|
|
std::unique_ptr<QCommonStyle> common_style_;
|
|
|
|
};
|
|
|
|
|
|
|
|
class PlaylistView : public QTreeView {
|
|
|
|
Q_OBJECT
|
|
|
|
public:
|
|
|
|
|
|
|
|
PlaylistView(QWidget *parent = nullptr);
|
2018-10-20 22:16:22 +02:00
|
|
|
~PlaylistView();
|
2018-02-27 18:06:05 +01:00
|
|
|
|
|
|
|
static ColumnAlignmentMap DefaultColumnAlignment();
|
|
|
|
|
|
|
|
void SetApplication(Application *app);
|
|
|
|
void SetItemDelegates(CollectionBackend *backend);
|
|
|
|
void SetPlaylist(Playlist *playlist);
|
|
|
|
void RemoveSelected(bool deleting_from_disk);
|
|
|
|
|
|
|
|
void SetReadOnlySettings(bool read_only) { read_only_settings_ = read_only; }
|
|
|
|
|
|
|
|
Playlist *playlist() const { return playlist_; }
|
2019-03-25 22:00:40 +01:00
|
|
|
AppearanceSettingsPage::BackgroundImageType background_image_type() const { return background_image_type_; }
|
2018-02-27 18:06:05 +01:00
|
|
|
Qt::Alignment column_alignment(int section) const;
|
|
|
|
|
|
|
|
// QTreeView
|
|
|
|
void drawTree(QPainter *painter, const QRegion ®ion) const;
|
|
|
|
void drawRow(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const;
|
|
|
|
void setModel(QAbstractItemModel *model);
|
|
|
|
|
2018-11-19 00:18:48 +01:00
|
|
|
void ResetColumns();
|
|
|
|
|
2018-02-27 18:06:05 +01:00
|
|
|
public slots:
|
|
|
|
void ReloadSettings();
|
2019-04-28 14:14:19 +02:00
|
|
|
void SaveGeometry();
|
2019-04-27 22:32:39 +02:00
|
|
|
void SaveSettings();
|
2018-02-27 18:06:05 +01:00
|
|
|
void SetColumnAlignment(int section, Qt::Alignment alignment);
|
2019-07-30 21:32:56 +02:00
|
|
|
void JumpToCurrentlyPlayingTrack();
|
2018-02-27 18:06:05 +01:00
|
|
|
|
|
|
|
signals:
|
|
|
|
void PlayItem(const QModelIndex &index);
|
|
|
|
void PlayPause();
|
|
|
|
void RightClicked(const QPoint &global_pos, const QModelIndex &index);
|
|
|
|
void SeekForward();
|
|
|
|
void SeekBackward();
|
|
|
|
void FocusOnFilterSignal(QKeyEvent *event);
|
|
|
|
void BackgroundPropertyChanged();
|
|
|
|
void ColumnAlignmentChanged(const ColumnAlignmentMap &alignment);
|
|
|
|
|
|
|
|
protected:
|
|
|
|
// QWidget
|
|
|
|
void keyPressEvent(QKeyEvent *event);
|
|
|
|
void contextMenuEvent(QContextMenuEvent *e);
|
|
|
|
void hideEvent(QHideEvent *event);
|
|
|
|
void showEvent(QShowEvent *event);
|
|
|
|
void timerEvent(QTimerEvent *event);
|
|
|
|
void mouseMoveEvent(QMouseEvent *event);
|
|
|
|
void mousePressEvent(QMouseEvent *event);
|
|
|
|
void leaveEvent(QEvent*);
|
|
|
|
void paintEvent(QPaintEvent *event);
|
|
|
|
void dragMoveEvent(QDragMoveEvent *event);
|
|
|
|
void dragEnterEvent(QDragEnterEvent *event);
|
|
|
|
void dragLeaveEvent(QDragLeaveEvent *event);
|
|
|
|
void dropEvent(QDropEvent *event);
|
|
|
|
bool eventFilter(QObject *object, QEvent *event);
|
|
|
|
void focusInEvent(QFocusEvent *event);
|
|
|
|
|
|
|
|
// QAbstractScrollArea
|
|
|
|
void scrollContentsBy(int dx, int dy);
|
|
|
|
|
|
|
|
// QAbstractItemView
|
|
|
|
void rowsInserted(const QModelIndex &parent, int start, int end);
|
2019-07-30 21:32:56 +02:00
|
|
|
void closeEditor(QWidget *editor, QAbstractItemDelegate::EndEditHint hint);
|
2018-02-27 18:06:05 +01:00
|
|
|
|
|
|
|
private slots:
|
|
|
|
void InhibitAutoscrollTimeout();
|
|
|
|
void MaybeAutoscroll();
|
|
|
|
void InvalidateCachedCurrentPixmap();
|
|
|
|
void PlaylistDestroyed();
|
|
|
|
void StretchChanged(bool stretch);
|
|
|
|
void FadePreviousBackgroundImage(qreal value);
|
2019-07-30 21:32:56 +02:00
|
|
|
void StopGlowing();
|
|
|
|
void StartGlowing();
|
|
|
|
void JumpToLastPlayedTrack();
|
|
|
|
void CopyCurrentSongToClipboard() const;
|
|
|
|
void Playing();
|
|
|
|
void Stopped();
|
|
|
|
void SongChanged(const Song &song);
|
|
|
|
void AlbumCoverLoaded(const Song &new_song, const QUrl &cover_url, const QImage &song_art);
|
2018-02-27 18:06:05 +01:00
|
|
|
|
|
|
|
private:
|
2019-07-30 21:32:56 +02:00
|
|
|
void LoadGeometry();
|
2018-02-27 18:06:05 +01:00
|
|
|
void ReloadBarPixmaps();
|
|
|
|
QList<QPixmap> LoadBarPixmap(const QString &filename);
|
2018-09-18 22:17:28 +02:00
|
|
|
void UpdateCachedCurrentRowPixmap(QStyleOptionViewItem option, const QModelIndex &index);
|
2018-02-27 18:06:05 +01:00
|
|
|
|
2019-03-25 22:00:40 +01:00
|
|
|
void set_background_image_type(AppearanceSettingsPage::BackgroundImageType bg) {
|
2018-02-27 18:06:05 +01:00
|
|
|
background_image_type_ = bg;
|
|
|
|
emit BackgroundPropertyChanged();
|
|
|
|
}
|
2018-05-01 00:41:33 +02:00
|
|
|
// Save image as the background_image_ after applying some modifications (opacity, ...).
|
2018-02-27 18:06:05 +01:00
|
|
|
// Should be used instead of modifying background_image_ directly
|
|
|
|
void set_background_image(const QImage &image);
|
|
|
|
|
2019-07-30 21:32:56 +02:00
|
|
|
void GlowIntensityChanged();
|
|
|
|
|
2018-02-27 18:06:05 +01:00
|
|
|
private:
|
|
|
|
static const int kGlowIntensitySteps;
|
|
|
|
static const int kAutoscrollGraceTimeout;
|
|
|
|
static const int kDropIndicatorWidth;
|
|
|
|
static const int kDropIndicatorGradientWidth;
|
|
|
|
|
|
|
|
QList<int> GetEditableColumns();
|
|
|
|
QModelIndex NextEditableIndex(const QModelIndex ¤t);
|
|
|
|
QModelIndex PrevEditableIndex(const QModelIndex ¤t);
|
|
|
|
|
|
|
|
Application *app_;
|
|
|
|
PlaylistProxyStyle *style_;
|
|
|
|
Playlist *playlist_;
|
|
|
|
PlaylistHeader *header_;
|
2019-03-25 22:00:40 +01:00
|
|
|
|
|
|
|
AppearanceSettingsPage::BackgroundImageType background_image_type_;
|
|
|
|
QString background_image_filename_;
|
|
|
|
AppearanceSettingsPage::BackgroundImagePosition background_image_position_;
|
|
|
|
int background_image_maxsize_;
|
|
|
|
bool background_image_stretch_;
|
2019-06-30 19:37:05 +02:00
|
|
|
bool background_image_do_not_cut_;
|
2019-03-25 22:00:40 +01:00
|
|
|
bool background_image_keep_aspect_ratio_;
|
|
|
|
int blur_radius_;
|
|
|
|
int opacity_level_;
|
|
|
|
|
2018-11-18 23:21:12 +01:00
|
|
|
bool initialized_;
|
2019-03-25 22:00:40 +01:00
|
|
|
bool background_initialized_;
|
2018-02-27 18:06:05 +01:00
|
|
|
bool setting_initial_header_layout_;
|
|
|
|
bool read_only_settings_;
|
2019-04-28 14:14:19 +02:00
|
|
|
bool state_loaded_;
|
2018-02-27 18:06:05 +01:00
|
|
|
|
|
|
|
QImage background_image_;
|
|
|
|
QImage current_song_cover_art_;
|
|
|
|
QPixmap cached_scaled_background_image_;
|
|
|
|
|
|
|
|
// For fading when image change
|
|
|
|
QPixmap previous_background_image_;
|
|
|
|
qreal previous_background_image_opacity_;
|
|
|
|
QTimeLine *fade_animation_;
|
|
|
|
|
|
|
|
// To know if we should redraw the background or not
|
2019-03-25 22:00:40 +01:00
|
|
|
bool force_background_redraw_;
|
2018-02-27 18:06:05 +01:00
|
|
|
int last_height_;
|
|
|
|
int last_width_;
|
2019-03-25 22:00:40 +01:00
|
|
|
int current_background_image_x_;
|
|
|
|
int current_background_image_y_;
|
|
|
|
int previous_background_image_x_;
|
|
|
|
int previous_background_image_y_;
|
2018-02-27 18:06:05 +01:00
|
|
|
|
|
|
|
bool glow_enabled_;
|
|
|
|
bool currently_glowing_;
|
|
|
|
QBasicTimer glow_timer_;
|
|
|
|
int glow_intensity_step_;
|
|
|
|
QModelIndex last_current_item_;
|
|
|
|
QRect last_glow_rect_;
|
|
|
|
|
|
|
|
QTimer *inhibit_autoscroll_timer_;
|
|
|
|
bool inhibit_autoscroll_;
|
|
|
|
bool currently_autoscrolling_;
|
|
|
|
|
|
|
|
int row_height_; // Used to invalidate the currenttrack_bar pixmaps
|
|
|
|
QList<QPixmap> currenttrack_bar_left_;
|
|
|
|
QList<QPixmap> currenttrack_bar_mid_;
|
|
|
|
QList<QPixmap> currenttrack_bar_right_;
|
|
|
|
QPixmap currenttrack_play_;
|
|
|
|
QPixmap currenttrack_pause_;
|
|
|
|
|
|
|
|
QRegion current_paint_region_;
|
|
|
|
QPixmap cached_current_row_;
|
|
|
|
QRect cached_current_row_rect_;
|
|
|
|
int cached_current_row_row_;
|
|
|
|
|
|
|
|
QPixmap cached_tree_;
|
|
|
|
int drop_indicator_row_;
|
|
|
|
bool drag_over_;
|
|
|
|
|
|
|
|
ColumnAlignmentMap column_alignment_;
|
2019-04-28 14:14:19 +02:00
|
|
|
|
|
|
|
QByteArray state_;
|
|
|
|
|
2019-07-30 21:32:56 +02:00
|
|
|
Song song_playing_;
|
|
|
|
|
2018-02-27 18:06:05 +01:00
|
|
|
};
|
|
|
|
|
|
|
|
#endif // PLAYLISTVIEW_H
|