]> git.sesse.net Git - vlc/blobdiff - modules/gui/qt4/util/pictureflow.cpp
Qt: adv settings: Optimize synchronization panel
[vlc] / modules / gui / qt4 / util / pictureflow.cpp
index c5a611258e61dd9196c0f2e39b68ab44aa508ef5..fc229810515d9bbb3ebefeac4d0ce4558ff3b20d 100644 (file)
@@ -26,6 +26,7 @@
 */
 
 #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
@@ -142,7 +145,7 @@ public:
     PFreal offsetX;
     PFreal offsetY;
 
-    PLModel *model;
+    VLCModel *model;
     SlideInfo centerSlide;
     QVector<SlideInfo> leftSlides;
     QVector<SlideInfo> rightSlides;
@@ -199,7 +202,8 @@ private:
     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 ---------------------------------------
@@ -414,6 +418,7 @@ PictureFlowSoftwareRenderer::PictureFlowSoftwareRenderer():
 PictureFlowSoftwareRenderer::~PictureFlowSoftwareRenderer()
 {
     buffer = QImage();
+    cache.clear();
     delete blankSurface;
 }
 
@@ -441,24 +446,6 @@ void PictureFlowSoftwareRenderer::paint()
 
     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()
@@ -498,7 +485,7 @@ static QRgb blendColor(QRgb c1, QRgb c2, int blend)
 
 
 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);
@@ -509,9 +496,13 @@ static QImage* prepareSurface(const QImage* slideImage, int w, int h, QRgb bgcol
 
     // 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
@@ -522,7 +513,7 @@ static QImage* prepareSurface(const QImage* slideImage, int w, int h, QRgb bgcol
         for (int y = 0; y < h; y++)
             result->setPixel(hofs + y, x, img.pixel(x, y));
     */
-    imagePainter.drawImage( hofs+h, 0, result->transformed( rotation ) );
+    imagePainter.drawImage( hofs+h, 0, img );
     if (reflectionEffect != PictureFlow::NoReflection) {
         // create the reflection
         int ht = hs - h - hofs;
@@ -601,30 +592,33 @@ static QImage* prepareSurface(const QImage* slideImage, int w, int h, QRgb bgcol
             }
 
             // 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)
+    if (!state || !index.isValid())
         return 0;
-    if (slideIndex < 0)
-        return 0;
-    if (slideIndex >= state->model->rowCount( state->model->currentIndex().parent() ) )
-        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;
@@ -638,7 +632,44 @@ QRect PictureFlowSoftwareRenderer::renderSlide(const SlideInfo &slide, int col1,
     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();
 
@@ -668,10 +699,9 @@ QRect PictureFlowSoftwareRenderer::renderSlide(const SlideInfo &slide, int col1,
     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;
     }
 
@@ -743,7 +773,6 @@ QRect PictureFlowSoftwareRenderer::renderSlide(const SlideInfo &slide, int col1,
 
     rect.setTop(0);
     rect.setBottom(h - 1);
-    delete src;
     return rect;
 }
 
@@ -788,10 +817,9 @@ public:
 };
 
 
-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();