[vlc-devel] [PATCH 4/7] Enabled the Qt4-PictureFlow (fixed bugs when PL/ML was changed)

VlcVelope 1034-135 at online.de
Sun Apr 22 22:38:13 CEST 2012


The class PictureFlowView needed an implementation of 'setModel' to reflect
changing ML/PL root items. Selecting invalid items caused crash and is fixed.
The blend-function is alpha-aware (i.e. if the item has an image with alpha
plane, the item is displayed accordingly).
---
 modules/gui/qt4/components/playlist/playlist.cpp   |    4 -
 .../gui/qt4/components/playlist/standardpanel.cpp  |    7 +-
 modules/gui/qt4/components/playlist/views.cpp      |    8 +-
 modules/gui/qt4/components/playlist/views.hpp      |    1 +
 modules/gui/qt4/util/pictureflow.cpp               |  179 +++++++++++++-------
 modules/gui/qt4/util/pictureflow.hpp               |    4 +
 6 files changed, 132 insertions(+), 71 deletions(-)
 mode change 100644 => 100755 modules/gui/qt4/components/playlist/playlist.cpp
 mode change 100644 => 100755 modules/gui/qt4/components/playlist/standardpanel.cpp
 mode change 100644 => 100755 modules/gui/qt4/components/playlist/views.cpp
 mode change 100644 => 100755 modules/gui/qt4/components/playlist/views.hpp
 mode change 100644 => 100755 modules/gui/qt4/util/pictureflow.cpp
 mode change 100644 => 100755 modules/gui/qt4/util/pictureflow.hpp

diff --git a/modules/gui/qt4/components/playlist/playlist.cpp b/modules/gui/qt4/components/playlist/playlist.cpp
old mode 100644
new mode 100755
index e6ba9e6..a19f4ea
--- a/modules/gui/qt4/components/playlist/playlist.cpp
+++ b/modules/gui/qt4/components/playlist/playlist.cpp
@@ -124,11 +124,7 @@ PlaylistWidget::PlaylistWidget( intf_thread_t *_p_i, QWidget *_par )
 
     QActionGroup *actionGroup = new QActionGroup( this );
 
-#ifndef NDEBUG
 # define MAX_VIEW StandardPLPanel::VIEW_COUNT
-#else
-# define MAX_VIEW StandardPLPanel::VIEW_COUNT - 1
-#endif
     for( int i = 0; i < MAX_VIEW; i++ )
     {
         viewActions[i] = actionGroup->addAction( viewNames[i] );
diff --git a/modules/gui/qt4/components/playlist/standardpanel.cpp b/modules/gui/qt4/components/playlist/standardpanel.cpp
old mode 100644
new mode 100755
index badb68c..bb05f1c
--- a/modules/gui/qt4/components/playlist/standardpanel.cpp
+++ b/modules/gui/qt4/components/playlist/standardpanel.cpp
@@ -193,9 +193,8 @@ void StandardPLPanel::setRootItem( playlist_item_t *p_item, bool b )
     Q_UNUSED( b );
 #endif
     {
-        if( currentView->model() != model )
-            currentView->setModel( model );
         model->rebuild( p_item );
+        currentView->setModel( model );
     }
 }
 
@@ -204,7 +203,6 @@ void StandardPLPanel::browseInto( const QModelIndex &index )
     if( currentView == iconView || currentView == listView || currentView == picFlowView )
     {
 
-        currentView->setRootIndex( index );
 
         /* When going toward root in LocationBar, scroll to the item
            that was previously as root */
@@ -216,6 +214,7 @@ void StandardPLPanel::browseInto( const QModelIndex &index )
 
         /* Store new rootindexid*/
         currentRootIndexId = model->itemId( index );
+        currentView->setRootIndex( index );
     }
 
     emit viewChanged( index );
@@ -443,10 +442,8 @@ void StandardPLPanel::cycleViews()
     else if( currentView == treeView )
         showView( LIST_VIEW );
     else if( currentView == listView )
-#ifndef NDEBUG
         showView( PICTUREFLOW_VIEW  );
     else if( currentView == picFlowView )
-#endif
         showView( ICON_VIEW );
     else
         assert( 0 );
diff --git a/modules/gui/qt4/components/playlist/views.cpp b/modules/gui/qt4/components/playlist/views.cpp
old mode 100644
new mode 100755
index 32009af..b698be3
--- a/modules/gui/qt4/components/playlist/views.cpp
+++ b/modules/gui/qt4/components/playlist/views.cpp
@@ -378,11 +378,17 @@ PicFlowView::PicFlowView( PLModel *p_model, QWidget *parent ) : QAbstractItemVie
     QHBoxLayout *layout = new QHBoxLayout( this );
     layout->setMargin( 0 );
     picFlow = new PictureFlow( this, p_model );
-    picFlow->setSlideSize(QSize(128,128));
     layout->addWidget( picFlow );
+	picFlow->setSlideSize(QSize( 4*LISTVIEW_ART_SIZE, 3*LISTVIEW_ART_SIZE) );
     setSelectionMode( QAbstractItemView::SingleSelection );
 }
 
+void PicFlowView::setModel( QAbstractItemModel *model )
+{
+    QAbstractItemView::setModel( model );
+    picFlow->setModel( model );
+}
+
 int PicFlowView::horizontalOffset() const
 {
     return 0;
diff --git a/modules/gui/qt4/components/playlist/views.hpp b/modules/gui/qt4/components/playlist/views.hpp
old mode 100644
new mode 100755
index 97384f7..74abb1a
--- a/modules/gui/qt4/components/playlist/views.hpp
+++ b/modules/gui/qt4/components/playlist/views.hpp
@@ -104,6 +104,7 @@ public:
     virtual QRect visualRect(const QModelIndex&) const;
     virtual void scrollTo(const QModelIndex&, QAbstractItemView::ScrollHint);
     virtual QModelIndex indexAt(const QPoint&) const;
+    virtual void setModel(QAbstractItemModel *model);
 
 protected:
     virtual int horizontalOffset() const;
diff --git a/modules/gui/qt4/util/pictureflow.cpp b/modules/gui/qt4/util/pictureflow.cpp
old mode 100644
new mode 100755
index 6b51863..93e57bf
--- a/modules/gui/qt4/util/pictureflow.cpp
+++ b/modules/gui/qt4/util/pictureflow.cpp
@@ -204,7 +204,7 @@ private:
 // ------------- PictureFlowState ---------------------------------------
 
 PictureFlowState::PictureFlowState():
-        backgroundColor(0), slideWidth(150), slideHeight(200),
+        backgroundColor(qRgba(0,0,0,0)), slideWidth(150), slideHeight(120),
         reflectionEffect(PictureFlow::BlurredReflection), centerIndex(0)
 {
 }
@@ -296,9 +296,9 @@ void PictureFlowAnimator::update()
     if (!state)
         return;
 
-    int speed = 16384;
+    int speed = 16384/2;
 
-#if 0
+#if 1
     // deaccelerate when approaching the target
     const int max = 2 * 65536;
 
@@ -437,6 +437,7 @@ void PictureFlowSoftwareRenderer::paint()
         render();
 
     QPainter painter(widget);
+    painter.setCompositionMode(QPainter::CompositionMode_Source);
     painter.drawImage(QPoint(0, 0), buffer);
 
     QModelIndex index = state->model->index( state->centerIndex, 0, state->model->currentIndex().parent() );
@@ -456,7 +457,7 @@ void PictureFlowSoftwareRenderer::init()
     int w = (ww + 1) / 2;
     int h = (wh + 1) / 2;
 
-    buffer = QImage(ww, wh, QImage::Format_RGB32);
+    buffer = QImage(ww, wh, QImage::Format_ARGB32);
     buffer.fill(bgcolor);
 
     rays.resize(w*2);
@@ -472,10 +473,23 @@ void PictureFlowSoftwareRenderer::init()
 // TODO: optimize this with lookup tables
 static QRgb blendColor(QRgb c1, QRgb c2, int blend)
 {
-    int r = qRed(c1) * blend / 256 + qRed(c2) * (256 - blend) / 256;
-    int g = qGreen(c1) * blend / 256 + qGreen(c2) * (256 - blend) / 256;
-    int b = qBlue(c1) * blend / 256 + qBlue(c2) * (256 - blend) / 256;
-    return qRgb(r, g, b);
+    unsigned int a,r,g,b,as,ad;
+    if(blend>255)
+        blend=255;
+    as=(qAlpha(c1)*blend)/256;
+    ad=qAlpha(c2);
+    a=as+((255-as)*ad)/256;
+    if(a>0)
+    {
+        r=(as*qRed(c1)+((255-as)*ad*qRed(c2))/256)/a;
+        g=(as*qGreen(c1)+((255-as)*ad*qGreen(c2))/256)/a;
+        b=(as*qBlue(c1)+((255-as)*ad*qBlue(c2))/256)/a;
+    }
+    else
+    {
+        r=g=b=0;
+    }
+    return qRgba(r, g, b, a);
 }
 
 
@@ -483,14 +497,14 @@ static QImage* prepareSurface(const QImage* slideImage, int w, int h, QRgb bgcol
                               PictureFlow::ReflectionEffect reflectionEffect, QModelIndex index)
 {
     Qt::TransformationMode mode = Qt::SmoothTransformation;
-    QImage img = slideImage->scaled(w, h, Qt::IgnoreAspectRatio, mode);
+    QImage img = slideImage->scaled(w, h, Qt::KeepAspectRatio, mode);
 
     // slightly larger, to accomodate for the reflection
     int hs = h * 2;
     int hofs = h / 3;
 
     // offscreen buffer: black is sweet
-    QImage* result = new QImage(hs, w, QImage::Format_RGB32);
+    QImage* result = new QImage(hs, w, QImage::Format_ARGB32);
     QFont font( index.data( Qt::FontRole ).value<QFont>() );
     QPainter imagePainter( result );
     QTransform rotation;
@@ -498,7 +512,8 @@ static QImage* prepareSurface(const QImage* slideImage, int w, int h, QRgb bgcol
     rotation.rotate(90);
     rotation.scale(1,-1);
     rotation.translate( 0, hofs );
-    result->fill(bgcolor);
+    QRgb bg=qRgba(0, 0, 0, 0);
+    result->fill(bg);
 
     // transpose the image, this is to speed-up the rendering
     // because we process one column at a time
@@ -508,7 +523,6 @@ 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, img );
     if (reflectionEffect != PictureFlow::NoReflection) {
         // create the reflection
         int ht = hs - h - hofs;
@@ -516,9 +530,15 @@ static QImage* prepareSurface(const QImage* slideImage, int w, int h, QRgb bgcol
         for (int x = 0; x < w; x++)
         {
             QRgb *line = (QRgb*)(result->scanLine( x ));
+			int xw=img.width(),yw=img.height();
+			QRgb color;
             for (int y = 0; y < ht; y++) {
-                QRgb color = img.pixel(x, img.height() - y - 1);
-                line[h+hofs+y] = blendColor( color, bgcolor, 128*(hte-y)/hte );
+				color=bg;
+				int x0=x-(w-xw)/2;
+				int y0=yw - y - 1+(h-yw)/2;
+				if(x0>=0 && x0<xw && y0>=0 && y0<yw)
+                	color = img.pixel(x0, y0);
+                line[h+hofs+y] = blendColor( color, bg, 128*(hte-y)/hte );
                 //result->setPixel(h + hofs + y, x, blendColor(color, bgcolor, 128*(hte - y) / hte));
             }
         }
@@ -585,22 +605,22 @@ static QImage* prepareSurface(const QImage* slideImage, int w, int h, QRgb bgcol
                             p[i] = (rgba[i] += (((p[i] << 4) - rgba[i])) >> 1) >> 4;
                 }
             }
-
-            // 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));
-            */
-        }
-    }
+		}
+	}
+    // overdraw to leave only the reflection blurred (but not the actual image)
+    imagePainter.setTransform( rotation );
+    imagePainter.drawImage( (w-img.width())/2, (h-img.height())/2, img );
+    imagePainter.setBrush( QColor(bg));//QBrush( Qt::lightGray ) );
+    imagePainter.setPen( QColor( Qt::lightGray ) );
+    QFontMetrics fm = imagePainter.fontMetrics();
+    imagePainter.setPen( QColor( Qt::darkGray ) );
+    imagePainter.drawText( 0+1, 1+h-fm.height()*2, VLCModel::getMeta( index, COLUMN_TITLE ) );
+    imagePainter.setPen( QColor( Qt::lightGray ) );
+    imagePainter.drawText( 0, h-fm.height()*2, VLCModel::getMeta( index, COLUMN_TITLE ) );
+    imagePainter.setPen( QColor( Qt::darkGray ) );
+    imagePainter.drawText( 0+1, 1+h-fm.height()*1, VLCModel::getMeta( index, COLUMN_ARTIST ) );
+    imagePainter.setPen( QColor( Qt::lightGray ) );
+    imagePainter.drawText( 0, h-fm.height()*1, VLCModel::getMeta( index, COLUMN_ARTIST ) );
 
     return result;
 }
@@ -740,23 +760,11 @@ QRect PictureFlowSoftwareRenderer::renderSlide(const SlideInfo &slide, int col1,
         int p2 = center * PFREAL_ONE + dy / 2;
 
         const QRgb *ptr = (const QRgb*)(src->scanLine(column));
-        if (blend == 256)
-            while ((y1 >= 0) && (y2 < h) && (p1 >= 0)) {
-                *pixel1 = ptr[p1 >> PFREAL_SHIFT];
-                *pixel2 = ptr[p2 >> PFREAL_SHIFT];
-                p1 -= dy;
-                p2 += dy;
-                y1--;
-                y2++;
-                pixel1 -= pixelstep;
-                pixel2 += pixelstep;
-            }
-        else
             while ((y1 >= 0) && (y2 < h) && (p1 >= 0)) {
                 QRgb c1 = ptr[p1 >> PFREAL_SHIFT];
                 QRgb c2 = ptr[p2 >> PFREAL_SHIFT];
-                *pixel1 = blendColor(c1, bgcolor, blend);
-                *pixel2 = blendColor(c2, bgcolor, blend);
+                *pixel1 = blendColor(c1, *pixel1+0*bgcolor, blend);
+                *pixel2 = blendColor(c2, *pixel2+0*bgcolor, blend);
                 p1 -= dy;
                 p2 += dy;
                 y1--;
@@ -776,20 +784,13 @@ void PictureFlowSoftwareRenderer::renderSlides()
     int nleft = state->leftSlides.count();
     int nright = state->rightSlides.count();
 
-    QRect r = renderSlide(state->centerSlide);
-    int c1 = r.left();
-    int c2 = r.right();
-
-    for (int index = 0; index < nleft; index++) {
-        QRect rs = renderSlide(state->leftSlides[index], 0, c1 - 1);
-        if (!rs.isEmpty())
-            c1 = rs.left();
+    for (int index = nleft-1; index >= 0; index--) {
+        renderSlide(state->leftSlides[index]);
     }
-    for (int index = 0; index < nright; index++) {
-        QRect rs = renderSlide(state->rightSlides[index], c2 + 1, buffer.width());
-        if (!rs.isEmpty())
-            c2 = rs.right();
+    for (int index = nright-1; index >= 0; index--) {
+        renderSlide(state->rightSlides[index]);
     }
+    renderSlide(state->centerSlide);
 }
 
 // Render the slides. Updates only the offscreen buffer.
@@ -844,6 +845,29 @@ PictureFlow::~PictureFlow()
     delete d;
 }
 
+/*!
+    Sets the \a model.
+
+    \bold {Note:} The view does not take ownership of the model unless it is the
+    model's parent object because it may be shared between many different views.
+ */
+void PictureFlow::setModel(QAbstractItemModel * model)
+{
+    d->state->model=(VLCModel*)model;
+    d->state->reset();
+    d->state->reposition();
+    d->renderer->init();
+    triggerRender();
+}
+
+/*!
+    Returns the model.
+ */
+QAbstractItemModel * PictureFlow::model()
+{
+    return d->state->model;
+}
+
 int PictureFlow::slideCount() const
 {
     return d->state->model->rowCount( d->state->model->currentIndex().parent() );
@@ -856,7 +880,7 @@ QColor PictureFlow::backgroundColor() const
 
 void PictureFlow::setBackgroundColor(const QColor& c)
 {
-    d->state->backgroundColor = c.rgb();
+    d->state->backgroundColor = c.rgba();
     triggerRender();
 }
 
@@ -953,7 +977,7 @@ void PictureFlow::showSlide(int index)
 {
     index = qMax(index, 0);
     index = qMin(slideCount() - 1, index);
-    if (index == d->state->centerSlide.slideIndex)
+    if (index < 0 || index == d->state->centerSlide.slideIndex)
         return;
 
     d->animator->start(index);
@@ -988,9 +1012,14 @@ void PictureFlow::mousePressEvent(QMouseEvent* event)
         showNext();
     else if (event->x() < width() / 2 - d->state->slideWidth/2 )
         showPrevious();
-    else if ( d->state->model->currentIndex().row() != d->state->centerIndex )
-        d->state->model->activateItem( d->state->model->index( d->state->centerIndex, 0,
-                                                               d->state->model->currentIndex().parent() ) );
+    else if ( d->state->model->rowCount()>0 && d->state->model->currentIndex().row() != d->state->centerIndex )
+    {
+        if(d->state->model->hasIndex( d->state->centerIndex, 0, d->state->model->currentIndex().parent() ))
+        {
+            QModelIndex i=d->state->model->index( d->state->centerIndex, 0, d->state->model->currentIndex().parent() );
+            d->state->model->activateItem( i );
+        }
+	}
 }
 
 void PictureFlow::paintEvent(QPaintEvent* event)
@@ -1005,6 +1034,34 @@ void PictureFlow::resizeEvent(QResizeEvent* event)
     QWidget::resizeEvent(event);
 }
 
+void PictureFlow::wheelEvent(QWheelEvent * event)
+{
+    if (event->orientation() == Qt::Horizontal)
+    {
+        event->ignore();
+    }
+    else
+    {
+        int numSteps = -((event->delta() / 8) / 15);
+
+        if (numSteps > 0)
+        {
+            for (int i = 0;i < numSteps;i++)
+            {
+                showNext();
+            }
+        }
+        else
+        {
+            for (int i = numSteps;i < 0;i++)
+            {
+                showPrevious();
+            }
+        }
+        event->accept();
+    }
+}
+
 void PictureFlow::updateAnimation()
 {
     int old_center = d->state->centerIndex;
diff --git a/modules/gui/qt4/util/pictureflow.hpp b/modules/gui/qt4/util/pictureflow.hpp
old mode 100644
new mode 100755
index da10990..6dd6eda
--- a/modules/gui/qt4/util/pictureflow.hpp
+++ b/modules/gui/qt4/util/pictureflow.hpp
@@ -70,6 +70,9 @@ public:
     */
     ~PictureFlow();
 
+    void setModel(QAbstractItemModel * model);
+    QAbstractItemModel * model();
+
     /*!
       Returns the background color.
     */
@@ -158,6 +161,7 @@ protected:
     void paintEvent(QPaintEvent *event);
     void keyPressEvent(QKeyEvent* event);
     void mousePressEvent(QMouseEvent* event);
+    void wheelEvent(QWheelEvent* event);
     void resizeEvent(QResizeEvent* event);
 
 private slots:
-- 
1.7.5.4




More information about the vlc-devel mailing list