From 9ff1e9c4ca79af6d78f1939bb95d387e9168984c Mon Sep 17 00:00:00 2001 From: drowe67 Date: Fri, 19 Oct 2012 23:22:35 +0000 Subject: [PATCH] bitmap test pattern working git-svn-id: https://svn.code.sf.net/p/freetel/code@781 01035d8c-6547-0410-b346-abe4f91aad63 --- fdmdv2/src/Makefile.linux | 2 +- fdmdv2/src/fdmdv2_main.cpp | 4 +- fdmdv2/src/fdmdv2_main.h | 4 + fdmdv2/src/fdmdv2_plot.cpp | 6 + fdmdv2/src/fdmdv2_plot_waterfall_linux.cpp | 474 +++++++++++++++++++++ fdmdv2/src/fdmdv2_plot_waterfall_linux.h | 75 ++++ 6 files changed, 562 insertions(+), 3 deletions(-) create mode 100644 fdmdv2/src/fdmdv2_plot_waterfall_linux.cpp create mode 100644 fdmdv2/src/fdmdv2_plot_waterfall_linux.h diff --git a/fdmdv2/src/Makefile.linux b/fdmdv2/src/Makefile.linux index 96d5318a..75f92a55 100644 --- a/fdmdv2/src/Makefile.linux +++ b/fdmdv2/src/Makefile.linux @@ -23,7 +23,7 @@ fdmdv2_plot.o \ fdmdv2_plot_scalar.o \ fdmdv2_plot_scatter.o \ fdmdv2_plot_spectrum.o \ -fdmdv2_plot_waterfall.o \ +fdmdv2_plot_waterfall_linux.o \ fdmdv2_pa_wrapper.o \ dlg_about.o \ dlg_audio.o \ diff --git a/fdmdv2/src/fdmdv2_main.cpp b/fdmdv2/src/fdmdv2_main.cpp index 9634ec46..0ca6a000 100644 --- a/fdmdv2/src/fdmdv2_main.cpp +++ b/fdmdv2/src/fdmdv2_main.cpp @@ -244,8 +244,8 @@ void MainFrame::OnTimer(wxTimerEvent &evt) { m_panelWaterfall->m_newdata = true; m_panelWaterfall->Refresh(); - m_panelSpectrum->m_newdata = true; - m_panelSpectrum->Refresh(); + //m_panelSpectrum->m_newdata = true; + //m_panelSpectrum->Refresh(); } #endif diff --git a/fdmdv2/src/fdmdv2_main.h b/fdmdv2/src/fdmdv2_main.h index f269f71a..117970f4 100644 --- a/fdmdv2/src/fdmdv2_main.h +++ b/fdmdv2/src/fdmdv2_main.h @@ -40,7 +40,11 @@ #include "fdmdv2_plot.h" #include "fdmdv2_plot_scalar.h" #include "fdmdv2_plot_scatter.h" +#ifdef __LINUX__ +#include "fdmdv2_plot_waterfall_linux.h" +#else #include "fdmdv2_plot_waterfall.h" +#endif #include "fdmdv2_plot_spectrum.h" #include "fdmdv2_pa_wrapper.h" #include "sndfile.h" diff --git a/fdmdv2/src/fdmdv2_plot.cpp b/fdmdv2/src/fdmdv2_plot.cpp index 5406394b..1dc1b3ba 100644 --- a/fdmdv2/src/fdmdv2_plot.cpp +++ b/fdmdv2/src/fdmdv2_plot.cpp @@ -106,10 +106,12 @@ void PlotPanel::OnErase(wxEraseEvent& event) //------------------------------------------------------------------------- void PlotPanel::OnSize(wxSizeEvent& event) { + printf("PlotPanel::OnSize\n"); m_rCtrlPrev = m_rCtrl; m_rCtrl = GetClientRect(); if(m_use_bitmap) { + printf(" m_use_bitmap\n"); if(!m_oImage.IsOk()) { m_oImage.Create(m_rCtrl.GetWidth(), m_rCtrl.GetHeight(), true); @@ -119,6 +121,10 @@ void PlotPanel::OnSize(wxSizeEvent& event) m_oImage.Rescale(m_rCtrl.GetWidth(), m_rCtrl.GetHeight()); } m_pBmp = new wxBitmap(m_oImage, wxBITMAP_SCREEN_DEPTH); + //m_pBmp = new wxBitmap(m_rCtrl.GetWidth(), m_rCtrl.GetHeight(), 24); + + printf(" create bitmap m_pBmp 0x%x width: %d height: %d\n", + (unsigned int)m_pBmp, m_rCtrl.GetWidth(), m_rCtrl.GetHeight()); m_firstPass = true; } this->Refresh(); diff --git a/fdmdv2/src/fdmdv2_plot_waterfall_linux.cpp b/fdmdv2/src/fdmdv2_plot_waterfall_linux.cpp new file mode 100644 index 00000000..8b01e5d4 --- /dev/null +++ b/fdmdv2/src/fdmdv2_plot_waterfall_linux.cpp @@ -0,0 +1,474 @@ +//========================================================================== +// Name: fdmdv2_plot_waterfall.cpp +// Purpose: Implements a waterfall plot derivative of fdmdv2_plot. +// Created: June 22, 2012 +// Initial author: David Witten +// Derived from: code written by David Rowe +// License: +// +// Copyright (C) 2012 David Witten +// +// All rights reserved. +// +// This program is free software; you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License version 2.1, +// as published by the Free Software Foundation. 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 Lesser General Public License +// along with this program; if not, see . +// +//========================================================================== +#include +#include "wx/wx.h" +#include "fdmdv2_main.h" +#include "fdmdv2_plot_waterfall_linux.h" + +/* + + Notes: + + The height h() pixels represents WATERFALL_SECS_Y of data. Every DT + seconds we get a vector of FDMDV_NSPEC spectrum samples which we use + to update the last row. The height of each row is dy pixels, which + maps to DT seconds. We call each dy high rectangle of pixels a + block. + +*/ + +extern float g_avmag[]; + +BEGIN_EVENT_TABLE(PlotWaterfall, PlotPanel) + EVT_PAINT (PlotWaterfall::OnPaint) + EVT_MOTION (PlotWaterfall::OnMouseMove) + EVT_LEFT_DOWN (PlotWaterfall::OnMouseDown) + EVT_LEFT_UP (PlotWaterfall::OnMouseUp) + EVT_MOUSEWHEEL (PlotWaterfall::OnMouseWheelMoved) + EVT_SIZE (PlotWaterfall::OnSize) + EVT_SHOW (PlotWaterfall::OnShow) +// EVT_ERASE_BACKGROUND(PlotWaterfall::OnErase) +END_EVENT_TABLE() + +//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=--=-=-=-= +// Class WaterfallPlot +// +// @class WaterfallPlot +// @author David Witten +// @date $(Date) +// @file $(CurrentFileName).$(CurrentFileExt) +// @brief +// +//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=--=-=-=-= +PlotWaterfall::PlotWaterfall(wxFrame* parent): PlotPanel(parent) +{ + + for(int i = 0; i < 255; i++) + { + m_heatmap_lut[i] = heatmap((float)i, 0.0, 255.0); + } + m_greyscale = 0; + m_Bufsz = GetMaxClientSize(); + m_newdata = false; + m_firstPass = true; + m_line_color = 0; + SetLabelSize(10.0); +} + +void PlotWaterfall::InitBitmap(int xsize, int ysize) + { + // draw some colourful stripes without alpha + //printf("m_pBitmap 0x%x\n", (unsigned int)m_pBitmap); + wxNativePixelData data(*m_pBitmap); + if ( !data ) + { + wxLogError(wxT("InitBitmap: Failed to gain raw access to bitmap data")); + return; + } + + wxNativePixelData::Iterator p(data); + for ( int y = 0; y < ysize; ++y ) + { + wxNativePixelData::Iterator rowStart = p; + + int r = y < ysize/3 ? 255 : 0, + g = (ysize/3 <= y) && (y < 2*(ysize/3)) ? 255 : 0, + b = 2*(ysize/3) <= y ? 255 : 0; + + for ( int x = 0; x < xsize; ++x ) + { + p.Red() = r; + p.Green() = g; + p.Blue() = b; + ++p; // same as p.OffsetX(1) + } + + p = rowStart; + p.OffsetY(data, 1); + } + } + +//---------------------------------------------------------------- +// paintEvent() +// +// @class $(Name) +// @author $(User) +// @date $(Date) +// @file $(CurrentFileName).$(CurrentFileExt) +// @brief +// +// Called by the system of by wxWidgets when the panel needs +// to be redrawn. You can also trigger this call by calling +// Refresh()/Update(). +//---------------------------------------------------------------- +void PlotWaterfall::OnPaint(wxPaintEvent & evt) +{ + printf("OnPaint\n"); + wxAutoBufferedPaintDC pdc(this); + draw(pdc); +} + +//---------------------------------------------------------------- +// OnShow() +//---------------------------------------------------------------- +void PlotWaterfall::OnShow(wxShowEvent& event) +{ +} + +//---------------------------------------------------------------- +// ~PlotWaterfall() +//---------------------------------------------------------------- +PlotWaterfall::~PlotWaterfall() +{ +} + +//---------------------------------------------------------------- +// heatmap() +// map val to a rgb colour +// from http://eddiema.ca/2011/01/21/c-sharp-heatmaps/ +//---------------------------------------------------------------- +unsigned PlotWaterfall::heatmap(float val, float min, float max) +{ + unsigned r = 0; + unsigned g = 0; + unsigned b = 0; + + val = (val - min) / (max - min); + if(val <= 0.2) + { + b = (unsigned)((val / 0.2) * 255); + } + else if(val > 0.2 && val <= 0.7) + { + b = (unsigned)((1.0 - ((val - 0.2) / 0.5)) * 255); + } + if(val >= 0.2 && val <= 0.6) + { + g = (unsigned)(((val - 0.2) / 0.4) * 255); + } + else if(val > 0.6 && val <= 0.9) + { + g = (unsigned)((1.0 - ((val - 0.6) / 0.3)) * 255); + } + if(val >= 0.5) + { + r = (unsigned)(((val - 0.5) / 0.5) * 255); + } + //printf("%f %x %x %x\n", val, r, g, b); + return (b << 16) + (g << 8) + r; +} + +#define PLOT_BOTTOM 0 +#define PLOT_TOP 1 + +//static long paint_count; + +//---------------------------------------------------------------- +// draw() +//---------------------------------------------------------------- +void PlotWaterfall::draw(wxAutoBufferedPaintDC& pDC) +{ + printf(" draw m_pBmp 0x%x\n", (unsigned int)m_pBmp); + + //m_pBitmap = new wxBitmap(SIZE, SIZE, 24); + + { + wxRect m_rCtrl = GetClientRect(); + printf("%d %d\n", m_rCtrl.GetWidth(), m_rCtrl.GetHeight()); + m_pBitmap = new wxBitmap(m_rCtrl.GetWidth(), m_rCtrl.GetHeight(), 24); + InitBitmap(m_rCtrl.GetWidth(), m_rCtrl.GetHeight()); + } + + printf("m_pBitmap 0x%x\n", (unsigned int)m_pBitmap); + + wxMemoryDC m_mDC; + m_mDC.SelectObject(*m_pBmp); + m_rCtrl = GetClientRect(); + m_rGrid = m_rCtrl; + + m_rGrid = m_rGrid.Deflate(PLOT_BORDER + (XLEFT_OFFSET/2), (PLOT_BORDER + (YBOTTOM_OFFSET/2))); + m_rGrid.Offset(PLOT_BORDER + XLEFT_OFFSET, PLOT_BORDER); + + pDC.Clear(); +// m_mDC.Clear(); + m_rPlot = wxRect(PLOT_BORDER + XLEFT_OFFSET, PLOT_BORDER, m_rGrid.GetWidth(), m_rGrid.GetHeight()); +// if(m_firstPass) +// { +// m_firstPass = false; +// m_mDC.FloodFill(0, 0, VERY_LTGREY_COLOR); + + // Draw a filled rectangle with aborder +// wxBrush ltGraphBkgBrush = wxBrush(DARK_BLUE_COLOR); +// m_mDC.SetBrush(ltGraphBkgBrush); +// m_mDC.SetPen(wxPen(BLACK_COLOR, 0)); +// m_mDC.DrawRectangle(m_rPlot); + +// } + wxBrush ltGraphBkgBrush = wxBrush(DARK_BLUE_COLOR); + pDC.SetBrush(ltGraphBkgBrush); + pDC.SetPen(wxPen(BLACK_COLOR, 0)); + pDC.DrawRectangle(m_rPlot); + drawGraticule(pDC); + + if(m_newdata) + { + printf(" m_newdata\n"); + m_newdata = false; + //plotPixelData(pDC); +//#ifdef _USE_TIMER + int t = m_rPlot.GetTop(); + int l = m_rPlot.GetLeft(); + int h = m_rPlot.GetHeight(); + int w = m_rPlot.GetWidth(); + int t2 = t + 1; + int w2 = w - 1; + int ht = (h - DATA_LINE_HEIGHT); + + printf("t %d l %d h %d w %d t2 %d w2 %d ht %d\n", t,l,h,w,t2,w2,ht); + drawData(); // m_mDC, PLOT_BOTTOM); + pDC.DrawLine(0,0,100,100); + pDC.DrawBitmap( *m_pBitmap, 0, 0/*SIZE+5+pDC.GetCharHeight()*/); + //pDC.DrawBitmap(*m_pBmp, 0, 0, true); + pDC.DrawLine(200,200,0,200); + //m_mDC.StretchBlit(l, t2, w2, ht, &m_mDC, l, t2 + DATA_LINE_HEIGHT, w2, ht - 2); + //pDC.Blit(l, t, w, h, &m_mDC, l, t); // Scroll Up from Bottom +// pDC.StretchBlit(l, (h - t) + 4, w, (-h) + 4, &m_mDC, l, t, w, h); // Scroll Down from top +// pDC.StretchBlit(l, (h - t) + 4, w, h - 4, &m_mDC, l, t, w, h); // Scroll Down from top +//#endif +#ifdef TMP +#endif + //drawGraticule(pDC); + } + m_mDC.SetBrush(wxNullBrush); + m_mDC.SelectObject(wxNullBitmap); + + delete m_pBitmap; +} + +//------------------------------------------------------------------------- +// drawData() +//------------------------------------------------------------------------- +void PlotWaterfall::drawData() //wxMemoryDC& pDC) +{ + int w = m_rPlot.GetWidth(); + int h = m_rPlot.GetHeight(); + printf(" drawData w = %d h = %d\n", w, h); + wxNativePixelData data(*m_pBmp); + if ( !data ) + { + wxLogError(wxT("Failed to gain raw access to bitmap data")); + return; + } + + wxNativePixelData::Iterator p(data); + p.Offset(data, 100, 100); + for ( int y = 0; y < 20; ++y ) + { + wxNativePixelData::Iterator rowStart = p; + + int r = y < h/3 ? 255 : 0, + g = (h/3 <= y) && (y < 2*(h/3)) ? 255 : 0, + b = 2*(h/3) <= y ? 255 : 0; + r=g=b=128; + + for ( int x = 0; x < 20; ++x ) + { + p.Red() = r; + p.Green() = g; + p.Blue() = b; + //printf("%d %d %d\n", r, g, b); + ++p; // same as p.OffsetX(1) + } + + p = rowStart; + p.OffsetY(data, 1); + } + +#ifdef PREV + wxNativePixelData dPix = wxNativePixelData(*m_pBmp, m_rCtrl); + m_pPix = &dPix; + if(m_pPix == NULL) + { + return; + } + wxNativePixelData::Iterator p(*m_pPix); + + int w = m_rPlot.GetWidth(); + int h = m_rPlot.GetHeight(); + p.Offset(*m_pPix, XLEFT_OFFSET + 3, h - (DATA_LINE_HEIGHT - 2)); + for(int y = 0; y < DATA_LINE_HEIGHT; ++y) + { + wxNativePixelData::Iterator rowStart = p; + for(int x = 0; x < (w - 1); ++x, ++p) + { +// p.Red() = m_pTopFrame->m_rxPa->m_av_mag[x]; +// p.Green() = m_pTopFrame->m_rxPa->m_av_mag[x]; +// p.Blue() = m_pTopFrame->m_rxPa->m_av_mag[x]; +/* + + p.Red() = g_avmag[x]; + p.Green() = g_avmag[x]; + p.Blue() = g_avmag[x]; +*/ + p.Red() = 0; + p.Green() = 0; + p.Blue() = 255; + } + p = rowStart; + p.OffsetY(*m_pPix, 1); + } +#endif +} + +//------------------------------------------------------------------------- +// drawGraticule() +//------------------------------------------------------------------------- +void PlotWaterfall::drawGraticule(wxAutoBufferedPaintDC& pDC) +{ + int p; + char buf[15]; + + wxString s; + + wxBrush ltGraphBkgBrush; + ltGraphBkgBrush.SetStyle(wxBRUSHSTYLE_TRANSPARENT); + ltGraphBkgBrush.SetColour(*wxBLACK); + pDC.SetBrush(ltGraphBkgBrush); + pDC.SetPen(wxPen(BLACK_COLOR, 1)); + + // Vertical gridlines + pDC.SetPen(m_penShortDash); + for(p = (PLOT_BORDER + XLEFT_OFFSET + GRID_INCREMENT); p < ((m_rGrid.GetWidth() - XLEFT_OFFSET) + GRID_INCREMENT); p += GRID_INCREMENT) + { + pDC.DrawLine(p, (m_rGrid.GetHeight() + PLOT_BORDER), p, PLOT_BORDER); + } + // Horizontal gridlines + pDC.SetPen(m_penDotDash); + for(p = (m_rGrid.GetHeight() - GRID_INCREMENT); p > PLOT_BORDER; p -= GRID_INCREMENT) + { + pDC.DrawLine(PLOT_BORDER + XLEFT_OFFSET, (p + PLOT_BORDER), (m_rGrid.GetWidth() + PLOT_BORDER + XLEFT_OFFSET), (p + PLOT_BORDER)); + } + // Label the X-Axis + pDC.SetPen(wxPen(GREY_COLOR, 1)); + for(p = GRID_INCREMENT; p < (m_rGrid.GetWidth() - YBOTTOM_OFFSET); p += GRID_INCREMENT) + { + sprintf(buf, "%1.1f Hz",(double)(p / 10)); + pDC.DrawText(buf, p - PLOT_BORDER + XLEFT_OFFSET, m_rGrid.GetHeight() + YBOTTOM_OFFSET/3); + } + // Label the Y-Axis + for(p = (m_rGrid.GetHeight() - GRID_INCREMENT); p > PLOT_BORDER; p -= GRID_INCREMENT) + { + sprintf(buf, "%1.0f", (double)((m_rGrid.GetHeight() - p) * 10)); + pDC.DrawText(buf, XLEFT_TEXT_OFFSET, p); + } +} + +//------------------------------------------------------------------------- +// plotPixelData() +//------------------------------------------------------------------------- +void PlotWaterfall::plotPixelData(wxAutoBufferedPaintDC& dc) +{ + float spec_index_per_px; + float intensity_per_dB; + int px_per_sec; + int index; + int dy; + int dy_blocks; + int bytes_in_row_of_blocks; + int b; + int px; + int py; + int intensity; + unsigned *last_row; + unsigned *pdest; + unsigned *psrc; + + // determine dy, the height of one "block" + px_per_sec = (float)m_rCtrl.GetHeight() / WATERFALL_SECS_Y; + dy = DT * px_per_sec; + // number of dy high blocks in spectrogram + dy_blocks = m_rCtrl.GetHeight()/ dy; + // shift previous bit map + bytes_in_row_of_blocks = dy * m_rCtrl.GetWidth() * sizeof(unsigned); + for(b = 0; b < dy_blocks - 1; b++) + { + pdest = (unsigned int *)m_pBmp + b * m_rCtrl.GetWidth() * dy; + psrc = (unsigned int *)m_pBmp + (b + 1) * m_rCtrl.GetWidth() * dy; + memcpy(pdest, psrc, bytes_in_row_of_blocks); + } + // create a new row of blocks at bottom + spec_index_per_px = (float)FDMDV_NSPEC / (float) m_rCtrl.GetWidth(); + intensity_per_dB = (float)256 /(MAX_DB - MIN_DB); + last_row = (unsigned int *)m_pBmp + dy *(dy_blocks - 1)* m_rCtrl.GetWidth(); + + wxNativePixelData data(*m_pBmp); + if(!data) + { + wxMessageBox(wxT("Unable to access Bitmap Data"), wxT("Error")); + return; + } + if(data.GetWidth() < 20 || data.GetHeight() < 20) + { + wxMessageBox(wxT("Bitmap is too small to use"), wxT("Warning")); + return; + } + wxNativePixelData::Iterator p(data); + // we draw a (10, 10)-(20, 20) rect manually using the given r, g, b + p.Offset(data, 10, 10); + for(px = 0; px < m_rCtrl.GetWidth(); px++) + { + index = px * spec_index_per_px; + // intensity = intensity_per_dB * (m_av_mag[index] - MIN_DB); + intensity = intensity_per_dB * (g_avmag[index] - MIN_DB); +// intensity = intensity_per_dB * (((MainFrame *)GetParent())->m_rxPa->m_av_mag[index] - MIN_DB); +// intensity = intensity_per_dB * (((MainFrame *)GetParent())->m_av_mag[index] - MIN_DB); + if(intensity > 255) + { + intensity = 255; + } + if(intensity > 255) + { + intensity = 255; + } + if (intensity < 0) + { + intensity = 0; + } + if(m_greyscale) + { + for(py = 0; py < dy; py++) + { + last_row[px + py * m_rCtrl.GetWidth()] = intensity << 8; + } + } + else + { + for(py = 0; py < dy; py++) + { + last_row[px + py * m_rCtrl.GetWidth()] = m_heatmap_lut[intensity]; + } + } + } +} diff --git a/fdmdv2/src/fdmdv2_plot_waterfall_linux.h b/fdmdv2/src/fdmdv2_plot_waterfall_linux.h new file mode 100644 index 00000000..2c017978 --- /dev/null +++ b/fdmdv2/src/fdmdv2_plot_waterfall_linux.h @@ -0,0 +1,75 @@ +//========================================================================== +// Name: fdmdv2_plot_waterfall.h +// Purpose: Defines a waterfall plot derivative of fdmdv2_plot. +// Created: June 22, 2012 +// Initial author: David Witten +// Derived from: code written by David Rowe +// License: +// +// Copyright (C) 2012 David Witten +// +// All rights reserved. +// +// This program is free software; you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License version 2.1, +// as published by the Free Software Foundation. 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 Lesser General Public License +// along with this program; if not, see . +// +//========================================================================== +#ifndef __FDMDV2_PLOT_WATERFALL__ +#define __FDMDV2_PLOT_WATERFALL__ + +#include "fdmdv2_plot.h" +#include "fdmdv2_defines.h" + +//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=--=-=-=-= +// Class PlotWaterfall +// +// @class $(Name) +// @author $(User) +// @date $(Date) +// @file $(CurrentFileName).$(CurrentFileExt) +// @brief +// +//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=--=-=-=-= +class PlotWaterfall : public PlotPanel +{ + public: + PlotWaterfall(wxFrame* parent); + ~PlotWaterfall(); +// bool m_newdata; + + enum + { + BORDER = 15, + SIZE = 150, + REAL_SIZE = SIZE - 2*BORDER + }; + protected: + // unsigned *m_pixel_buf; + unsigned m_heatmap_lut[256]; + wxMemoryDC m_mDC; + wxBitmap *m_pBitmap; + + unsigned heatmap(float val, float min, float max); + + void InitBitmap(int xsize, int ysize); + void OnPaint(wxPaintEvent & evt); + //void OnSize(wxSizeEvent& event); + void OnShow(wxShowEvent& event); + void drawGraticule(wxAutoBufferedPaintDC& dc); + void draw(wxAutoBufferedPaintDC& pdc); + void plotPixelData(wxAutoBufferedPaintDC& dc); + void drawData(); // wxMemoryDC& pDC); + void drawData2(wxMemoryDC& pDC, int barpos, int l, int t, int w, int h); + + DECLARE_EVENT_TABLE() +}; + +#endif //__FDMDV2_PLOT_WATERFALL__ -- 2.25.1