| | 452 | Lyrics::Lyrics(MainVisual *parent) |
| | 453 | { |
| | 454 | m_pParent = parent; |
| | 455 | |
| | 456 | findFrontCover(); |
| | 457 | |
| | 458 | Decoder *dec = m_pParent->decoder(); |
| | 459 | if (dec) |
| | 460 | m_filename = dec->getFilename(); |
| | 461 | |
| | 462 | fps = 1; |
| | 463 | } |
| | 464 | |
| | 465 | void Lyrics::findFrontCover(void) |
| | 466 | { |
| | 467 | // if a front cover image is available show that first |
| | 468 | AlbumArtImages albumArt(m_pParent->metadata()); |
| | 469 | if (albumArt.isImageAvailable(IT_FRONTCOVER)) |
| | 470 | m_currImageType = IT_FRONTCOVER; |
| | 471 | else |
| | 472 | { |
| | 473 | // not available so just show the first image available |
| | 474 | if (albumArt.getImageCount() > 0) |
| | 475 | m_currImageType = albumArt.getImageAt(0).imageType; |
| | 476 | else |
| | 477 | m_currImageType = IT_UNKNOWN; |
| | 478 | } |
| | 479 | } |
| | 480 | |
| | 481 | Lyrics::~Lyrics() |
| | 482 | { |
| | 483 | } |
| | 484 | |
| | 485 | void Lyrics::resize(const QSize &newsize) |
| | 486 | { |
| | 487 | m_size = newsize; |
| | 488 | } |
| | 489 | |
| | 490 | bool Lyrics::process(VisualNode *node) |
| | 491 | { |
| | 492 | node = node; |
| | 493 | return true; |
| | 494 | } |
| | 495 | |
| | 496 | void Lyrics::handleKeyPress(const QString &action) |
| | 497 | { |
| | 498 | if (action == "DOWN") |
| | 499 | { |
| | 500 | if (m_start + 1 + m_visible_lines < int(m_lyrics.size())) |
| | 501 | m_start++; |
| | 502 | } |
| | 503 | |
| | 504 | if (action == "UP") |
| | 505 | { |
| | 506 | if (m_start != 0) |
| | 507 | m_start--; |
| | 508 | } |
| | 509 | |
| | 510 | if (action == "PAGEDOWN") |
| | 511 | { |
| | 512 | if (m_start + m_page_amount + m_visible_lines < int(m_lyrics.size())) |
| | 513 | m_start += m_page_amount; |
| | 514 | else |
| | 515 | m_start = int(m_lyrics.size()) - m_page_amount; |
| | 516 | } |
| | 517 | |
| | 518 | if (action == "PAGEUP") |
| | 519 | { |
| | 520 | if (m_start < m_page_amount) |
| | 521 | m_start = 0; |
| | 522 | else |
| | 523 | m_start -= m_page_amount; |
| | 524 | } |
| | 525 | |
| | 526 | if (action == "SELECT") |
| | 527 | { |
| | 528 | AlbumArtImages albumArt(m_pParent->metadata()); |
| | 529 | |
| | 530 | int newType = m_currImageType; |
| | 531 | if (albumArt.getImageCount() > 0) |
| | 532 | { |
| | 533 | while(!albumArt.isImageAvailable((ImageType) ++newType)) |
| | 534 | if (newType == IT_LAST) |
| | 535 | newType = IT_UNKNOWN; |
| | 536 | } |
| | 537 | |
| | 538 | if (newType != m_currImageType) |
| | 539 | { |
| | 540 | m_currImageType = (ImageType) newType; |
| | 541 | // force an update |
| | 542 | m_cursize = QSize(0, 0); |
| | 543 | } |
| | 544 | } |
| | 545 | } |
| | 546 | |
| | 547 | bool Lyrics::needsUpdate() |
| | 548 | { |
| | 549 | if (m_cursize != m_size) |
| | 550 | return true; |
| | 551 | |
| | 552 | if (m_filename != m_pParent->decoder()->getFilename()) |
| | 553 | { |
| | 554 | m_filename = m_pParent->decoder()->getFilename(); |
| | 555 | findFrontCover(); |
| | 556 | return true; |
| | 557 | } |
| | 558 | |
| | 559 | return false; |
| | 560 | } |
| | 561 | |
| | 562 | void Lyrics::calculateScreenInfo(QPainter *p) |
| | 563 | { |
| | 564 | m_start = 0; |
| | 565 | m_indentx = 0; |
| | 566 | m_indenty = 0; |
| | 567 | m_max_line_width = 0; |
| | 568 | m_visible_lines = 0; |
| | 569 | m_page_amount = 0; |
| | 570 | m_font_height = 0; |
| | 571 | m_lyrics_too_wide = false; |
| | 572 | m_image_too_small = false; |
| | 573 | |
| | 574 | if (!m_lyrics.empty()) |
| | 575 | { |
| | 576 | p->setFont(gContext->GetMediumFont()); |
| | 577 | QFontMetrics fm(p->font()); |
| | 578 | m_font_height = fm.height(); |
| | 579 | |
| | 580 | for (QValueVector<QString>::iterator i = m_lyrics.begin(); |
| | 581 | i != m_lyrics.end(); i++) |
| | 582 | { |
| | 583 | int width = fm.width(*i); |
| | 584 | if (width > m_max_line_width) m_max_line_width = width; |
| | 585 | } |
| | 586 | |
| | 587 | m_indentx = int(0.03 * m_size.width()); |
| | 588 | m_indenty = int(0.03 * m_size.height()); |
| | 589 | |
| | 590 | if ((m_max_line_width + 2 * m_indentx) > m_size.width()) |
| | 591 | { |
| | 592 | // Lyrics don't fit. Remove them. |
| | 593 | m_lyrics.clear(); |
| | 594 | m_max_line_width = 0; |
| | 595 | m_indentx = 0; |
| | 596 | m_indenty = 0; |
| | 597 | m_lyrics_too_wide = true; |
| | 598 | } |
| | 599 | else |
| | 600 | { |
| | 601 | m_visible_lines = (m_size.height() - 2 * m_indenty) / m_font_height; |
| | 602 | m_page_amount = m_visible_lines / 2; |
| | 603 | if (m_size.width() < m_max_line_width + 3 * m_indentx + |
| | 604 | int(0.1 * m_size.width())) |
| | 605 | { |
| | 606 | // Don't draw really small images |
| | 607 | m_image_too_small = true; |
| | 608 | } |
| | 609 | } |
| | 610 | } |
| | 611 | } |
| | 612 | |
| | 613 | bool Lyrics::draw(QPainter *p, const QColor &back) |
| | 614 | { |
| | 615 | if (!m_pParent->decoder()) |
| | 616 | return false; |
| | 617 | |
| | 618 | // If the song has changed or the size, reload |
| | 619 | if (needsUpdate()) |
| | 620 | { |
| | 621 | m_lyrics = m_pParent->metadata()->getUnsynchronizedLyrics(); |
| | 622 | calculateScreenInfo(p); |
| | 623 | |
| | 624 | // Now we know how much room we have for the image. |
| | 625 | QImage art(m_pParent->metadata()->getAlbumArt(m_currImageType)); |
| | 626 | if (art.isNull()) |
| | 627 | { |
| | 628 | m_cursize = m_size; |
| | 629 | m_image = QImage(); |
| | 630 | } |
| | 631 | else if (!m_image_too_small) |
| | 632 | { |
| | 633 | int height_adjustment = m_lyrics_too_wide ? m_font_height : 0; |
| | 634 | QSize a_size(m_size.width() - m_max_line_width - 3 * m_indentx, |
| | 635 | m_size.height() - height_adjustment); |
| | 636 | m_image = art.smoothScale(a_size, QImage::ScaleMin); |
| | 637 | } |
| | 638 | } |
| | 639 | |
| | 640 | if (m_image.isNull() && !m_image_too_small && m_lyrics.empty()) |
| | 641 | { |
| | 642 | drawWarning(p, back, m_size, QObject::tr("?")); |
| | 643 | return true; |
| | 644 | } |
| | 645 | |
| | 646 | p->fillRect(0, 0, m_size.width(), m_size.height(), back); |
| | 647 | |
| | 648 | // Paint the image |
| | 649 | if (!m_image_too_small) |
| | 650 | { |
| | 651 | int xpos = (m_size.width() - m_max_line_width - |
| | 652 | m_indentx - m_image.width()) /2; |
| | 653 | int ypos = m_lyrics_too_wide ? 0 : |
| | 654 | (m_size.height() - m_image.height()) / 2; |
| | 655 | p->drawPixmap(xpos, ypos, m_image); |
| | 656 | } |
| | 657 | |
| | 658 | // Paint the Lyrics |
| | 659 | p->setFont(gContext->GetMediumFont()); |
| | 660 | if (m_lyrics_too_wide) |
| | 661 | { |
| | 662 | // Lyrics are too wide to fit on the display. Just write "Lyrics" |
| | 663 | // at the bottom on the display to indicate they are available. |
| | 664 | QFontMetrics fm(p->font()); |
| | 665 | QString l = "Lyrics"; |
| | 666 | int width = fm.width(l); |
| | 667 | int height = m_font_height; |
| | 668 | int x = m_size.width() / 2 - width / 2; |
| | 669 | int y = m_size.height() - height; |
| | 670 | p->setPen(Qt::white); |
| | 671 | p->drawText(x, y, width, height, Qt::AlignCenter, l); |
| | 672 | } |
| | 673 | else |
| | 674 | { |
| | 675 | int textWidth = m_max_line_width; |
| | 676 | int textHeight = m_font_height * m_lyrics.size(); |
| | 677 | int x = m_size.width() - m_max_line_width - m_indentx; |
| | 678 | int y = m_indenty; |
| | 679 | |
| | 680 | int line = m_start; |
| | 681 | for (int offset = 0; |
| | 682 | line <= m_start + m_visible_lines-1 && line < int(m_lyrics.size()); |
| | 683 | offset += m_font_height, line++) |
| | 684 | { |
| | 685 | QString l = m_lyrics[line] + "\n"; |
| | 686 | p->setPen(Qt::white); |
| | 687 | p->drawText(x, y + offset, textWidth, textHeight, Qt::AlignLeft, l); |
| | 688 | } |
| | 689 | } |
| | 690 | |
| | 691 | // Store our new size |
| | 692 | m_cursize = m_size; |
| | 693 | |
| | 694 | return true; |
| | 695 | } |
| | 696 | |
| | 697 | static class LyricsFactory : public VisFactory |
| | 698 | { |
| | 699 | public: |
| | 700 | const QString &name(void) const |
| | 701 | { |
| | 702 | static QString name("Lyrics"); |
| | 703 | return name; |
| | 704 | } |
| | 705 | |
| | 706 | uint plugins(QStringList *list) const |
| | 707 | { |
| | 708 | *list << name(); |
| | 709 | return 1; |
| | 710 | } |
| | 711 | |
| | 712 | VisualBase *create(MainVisual *parent, long int winid, const QString &pluginName) const |
| | 713 | { |
| | 714 | (void)winid; |
| | 715 | (void)pluginName; |
| | 716 | return new Lyrics(parent); |
| | 717 | } |
| | 718 | }LyricsFactory; |
| | 719 | |