Ticket #2256: mbanner.patch
File mbanner.patch, 19.4 KB (added by , 18 years ago) |
---|
-
mythplugins/mythmusic/mythmusic/playbackbox.h
67 67 void checkForPlaylists(); 68 68 void handleTreeListSignals(int, IntVector*); 69 69 void visEnable(); 70 void bannerDisable(); 70 71 void changeVolume(bool up_or_down); 71 72 void toggleMute(); 72 73 void resetTimer(); … … 109 110 void openOutputDevice(void); 110 111 void postUpdate(); 111 112 void playFirstTrack(); 113 void bannerEnable(Metadata *mdata); 114 void bannerToggle(Metadata *mdata); 112 115 113 116 QIODevice *input; 114 117 AudioOutput *output; … … 159 162 int visual_mode_delay; 160 163 QTimer *visual_mode_timer; 161 164 QTimer *lcd_update_timer; 165 QTimer *banner_timer; 162 166 int visualizer_status; 163 167 164 168 bool showrating; -
mythplugins/mythmusic/mythmusic/playbackbox.cpp
42 42 mainvisual = NULL; 43 43 visual_mode_timer = NULL; 44 44 lcd_update_timer = NULL; 45 banner_timer = NULL; 45 46 waiting_for_playlists_timer = NULL; 46 47 playlist_tree = NULL; 47 48 playlist_popup = NULL; … … 61 62 curSmartPlaylistCategory = ""; 62 63 curSmartPlaylistName = ""; 63 64 65 banner_timer = new QTimer(this); 66 connect(banner_timer, SIGNAL(timeout()), this, SLOT(bannerDisable())); 67 64 68 menufilters = gContext->GetNumSetting("MusicMenuFilters", 0); 65 69 66 70 cd_reader_thread = NULL; … … 367 371 showMenu(); 368 372 } 369 373 else if (action == "INFO") 370 showEditMetadataDialog(); 374 if (visualizer_status == 2) 375 bannerToggle(curMeta); 376 else 377 showEditMetadataDialog(); 371 378 else 372 379 handled = false; 373 380 } … … 401 408 160, 160); 402 409 setUpdatesEnabled(true); 403 410 mainvisual->setVisual(visual_workaround); 411 bannerDisable(); 404 412 405 413 if (!m_parent->IsExitingToMain()) 406 414 handled = true; … … 1122 1130 1123 1131 decoder->start(); 1124 1132 1133 bannerEnable(curMeta); 1125 1134 isplaying = true; 1126 1135 curMeta->setLastPlay(); 1127 1136 curMeta->incPlayCount(); … … 1135 1144 setUpdatesEnabled(false); 1136 1145 mainvisual->setGeometry(0, 0, screenwidth, screenheight); 1137 1146 visualizer_status = 2; 1147 } 1148 else 1149 { 1150 bannerDisable(); 1138 1151 } 1139 1152 } 1140 1153 1154 void PlaybackBoxMusic::bannerEnable(Metadata *mdata) 1155 { 1156 if (visualizer_status != 2) 1157 return; 1158 1159 banner_timer->start(8000); 1160 mainvisual->addInformation("\"" + mdata->Title() + "\"\n" + 1161 mdata->Artist() + " - " + mdata->Album()); 1162 } 1163 1164 void PlaybackBoxMusic::bannerToggle(Metadata *mdata) 1165 { 1166 if (banner_timer->isActive()) 1167 bannerDisable(); 1168 else 1169 bannerEnable(mdata); 1170 } 1171 1172 void PlaybackBoxMusic::bannerDisable() 1173 { 1174 banner_timer->stop(); 1175 mainvisual->addInformation(""); 1176 } 1177 1141 1178 void PlaybackBoxMusic::CycleVisualizer() 1142 1179 { 1143 1180 QString new_visualizer; … … 1905 1942 mainvisual->setGeometry(screenwidth + 10, screenheight + 10, 1906 1943 160, 160); 1907 1944 mainvisual->setVisual(visual_mode); 1945 bannerDisable(); 1908 1946 visualizer_status = 1; 1909 1947 if(visual_mode_delay > 0) 1910 1948 { -
mythplugins/mythmusic/mythmusic/visualize.h
51 51 Spectrum(); 52 52 virtual ~Spectrum(); 53 53 54 v oid resize(const QSize &size);54 virtual void resize(const QSize &size); 55 55 bool process(VisualNode *node); 56 bool draw(QPainter *p, const QColor &back = Qt::black);56 virtual bool draw(QPainter *p, const QColor &back = Qt::black); 57 57 58 pr ivate:58 protected: 59 59 inline double clamp(double cur, double max, double min); 60 60 61 61 QColor startColor, targetColor; … … 93 93 void resize(const QSize &size); 94 94 bool process(VisualNode *node = 0); 95 95 bool draw(QPainter *p, const QColor &back = Qt::black); 96 bool needsUpdate(); 97 QString getImageFilename(); 96 98 97 99 private: 98 100 QSize size, cursize; 99 101 QString filename; 100 102 QString directory; 101 103 MainVisual *pParent; 104 QImage image; 102 105 }; 103 106 104 107 class AlbumArtFactory : public VisFactory … … 132 135 VisualBase *create(MainVisual *parent, long int winid); 133 136 }; 134 137 138 class Squares : public Spectrum 139 { 140 public: 141 Squares(); 142 virtual ~Squares(); 143 144 void resize (const QSize &newsize); 145 bool draw(QPainter *p, const QColor &back = Qt::black); 146 147 private: 148 void drawRect(QPainter *p, QRect *rect, int i, int c, int w, int h); 149 QSize size; 150 MainVisual *pParent; 151 int fake_height; 152 int number_of_squares; 153 }; 154 155 class SquaresFactory : public VisFactory 156 { 157 public: 158 const QString &name(void) const; 159 const QString &description(void) const; 160 VisualBase *create(MainVisual *parent, long int winid); 161 }; 162 135 163 #ifdef OPENGL_SUPPORT 136 164 137 165 class Gears : public QGLWidget, public VisualBase -
mythplugins/mythmusic/mythmusic/visualize.cpp
19 19 #include <qpixmap.h> 20 20 #include <qimage.h> 21 21 #include <qdir.h> 22 #include <qurl.h> 22 23 23 24 #include <iostream> 24 25 using namespace std; … … 266 267 267 268 #else 268 269 // Oops ... user doesn't have a Fast Fourier Library 269 p->fillRect(0, 0, size.width(), size.height(), back); 270 p->setPen(Qt::white); 271 p->setFont(gContext->GetMediumFont()); 272 p->drawText(size.width() / 2 - 200, size.height() / 2 - 20, 400, 20, 273 Qt::AlignCenter, QObject::tr("Visualization requires FFT library")); 274 p->drawText(size.width() / 2 - 200, size.height() / 2, 400, 20, 275 Qt::AlignCenter, QObject::tr("Did you run configure?")); 270 drawWarning(p, back, size, 271 QObject::tr("Visualization requires FFT library") + "\n" + 272 QObject::tr("Did you run configure?")); 276 273 #endif 277 274 278 275 return true; … … 304 301 if (dec) 305 302 { 306 303 filename = dec->getFilename(); 307 directory = filename.left(filename.findRev("/"));304 directory = QUrl(filename).dirPath(); 308 305 } 309 306 310 fps = 20;307 fps = 1; 311 308 } 312 309 313 310 AlbumArt::~AlbumArt() … … 325 322 return true; 326 323 } 327 324 325 bool AlbumArt::needsUpdate() { 326 if (cursize != size) 327 return true; 328 329 if (filename != pParent->decoder()->getFilename()) { 330 QString curdir = QUrl(pParent->decoder()->getFilename()).dirPath(); 331 if (directory != curdir) 332 return true; 333 } 334 335 return false; 336 } 337 338 QString AlbumArt::getImageFilename() 339 { 340 QString result; 341 QString curfile = pParent->decoder()->getFilename(); 342 QString curdir = QUrl(curfile).dirPath(); 343 QString namefilter = gContext->GetSetting("AlbumArtFilter", 344 "*.png;*.jpg;*.jpeg;*.gif;*.bmp"); 345 // Get directory contents based on filter 346 QDir folder(curdir, namefilter, QDir::Name | QDir::IgnoreCase, 347 QDir::Files | QDir::Hidden); 348 349 if (folder.count()) 350 result = folder[rand() % folder.count()]; 351 352 result.prepend("/"); 353 result.prepend(curdir); 354 355 return result; 356 } 357 328 358 bool AlbumArt::draw(QPainter *p, const QColor &back) 329 359 { 330 360 if (!pParent->decoder()) 331 361 return false; 332 362 333 QString curfile = pParent->decoder()->getFilename();334 QString curdir = curfile.left(curfile.findRev("/"));335 QImage art;336 337 363 // If the directory has changed (new album) or the size, reload 338 if ( (directory.compare(curdir) != 0) || (cursize != size))364 if (needsUpdate()) 339 365 { 340 // Directory has changed 341 directory = curdir; 342 // Get filter 343 QString namefilter = gContext->GetSetting("AlbumArtFilter", 344 "*.png;*.jpg;*.jpeg;*.gif;*.bmp"); 345 // Get directory contents based on filter 346 QDir folder(curdir, namefilter, QDir::Name | QDir::IgnoreCase, 347 QDir::Files | QDir::Hidden); 348 349 QString fileart = ""; 350 351 if (folder.count()) 352 fileart = folder[rand() % folder.count()]; 353 354 curdir.append("/"); 355 curdir.append(fileart); 356 art.load(curdir); 366 QImage art(getImageFilename()); 357 367 if (art.isNull()) 358 368 { 359 p->fillRect(0, 0, size.width(), size.height(), back); 360 p->setPen(Qt::white); 361 p->setFont(gContext->GetMediumFont()); 362 p->drawText(size.width() / 2 - 200, size.height() / 2 - 10, 400, 20, 363 Qt::AlignCenter, QObject::tr("?")); 369 drawWarning(p, back, size, QObject::tr("?")); 370 cursize = size; 364 371 return true; 365 372 } 373 image = art.smoothScale(size, QImage::ScaleMin); 374 } 366 375 367 QSize artsize = art.scale(size, QImage::ScaleMin).size(); 376 // Paint the image 377 p->fillRect(0, 0, size.width(), size.height(), back); 378 p->drawPixmap((size.width() - image.width()) / 2, 379 (size.height() - image.height()) / 2, 380 image); 381 382 // Store our new size 383 cursize = size; 368 384 369 // Paint the image370 p->fillRect(0, 0, size.width(), size.height(), back);371 p->drawPixmap((size.width() - artsize.width()) / 2,372 (size.height() - artsize.height()) / 2,373 art.smoothScale(size, QImage::ScaleMin));374 // Store our new size375 cursize = size;376 return true;377 }378 art.reset();379 385 return true; 380 386 } 381 387 … … 446 452 return new Blank(); 447 453 } 448 454 455 Squares::Squares() 456 { 457 number_of_squares = 16; 458 fake_height = number_of_squares * analyzerBarWidth; 459 } 449 460 461 Squares::~Squares() 462 { 463 } 464 465 void Squares::resize (const QSize &newsize) { 466 // Trick the spectrum analyzer into calculating 16 rectangles 467 Spectrum::resize (QSize (fake_height, fake_height)); 468 // We have our own copy, Spectrum has it's own... 469 size = newsize; 470 } 471 472 void Squares::drawRect(QPainter *p, QRect *rect, int i, int c, int w, int h) 473 { 474 double r, g, b, per; 475 int correction = (size.width() % rects.size ()) / 2; 476 int x = ((i / 2) * w) + correction; 477 int y; 478 479 if (i % 2 == 0) 480 { 481 y = c - h; 482 per = double(fake_height - rect->top()) / double(fake_height); 483 } 484 else 485 { 486 y = c; 487 per = double(rect->bottom()) / double(fake_height); 488 } 489 490 per = clamp(per, 1.0, 0.0); 491 492 r = startColor.red() + 493 (targetColor.red() - startColor.red()) * (per * per); 494 g = startColor.green() + 495 (targetColor.green() - startColor.green()) * (per * per); 496 b = startColor.blue() + 497 (targetColor.blue() - startColor.blue()) * (per * per); 498 499 r = clamp(r, 255.0, 0.0); 500 g = clamp(g, 255.0, 0.0); 501 b = clamp(b, 255.0, 0.0); 502 503 p->fillRect (x, y, w, h, QColor (int(r), int(g), int(b))); 504 } 505 506 bool Squares::draw(QPainter *p, const QColor &back) 507 { 508 p->fillRect (0, 0, size.width (), size.height (), back); 509 int w = size.width () / (rects.size () / 2); 510 int h = w; 511 int center = size.height () / 2; 512 513 #if defined(FFTW3_SUPPORT) || defined(FFTW2_SUPPORT) 514 QRect *rectsp = rects.data(); 515 for (uint i = 0; i < rects.count(); i++) 516 drawRect(p, &(rectsp[i]), i, center, w, h); 517 518 #else 519 // Oops ... user doesn't have a Fast Fourier Library 520 drawWarning(p, back, size, 521 QObject::tr("Visualization requires FFT library") + "\n" + 522 QObject::tr("Did you run configure?")); 523 #endif 524 525 return true; 526 527 for (int x = 0; x < size.width (); x += w) { 528 p->fillRect (x, center - h / 2, w, h, QColor ("red")); 529 p->fillRect (x, center + h / 2, w, h, QColor ("blue")); 530 } 531 return true; 532 } 533 534 const QString &SquaresFactory::name(void) const 535 { 536 static QString name("Squares"); 537 return name; 538 } 539 540 const QString &SquaresFactory::description(void) const 541 { 542 static QString name("Square visualizer"); 543 return name; 544 } 545 546 VisualBase *SquaresFactory::create(MainVisual *parent, long int winid) 547 { 548 (void)winid; 549 (void)parent; 550 return new Squares(); 551 } 552 450 553 #ifdef OPENGL_SUPPORT 451 554 452 555 // Need this for the Gears Object (below) -
mythplugins/mythmusic/mythmusic/mainvisual.h
15 15 #include <qdialog.h> 16 16 #include <qmemarray.h> 17 17 #include <qpixmap.h> 18 #include <qimage.h> 18 19 #include <qptrlist.h> 19 20 #include <qstringlist.h> 20 21 … … 37 38 38 39 ~VisualNode() 39 40 { 40 41 41 delete [] left; 42 delete [] right; 42 43 } 43 44 44 45 short *left, *right; … … 57 58 virtual bool draw( QPainter *, const QColor & ) = 0; 58 59 virtual void resize( const QSize &size ) = 0; 59 60 virtual int getDesiredFPS(void) { return fps; } 61 void drawWarning(QPainter *, const QColor &, const QSize &, QString); 60 62 61 63 protected: 62 64 int fps; … … 94 96 void setFrameRate( int newfps ); 95 97 int frameRate() const { return fps; } 96 98 99 void addInformation(const QString &); 100 97 101 static void registerVisFactory(VisFactory *); 98 102 static VisualBase *createVis(const QString &name, 99 103 MainVisual *parent, long int winid); … … 106 110 107 111 private: 108 112 VisualBase *vis; 113 QString info; 114 QPixmap info_pixmap; 109 115 QPixmap pixmap; 110 116 QPtrList<VisualNode> nodes; 111 117 QTimer *timer; -
mythplugins/mythmusic/mythmusic/mainvisual.cpp
50 50 MainVisual::registerVisFactory(new SynaesthesiaFactory); 51 51 MainVisual::registerVisFactory(new SpectrumFactory); 52 52 MainVisual::registerVisFactory(new AlbumArtFactory); 53 MainVisual::registerVisFactory(new SquaresFactory); 53 54 #ifdef OPENGL_SUPPORT 54 55 MainVisual::registerVisFactory(new GearsFactory); 55 56 #endif … … 70 71 gContext->DoDisableScreensaver(); 71 72 } 72 73 74 VisualBase::~VisualBase() 75 { 76 // 77 // This is only here so 78 // that derived classes 79 // can destruct properly 80 // 81 if (!xscreensaverenable) 82 gContext->DoRestoreScreensaver(); 83 } 84 85 void VisualBase::drawWarning(QPainter *p, const QColor &back, const QSize &size, QString warning) 86 { 87 p->fillRect(0, 0, size.width(), size.height(), back); 88 p->setPen(Qt::white); 89 p->setFont(gContext->GetMediumFont()); 90 91 QFontMetrics fm(p->font()); 92 int width = fm.width(warning); 93 int height = fm.height() * (warning.contains("\n") + 1); 94 int x = size.width() / 2 - width / 2; 95 int y = size.height() / 2 - height / 2; 96 97 for (int offset = 0; offset < height; offset += fm.height()) { 98 QString l = warning.left(warning.find("\n")); 99 p->drawText(x, y + offset, width, height, Qt::AlignCenter, l); 100 warning.remove(0, l.length () + 1); 101 } 102 } 103 73 104 MainVisual::MainVisual(QWidget *parent, const char *name) 74 105 : QWidget( parent, name ), vis( 0 ), playing( FALSE ), fps( 20 ) 75 106 { … … 243 274 } 244 275 245 276 VisualNode *node = 0; 246 277 247 278 if (playing && output()) { 248 279 long synctime = output()->GetAudiotime(); 249 250 251 252 253 254 255 256 257 258 259 260 280 mutex()->lock(); 281 VisualNode *prev = 0; 282 while ((node = nodes.first())) { 283 if (node->offset > synctime) 284 break; 285 286 delete prev; 287 nodes.removeFirst(); 288 prev = node; 289 } 290 mutex()->unlock(); 291 node = prev; 261 292 } 262 293 263 294 bool stop = TRUE; 264 295 if (vis && process) 265 296 stop = vis->process(node); 266 297 if (node) 267 298 delete node; 268 299 … … 270 301 { 271 302 QPainter p(&pixmap); 272 303 if (vis->draw(&p, Qt::black)) 304 { 305 p.drawPixmap((int)(pixmap.width() * 0.1), (int)(pixmap.height() * 0.8), info_pixmap); 273 306 bitBlt(this, 0, 0, &pixmap); 307 } 274 308 } 275 309 276 310 if (!playing && stop) 277 311 timer->stop(); 278 312 } 279 313 280 314 void MainVisual::paintEvent(QPaintEvent *) 281 315 { 316 QPainter p(&pixmap); 317 p.drawPixmap((int)(pixmap.width() * 0.1), (int)(pixmap.height() * 0.8), info_pixmap); 282 318 bitBlt(this, 0, 0, &pixmap); 283 319 } 284 320 … … 323 359 QWidget::hideEvent(e); 324 360 } 325 361 362 void MainVisual::addInformation(const QString &new_info) { 363 if (new_info == info) 364 return; 365 366 info = new_info; 367 if (info.isEmpty()) 368 { 369 info_pixmap.resize(0, 0); 370 return; 371 } 372 373 info_pixmap = QPixmap((int)(pixmap.width() * 0.8), 374 (int)(pixmap.height() * 0.15), 375 pixmap.depth ()); 376 QPainter p(&info_pixmap); 377 378 int indent = int(info_pixmap.width() * 0.02); 379 380 p.fillRect(0, 0, 381 info_pixmap.width(), info_pixmap.height(), 382 QColor ("darkblue")); 383 384 385 p.setFont(gContext->GetMediumFont()); 386 387 QFontMetrics fm(p.font()); 388 int width = fm.width(info); 389 int height = fm.height() * (info.contains("\n") + 1); 390 int x = indent; 391 int y = indent; 392 393 QString info_copy = info; 394 for (int offset = 0; offset < height; offset += fm.height()) { 395 QString l = info_copy.left(info_copy.find("\n")); 396 p.setPen(Qt::black); 397 p.drawText(x + 2, y + offset + 2, width, height, Qt::AlignLeft, l); 398 p.setPen(Qt::white); 399 p.drawText(x, y + offset, width, height, Qt::AlignLeft, l); 400 info_copy.remove(0, l.length () + 1); 401 } 402 } 403 326 404 void MainVisual::registerVisFactory(VisFactory *vis) 327 405 { 328 406 visfactories->append(vis); … … 837 915 return indices[index]; 838 916 } 839 917 840 VisualBase::~VisualBase()841 {842 //843 // This is only here so844 // that derived classes845 // can destruct properly846 //847 if (!xscreensaverenable)848 gContext->DoRestoreScreensaver();849 } -
mythplugins/mythmusic/mythmusic/globalsettings.cpp
384 384 gc->setHelpText(QObject::tr("List of visualizations to use during playback. " 385 385 "Possible values are space-separated list of ") + "Random, " 386 386 "MonoScope, StereoScope, Spectrum, BumpScope, Goom, " 387 "Synaesthesia, AlbumArt, Gears, " + QObject::tr("and") +387 "Synaesthesia, AlbumArt, Gears, Squares" + QObject::tr("and") + 388 388 " Blank"); 389 389 return gc; 390 390 };