diff options
Diffstat (limited to 'src/widgets')
-rw-r--r-- | src/widgets/scrolltext/scrolltext.cpp | 179 | ||||
-rw-r--r-- | src/widgets/scrolltext/scrolltext.h | 53 |
2 files changed, 232 insertions, 0 deletions
diff --git a/src/widgets/scrolltext/scrolltext.cpp b/src/widgets/scrolltext/scrolltext.cpp new file mode 100644 index 0000000..00696af --- /dev/null +++ b/src/widgets/scrolltext/scrolltext.cpp @@ -0,0 +1,179 @@ +#include "scrolltext.h" +#include <QPainter> +#include <QHoverEvent> + +ScrollText::ScrollText(QWidget *parent) : + QWidget(parent), scrollPos(0) +{ + + staticText.setTextFormat(Qt::PlainText); + + setSizePolicy(QSizePolicy::Expanding,QSizePolicy::Expanding); + + setMinimumHeight(fontMetrics().height()+10); + setMaximumHeight(this->minimumHeight()+6); + + leftMargin = 0; //height() / 3; + + setSeparator(" "); + + connect(&timer, SIGNAL(timeout()), this, SLOT(timer_timeout())); + timer.setInterval(50); +} + +QString ScrollText::text() const +{ + return _text; +} + +void ScrollText::setText(QString text) +{ + _text = text; + updateText(); + update(); +} + +QString ScrollText::separator() const +{ + return _separator; +} + +void ScrollText::setSeparator(QString separator) +{ + _separator = separator; + updateText(); + update(); +} + +void ScrollText::setLeftMargin(int pixels) +{ + leftMargin = pixels; + update(); +} + +void ScrollText::pause() +{ + if(scrollEnabled){ + timer.stop(); + } +} + +void ScrollText::resume() +{ + if(scrollEnabled){ + timer.start(); + scrolledOnce = false; + } +} + +void ScrollText::updateText() +{ + scrolledOnce = false; + timer.stop(); + + singleTextWidth = fontMetrics().horizontalAdvance(_text); +// scrollEnabled = true; + scrollEnabled = (singleTextWidth > width() - leftMargin); + + if(scrollEnabled) + { + scrollPos = -64; + staticText.setText(_text + _separator); + timer.start(); + } + else{ + staticText.setText(_text); + } + staticText.prepare(QTransform(), font()); + //wholeTextSize = QSize(fontMetrics().width(staticText.text()), fontMetrics().height()); + wholeTextSize = QSize(fontMetrics().horizontalAdvance(staticText.text()), fontMetrics().height()); + +} + +void ScrollText::paintEvent(QPaintEvent*) +{ + QPainter p(this); + + if(scrollEnabled) + { + buffer.fill(qRgba(0, 0, 0, 0)); + QPainter pb(&buffer); + pb.setPen(p.pen()); + pb.setFont(p.font()); + + int x = qMin(-scrollPos, 0) + leftMargin; + while(x < width()) + { + pb.drawStaticText(QPointF(x, (height() - wholeTextSize.height()) / 2) + QPoint(2, 2), staticText); + x += wholeTextSize.width(); + } + + //Apply Alpha Channel + pb.setCompositionMode(QPainter::CompositionMode_DestinationIn); + pb.setClipRect(width() - 15, 0, 15, height()); + pb.drawImage(0, 0, alphaChannel); + pb.setClipRect(0, 0, 15, height()); + //initial situation: don't apply alpha channel in the left half of the image at all; apply it more and more until scrollPos gets positive + if(scrollPos < 0) + pb.setOpacity((qreal)(qMax(-8, scrollPos) + 8) / 8.0); + pb.drawImage(0, 0, alphaChannel); + p.drawImage(0, 0, buffer); + } + else + { + p.drawText(QRectF(0, 0, width(), height()), Qt::AlignCenter, text()); +// p.drawStaticText(QPointF(leftMargin, (height() - wholeTextSize.height()) / 2), staticText); + } +} + +void ScrollText::resizeEvent(QResizeEvent*) +{ + //When the widget is resized, we need to update the alpha channel. + + alphaChannel = QImage(size(), QImage::Format_ARGB32_Premultiplied); + buffer = QImage(size(), QImage::Format_ARGB32_Premultiplied); + + //Create Alpha Channel: + if(width() > 64) + { + //create first scanline + QRgb* scanline1 = (QRgb*)alphaChannel.scanLine(0); + for(int x = 1; x < 16; ++x) + scanline1[x - 1] = scanline1[width() - x] = qRgba(0, 0, 0, x << 4); + for(int x = 15; x < width() - 15; ++x) + scanline1[x] = qRgb(0, 0, 0); + //copy scanline to the other ones + for(int y = 1; y < height(); ++y) + memcpy(alphaChannel.scanLine(y), (uchar*)scanline1, width() * 4); + } + else + alphaChannel.fill(qRgb(0, 0, 0)); + + + //Update scrolling state + bool newScrollEnabled = (singleTextWidth > width() - leftMargin); + if(newScrollEnabled != scrollEnabled) + updateText(); +} + +void ScrollText::timer_timeout() +{ + scrollPos = (scrollPos + 2) + % wholeTextSize.width(); + pauseAfterOneRotation(scrollPos); + update(); +} + +void ScrollText::pauseAfterOneRotation(int scrollPos) +{ + if(scrolledOnce == false && scrollPos+2==wholeTextSize.width()){ + scrolledOnce = true; + } + if(scrolledOnce){ + pause(); + } +} + + + + diff --git a/src/widgets/scrolltext/scrolltext.h b/src/widgets/scrolltext/scrolltext.h new file mode 100644 index 0000000..a660615 --- /dev/null +++ b/src/widgets/scrolltext/scrolltext.h @@ -0,0 +1,53 @@ +#ifndef SCROLLTEXT_H +#define SCROLLTEXT_H + +#include <QWidget> +#include <QStaticText> +#include <QTimer> + + +class ScrollText : public QWidget +{ + Q_OBJECT + Q_PROPERTY(QString text READ text WRITE setText) + Q_PROPERTY(QString separator READ separator WRITE setSeparator) + +public: + explicit ScrollText(QWidget *parent = 0); + +public slots: + QString text() const; + void setText(QString text); + + QString separator() const; + void setSeparator(QString separator); + void setLeftMargin(int pixels); + void pause(); + void resume(); + + +protected: + virtual void paintEvent(QPaintEvent *); + virtual void resizeEvent(QResizeEvent *); + +private: + void updateText(); + QString _text; + QString _separator; + QStaticText staticText; + int singleTextWidth; + QSize wholeTextSize; + int leftMargin; + bool scrollEnabled; + int scrollPos; + QImage alphaChannel; + QImage buffer; + QTimer timer; + bool scrolledOnce = false; + +private slots: + virtual void timer_timeout(); + void pauseAfterOneRotation(int scrollPos); +}; + +#endif // SCROLLTEXT_H |