From befadabc2f18b483c71250adfd7dbf42f66b16f0 Mon Sep 17 00:00:00 2001
From: Tom Rondeau <trondeau@vt.edu>
Date: Sun, 27 Mar 2011 12:55:16 -0400
Subject: gr-qtgui: restructuring qtgui directory to new layout.

---
 gr-qtgui/lib/plot_waterfall.cc | 325 +++++++++++++++++++++++++++++++++++++++++
 1 file changed, 325 insertions(+)
 create mode 100644 gr-qtgui/lib/plot_waterfall.cc

(limited to 'gr-qtgui/lib/plot_waterfall.cc')

diff --git a/gr-qtgui/lib/plot_waterfall.cc b/gr-qtgui/lib/plot_waterfall.cc
new file mode 100644
index 0000000000..2b1447e031
--- /dev/null
+++ b/gr-qtgui/lib/plot_waterfall.cc
@@ -0,0 +1,325 @@
+#include <qimage.h>
+#include <qpen.h>
+#include <qpainter.h>
+#include "qwt_painter.h"
+#include "qwt_double_interval.h"
+#include "qwt_scale_map.h"
+#include "qwt_color_map.h"
+#include "plot_waterfall.h"
+
+#if QT_VERSION < 0x040000
+typedef Q3ValueVector<QRgb> QwtColorTable;
+#else
+typedef QVector<QRgb> QwtColorTable;
+#endif
+
+
+class PlotWaterfallImage: public QImage
+{
+    // This class hides some Qt3/Qt4 API differences
+public:
+    PlotWaterfallImage(const QSize &size, QwtColorMap::Format format):
+#if QT_VERSION < 0x040000
+        QImage(size, format == QwtColorMap::RGB ? 32 : 8)
+#else
+        QImage(size, format == QwtColorMap::RGB
+	       ? QImage::Format_ARGB32 : QImage::Format_Indexed8 )
+#endif
+	{
+	}
+
+    PlotWaterfallImage(const QImage &other):
+        QImage(other)
+	{
+	}
+
+    void initColorTable(const QImage& other)
+	{
+#if QT_VERSION < 0x040000
+	    const unsigned int numColors = other.numColors();
+
+	    setNumColors(numColors);
+	    for ( unsigned int i = 0; i < numColors; i++ )
+		setColor(i, other.color(i));
+#else
+	    setColorTable(other.colorTable());
+#endif
+	}
+
+#if QT_VERSION < 0x040000
+
+    void setColorTable(const QwtColorTable &colorTable)
+	{
+	    setNumColors(colorTable.size());
+	    for ( unsigned int i = 0; i < colorTable.size(); i++ )
+		setColor(i, colorTable[i]);
+	}
+
+    QwtColorTable colorTable() const
+	{
+	    QwtColorTable table(numColors());
+	    for ( int i = 0; i < numColors(); i++ )
+		table[i] = color(i);
+
+	    return table;
+	}
+#endif
+};
+
+class PlotWaterfall::PrivateData
+{
+public:
+    PrivateData()
+	{
+	    data = NULL;
+	    colorMap = new QwtLinearColorMap();
+	}
+    ~PrivateData()
+	{
+	    delete colorMap;
+	}
+
+    WaterfallData *data;
+    QwtColorMap *colorMap;
+};
+
+/*!
+  Sets the following item attributes:
+  - QwtPlotItem::AutoScale: true
+  - QwtPlotItem::Legend:    false
+
+  The z value is initialized by 8.0.
+   
+  \param title Title
+
+  \sa QwtPlotItem::setItemAttribute(), QwtPlotItem::setZ()
+*/
+PlotWaterfall::PlotWaterfall(WaterfallData* data, const QString &title):
+    QwtPlotRasterItem(title)
+{
+    d_data = new PrivateData();
+    d_data->data = data;
+
+//    setCachePolicy(QwtPlotRasterItem::PaintCache);
+
+    setItemAttribute(QwtPlotItem::AutoScale, true);
+    setItemAttribute(QwtPlotItem::Legend, false);
+
+    setZ(8.0);
+}
+
+//! Destructor
+PlotWaterfall::~PlotWaterfall()
+{
+    delete d_data;
+}
+
+const WaterfallData* PlotWaterfall::data()const{
+    return d_data->data;
+}
+
+//! \return QwtPlotItem::Rtti_PlotSpectrogram
+int PlotWaterfall::rtti() const
+{
+    return QwtPlotItem::Rtti_PlotSpectrogram;
+}
+
+/*!
+  Change the color map
+
+  Often it is useful to display the mapping between intensities and
+  colors as an additional plot axis, showing a color bar.
+
+  \param colorMap Color Map
+
+  \sa colorMap(), QwtScaleWidget::setColorBarEnabled(),
+  QwtScaleWidget::setColorMap()
+*/
+void PlotWaterfall::setColorMap(const QwtColorMap &colorMap)
+{
+    delete d_data->colorMap;
+    d_data->colorMap = colorMap.copy();
+
+    invalidateCache();
+    itemChanged();
+}
+
+/*!
+  \return Color Map used for mapping the intensity values to colors
+  \sa setColorMap()
+*/
+const QwtColorMap &PlotWaterfall::colorMap() const
+{
+    return *d_data->colorMap;
+}
+/*!
+  \return Bounding rect of the data
+  \sa QwtRasterData::boundingRect
+*/
+QwtDoubleRect PlotWaterfall::boundingRect() const
+{
+    return d_data->data->boundingRect();
+}
+
+/*!
+  \brief Returns the recommended raster for a given rect.
+
+  F.e the raster hint is used to limit the resolution of
+  the image that is rendered.
+
+  \param rect Rect for the raster hint
+  \return data().rasterHint(rect)
+*/
+QSize PlotWaterfall::rasterHint(const QwtDoubleRect &rect) const
+{
+    return d_data->data->rasterHint(rect);
+}
+
+/*!
+  \brief Render an image from the data and color map.
+
+  The area is translated into a rect of the paint device. 
+  For each pixel of this rect the intensity is mapped
+  into a color.
+
+  \param xMap X-Scale Map
+  \param yMap Y-Scale Map
+  \param area Area that should be rendered in scale coordinates.
+
+  \return A QImage::Format_Indexed8 or QImage::Format_ARGB32 depending 
+  on the color map.
+
+  \sa QwtRasterData::intensity(), QwtColorMap::rgb(),
+  QwtColorMap::colorIndex()
+*/
+QImage PlotWaterfall::renderImage(
+    const QwtScaleMap &xMap, const QwtScaleMap &yMap, 
+    const QwtDoubleRect &area) const
+{
+    if ( area.isEmpty() )
+        return QImage();
+
+    QRect rect = transform(xMap, yMap, area);
+
+    QwtScaleMap xxMap = xMap;
+    QwtScaleMap yyMap = yMap;
+
+    const QSize res = d_data->data->rasterHint(area);
+    if ( res.isValid() )
+    {
+        /*
+          It is useless to render an image with a higher resolution
+          than the data offers. Of course someone will have to
+          scale this image later into the size of the given rect, but f.e.
+          in case of postscript this will done on the printer.
+	*/
+        rect.setSize(rect.size().boundedTo(res));
+
+        int px1 = rect.x();
+        int px2 = rect.x() + rect.width();
+        if ( xMap.p1() > xMap.p2() )
+            qSwap(px1, px2);
+
+        double sx1 = area.x();
+        double sx2 = area.x() + area.width();
+        if ( xMap.s1() > xMap.s2() )
+            qSwap(sx1, sx2);
+
+        int py1 = rect.y();
+        int py2 = rect.y() + rect.height();
+        if ( yMap.p1() > yMap.p2() )
+            qSwap(py1, py2);
+
+        double sy1 = area.y();
+        double sy2 = area.y() + area.height();
+        if ( yMap.s1() > yMap.s2() )
+            qSwap(sy1, sy2);
+
+        xxMap.setPaintInterval(px1, px2);
+        xxMap.setScaleInterval(sx1, sx2);
+        yyMap.setPaintInterval(py1, py2);
+        yyMap.setScaleInterval(sy1, sy2); 
+    }
+
+    PlotWaterfallImage image(rect.size(), d_data->colorMap->format());
+
+    const QwtDoubleInterval intensityRange = d_data->data->range();
+    if ( !intensityRange.isValid() )
+        return image;
+
+    d_data->data->initRaster(area, rect.size());
+
+    if ( d_data->colorMap->format() == QwtColorMap::RGB )
+    {
+        for ( int y = rect.top(); y <= rect.bottom(); y++ )
+        {
+            const double ty = yyMap.invTransform(y);
+
+            QRgb *line = (QRgb *)image.scanLine(y - rect.top());
+            for ( int x = rect.left(); x <= rect.right(); x++ )
+            {
+                const double tx = xxMap.invTransform(x);
+
+                *line++ = d_data->colorMap->rgb(intensityRange,
+						d_data->data->value(tx, ty));
+            }
+        }
+    }
+    else if ( d_data->colorMap->format() == QwtColorMap::Indexed )
+    {
+        image.setColorTable(d_data->colorMap->colorTable(intensityRange));
+
+        for ( int y = rect.top(); y <= rect.bottom(); y++ )
+        {
+            const double ty = yyMap.invTransform(y);
+
+            unsigned char *line = image.scanLine(y - rect.top());
+            for ( int x = rect.left(); x <= rect.right(); x++ )
+            {
+                const double tx = xxMap.invTransform(x);
+
+                *line++ = d_data->colorMap->colorIndex(intensityRange,
+						       d_data->data->value(tx, ty));
+            }
+        }
+    }
+
+    d_data->data->discardRaster();
+
+    // Mirror the image in case of inverted maps
+
+    const bool hInvert = xxMap.p1() > xxMap.p2();
+    const bool vInvert = yyMap.p1() < yyMap.p2();
+    if ( hInvert || vInvert )
+    {
+#ifdef __GNUC__
+#endif
+#if QT_VERSION < 0x040000
+        image = image.mirror(hInvert, vInvert);
+#else
+        image = image.mirrored(hInvert, vInvert);
+#endif
+    }
+
+    return image;
+}
+
+/*!
+  \brief Draw the spectrogram
+
+  \param painter Painter
+  \param xMap Maps x-values into pixel coordinates.
+  \param yMap Maps y-values into pixel coordinates.
+  \param canvasRect Contents rect of the canvas in painter coordinates 
+
+  \sa setDisplayMode, renderImage, 
+  QwtPlotRasterItem::draw, drawContourLines
+*/
+
+void PlotWaterfall::draw(QPainter *painter,
+			 const QwtScaleMap &xMap, const QwtScaleMap &yMap,
+			 const QRect &canvasRect) const
+{
+    QwtPlotRasterItem::draw(painter, xMap, yMap, canvasRect);
+}
+
-- 
cgit v1.2.3