Ticket #1796: music-slideshow.patch

File music-slideshow.patch, 9.2 KB (added by gary@…, 14 years ago)

patch against 19-fixes (9914) mythplugins

  • mythmusic/mythmusic/mainvisual.cpp

     
    5050        MainVisual::registerVisFactory(new SynaesthesiaFactory);
    5151        MainVisual::registerVisFactory(new SpectrumFactory);
    5252        MainVisual::registerVisFactory(new AlbumArtFactory);
     53        MainVisual::registerVisFactory(new SlideShowFactory);
    5354#ifdef OPENGL_SUPPORT
    5455        MainVisual::registerVisFactory(new GearsFactory);
    5556#endif
  • mythmusic/mythmusic/visualize.cpp

     
    398398}
    399399
    400400
     401SlideShow::SlideShow(MainVisual *parent)
     402{
     403    pParent = parent;
     404    m_curImg.reset();
     405   
     406    // get GalleryDir from settings.  if it doesn't exist, set
     407    // the m_msg to an error, and never start the thread to load
     408    // m_files
     409    QString rootDir = gContext->GetSetting("GalleryDir");
     410    QDir dir(rootDir);
     411    if (!dir.exists() || !dir.isReadable())
     412    {
     413        m_msg = "MythGallery misconfigured";
     414        m_bNeedToDraw = true;
     415    }
     416    else
     417    {
     418        fps = 2;
     419        m_nSlideDelay = gContext->GetNumSetting("SlideshowDelay", 5);
     420        m_nCurrentFrame = m_nSlideDelay * fps;
     421        m_bNeedToDraw = false;
     422        m_imageFinder.m_baseDir = dir.path();
     423
     424        // create and start the thread that fills m_files
     425        m_imageFinder.start(QThread::LowestPriority);
     426    }
     427}
     428
     429SlideShow::ImageFinder::ImageFinder(void)
     430{
     431    m_abort = false;
     432}
     433
     434unsigned SlideShow::ImageFinder::GetCount(void)
     435{
     436    m_filesMux.lock();
     437    unsigned cnt = m_files.count();
     438    m_filesMux.unlock();
     439    return cnt;
     440}
     441
     442bool SlideShow::ImageFinder::GetRandImage(QImage *pImage)
     443{
     444    bool ret = false;
     445
     446    if (m_filesMux.tryLock())
     447    {
     448        if (m_files.count())
     449        {
     450            int nFile = rand() % m_files.count();
     451            QImage tmpImage(m_files[nFile]);
     452            // only modify pImage if there's a valid replacement
     453            if (!tmpImage.isNull())
     454            {
     455                pImage->reset();
     456                *pImage = tmpImage;
     457                ret = true;
     458            }
     459        }
     460        m_filesMux.unlock();
     461    }
     462    return ret;
     463}
     464
     465void SlideShow::ImageFinder::abort(void)
     466{
     467    // if the thread isn't finished, tell it to abort and then
     468    // wait for it.
     469    if (!this->finished())
     470    {
     471        m_filesMux.lock();
     472        m_abort = true;
     473        m_filesMux.unlock();
     474        this->wait();
     475    }
     476}
     477
     478void SlideShow::ImageFinder::run()
     479{
     480    bool abort = false;
     481 
     482    // gather a list of all directories under m_baseDir (including m_baseDir)
     483    // to unlimited depth.  Store them as absolute paths and check for dupes
     484    // to prevent recursive symbolic links.
     485    QStringList dirList;
     486    dirList.append(m_baseDir);
     487
     488    QStringList::Iterator it = dirList.begin();
     489    while (!abort && (it != dirList.end()))
     490    {
     491        QDir dir(*it, QString::null, QDir::Unsorted,
     492                 QDir::Dirs | QDir::Readable | QDir::Executable);
     493        for (unsigned i = 0; !abort && (i < dir.count()); i++)
     494        {
     495            // completely skip ANY directory that starts with a period.
     496            // this will eliminate hidden stuff as well as stuff like
     497            // "." and ".." (and gallery's .thumbnails)
     498            if (dir[i][0] != '.')
     499            {
     500                QString path = *it + QDir::separator() + dir[i];
     501                path = QDir(path).canonicalPath();
     502                // if path isn't in dirList, append it
     503                if (dirList.find(path) == dirList.end())
     504                {
     505                    dirList.append(path);
     506                }
     507            }
     508        }
     509        it++;
     510    }
     511
     512    // now loop the directories, and find images within
     513    for (unsigned i = 0; !abort && (i < dirList.count()); i++)
     514    {
     515      // Get directory contents based on filter
     516        QDir folder(dirList[i], "*.png;*.jpg;*.jpeg;*.gif;*.bmp",
     517                    QDir::Name | QDir::IgnoreCase,
     518                    QDir::Files | QDir::Readable);
     519        QString dirname = dirList[i] + QDir::separator();
     520   
     521        for (unsigned j = 0; !abort && (j < folder.count()); j++)
     522        {
     523            // for each file that looks like an image, validate that
     524            // Qt can load it before adding it to The List
     525            QString fname = dirname + folder[j];
     526            QImage img(fname);
     527            if (!img.isNull())
     528            {
     529                m_filesMux.lock();
     530                abort = m_abort;
     531                m_files.append(fname);
     532                m_filesMux.unlock();
     533            }
     534            img.reset();
     535        }
     536    }
     537}
     538
     539SlideShow::~SlideShow()
     540{
     541    // if the finder is running, tell it to abort
     542    if (m_imageFinder.running())
     543    {
     544        m_imageFinder.abort();
     545    }
     546}
     547
     548void SlideShow::resize(const QSize &newsize)
     549{
     550    m_size = newsize;
     551    m_bNeedToDraw = true;
     552}
     553
     554bool SlideShow::process(VisualNode *)
     555
     556    if (m_nCurrentFrame >= (m_nSlideDelay * fps))
     557    {
     558        // is anything available to load? if so, set redraw
     559        if (m_imageFinder.GetRandImage(&m_curImg))
     560        {
     561          // random image retrieved - set redraw
     562            m_msg = "";
     563            m_bNeedToDraw = true;
     564            m_nCurrentFrame = 0;
     565        }
     566        else if (m_imageFinder.finished())
     567        {
     568            // no image?  is the image finder done?  if so,
     569            // must not be any images to load
     570            m_msg = "No Images Found";
     571            m_bNeedToDraw = true;
     572        }
     573        else if (m_curImg.isNull())
     574        {
     575            // no image, but the finder isn't done.  Display
     576            // some text to prevent black screens
     577            m_msg = "Loading Images...";
     578            m_bNeedToDraw = true;
     579        }
     580    }
     581    else
     582    {
     583        m_nCurrentFrame++;
     584    }
     585    return true;
     586}
     587
     588bool SlideShow::draw(QPainter *p, const QColor &back)
     589{
     590    bool ret = true;
     591   
     592    if (!pParent->decoder())
     593    {
     594        ret = false;
     595    }
     596    else if (m_bNeedToDraw)
     597    {
     598        if (!m_msg.isEmpty())
     599        {
     600            p->fillRect(0, 0, m_size.width(), m_size.height(), back);
     601            p->setPen(Qt::white);
     602            p->setFont(gContext->GetMediumFont());
     603            p->drawText(m_size.width() / 2 - 200,
     604                        m_size.height() / 2 - 10, 400, 20,
     605                        Qt::AlignCenter, QObject::tr(m_msg));
     606            m_bNeedToDraw = false;
     607        }
     608        else if (!m_curImg.isNull())
     609        {
     610            QSize artsize = m_curImg.scale(m_size, QImage::ScaleMin).size();
     611       
     612            // Paint the image
     613            p->fillRect(0, 0, m_size.width(), m_size.height(), back);
     614            p->drawPixmap((m_size.width() - artsize.width()) / 2,
     615                          (m_size.height() - artsize.height()) / 2,
     616                          m_curImg.smoothScale(m_size, QImage::ScaleMin));
     617            // Store our new size
     618            m_bNeedToDraw = false;
     619        }
     620    } // if need redraw
     621    return ret;
     622}
     623
     624const QString &SlideShowFactory::name(void) const
     625{
     626    static QString name("SlideShow");
     627    return name;
     628}
     629
     630const QString &SlideShowFactory::description(void) const
     631{
     632    static QString name("Displays a mythgallery based slideshow");
     633    return name;
     634}
     635
     636VisualBase *SlideShowFactory::create(MainVisual *parent, long int winid)
     637{
     638    (void)winid;
     639    return new SlideShow(parent);
     640}
     641
     642
     643
    401644Blank::Blank()
    402645    : VisualBase(true)
    403646{
  • mythmusic/mythmusic/visualize.h

     
    1313#define VISUALIZE_H
    1414
    1515#include <mythtv/visual.h>
     16#include <qvaluevector.h>
     17#include <qthread.h>
     18#include <qimage.h>
    1619#include "mainvisual.h"
    1720#include "constants.h"
    1821#include "config.h"
     
    109112    VisualBase *create(MainVisual *parent, long int winid);
    110113};
    111114
     115
     116class SlideShow : public VisualBase
     117{
     118  public:
     119    SlideShow(MainVisual *parent);
     120    virtual ~SlideShow();
     121
     122    void resize(const QSize &size);
     123    bool process(VisualNode *node = 0);
     124    bool draw(QPainter *p, const QColor &back = Qt::black);
     125
     126  private:
     127    QImage m_curImg;
     128    QSize m_size;
     129    QString m_msg;
     130    int m_nSlideDelay;
     131    int m_nCurrentFrame;
     132    bool m_bNeedToDraw;
     133    MainVisual *pParent;
     134
     135    class ImageFinder : public QThread
     136    {
     137      public:
     138        ImageFinder(void);
     139        virtual void run();
     140       
     141        bool GetRandImage(QImage *pImage);
     142        unsigned GetCount(void);
     143        void abort(void);
     144       
     145        QMutex m_filesMux;
     146        QString m_baseDir;
     147      private:
     148        bool m_abort;
     149        QValueVector <QString> m_files;
     150    };
     151
     152    ImageFinder m_imageFinder;
     153   
     154};
     155
     156class SlideShowFactory : public VisFactory
     157{
     158  public:
     159    const QString &name(void) const;
     160    const QString &description(void) const;
     161    VisualBase *create(MainVisual *parent, long int winid);
     162};
     163
     164
     165
    112166class Blank : public VisualBase
    113167{
    114168    // This draws ... well ... nothing