diff options
Diffstat (limited to 'src/plugins/Ui/skinned/textscroller.cpp')
| -rw-r--r-- | src/plugins/Ui/skinned/textscroller.cpp | 314 |
1 files changed, 314 insertions, 0 deletions
diff --git a/src/plugins/Ui/skinned/textscroller.cpp b/src/plugins/Ui/skinned/textscroller.cpp new file mode 100644 index 000000000..1fac2a753 --- /dev/null +++ b/src/plugins/Ui/skinned/textscroller.cpp @@ -0,0 +1,314 @@ +/*************************************************************************** + * Copyright (C) 2006-2011 by Ilya Kotov * + * forkotov02@hotmail.ru * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program; if not, write to the * + * Free Software Foundation, Inc., * + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * + ***************************************************************************/ +#include <QPainter> +#include <QTimer> +#include <QSettings> +#include <QAction> +#include <QMenu> +#include <QMouseEvent> +#include <QSettings> +#include <qmmp/qmmp.h> +#include <qmmp/soundcore.h> +#include <qmmpui/metadataformatter.h> +#include "skin.h" +#include "textscroller.h" + +#define SCROLL_SEP " *** " +#define TITLE_FORMAT "%if(%p&%t,%p - %t,%p%t)%if(%p&%t,,%f)%if(%l, - %l,)" + +TextScroller::TextScroller (QWidget *parent) + : QWidget (parent) +{ + m_pressed = false; + m_press_pos = 0; + m_metrics = 0; + m_defautText = QString("Qmmp ") + Qmmp::strVersion(); + m_core = SoundCore::instance(); + m_skin = Skin::instance(); + m_ratio = m_skin->ratio(); + + m_timer = new QTimer (this); + m_timer->setInterval(50); + m_timer->start(); + + m_menu = new QMenu(this); + m_scrollAction = m_menu->addAction(tr("Autoscroll Songname")); + m_scrollAction->setCheckable(true); + connect(m_scrollAction, SIGNAL(toggled(bool)), SLOT(updateText())); + connect(m_timer, SIGNAL (timeout()), SLOT (addOffset())); + connect(m_skin, SIGNAL(skinChanged()), SLOT(updateSkin())); + connect(m_core, SIGNAL(stateChanged(Qmmp::State)), SLOT(processState(Qmmp::State))); + connect(m_core, SIGNAL(metaDataChanged()), SLOT(processMetaData())); + //readSettings(); + updateSkin(); +} + +TextScroller::~TextScroller() +{ + QSettings settings(Qmmp::configFile(), QSettings::IniFormat); + settings.setValue("TextScroller/autoscroll", m_scrollAction->isChecked()); + if(m_metrics) + delete m_metrics; +} + +void TextScroller::setText(const QString &text) +{ + m_sliderText = text; + updateText(); +} + +void TextScroller::clear() +{ + setText(QString()); +} + +void TextScroller::addOffset() +{ + if(!m_scroll) + { + m_timer->stop(); + return; + } + m_x1--; + m_x2--; + if(m_x1 < - m_pixmap.width()) + m_x1 = m_pixmap.width(); + if(m_x2 < - m_pixmap.width()) + m_x2 = m_pixmap.width(); + update(); +} + +void TextScroller::updateSkin() +{ + m_color.setNamedColor(m_skin->getPLValue("mbfg")); + setCursor(m_skin->getCursor(Skin::CUR_SONGNAME)); + QSettings settings(Qmmp::configFile(), QSettings::IniFormat); + m_bitmap = settings.value("MainWindow/bitmap_font", false).toBool(); + m_ratio = m_skin->ratio(); + QString fontname = settings.value("MainWindow/Font").toString(); + m_font.fromString(fontname); + if (m_metrics) + delete m_metrics; + else + m_scrollAction->setChecked(settings.value("TextScroller/autoscroll", true).toBool()); + m_metrics = new QFontMetrics(m_font); + updateText(); +} + +void TextScroller::setProgress(int progress) +{ + m_bufferText = tr("Buffering: %1%").arg(progress); + updateText(); +} + +void TextScroller::hideEvent (QHideEvent *) +{ + m_timer->stop(); +} + +void TextScroller::showEvent (QShowEvent *) +{ + if (m_scroll) + m_timer->start(); +} + +inline void drawBitmapText(int x, int y, const QString &text, QPainter *paint, Skin *skin) +{ + QString lowertext = text.toLower(); + int chwidth, ypix; + { + QPixmap samplechar = skin->getLetter('a'); + chwidth = samplechar.width(); + ypix = y - samplechar.height(); + } + for (int i = 0; i < lowertext.size(); i++) + { + QPixmap pixchar = skin->getLetter(lowertext[i]); + paint->drawPixmap(x, ypix, pixchar); + x += chwidth; + } +} + +void TextScroller::paintEvent (QPaintEvent *) +{ + QPainter paint(this); + if(m_scroll) + { + paint.drawPixmap(m_x1,0, m_pixmap); + paint.drawPixmap(m_x2,0, m_pixmap); + } + else + paint.drawPixmap(4,0, m_pixmap); +} + +void TextScroller::mousePressEvent (QMouseEvent *e) +{ + if (e->button() == Qt::RightButton) + m_menu->exec(e->globalPos()); + else if (e->button() == Qt::LeftButton && m_scroll) + { + m_timer->stop(); + m_press_pos = e->x() - m_x1; + m_pressed = true; + } + else + QWidget::mousePressEvent(e); +} + +void TextScroller::mouseReleaseEvent (QMouseEvent *e) +{ + if(e->button() == Qt::RightButton) + m_menu->exec(e->globalPos()); + else if (e->button() == Qt::LeftButton && m_scroll) + m_timer->start(); + else + QWidget::mouseReleaseEvent(e); + m_pressed = false; +} + +void TextScroller::mouseMoveEvent (QMouseEvent *e) +{ + if (m_pressed) + { + int bound = m_pixmap.width(); + m_x1 = (e->x() - m_press_pos) % bound; + if (m_x1 > 0) + m_x1 -= bound; + m_x2 = m_x1 + m_pixmap.width(); + update(); + } + else + QWidget::mouseMoveEvent(e); +} + +void TextScroller::processState(Qmmp::State state) +{ + switch(state) + { + case Qmmp::Buffering: + { + connect(m_core, SIGNAL(bufferingProgress(int)), SLOT(setProgress(int))); + break; + } + case Qmmp::Playing: + { + disconnect(m_core, SIGNAL(bufferingProgress(int)), this, 0); + m_bufferText.clear(); + updateText(); + break; + } + case Qmmp::Paused: + { + break; + } + case Qmmp::Stopped: + { + m_bufferText.clear(); + m_titleText.clear(); + updateText(); + break; + } + default: + break; + } +} + +void TextScroller::processMetaData() +{ + MetaDataFormatter formater(TITLE_FORMAT); + if(m_core->state() == Qmmp::Playing) + { + m_titleText = formater.parse(m_core->metaData(), m_core->totalTime()/1000); + updateText(); + } +} + +void TextScroller::preparePixmap(const QString &text, bool scrollable) +{ + m_scroll = scrollable; + bool bitmap = m_bitmap && (text.toLatin1() == text.toLocal8Bit()); //use bitmap font if possible + if(scrollable) + { + int textWidth = m_bitmap ? QString(text + SCROLL_SEP).size() * 5 + : m_metrics->width(text + SCROLL_SEP); + int count = 150*m_ratio / textWidth + 1; + int width = count * textWidth; + QString fullText; + for(int i = 0; i < count; ++i) + { + fullText.append(text + SCROLL_SEP); + } + m_pixmap = QPixmap(width,15*m_ratio); + m_pixmap.fill(Qt::transparent); + QPainter painter(&m_pixmap); + painter.setPen(m_color); + painter.setFont(m_font); + if(m_bitmap) + drawBitmapText (0,12, fullText, &painter, m_skin); + else + painter.drawText (0,12, fullText); + m_x1 = 0; + m_x2 = m_pixmap.width(); + } + else + { + m_pixmap = QPixmap(150*m_ratio,15*m_ratio); + m_pixmap.fill(Qt::transparent); + QPainter painter(&m_pixmap); + painter.setPen(m_color); + painter.setFont(m_font); + if(bitmap) + drawBitmapText (0,12, text, &painter, m_skin); + else + painter.drawText (0,12, text); + } +} + +void TextScroller::updateText() //draw text according priority +{ + if(!m_sliderText.isEmpty()) + { + preparePixmap(m_sliderText); + m_timer->stop(); + } + else if(!m_bufferText.isEmpty()) + { + preparePixmap(m_bufferText); + m_timer->stop(); + } + else if (!m_titleText.isEmpty()) + { + preparePixmap(m_titleText, m_scrollAction->isChecked()); + m_timer->start(); + } + else if(!m_defautText.isEmpty()) + { + preparePixmap(m_defautText); + m_timer->stop(); + } + else + { + m_timer->stop(); + m_pixmap = QPixmap (150*m_ratio,15*m_ratio); + m_pixmap.fill(Qt::transparent); + m_scroll = false; + } + update(); +} |
