[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