File indexing completed on 2025-01-05 04:25:41

0001 /*
0002  * Copyright (c) 2003-2005 Max Howell <max.howell@methylblue.com>
0003  * Copyright (c) 2005-2013 Mark Kretschmann <kretschmann@kde.org>
0004  * Copyright 2017 Malte Veerman <malte.veerman@gmail.com>
0005  *
0006  * This program is free software; you can redistribute it and/or
0007  * modify it under the terms of the GNU General Public License as
0008  * published by the Free Software Foundation; either version 2 of
0009  * the License or (at your option) version 3 or any later version
0010  * accepted by the membership of KDE e.V. (or its successor approved
0011  * by the membership of KDE e.V.), which shall act as a proxy
0012  * defined in Section 14 of version 3 of the license.
0013  *
0014  * This program is distributed in the hope that it will be useful,
0015  * but WITHOUT ANY WARRANTY; without even the implied warranty of
0016  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
0017  * GNU General Public License for more details.
0018  *
0019  * You should have received a copy of the GNU General Public License
0020  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
0021  *
0022  */
0023 
0024 #ifndef BLOCKRENDERER_H
0025 #define BLOCKRENDERER_H
0026 
0027 #include "BlockAnalyzer.h"
0028 #include "BlockWorker.h"
0029 
0030 #include <QOpenGLFramebufferObject>
0031 #include <QOpenGLPaintDevice>
0032 #include <QPainter>
0033 #include <QPointer>
0034 #include <QQuickFramebufferObject>
0035 
0036 
0037 class BlockRenderer : public QQuickFramebufferObject::Renderer
0038 {
0039 public:
0040     static const int BLOCK_HEIGHT = BlockAnalyzer::BLOCK_HEIGHT;
0041 
0042     BlockRenderer() : m_worker( nullptr ) {}
0043 
0044 protected:
0045     QOpenGLFramebufferObject* createFramebufferObject(const QSize &size) override
0046     {
0047         QOpenGLFramebufferObject* fo = new QOpenGLFramebufferObject(size);
0048         fo->setAttachment(QOpenGLFramebufferObject::CombinedDepthStencil);
0049         return fo;
0050     }
0051 
0052     void render() override
0053     {
0054         // Synchronize worker data
0055         if (!m_worker)
0056             return;
0057 
0058         m_worker->m_mutex.lock();
0059         const QVector<double> store = m_worker->m_store;
0060         const QVector<QList<BlockWorker::Fadebar> > fadebars = m_worker->m_fadebars;
0061         m_worker->m_mutex.unlock();
0062 
0063         QOpenGLPaintDevice d;
0064         d.setSize(framebufferObject()->size());
0065         QPainter p(&d);
0066 
0067         // Draw the background
0068         p.drawPixmap(QRect(QPoint(0, 0), framebufferObject()->size()), m_backgroundPixmap);
0069 
0070         for(uint x = 0; x < (uint)store.size(); ++x)
0071         {
0072             // Draw fade bars
0073             for(const auto &fadebar : qAsConst(fadebars.at(x)))
0074             {
0075                 if(fadebar.intensity > 0)
0076                 {
0077                     const uint offset = fadebar.intensity;
0078                     const int fadeHeight = fadebar.y * (BLOCK_HEIGHT + 1);
0079                     if(fadeHeight > 0)
0080                         p.drawPixmap(x * (m_columnWidth + 1), 0, m_fadeBarsPixmaps.value(offset), 0, 0, m_columnWidth, fadeHeight);
0081                 }
0082             }
0083 
0084             // Draw bars
0085             const int height = store.at(x) * (BLOCK_HEIGHT + 1);
0086             if (height > 0)
0087                 p.drawPixmap(x * (m_columnWidth + 1), 0, m_barPixmap, 0, 0, m_columnWidth, height);
0088 
0089             // Draw top bar
0090             p.drawPixmap(x * (m_columnWidth + 1), height + BLOCK_HEIGHT - 1, m_topBarPixmap);
0091         }
0092     }
0093 
0094     void synchronize(QQuickFramebufferObject *item) override
0095     {
0096         auto analyzer = qobject_cast<BlockAnalyzer*>(item);
0097         if (!analyzer)
0098             return;
0099 
0100         m_rows = analyzer->m_rows;
0101         m_columnWidth = analyzer->m_columnWidth;
0102 
0103         if (!m_worker)
0104             m_worker = qobject_cast<const BlockWorker*>(analyzer->worker());
0105 
0106         if (analyzer->m_pixmapsChanged)
0107         {
0108             m_barPixmap = analyzer->m_barPixmap;
0109             m_topBarPixmap = analyzer->m_topBarPixmap;
0110             m_backgroundPixmap = analyzer->m_backgroundPixmap;
0111             m_fadeBarsPixmaps = analyzer->m_fadeBarsPixmaps;
0112 
0113             analyzer->m_pixmapsChanged = false;
0114         }
0115     }
0116 
0117 private:
0118     QPointer<const BlockWorker> m_worker;
0119 
0120     int m_rows;
0121     int m_columnWidth;
0122 
0123     QPixmap m_barPixmap;
0124     QPixmap m_topBarPixmap;
0125     QPixmap m_backgroundPixmap;
0126     QVector<QPixmap> m_fadeBarsPixmaps;
0127 };
0128 
0129 #endif //BLOCKRENDERER_H