Commit ba0abdcf authored by Scott Wheeler's avatar Scott Wheeler

Ok, this isn't really done yet, but this was what I'd been thinking of

for the "Now Playing" when I discovered the one that was part of Nathan's
patch.  This one does quite a bit more and makes it possible to easily add
or switch elements in the future.

Eventually the links for the artist and album will go to a filtered playlist
based on that and the history links will either jump to the item in the playlist
or start playing it.  We'll see.

Also clicking on the image should show the original -- but I'm not sure I want
that in a real window -- probably just a borderless thing that goes away when
you click it.

svn path=/trunk/kdemultimedia/juk/; revision=361877
parent 521bcbe1
......@@ -26,7 +26,6 @@
<Menu name="view" noMerge="1"><text>&amp;View</text>
<Action name="showSearch"/>
<Action name="showEditor"/>
<Action name="showNowPlaying"/>
<Action name="showHistory"/>
<Action name="showUpcoming"/>
<Action name="showColumns"/>
......
......@@ -28,7 +28,6 @@
<Menu name="view" noMerge="1"><text>&amp;View</text>
<Action name="showSearch"/>
<Action name="showEditor"/>
<Action name="showNowPlaying"/>
<Action name="showHistory"/>
<Action name="showUpcoming"/>
<Action name="showColumns"/>
......
/***************************************************************************
copyright : (C) 2004 Nathan Toone
email : nathan@toonetown.com
***************************************************************************/
begin : Tue Nov 9 2004
copyright : (C) 2004 by Scott Wheeler
email : wheeler@kde.org
***************************************************************************/
/***************************************************************************
* *
......@@ -13,176 +14,180 @@
***************************************************************************/
#include <kiconloader.h>
#include <kactionclasses.h>
#include <kconfig.h>
#include <klocale.h>
#include <kfiledialog.h>
#include <kdebug.h>
#include <qsize.h>
#include <qsizepolicy.h>
#include <qpixmap.h>
#include <qimage.h>
#include <qvaluelist.h>
#include <qsplitter.h>
#include <qpushbutton.h>
#include <qlayout.h>
#include "nowplaying.h"
#include "playermanager.h"
#include "filehandle.h"
#include "actioncollection.h"
#include "coverinfo.h"
#include "tag.h"
using namespace ActionCollection;
////////////////////////////////////////////////////////////////////////////////
// public members
////////////////////////////////////////////////////////////////////////////////
NowPlaying::NowPlaying(QSplitter *parent, const char *name) :
QWidget(parent, name),
m_button(0)
{
setupActions();
setupLayout();
readConfig();
slotClear();
}
static const int imageSize = 64;
NowPlaying::~NowPlaying()
struct Line : public QFrame
{
saveConfig();
}
Line(QWidget *parent) : QFrame(parent) { setFrameShape(VLine); }
};
////////////////////////////////////////////////////////////////////////////////
// public slots
// NowPlaying
////////////////////////////////////////////////////////////////////////////////
void NowPlaying::slotRefresh()
NowPlaying::NowPlaying(QWidget *parent, const char *name) :
QHBox(parent, name)
{
if(!PlayerManager::instance()->playing())
return;
layout()->setMargin(5);
layout()->setSpacing(3);
setFixedHeight(imageSize + 2 + layout()->margin() * 2);
m_button->hide();
setStretchFactor(new CoverItem(this), 0);
setStretchFactor(new TrackItem(this), 2);
setStretchFactor(new Line(this), 0);
setStretchFactor(new HistoryItem(this), 1);
FileHandle playingFile = PlayerManager::instance()->playingFile();
connect(PlayerManager::instance(), SIGNAL(signalPlay()), this, SLOT(slotUpdate()));
connect(PlayerManager::instance(), SIGNAL(signalStop()), this, SLOT(slotUpdate()));
if(playingFile.coverInfo()->hasCover()){
QImage image = playingFile.coverInfo()->pixmap(CoverInfo::FullSize).convertToImage();
QPixmap cover = image.smoothScale(size().width(), size().width());
setPaletteBackgroundPixmap(cover);
}
else {
m_button->show();
m_button->setText(i18n("Add Cover Image"));
setPaletteBackgroundPixmap(QPixmap());
}
}
void NowPlaying::slotClear()
{
m_button->show();
m_button->setPixmap(DesktopIcon("juk", 72));
setPaletteBackgroundPixmap(QPixmap());
hide();
}
void NowPlaying::mousePressEvent(QMouseEvent *)
void NowPlaying::addItem(NowPlayingItem *item)
{
if(PlayerManager::instance()->playing())
slotButtonPress();
m_items.append(item);
}
void NowPlaying::resizeEvent(QResizeEvent *ev)
void NowPlaying::slotUpdate()
{
// if the width hasn't changed, just return.
FileHandle file = PlayerManager::instance()->playingFile();
if(!ev || ev->oldSize().width() == size().width())
if(file.isNull()) {
hide();
return;
}
else
show();
QSplitter *parentSplitter = static_cast<QSplitter *>(parent());
setMaximumHeight(parentSplitter->size().height());
setMinimumHeight(0);
resize(QSize(width(), width()));
int newTop = parentSplitter->size().height() - size().height() - parentSplitter->handleWidth();
int newBottom = size().height();
QValueList<int> sizeList;
sizeList.append(newTop);
sizeList.append(newBottom);
parentSplitter->setSizes(sizeList);
FileHandle playingFile=PlayerManager::instance()->playingFile();
if((PlayerManager::instance()->playing() || PlayerManager::instance()->paused()) &&
playingFile.coverInfo()->hasCover())
for(QValueList<NowPlayingItem *>::Iterator it = m_items.begin();
it != m_items.end(); ++it)
{
QImage image = playingFile.coverInfo()->pixmap(CoverInfo::FullSize).convertToImage();
setPaletteBackgroundPixmap(image.smoothScale(size().width(), size().width()));
(*it)->update(file);
}
setMaximumHeight(width());
setMinimumHeight(width());
}
///////////////////////////////////////////////////////////////////////////////
// private slots
////////////////////////////////////////////////////////////////////////////////
// CoverItem
////////////////////////////////////////////////////////////////////////////////
void NowPlaying::slotButtonPress()
CoverItem::CoverItem(NowPlaying *parent) :
QLabel(parent, "CoverItem"),
NowPlayingItem(parent)
{
if(!PlayerManager::instance()->playing()) {
action<KAction>("help_about_app")->activate();
return;
}
FileHandle playingFile = PlayerManager::instance()->playingFile();
setFixedHeight(parent->height() - parent->layout()->margin() * 2);
setFrameStyle(Box | Plain);
setLineWidth(1);
setMargin(1);
}
if(playingFile.coverInfo()->hasCover())
playingFile.coverInfo()->popupLargeCover();
else {
KURL file = KFileDialog::getImageOpenURL(":homedir", this, i18n("Select cover image file - JuK"));
QImage image(file.directory() + "/" + file.fileName());
playingFile.coverInfo()->setCover(image);
slotRefresh();
void CoverItem::update(const FileHandle &file)
{
if(file.coverInfo()->hasCover()) {
show();
QImage image = file.coverInfo()->pixmap(CoverInfo::FullSize).convertToImage();
setPixmap(image.smoothScale(imageSize, imageSize, QImage::ScaleMax));
}
else
hide();
}
////////////////////////////////////////////////////////////////////////////////
// private members
// TrackItem
////////////////////////////////////////////////////////////////////////////////
void NowPlaying::readConfig()
TrackItem::TrackItem(NowPlaying *parent) :
QWidget(parent, "TrackItem"),
NowPlayingItem(parent)
{
KConfigGroup config(KGlobal::config(), "NowPlaying");
bool show = config.readBoolEntry("Show", false);
action<KToggleAction>("showNowPlaying")->setChecked(show);
setShown(show);
setFixedHeight(parent->height() - parent->layout()->margin() * 2);
setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Fixed);
QVBoxLayout *layout = new QVBoxLayout(this);
m_label = new KActiveLabel(this);
m_label->setLinkUnderline(false);
layout->addStretch();
layout->addWidget(m_label);
layout->addStretch();
}
void NowPlaying::saveConfig()
void TrackItem::update(const FileHandle &file)
{
KConfigGroup config(KGlobal::config(), "NowPlaying");
config.writeEntry("Show", action<KToggleAction>("showNowPlaying")->isChecked());
QString title = QStyleSheet::escape(file.tag()->title());
QString artist = QStyleSheet::escape(file.tag()->artist());
QString album = QStyleSheet::escape(file.tag()->album());
QString separator = (artist.isNull() || album.isNull()) ? QString::null : QString(" - ");
// This block-o-nastiness makes the font smaller and smaller until it actually fits.
int size = 4;
QString format =
"<font size=\"+%1\"><b>%2</b></font>"
"<br />"
"<font size=\"+%3\"><b><a href=\"#\">%4</a>%5<a href=\"#\">%6</a></b></font>";
do {
m_label->setText(format.arg(size).arg(title).arg(size - 2)
.arg(artist).arg(separator).arg(album));
--size;
} while(m_label->heightForWidth(m_label->width()) > imageSize && size >= 0);
m_label->setFixedHeight(QMIN(imageSize, m_label->heightForWidth(m_label->width())));
}
void NowPlaying::setupActions()
////////////////////////////////////////////////////////////////////////////////
// HistoryItem
////////////////////////////////////////////////////////////////////////////////
HistoryItem::HistoryItem(NowPlaying *parent) :
KActiveLabel(parent, "HistoryItem"),
NowPlayingItem(parent)
{
KToggleAction *show =
new KToggleAction(i18n("Show Now Playing"), "player_play", 0, actions(), "showNowPlaying");
show->setCheckedState(i18n("Hide Now Playing"));
connect(show, SIGNAL(toggled(bool)), this, SLOT(setShown(bool)));
setFixedHeight(parent->height() - parent->layout()->margin() * 2);
setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Fixed);
setLinkUnderline(false);
setText(QString("<b>%1</b><br>").arg(i18n("History")));
}
void NowPlaying::setupLayout()
void HistoryItem::update(const FileHandle &file)
{
QVBoxLayout *vLayout = new QVBoxLayout(this);
QHBoxLayout *hLayout = new QHBoxLayout(vLayout);
m_button = new QPushButton(this);
m_button->setSizePolicy(QSizePolicy::Maximum, QSizePolicy::Maximum);
hLayout->addWidget(m_button);
connect(m_button, SIGNAL(clicked()), this, SLOT(slotButtonPress()));
if(file.isNull() || (!m_history.isEmpty() && m_history.front() == file))
return;
if(m_history.count() >= 10)
m_history.remove(m_history.fromLast());
m_history.prepend(file);
QString format = "<a href=\"#\"><font size=\"-2\">%1</font></a>";
QString current = QString("<b>%1</b><br>").arg(i18n("History"));
QString previous;
for(FileHandleList::ConstIterator it = m_history.begin();
it != m_history.end(); ++it)
{
previous = current;
current.append(format.arg(QStyleSheet::escape((*it).tag()->title())));
setText(current);
if(heightForWidth(width()) < imageSize)
current.append("<br>");
else {
setText(previous);
return;
}
}
}
#include "nowplaying.moc"
/***************************************************************************
copyright : (C) 2004 Nathan Toone
email : nathan@toonetown.com
begin : Tue Nov 9 2004
copyright : (C) 2004 by Scott Wheeler
email : wheeler@kde.org
***************************************************************************/
/***************************************************************************
......@@ -15,38 +16,88 @@
#ifndef NOWPLAYING_H
#define NOWPLAYING_H
#include <qwidget.h>
#include <kactivelabel.h>
class QPushButton;
class QSplitter;
#include <qhbox.h>
#include <qlabel.h>
class NowPlaying : public QWidget
#include "filehandle.h"
class NowPlayingItem;
/**
* This is the widget that holds all of the other items and handles updating them
* when the playing item changes.
*/
class NowPlaying : public QHBox
{
Q_OBJECT
public:
NowPlaying(QSplitter *parent, const char *name = 0);
virtual ~NowPlaying();
NowPlaying(QWidget *parent, const char *name = 0);
void addItem(NowPlayingItem *item);
private slots:
void slotUpdate();
private:
void setupActions();
void setupLayout();
void readConfig();
void saveConfig();
QValueList<NowPlayingItem *> m_items;
};
public slots:
void slotRefresh();
void slotClear();
/**
* Abstract base for the other NowPlaying items.
*/
private slots:
void slotButtonPress();
class NowPlayingItem
{
public:
virtual void update(const FileHandle &file) = 0;
protected:
virtual void resizeEvent(QResizeEvent *ev);
virtual void mousePressEvent(QMouseEvent *e);
NowPlayingItem(NowPlaying *parent) { parent->addItem(this); }
};
/**
* Displays the cover of the currently playing file if available, or hides
* itself if not.
*/
class CoverItem : public QLabel, public NowPlayingItem
{
public:
CoverItem(NowPlaying *parent);
virtual void update(const FileHandle &file);
};
/**
* Show the text information on the current track and provides links to the
* album and artist of the currently playing item.
*/
class TrackItem : public QWidget, public NowPlayingItem
{
public:
TrackItem(NowPlaying *parent);
virtual void update(const FileHandle &file);
private:
KActiveLabel *m_label;
};
/**
* Shows up to 10 items of history and links to those items.
*/
class HistoryItem : public KActiveLabel, public NowPlayingItem
{
public:
HistoryItem(NowPlaying *parent);
virtual void update(const FileHandle &file);
private:
QPushButton *m_button;
FileHandleList m_history;
KActiveLabel *m_label;
};
#endif
......@@ -118,14 +118,7 @@ void PlaylistSplitter::setupLayout()
connect(CollectionList::instance(), SIGNAL(signalCollectionChanged()),
m_editor, SLOT(slotUpdateCollection()));
NowPlaying *nowPlaying = new NowPlaying(boxSplitter);
boxSplitter->moveToFirst(m_playlistBox);
connect(PlayerManager::instance(), SIGNAL(signalPlay()), nowPlaying, SLOT(slotRefresh()));
connect(PlayerManager::instance(), SIGNAL(signalStop()), nowPlaying, SLOT(slotClear()));
connect(PlayerManager::instance(), SIGNAL(signalCoverChanged()), nowPlaying, SLOT(slotRefresh()));
boxSplitter->setResizeMode(nowPlaying, QSplitter::KeepSize);
NowPlaying *nowPlaying = new NowPlaying(top);
// Create the search widget -- this must be done after the CollectionList is created.
......@@ -139,6 +132,7 @@ void PlaylistSplitter::setupLayout()
connect(action<KToggleAction>("showSearch"), SIGNAL(toggled(bool)),
m_searchWidget, SLOT(setEnabled(bool)));
topLayout->addWidget(nowPlaying);
topLayout->addWidget(m_searchWidget);
topLayout->addWidget(m_playlistStack);
......
......@@ -261,11 +261,15 @@ void SearchWidget::setupLayout()
connect(clearSearchButton, SIGNAL(pressed()), m_searchLine, SLOT(clear()));
setStretchableWidget(m_searchLine);
QToolButton *b = new QToolButton(this);
b->setTextLabel(i18n("Advanced Search"), true);
b->setIconSet(SmallIconSet("wizard"));
// I've decided that I think this is ugly, for now.
connect(b, SIGNAL(clicked()), this, SIGNAL(signalAdvancedSearchClicked()));
/*
QToolButton *b = new QToolButton(this);
b->setTextLabel(i18n("Advanced Search"), true);
b->setIconSet(SmallIconSet("wizard"));
connect(b, SIGNAL(clicked()), this, SIGNAL(signalAdvancedSearchClicked()));
*/
}
#include "searchwidget.moc"
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment