automatic scaling of spectrogram, and toggling color mapping. Think it works better...
authordrowe67 <drowe67@01035d8c-6547-0410-b346-abe4f91aad63>
Tue, 27 Nov 2012 01:24:40 +0000 (01:24 +0000)
committerdrowe67 <drowe67@01035d8c-6547-0410-b346-abe4f91aad63>
Tue, 27 Nov 2012 01:24:40 +0000 (01:24 +0000)
git-svn-id: https://svn.code.sf.net/p/freetel/code@1079 01035d8c-6547-0410-b346-abe4f91aad63

fdmdv2/src/fdmdv2_defines.h
fdmdv2/src/fdmdv2_main.cpp
fdmdv2/src/fdmdv2_plot.cpp
fdmdv2/src/fdmdv2_plot.h
fdmdv2/src/fdmdv2_plot_scalar.cpp
fdmdv2/src/fdmdv2_plot_scatter.cpp
fdmdv2/src/fdmdv2_plot_spectrum.cpp
fdmdv2/src/fdmdv2_plot_spectrum.h
fdmdv2/src/fdmdv2_plot_waterfall_linux.cpp
fdmdv2/src/fdmdv2_plot_waterfall_linux.h
fdmdv2/src/topFrame.cpp

index 9116d7f211183958b0ceb643cb0409b20139d50d..f751c717c80e87b336157c909384d8791010e6f9 100644 (file)
@@ -32,7 +32,8 @@
 #define BETA                0.95    // constant for time averaging spectrum data
 #define MIN_F_HZ            0       // min freq on Waterfall and Spectrum
 #define MAX_F_HZ            4000    // max freq on Waterfall and Spectrum
-#define STEP_F_HZ           500     // freq step on Waterfall and Spectrum graticule
+#define STEP_F_HZ           500     // major (e.g. text legend) freq step on Waterfall and Spectrum graticule
+#define STEP_MINOR_F_HZ     100     // minor (ticks) freq step on Waterfall and Spectrum graticule
 #define WATERFALL_SECS_Y    30      // number of seconds respresented by y axis of waterfall
 #define WATERFALL_SECS_STEP 5       // graticule y axis steps of waterfall
 #define DT                  0.1     // time between real time graphing updates
index fcbd8593dfd5473b7e72186cefaa3e63007584ec..8b574003777c1697ba34fcc07e670a00cbc700fd 100644 (file)
@@ -218,13 +218,15 @@ MainFrame::MainFrame(wxWindow *parent) : TopFrame(parent)
     {
         // Add Waterfall Plot window
 
-        m_panelWaterfall = new PlotWaterfall((wxFrame*) m_auiNbookCtrl, false);
+        m_panelWaterfall = new PlotWaterfall((wxFrame*) m_auiNbookCtrl, false, 0);
+        m_panelWaterfall->SetToolTip(_("Left click to tune, Right click to toggle mono/colour"));
         m_auiNbookCtrl->AddPage(m_panelWaterfall, _("Waterfall"), true, wxNullBitmap);
     }
     if(wxGetApp().m_show_spect)
     {
         // Add Spectrum Plot window
         m_panelSpectrum = new PlotSpectrum((wxFrame*) m_auiNbookCtrl);
+        m_panelSpectrum->SetToolTip(_("Left click to tune"));
         m_auiNbookCtrl->AddPage(m_panelSpectrum, _("Spectrum"), true, wxNullBitmap);
     }
     if(wxGetApp().m_show_scatter)
@@ -817,6 +819,9 @@ void MainFrame::OnTogBtnTXClick(wxCommandEvent& event)
 //-------------------------------------------------------------------------
 void MainFrame::OnTogBtnRxID(wxCommandEvent& event)
 {
+    // empty any junk in rx data FIFO
+    short junk;
+    while(fifo_read(g_rxDataOutFifo,&junk,1) == 0);
     event.Skip();
 }
 
index e59871488a8ecac795ba434feac12b7ede57689a..1b85cd90028af911773697c0ce2213e5d01e343c 100644 (file)
@@ -24,8 +24,9 @@
 BEGIN_EVENT_TABLE(PlotPanel, wxPanel)
     EVT_PAINT           (PlotPanel::OnPaint)
     EVT_MOTION          (PlotPanel::OnMouseMove)
-    EVT_LEFT_DOWN       (PlotPanel::OnMouseDown)
-    EVT_LEFT_UP         (PlotPanel::OnMouseUp)
+    EVT_LEFT_DOWN       (PlotPanel::OnMouseLeftDown)
+    EVT_LEFT_UP         (PlotPanel::OnMouseLeftUp)
+    EVT_RIGHT_DOWN      (PlotPanel::OnMouseRightDown)
     EVT_MOUSEWHEEL      (PlotPanel::OnMouseWheelMoved)
     EVT_SIZE            (PlotPanel::OnSize)
     EVT_SHOW            (PlotPanel::OnShow)
@@ -140,9 +141,16 @@ void PlotPanel::OnMouseMove(wxMouseEvent& event)
 }
 
 //-------------------------------------------------------------------------
-// OnMouseDown()
+// OnMouseLeftDown()
 //-------------------------------------------------------------------------
-void PlotPanel::OnMouseDown(wxMouseEvent& event)
+void PlotPanel::OnMouseLeftDown(wxMouseEvent& event)
+{
+}
+
+//-------------------------------------------------------------------------
+// OnMouseRightDown()
+//-------------------------------------------------------------------------
+void PlotPanel::OnMouseRightDown(wxMouseEvent& event)
 {
 }
 
@@ -154,9 +162,9 @@ void PlotPanel::OnMouseWheelMoved(wxMouseEvent& event)
 }
 
 //-------------------------------------------------------------------------
-// OnMouseUp()
+// OnMouseLeftUp()
 //-------------------------------------------------------------------------
-void PlotPanel::OnMouseUp(wxMouseEvent& event)
+void PlotPanel::OnMouseLeftUp(wxMouseEvent& event)
 {
     m_mouseDown = false;
 }
index 453f58b38c8e39470aba5073e3712a26e447d676..25309d3a8c3aa958132a00e33efcd5bef4ddcea6 100644 (file)
@@ -45,7 +45,7 @@
 #define XLEFT_OFFSET        40
 #define XLEFT_TEXT_OFFSET   6
 #define YBOTTOM_OFFSET      20
-#define YBOTTOM_TEXT_OFFSET 6
+#define YBOTTOM_TEXT_OFFSET 15
 #define GRID_INCREMENT      50
 
 #define BLACK_COLOR         wxColor(0x00, 0x00, 0x00)
@@ -109,8 +109,9 @@ class PlotPanel : public wxPanel
 
         // some useful events
         void            OnMouseMove(wxMouseEvent& event);
-        virtual void    OnMouseDown(wxMouseEvent& event);
-        void            OnMouseUp(wxMouseEvent& event);
+        virtual void    OnMouseLeftDown(wxMouseEvent& event);
+        void            OnMouseLeftUp(wxMouseEvent& event);
+        virtual void    OnMouseRightDown(wxMouseEvent& event);
         void            OnMouseWheelMoved(wxMouseEvent& event);
         void            OnClose(wxCloseEvent& event ){ event.Skip(); }
         void            OnSize( wxSizeEvent& event );
index e19ff3d3b7ec8bf3ae7c7d21d0db343afcc80e5e..8b5d8184c0d7d114fb648915fc8345e72f2bbed4 100644 (file)
@@ -26,8 +26,6 @@
 BEGIN_EVENT_TABLE(PlotScalar, PlotPanel)
     EVT_PAINT           (PlotScalar::OnPaint)
     EVT_MOTION          (PlotScalar::OnMouseMove)
-    EVT_LEFT_DOWN       (PlotScalar::OnMouseDown)
-    EVT_LEFT_UP         (PlotScalar::OnMouseUp)
     EVT_MOUSEWHEEL      (PlotScalar::OnMouseWheelMoved)
     EVT_SIZE            (PlotScalar::OnSize)
     EVT_SHOW            (PlotScalar::OnShow)
index 4b5b92b605bfb3e9227cdcc3b47f413730ac3c12..1c9707a69c530cad7587cbcde7a014dfa0697591 100644 (file)
@@ -25,8 +25,6 @@
 BEGIN_EVENT_TABLE(PlotScatter, PlotPanel)
     EVT_PAINT           (PlotScatter::OnPaint)
     EVT_MOTION          (PlotScatter::OnMouseMove)
-    EVT_LEFT_DOWN       (PlotScatter::OnMouseDown)
-    EVT_LEFT_UP         (PlotScatter::OnMouseUp)
     EVT_MOUSEWHEEL      (PlotScatter::OnMouseWheelMoved)
     EVT_SIZE            (PlotScatter::OnSize)
     EVT_SHOW            (PlotScatter::OnShow)
index b4a171fe40d914f73867f14221d4cd9eb691b3f1..12940be07ec5ff10be5068190f3d67c38ccf25bd 100644 (file)
@@ -28,8 +28,8 @@ void fdmdv2_clickTune(float frequency); // callback to pass new click freq
 
 BEGIN_EVENT_TABLE(PlotSpectrum, PlotPanel)
     EVT_MOTION          (PlotSpectrum::OnMouseMove)
-    EVT_LEFT_DOWN       (PlotSpectrum::OnMouseDown)
-    EVT_LEFT_UP         (PlotSpectrum::OnMouseUp)
+    EVT_LEFT_DOWN       (PlotSpectrum::OnMouseLeftDown)
+    EVT_LEFT_UP         (PlotSpectrum::OnMouseLeftUp)
     EVT_MOUSEWHEEL      (PlotSpectrum::OnMouseWheelMoved)
     EVT_PAINT           (PlotSpectrum::OnPaint)
     EVT_SHOW            (PlotSpectrum::OnShow)
@@ -175,16 +175,28 @@ void PlotSpectrum::drawGraticule(wxAutoBufferedPaintDC&  dc)
 
     // Vertical gridlines
 
-    dc.SetPen(m_penShortDash);
     for(f=STEP_F_HZ; f<MAX_F_HZ; f+=STEP_F_HZ) {
        x = f*freq_hz_to_px;
        x += PLOT_BORDER + XLEFT_OFFSET;
+
+        dc.SetPen(m_penShortDash);
         dc.DrawLine(x, m_rGrid.GetHeight() + PLOT_BORDER, x, PLOT_BORDER);
+        dc.SetPen(wxPen(BLACK_COLOR, 1));
+        dc.DrawLine(x, m_rGrid.GetHeight() + PLOT_BORDER, x, m_rGrid.GetHeight() + PLOT_BORDER + YBOTTOM_TEXT_OFFSET);
+
         sprintf(buf, "%4.0fHz", f);
        GetTextExtent(buf, &text_w, &text_h);
         dc.DrawText(buf, x - text_w/2, m_rGrid.GetHeight() + PLOT_BORDER + YBOTTOM_TEXT_OFFSET);
     }
 
+    dc.SetPen(wxPen(BLACK_COLOR, 1));
+    for(f=STEP_MINOR_F_HZ; f<MAX_F_HZ; f+=STEP_MINOR_F_HZ) 
+    {
+        x = f*freq_hz_to_px;
+        x += PLOT_BORDER + XLEFT_OFFSET;
+        dc.DrawLine(x, m_rGrid.GetHeight() + PLOT_BORDER, x, m_rGrid.GetHeight() + PLOT_BORDER + YBOTTOM_TEXT_OFFSET-5);
+    }
+    
     // Horizontal gridlines
 
     dc.SetPen(m_penDotDash);
@@ -203,14 +215,14 @@ void PlotSpectrum::drawGraticule(wxAutoBufferedPaintDC&  dc)
     x = m_rxFreq*freq_hz_to_px;
     x += PLOT_BORDER + XLEFT_OFFSET;
     //printf("m_rxFreq %f x %d\n", m_rxFreq, x);
-    dc.DrawLine(x, m_rGrid.GetHeight()+ PLOT_BORDER, x, m_rGrid.GetHeight() + m_rCtrl.GetHeight());
+    dc.DrawLine(x, m_rGrid.GetHeight()+ PLOT_BORDER, x, m_rCtrl.GetHeight());
 
 }
 
 //-------------------------------------------------------------------------
 // OnMouseDown()
 //-------------------------------------------------------------------------
-void PlotSpectrum::OnMouseDown(wxMouseEvent& event)
+void PlotSpectrum::OnMouseLeftDown(wxMouseEvent& event)
 {
     m_mouseDown = true;
     wxClientDC dc(this);
index 9fa813c5d9e920c74a04784178798cd37a14daf6..f6684c1dee2242dcf21add62656251d492fcc813 100644 (file)
@@ -40,7 +40,7 @@ class PlotSpectrum : public PlotPanel
         void        OnShow(wxShowEvent& event);
         void        drawGraticule(wxAutoBufferedPaintDC& dc);
         void        draw(wxAutoBufferedPaintDC& dc);
-        void        OnMouseDown(wxMouseEvent& event);
+        void        OnMouseLeftDown(wxMouseEvent& event);
 
    private:
         float       m_rxFreq;
index 0d039e789338955c5412e92ad90ed9b11a4e15d4..65eb040138dc75a71812e51b2b39962906b8ea47 100644 (file)
@@ -28,8 +28,9 @@ void fdmdv2_clickTune(float frequency); // callback to pass new click freq
 BEGIN_EVENT_TABLE(PlotWaterfall, PlotPanel)
     EVT_PAINT           (PlotWaterfall::OnPaint)
     EVT_MOTION          (PlotWaterfall::OnMouseMove)
-    EVT_LEFT_DOWN       (PlotWaterfall::OnMouseDown)
-    EVT_LEFT_UP         (PlotWaterfall::OnMouseUp)
+    EVT_LEFT_DOWN       (PlotWaterfall::OnMouseLeftDown)
+    EVT_RIGHT_DOWN      (PlotWaterfall::OnMouseRightDown)
+    EVT_LEFT_UP         (PlotWaterfall::OnMouseLeftUp)
     EVT_MOUSEWHEEL      (PlotWaterfall::OnMouseWheelMoved)
     EVT_SIZE            (PlotWaterfall::OnSize)
     EVT_SHOW            (PlotWaterfall::OnShow)
@@ -45,14 +46,15 @@ END_EVENT_TABLE()
 // @brief
 //
 //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=--=-=-=-=
-PlotWaterfall::PlotWaterfall(wxFrame* parent, bool greyscale): PlotPanel(parent)
+PlotWaterfall::PlotWaterfall(wxFrame* parent, bool graticule, int colour): PlotPanel(parent)
 {
 
     for(int i = 0; i < 255; i++)
     {
         m_heatmap_lut[i] = heatmap((float)i, 0.0, 255.0);
     }
-    m_greyscale     = greyscale;
+    m_graticule     = graticule;
+    m_colour        = colour;
     m_Bufsz         = GetMaxClientSize();
     m_newdata       = false;
     m_firstPass     = true;
@@ -60,6 +62,8 @@ PlotWaterfall::PlotWaterfall(wxFrame* parent, bool greyscale): PlotPanel(parent)
     SetLabelSize(10.0);
 
     m_pBmp = NULL;
+    m_max_mag = MAX_MAG_DB;
+    m_min_mag = MIN_MAG_DB;
 }
 
 // When the window size gets set we can work outthe size of the window
@@ -241,25 +245,40 @@ void PlotWaterfall::drawGraticule(wxAutoBufferedPaintDC& dc)
     // upper LH coords of plot area are (PLOT_BORDER + XLEFT_OFFSET, PLOT_BORDER)
     // lower RH coords of plot area are (PLOT_BORDER + XLEFT_OFFSET + m_rGrid.GetWidth(), 
     //                                   PLOT_BORDER + m_rGrid.GetHeight())
-    // Vertical gridlines
-    dc.SetPen(m_penShortDash);
+
+    // Major Vertical gridlines and legend
+    //dc.SetPen(m_penShortDash);
     for(f=STEP_F_HZ; f<MAX_F_HZ; f+=STEP_F_HZ) 
     {
         x = f*freq_hz_to_px;
         x += PLOT_BORDER + XLEFT_OFFSET;
-        dc.DrawLine(x, m_rGrid.GetHeight() + PLOT_BORDER, x, PLOT_BORDER);
+
+        if (m_graticule)
+            dc.DrawLine(x, m_rGrid.GetHeight() + PLOT_BORDER, x, PLOT_BORDER);
+        else
+            dc.DrawLine(x, m_rGrid.GetHeight() + PLOT_BORDER, x, m_rGrid.GetHeight() + PLOT_BORDER + YBOTTOM_TEXT_OFFSET);
+            
         sprintf(buf, "%4.0fHz", f);
         GetTextExtent(buf, &text_w, &text_h);
-            dc.DrawText(buf, x - text_w/2, m_rGrid.GetHeight() + PLOT_BORDER + YBOTTOM_TEXT_OFFSET);
+        dc.DrawText(buf, x - text_w/2, m_rGrid.GetHeight() + PLOT_BORDER + YBOTTOM_TEXT_OFFSET);
     }
 
+    for(f=STEP_MINOR_F_HZ; f<MAX_F_HZ; f+=STEP_MINOR_F_HZ) 
+    {
+        x = f*freq_hz_to_px;
+        x += PLOT_BORDER + XLEFT_OFFSET;
+        dc.DrawLine(x, m_rGrid.GetHeight() + PLOT_BORDER, x, m_rGrid.GetHeight() + PLOT_BORDER + YBOTTOM_TEXT_OFFSET-5);
+    }
+    
     // Horizontal gridlines
     dc.SetPen(m_penDotDash);
     for(time=0; time<=WATERFALL_SECS_Y; time+=WATERFALL_SECS_STEP) {
-       y = m_rGrid.GetHeight() - time*time_s_to_py;
-       y += PLOT_BORDER;
-       dc.DrawLine(PLOT_BORDER + XLEFT_OFFSET, y, 
-                   (m_rGrid.GetWidth() + PLOT_BORDER + XLEFT_OFFSET), y);
+       y = m_rGrid.GetHeight() - time*time_s_to_py;
+       y += PLOT_BORDER;
+
+        if (m_graticule)
+            dc.DrawLine(PLOT_BORDER + XLEFT_OFFSET, y, 
+                        (m_rGrid.GetWidth() + PLOT_BORDER + XLEFT_OFFSET), y);
         sprintf(buf, "%3.0fs", time);
        GetTextExtent(buf, &text_w, &text_h);
         dc.DrawText(buf, PLOT_BORDER + XLEFT_OFFSET - text_w - XLEFT_TEXT_OFFSET, y-text_h/2);
@@ -270,7 +289,7 @@ void PlotWaterfall::drawGraticule(wxAutoBufferedPaintDC& dc)
     x = m_rxFreq*freq_hz_to_px;
     x += PLOT_BORDER + XLEFT_OFFSET;
     //printf("m_rxFreq %f x %d\n", m_rxFreq, x);
-    dc.DrawLine(x, m_rGrid.GetHeight()+ PLOT_BORDER, x, m_rGrid.GetHeight() + m_rCtrl.GetHeight());
+    dc.DrawLine(x, m_rGrid.GetHeight()+ PLOT_BORDER, x, m_rCtrl.GetHeight());
     
 }
 
@@ -308,7 +327,18 @@ void PlotWaterfall::plotPixelData()
     // number of dy high blocks in spectrogram
     dy_blocks = m_rGrid.GetHeight()/ dy;
 
-    intensity_per_dB  = (float)256 /(MAX_MAG_DB - MIN_MAG_DB);
+    // update min and max amplitude estimates
+
+    float max_mag = MIN_MAG_DB;
+    for(int i=0; i<FDMDV_NSPEC; i++) {
+        if (g_avmag[i] > max_mag)
+            max_mag = g_avmag[i];
+    }
+    m_max_mag = BETA*m_max_mag + (1 - BETA)*max_mag;
+    m_min_mag = max_mag - 20.0;
+    //printf("max_mag: %f m_max_mag: %f\n", max_mag, m_max_mag);
+    //intensity_per_dB  = (float)256 /(MAX_MAG_DB - MIN_MAG_DB);
+    intensity_per_dB  = (float)256 /(m_max_mag - m_min_mag);
     spec_index_per_px = (float)FDMDV_NSPEC / (float) m_rGrid.GetWidth();
 
     /*
@@ -365,27 +395,35 @@ void PlotWaterfall::plotPixelData()
             index = px * spec_index_per_px;
             assert(index < FDMDV_NSPEC);
 
-            intensity = intensity_per_dB * (g_avmag[index] - MIN_MAG_DB);
+            intensity = intensity_per_dB * (g_avmag[index] - m_min_mag);
             if(intensity > 255) intensity = 255;
             if (intensity < 0) intensity = 0;
             //printf("%d %f %d \n", index, g_avmag[index], intensity);
 
-            if (m_greyscale) {
-                if (intensity > 200) {
+            switch (m_colour) {
+            case 0:
+                p.Red() = m_heatmap_lut[intensity] & 0xff;
+                p.Green() = (m_heatmap_lut[intensity] >> 8) & 0xff;
+                p.Blue() = (m_heatmap_lut[intensity] >> 16) & 0xff;
+                break;
+            case 1:
+                p.Red() = intensity;
+                p.Green() = intensity;
+                p.Blue() = intensity;       
+                break;
+            case 2:
+                if (intensity > 250) {
                     p.Red() = intensity;
                     p.Green() = intensity;
-                    p.Blue() = intensity;            
+                    p.Blue() = intensity;
                 }
                 else {
                     p.Red() = 0;
                     p.Green() = 0;
-                    p.Blue() = intensity;            
+                    p.Blue() = intensity;
                 }
-            }
-            else {
-                p.Red() = m_heatmap_lut[intensity] & 0xff;
-                p.Green() = (m_heatmap_lut[intensity] >> 8) & 0xff;
-                p.Blue() = (m_heatmap_lut[intensity] >> 16) & 0xff;
+                    
+                break;
             }
             ++p;
         }
@@ -396,9 +434,9 @@ void PlotWaterfall::plotPixelData()
 }
 
 //-------------------------------------------------------------------------
-// OnMouseDown()
+// OnMouseLeftDown()
 //-------------------------------------------------------------------------
-void PlotWaterfall::OnMouseDown(wxMouseEvent& event)
+void PlotWaterfall::OnMouseLeftDown(wxMouseEvent& event)
 {
     m_mouseDown = true;
     wxClientDC dc(this);
@@ -419,3 +457,14 @@ void PlotWaterfall::OnMouseDown(wxMouseEvent& event)
         fdmdv2_clickTune(clickFreq);
     }
 }
+
+//-------------------------------------------------------------------------
+// OnMouseRightDown()
+//-------------------------------------------------------------------------
+void PlotWaterfall::OnMouseRightDown(wxMouseEvent& event)
+{
+    m_colour++;
+    if (m_colour == 3)
+        m_colour = 0;
+}
+
index 92ecfa889119d60feb400afa02cf828736a561ed..e5c0e836f9cd395892674193a69290e7ad5720bc 100644 (file)
@@ -37,7 +37,7 @@
 class PlotWaterfall : public PlotPanel
 {
     public:
-    PlotWaterfall(wxFrame* parent, bool greyscale);
+    PlotWaterfall(wxFrame* parent, bool graticule, int colour);
         ~PlotWaterfall();
         bool checkDT(void);
         void setGreyscale(bool greyscale) { m_greyscale = greyscale; }
@@ -54,11 +54,16 @@ class PlotWaterfall : public PlotPanel
         void        drawGraticule(wxAutoBufferedPaintDC&  dc);
         void        draw(wxAutoBufferedPaintDC& dc);
         void        plotPixelData();
-        void        OnMouseDown(wxMouseEvent& event);
+        void        OnMouseLeftDown(wxMouseEvent& event);
+        void        OnMouseRightDown(wxMouseEvent& event);
 
     private:
         float       m_dT;
         float       m_rxFreq;
+        bool        m_graticule;
+        float       m_min_mag;
+        float       m_max_mag;
+        int         m_colour;
 
         DECLARE_EVENT_TABLE()
 };
index ec5fa1916e955d84366f4ceff65d7c50fea0c96a..6b2093547e86bc341acf1886297fda668dea64a1 100644 (file)
@@ -128,7 +128,7 @@ TopFrame::TopFrame(wxWindow* parent, wxWindowID id, const wxString& title, const
     wxStaticBoxSizer* levelSizer;
     levelSizer = new wxStaticBoxSizer(new wxStaticBox(this, wxID_ANY, _("Level")), wxVERTICAL);
 
-    m_textLevel = new wxStaticText(this, wxID_ANY, wxT(""), wxDefaultPosition, wxSize(50,-1), wxALIGN_CENTRE);
+    m_textLevel = new wxStaticText(this, wxID_ANY, wxT(""), wxDefaultPosition, wxSize(60,-1), wxALIGN_CENTRE);
     m_textLevel->SetForegroundColour(wxColour(255,0,0));
     levelSizer->Add(m_textLevel, 0, wxALIGN_LEFT, 1);