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

277 lines
8.3 KiB
C++

/*
* 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/>.
*
*/
#ifndef PLAYLISTVIEW_H
#define PLAYLISTVIEW_H
#include "config.h"
#include <memory>
#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>
#include <QProxyStyle>
#include <QTreeView>
#include <QPoint>
#include <QTimer>
#include <QBasicTimer>
#include <QTimeLine>
#include <QCommonStyle>
#include <QPainter>
#include <QAbstractItemDelegate>
#include <QAbstractItemModel>
#include <QStyleOptionViewItem>
#include <QtEvents>
#include "playlist.h"
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;
class Application;
class Song;
class CollectionBackend;
class PlaylistHeader;
// 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.
// This proxy style uses QCommonStyle to paint the affected elements.
// This class is used by internet search view as well.
class PlaylistProxyStyle : public QProxyStyle {
public:
PlaylistProxyStyle(QStyle *base);
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:
enum BackgroundImageType {
Default,
None,
Custom,
Album
};
PlaylistView(QWidget *parent = nullptr);
~PlaylistView();
// Constants for settings: are persistent, values should not be changed
static const char *kSettingBackgroundImageType;
static const char *kSettingBackgroundImageFilename;
static const int kDefaultBlurRadius;
static const int kDefaultOpacityLevel;
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_; }
BackgroundImageType background_image_type() const { return background_image_type_; }
Qt::Alignment column_alignment(int section) const;
// QTreeView
void drawTree(QPainter *painter, const QRegion &region) const;
void drawRow(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const;
void setModel(QAbstractItemModel *model);
void ResetColumns();
public slots:
void ReloadSettings();
void StopGlowing();
void StartGlowing();
void JumpToCurrentlyPlayingTrack();
void JumpToLastPlayedTrack();
void closeEditor(QWidget *editor, QAbstractItemDelegate::EndEditHint hint);
void SetColumnAlignment(int section, Qt::Alignment alignment);
void CopyCurrentSongToClipboard() const;
void CurrentSongChanged(const Song &new_song, const QString &uri, const QImage &cover_art);
void PlayerStopped();
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);
//void resizeEvent(QResizeEvent *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);
private slots:
void LoadGeometry();
void SaveGeometry();
void GlowIntensityChanged();
void InhibitAutoscrollTimeout();
void MaybeAutoscroll();
void InvalidateCachedCurrentPixmap();
void PlaylistDestroyed();
void SaveSettings();
void StretchChanged(bool stretch);
void FadePreviousBackgroundImage(qreal value);
private:
void ReloadBarPixmaps();
QList<QPixmap> LoadBarPixmap(const QString &filename);
void UpdateCachedCurrentRowPixmap(QStyleOptionViewItem option, const QModelIndex &index);
void set_background_image_type(BackgroundImageType bg) {
background_image_type_ = bg;
emit BackgroundPropertyChanged();
}
// Save image as the background_image_ after applying some modifications (opacity, ...).
// Should be used instead of modifying background_image_ directly
void set_background_image(const QImage &image);
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);
Application *app_;
PlaylistProxyStyle *style_;
Playlist *playlist_;
PlaylistHeader *header_;
bool initialized_;
bool setting_initial_header_layout_;
bool read_only_settings_;
bool header_loaded_;
bool background_initialized_;
BackgroundImageType background_image_type_;
// Stores the background image to be displayed.
// As we want this image to be particular (in terms of format, opacity),
// you should probably use set_background_image_type instead of modifying background_image_ directly
QImage background_image_;
int blur_radius_;
int opacity_level_;
// Used if background image is a filemane
QString background_image_filename_;
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
int last_height_;
int last_width_;
bool force_background_redraw_;
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_;
};
#endif // PLAYLISTVIEW_H