*/
#include "pictureflow.hpp"
+#include "components/playlist/ml_model.hpp"
// detect Qt version
#if QT_VERSION < 0x040300
#include <QTimer>
#include <QVector>
#include <QWidget>
+#include <QHash>
#include "../components/playlist/playlist_model.hpp" /* getArtPixmap etc */
#include "../components/playlist/sorting.h" /* Columns List */
+#include "input_manager.hpp"
// for fixed-point arithmetic, we need minimum 32-bit long
// long long (64-bit) might be useful for multiplication and division
PFreal offsetX;
PFreal offsetY;
- PLModel *model;
+ VLCModel *model;
SlideInfo centerSlide;
QVector<SlideInfo> leftSlides;
QVector<SlideInfo> rightSlides;
void render();
void renderSlides();
QRect renderSlide(const SlideInfo &slide, int col1 = -1, int col2 = -1);
- QImage* surface(int slideIndex);
+ QImage* surface(QModelIndex);
+ QHash<QString, QImage*> cache;
};
// ------------- PictureFlowState ---------------------------------------
PictureFlowSoftwareRenderer::~PictureFlowSoftwareRenderer()
{
buffer = QImage();
+ cache.clear();
delete blankSurface;
}
QModelIndex index = state->model->index( state->centerIndex, 0, state->model->currentIndex().parent() );
- if( index.isValid() )
- {
- QString title = PLModel::getMeta( index, COLUMN_TITLE );
- QString artist = PLModel::getMeta( index, COLUMN_ARTIST );
- QFont font( index.data( Qt::FontRole ).value<QFont>() );
- painter.setFont( font );
- painter.setBrush( QBrush( Qt::lightGray ) );
- painter.setPen( QColor( Qt::lightGray ) );
- QFontMetrics fm = painter.fontMetrics();
-
- QPoint textstart( buffer.width() / 2 - state->slideWidth/2 , buffer.height() / 2 + state->slideWidth/2 + 5 );
- QPoint artiststart( 0, fm.xHeight() * 2 );
-
- painter.drawText( textstart, title );
-
- textstart += artiststart;
- painter.drawText( textstart, artist);
- }
}
void PictureFlowSoftwareRenderer::init()
static QImage* prepareSurface(const QImage* slideImage, int w, int h, QRgb bgcolor,
- PictureFlow::ReflectionEffect reflectionEffect)
+ PictureFlow::ReflectionEffect reflectionEffect, QModelIndex index)
{
Qt::TransformationMode mode = Qt::SmoothTransformation;
QImage img = slideImage->scaled(w, h, Qt::IgnoreAspectRatio, mode);
// offscreen buffer: black is sweet
QImage* result = new QImage(hs, w, QImage::Format_RGB32);
+ QFont font( index.data( Qt::FontRole ).value<QFont>() );
+ QPainter imagePainter( result );
+ QTransform rotation;
+ imagePainter.setFont( font );
+ rotation.rotate(90);
+ rotation.scale(1,-1);
+ rotation.translate( 0, hofs );
result->fill(bgcolor);
// transpose the image, this is to speed-up the rendering
// because we process one column at a time
// (and much better and faster to work row-wise, i.e in one scanline)
+ /*
for (int x = 0; x < w; x++)
for (int y = 0; y < h; y++)
result->setPixel(hofs + y, x, img.pixel(x, y));
-
+ */
+ imagePainter.drawImage( hofs+h, 0, img );
if (reflectionEffect != PictureFlow::NoReflection) {
// create the reflection
int ht = hs - h - hofs;
int hte = ht;
for (int x = 0; x < w; x++)
+ {
+ QRgb *line = (QRgb*)(result->scanLine( x ));
for (int y = 0; y < ht; y++) {
QRgb color = img.pixel(x, img.height() - y - 1);
- result->setPixel(h + hofs + y, x, blendColor(color, bgcolor, 128*(hte - y) / hte));
+ line[h+hofs+y] = blendColor( color, bgcolor, 128*(hte-y)/hte );
+ //result->setPixel(h + hofs + y, x, blendColor(color, bgcolor, 128*(hte - y) / hte));
}
+ }
if (reflectionEffect == PictureFlow::BlurredReflection) {
// blur the reflection everything first
}
// overdraw to leave only the reflection blurred (but not the actual image)
+ imagePainter.setTransform( rotation );
+ imagePainter.drawImage( 0, 0, img );
+ imagePainter.setBrush( QBrush( Qt::lightGray ) );
+ imagePainter.setPen( QColor( Qt::lightGray ) );
+ QFontMetrics fm = imagePainter.fontMetrics();
+ imagePainter.drawText( 0, img.height()+ 13, VLCModel::getMeta( index, COLUMN_TITLE ) );
+ imagePainter.drawText( 0, img.height()+ 13 + fm.xHeight()*2, VLCModel::getMeta( index, COLUMN_ARTIST ) );
+ /*
for (int x = 0; x < w; x++)
for (int y = 0; y < h; y++)
result->setPixel(hofs + y, x, img.pixel(x, y));
+ */
}
}
return result;
}
-QImage* PictureFlowSoftwareRenderer::surface(int slideIndex)
+QImage* PictureFlowSoftwareRenderer::surface(QModelIndex index)
{
- if (!state)
- return 0;
- if (slideIndex < 0)
- return 0;
- if (slideIndex >= state->model->rowCount( state->model->currentIndex().parent() ) )
+ if (!state || !index.isValid())
return 0;
- int key = slideIndex;
-
- QImage* img = new QImage(PLModel::getArtPixmap( state->model->index( slideIndex, 0, state->model->currentIndex().parent() ),
+ QImage* img = new QImage(VLCModel::getArtPixmap( index,
QSize( state->slideWidth, state->slideHeight ) ).toImage());
- QImage* sr = prepareSurface(img, state->slideWidth, state->slideHeight, bgcolor, state->reflectionEffect);
+ QImage* sr = prepareSurface(img, state->slideWidth, state->slideHeight, bgcolor, state->reflectionEffect, index );
delete img;
return sr;
if (!blend)
return QRect();
- QImage* src = surface(slide.slideIndex);
+ QModelIndex index;
+
+ QString artURL;
+
+ PLModel* plm = dynamic_cast<PLModel*>( state->model );
+#ifdef MEDIA_LIBRARY
+ MLModel* mlm = dynamic_cast<MLModel*>( state->model );
+#endif
+ if( plm != 0 )
+ {
+ index = ((PLModel*)state->model)->index( slide.slideIndex, 0, state->model->currentIndex().parent() );
+ if( !index.isValid() )
+ return QRect();
+
+ PLItem *item = static_cast<PLItem*>( index.internalPointer() );
+ artURL = InputManager::decodeArtURL( item->inputItem() );
+ }
+#ifdef MEDIA_LIBRARY
+ else if( mlm != 0 )
+ {
+ index = ((MLModel*)state->model)->index( slide.slideIndex, 0, QModelIndex() );
+ if( !index.isValid() )
+ return QRect();
+
+ MLItem *item = static_cast<MLItem*>( index.internalPointer() );
+ artURL = qfu( item->getMedia()->psz_cover );
+ }
+#endif
+ QString key = QString("%1%2%3%4").arg(VLCModel::getMeta( index, COLUMN_TITLE )).arg( VLCModel::getMeta( index, COLUMN_ARTIST ) ).arg(index.data( VLCModel::IsCurrentRole ).toBool() ).arg( artURL );
+
+ QImage* src;
+ if( cache.contains( key ) )
+ src = cache.value( key );
+ else
+ {
+ src = surface( index );
+ cache.insert( key, src );
+ }
if (!src)
return QRect();
PFreal ys = slide.cy - state->slideWidth * sdy / 2;
PFreal dist = distance * PFREAL_ONE;
- int xi = qMax((PFreal)0, (w * PFREAL_ONE / 2) + fdiv(xs * h, dist + ys) >> PFREAL_SHIFT);
+ int xi = qMax((PFreal)0, ((w * PFREAL_ONE / 2) + fdiv(xs * h, dist + ys)) >> PFREAL_SHIFT);
if (xi >= w)
{
- delete src;
return rect;
}
rect.setTop(0);
rect.setBottom(h - 1);
- delete src;
return rect;
}
};
-PictureFlow::PictureFlow(QWidget* parent, PLModel* _p_model): QWidget(parent)
+PictureFlow::PictureFlow(QWidget* parent, VLCModel* _p_model): QWidget(parent)
{
d = new PictureFlowPrivate;
-
d->state = new PictureFlowState;
d->state->model = _p_model;
d->state->reset();