strawberry-audio-player-win.../src/playlist/playlistview.h

307 lines
9.5 KiB
C
Raw Normal View History

2018-02-27 18:06:05 +01:00
/*
* Strawberry Music Player
* This file was part of Clementine.
* Copyright 2010, David Sansome <me@davidsansome.com>
2021-03-20 21:14:47 +01:00
* Copyright 2018-2021, Jonas Kvinge <jonas@jkvinge.net>
2018-02-27 18:06:05 +01:00
*
* 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>
#include <QtGlobal>
#include <QObject>
2020-02-08 15:03:11 +01:00
#include <QAbstractItemDelegate>
#include <QAbstractItemModel>
#include <QStyleOptionViewItem>
#include <QAbstractItemView>
#include <QTreeView>
#include <QList>
2020-02-08 15:03:11 +01:00
#include <QByteArray>
#include <QString>
#include <QImage>
#include <QPixmap>
#include <QColor>
#include <QRect>
#include <QRegion>
#include <QStyleOption>
2018-02-27 18:06:05 +01:00
#include <QProxyStyle>
#include <QPoint>
#include <QBasicTimer>
#include <QCommonStyle>
2018-02-27 18:06:05 +01:00
#include "core/song.h"
#include "covermanager/albumcoverloaderresult.h"
2019-03-25 22:00:40 +01:00
#include "settings/appearancesettingspage.h"
2018-02-27 18:06:05 +01:00
#include "playlist.h"
2020-02-08 15:03:11 +01:00
class QWidget;
class QTimer;
class QTimeLine;
class QPainter;
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;
class DynamicPlaylistControls;
class RatingItemDelegate;
2018-02-27 18:06:05 +01:00
// This proxy style works around a bug/feature introduced in Qt 4.7's QGtkStyle
// 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 {
2021-06-20 19:04:08 +02:00
Q_OBJECT
public:
2021-06-20 19:04:08 +02:00
explicit PlaylistProxyStyle(QObject *parent = nullptr);
2020-06-15 21:55:05 +02:00
void drawControl(ControlElement element, const QStyleOption *option, QPainter *painter, const QWidget *widget) const override;
void drawPrimitive(PrimitiveElement element, const QStyleOption *option, QPainter *painter, const QWidget *widget) const override;
2018-02-27 18:06:05 +01:00
private:
std::unique_ptr<QCommonStyle> common_style_;
};
class PlaylistView : public QTreeView {
Q_OBJECT
2020-06-15 21:55:05 +02:00
public:
2020-04-07 16:49:15 +02:00
explicit PlaylistView(QWidget *parent = nullptr);
2020-06-15 21:55:05 +02:00
~PlaylistView() override;
2018-02-27 18:06:05 +01:00
static ColumnAlignmentMap DefaultColumnAlignment();
void Init(Application *app);
void SetItemDelegates();
2018-02-27 18:06:05 +01:00
void SetPlaylist(Playlist *playlist);
void RemoveSelected();
2018-02-27 18:06:05 +01:00
2021-06-20 23:53:28 +02:00
void SetReadOnlySettings(const bool read_only) { read_only_settings_ = read_only; }
2018-02-27 18:06:05 +01:00
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;
void ResetHeaderState();
2018-11-19 00:18:48 +01:00
2020-06-15 21:55:05 +02:00
// QTreeView
void setModel(QAbstractItemModel *model) override;
2018-02-27 18:06:05 +01:00
public slots:
void ReloadSettings();
void SaveSettings();
2020-08-23 19:17:50 +02:00
void SetColumnAlignment(const int section, const Qt::Alignment alignment);
void JumpToCurrentlyPlayingTrack();
2021-06-20 19:04:08 +02:00
void edit(const QModelIndex &idx) { QAbstractItemView::edit(idx); }
2018-02-27 18:06:05 +01:00
signals:
void PlayItem(QModelIndex idx, Playlist::AutoScroll autoscroll);
void PlayPause(const quint64 offset_nanosec = 0, Playlist::AutoScroll autoscroll = Playlist::AutoScroll_Never);
2020-08-23 19:17:50 +02:00
void RightClicked(QPoint global_pos, QModelIndex idx);
2018-02-27 18:06:05 +01:00
void SeekForward();
void SeekBackward();
void FocusOnFilterSignal(QKeyEvent *event);
void BackgroundPropertyChanged();
2020-08-23 19:17:50 +02:00
void ColumnAlignmentChanged(ColumnAlignmentMap alignment);
2018-02-27 18:06:05 +01:00
protected:
// QWidget
2020-06-15 21:55:05 +02:00
void keyPressEvent(QKeyEvent *event) override;
void contextMenuEvent(QContextMenuEvent *e) override;
void hideEvent(QHideEvent *event) override;
void showEvent(QShowEvent *event) override;
void timerEvent(QTimerEvent *event) override;
void mouseMoveEvent(QMouseEvent *event) override;
void mousePressEvent(QMouseEvent *event) override;
void leaveEvent(QEvent*) override;
void paintEvent(QPaintEvent *event) override;
void dragMoveEvent(QDragMoveEvent *event) override;
void dragEnterEvent(QDragEnterEvent *event) override;
void dragLeaveEvent(QDragLeaveEvent *event) override;
void dropEvent(QDropEvent *event) override;
bool eventFilter(QObject *object, QEvent *event) override;
void focusInEvent(QFocusEvent *event) override;
void resizeEvent(QResizeEvent *event) override;
2020-06-15 21:55:05 +02:00
// QTreeView
void drawTree(QPainter *painter, const QRegion &region) const;
2020-08-23 19:17:50 +02:00
void drawRow(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &idx) const override;
2018-02-27 18:06:05 +01:00
// QAbstractScrollArea
2020-06-15 21:55:05 +02:00
void scrollContentsBy(int dx, int dy) override;
2018-02-27 18:06:05 +01:00
// QAbstractItemView
2020-06-15 21:55:05 +02:00
void rowsInserted(const QModelIndex &parent, int start, int end) override;
2020-08-23 19:17:50 +02:00
bool edit(const QModelIndex &idx, QAbstractItemView::EditTrigger trigger, QEvent *event) override;
2020-06-15 21:55:05 +02:00
void closeEditor(QWidget *editor, QAbstractItemDelegate::EndEditHint hint) override;
2018-02-27 18:06:05 +01:00
private slots:
2021-01-26 16:48:04 +01:00
void Update() { update(); }
void SetHeaderState();
2018-02-27 18:06:05 +01:00
void InhibitAutoscrollTimeout();
void MaybeAutoscroll(const Playlist::AutoScroll autoscroll);
2018-02-27 18:06:05 +01:00
void InvalidateCachedCurrentPixmap();
void PlaylistDestroyed();
2020-08-23 19:17:50 +02:00
void StretchChanged(const bool stretch);
void FadePreviousBackgroundImage(const qreal value);
void StopGlowing();
void StartGlowing();
void JumpToLastPlayedTrack();
void CopyCurrentSongToClipboard() const;
void Playing();
void Stopped();
void SongChanged(const Song &song);
2021-06-20 19:04:08 +02:00
void AlbumCoverLoaded(const Song &song, const AlbumCoverLoaderResult &result = AlbumCoverLoaderResult());
void DynamicModeChanged(const bool dynamic);
void SetRatingLockStatus(const bool state);
2021-06-20 19:04:08 +02:00
void RatingHoverIn(const QModelIndex &idx, const QPoint pos);
void RatingHoverOut();
2018-02-27 18:06:05 +01:00
private:
void LoadHeaderState();
void RestoreHeaderState();
2018-02-27 18:06:05 +01:00
void ReloadBarPixmaps();
QList<QPixmap> LoadBarPixmap(const QString &filename);
2020-08-23 19:17:50 +02:00
void UpdateCachedCurrentRowPixmap(QStyleOptionViewItem option, const QModelIndex &idx);
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;
2021-06-20 19:04:08 +02:00
emit BackgroundPropertyChanged(); // clazy:exclude=incorrect-emit
2018-02-27 18:06:05 +01: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);
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 &current);
QModelIndex PrevEditableIndex(const QModelIndex &current);
void RepositionDynamicControls();
2018-02-27 18:06:05 +01:00
Application *app_;
PlaylistProxyStyle *style_;
Playlist *playlist_;
PlaylistHeader *header_;
2019-03-25 22:00:40 +01:00
qreal device_pixel_ratio_;
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_;
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_;
bool background_initialized_;
bool set_initial_header_layout_;
bool header_state_loaded_;
bool header_state_restored_;
2021-06-20 23:53:28 +02:00
bool read_only_settings_;
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 select_track_;
bool auto_sort_;
2018-02-27 18:06:05 +01:00
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_;
int header_state_version_;
QByteArray header_state_;
2018-02-27 18:06:05 +01:00
ColumnAlignmentMap column_alignment_;
bool rating_locked_;
2019-04-28 14:14:19 +02:00
Song song_playing_;
DynamicPlaylistControls *dynamic_controls_;
RatingItemDelegate *rating_delegate_;
QColor playlist_playing_song_color_;
2018-02-27 18:06:05 +01:00
};
#endif // PLAYLISTVIEW_H