diff --git a/CMakeLists.txt b/CMakeLists.txt index a222e4a..d8d9868 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -136,6 +136,7 @@ SET (cubicsdr_sources src/util/MouseTracker.cpp src/util/GLFont.cpp src/visual/PrimaryGLContext.cpp + src/visual/InteractiveCanvas.cpp src/visual/MeterCanvas.cpp src/visual/MeterContext.cpp src/visual/ScopeCanvas.cpp @@ -167,6 +168,7 @@ SET (cubicsdr_headers src/util/MouseTracker.h src/util/GLFont.h src/visual/PrimaryGLContext.h + src/visual/InteractiveCanvas.h src/visual/MeterCanvas.h src/visual/MeterContext.h src/visual/ScopeCanvas.h diff --git a/src/visual/InteractiveCanvas.cpp b/src/visual/InteractiveCanvas.cpp new file mode 100644 index 0000000..596943a --- /dev/null +++ b/src/visual/InteractiveCanvas.cpp @@ -0,0 +1,125 @@ +#include "InteractiveCanvas.h" + +#include "wx/wxprec.h" + +#ifndef WX_PRECOMP +#include "wx/wx.h" +#endif + +#if !wxUSE_GLCANVAS +#error "OpenGL required: set wxUSE_GLCANVAS to 1 and rebuild the library" +#endif + +#include "CubicSDR.h" +#include "CubicSDRDefs.h" +#include "AppFrame.h" +#include + +#include + +InteractiveCanvas::InteractiveCanvas(wxWindow *parent, int *attribList) : + wxGLCanvas(parent, wxID_ANY, attribList, wxDefaultPosition, wxDefaultSize, + wxFULL_REPAINT_ON_RESIZE), parent(parent), shiftDown(false), altDown(false), ctrlDown(false), center_freq(0), bandwidth(0), last_bandwidth(0), isView( + false) { + mTracker.setTarget(this); +} + +InteractiveCanvas::~InteractiveCanvas() { +} + +void InteractiveCanvas::SetView(int center_freq_in, int bandwidth_in) { + isView = true; + center_freq = center_freq_in; + bandwidth = bandwidth_in; + last_bandwidth = 0; +} + +void InteractiveCanvas::DisableView() { + isView = false; + center_freq = wxGetApp().getFrequency(); + bandwidth = SRATE; + last_bandwidth = 0; +} + +int InteractiveCanvas::GetFrequencyAt(float x) { + int iqCenterFreq = GetCenterFrequency(); + int iqBandwidth = GetBandwidth(); + int freq = iqCenterFreq - (int) (0.5 * (float) iqBandwidth) + (int) ((float) x * (float) iqBandwidth); + + return freq; +} + +void InteractiveCanvas::SetCenterFrequency(unsigned int center_freq_in) { + center_freq = center_freq_in; +} + +unsigned int InteractiveCanvas::GetCenterFrequency() { + if (isView) { + return center_freq; + } else { + return (unsigned int) wxGetApp().getFrequency(); + } +} + +void InteractiveCanvas::SetBandwidth(unsigned int bandwidth_in) { + bandwidth = bandwidth_in; +} + +unsigned int InteractiveCanvas::GetBandwidth() { + if (isView) { + return bandwidth; + } else { + return SRATE; + } +} + +void InteractiveCanvas::OnKeyUp(wxKeyEvent& event) { + shiftDown = event.ShiftDown(); + altDown = event.AltDown(); + ctrlDown = event.ControlDown(); +} + +void InteractiveCanvas::OnKeyDown(wxKeyEvent& event) { + float angle = 5.0; + + shiftDown = event.ShiftDown(); + altDown = event.AltDown(); + ctrlDown = event.ControlDown(); +} + +void InteractiveCanvas::mouseMoved(wxMouseEvent& event) { + mTracker.OnMouseMoved(event); + + shiftDown = event.ShiftDown(); + altDown = event.AltDown(); + ctrlDown = event.ControlDown(); +} + +void InteractiveCanvas::mouseDown(wxMouseEvent& event) { + mTracker.OnMouseDown(event); + + shiftDown = event.ShiftDown(); + altDown = event.AltDown(); + ctrlDown = event.ControlDown(); +} + +void InteractiveCanvas::mouseWheelMoved(wxMouseEvent& event) { + mTracker.OnMouseWheelMoved(event); +} + +void InteractiveCanvas::mouseReleased(wxMouseEvent& event) { + mTracker.OnMouseReleased(event); + + shiftDown = event.ShiftDown(); + altDown = event.AltDown(); + ctrlDown = event.ControlDown(); +} + +void InteractiveCanvas::mouseLeftWindow(wxMouseEvent& event) { + mTracker.OnMouseLeftWindow(event); +} + +void InteractiveCanvas::mouseEnterWindow(wxMouseEvent& event) { + mTracker.OnMouseEnterWindow(event); +} + diff --git a/src/visual/InteractiveCanvas.h b/src/visual/InteractiveCanvas.h new file mode 100644 index 0000000..979dadd --- /dev/null +++ b/src/visual/InteractiveCanvas.h @@ -0,0 +1,48 @@ +#pragma once + +#include "wx/glcanvas.h" +#include "wx/timer.h" + +#include "MouseTracker.h" + +class InteractiveCanvas: public wxGLCanvas { +public: + InteractiveCanvas(wxWindow *parent, int *attribList = NULL); + ~InteractiveCanvas(); + + int GetFrequencyAt(float x); + + void SetView(int center_freq_in, int bandwidth_in); + void DisableView(); + + void SetCenterFrequency(unsigned int center_freq_in); + unsigned int GetCenterFrequency(); + + void SetBandwidth(unsigned int bandwidth_in); + unsigned int GetBandwidth(); + +protected: + void OnKeyDown(wxKeyEvent& event); + void OnKeyUp(wxKeyEvent& event); + + void mouseMoved(wxMouseEvent& event); + void mouseDown(wxMouseEvent& event); + void mouseWheelMoved(wxMouseEvent& event); + void mouseReleased(wxMouseEvent& event); + void mouseEnterWindow(wxMouseEvent& event); + void mouseLeftWindow(wxMouseEvent& event); + + wxWindow *parent; + MouseTracker mTracker; + + bool shiftDown; + bool altDown; + bool ctrlDown; + + unsigned int center_freq; + unsigned int bandwidth; + unsigned int last_bandwidth; + + bool isView; +}; + diff --git a/src/visual/SpectrumCanvas.cpp b/src/visual/SpectrumCanvas.cpp index 404aab7..63bb8cf 100644 --- a/src/visual/SpectrumCanvas.cpp +++ b/src/visual/SpectrumCanvas.cpp @@ -27,13 +27,11 @@ EVT_MOUSEWHEEL(SpectrumCanvas::mouseWheelMoved) wxEND_EVENT_TABLE() SpectrumCanvas::SpectrumCanvas(wxWindow *parent, int *attribList) : - wxGLCanvas(parent, wxID_ANY, attribList, wxDefaultPosition, wxDefaultSize, - wxFULL_REPAINT_ON_RESIZE), parent(parent), fft_size(0), in(NULL), out(NULL), plan(NULL), waterfallCanvas(NULL), center_freq(0), bandwidth(0), isView( - 0) { + InteractiveCanvas(parent, attribList), fft_size(0), in(NULL), out(NULL), plan(NULL), fft_ceil_ma(1), fft_ceil_maa(1), fft_floor_ma(0), fft_floor_maa( + 0), waterfallCanvas(NULL) { glContext = new SpectrumContext(this, &wxGetApp().GetContext(this)); - mTracker.setTarget(this); mTracker.setVertDragLock(true); SetCursor(wxCURSOR_SIZEWE); @@ -131,7 +129,6 @@ void SpectrumCanvas::setData(DemodulatorThreadIQData *input) { double b = out[n][1]; double c = sqrt(a * a + b * b); -// n = (i == FFT_SIZE / 2) ? (FFT_SIZE / 2 + 1) : i; double x = out[fft_size / 2 + n][0]; double y = out[fft_size / 2 + n][1]; double z = sqrt(x * x + y * y); @@ -172,48 +169,12 @@ void SpectrumCanvas::setData(DemodulatorThreadIQData *input) { } } -void SpectrumCanvas::SetView(int center_freq_in, int bandwidth_in) { - isView = true; - center_freq = center_freq_in; - bandwidth = bandwidth_in; -} - -void SpectrumCanvas::DisableView() { - isView = false; - center_freq = wxGetApp().getFrequency(); - bandwidth = SRATE; -} - -void SpectrumCanvas::SetCenterFrequency(unsigned int center_freq_in) { - center_freq = center_freq_in; -} - -unsigned int SpectrumCanvas::GetCenterFrequency() { - if (isView) { - return center_freq; - } else { - return (unsigned int) wxGetApp().getFrequency(); - } -} - -void SpectrumCanvas::SetBandwidth(unsigned int bandwidth_in) { - bandwidth = bandwidth_in; -} - -unsigned int SpectrumCanvas::GetBandwidth() { - if (isView) { - return bandwidth; - } else { - return SRATE; - } -} - void SpectrumCanvas::OnIdle(wxIdleEvent &event) { Refresh(false); } void SpectrumCanvas::mouseMoved(wxMouseEvent& event) { - mTracker.OnMouseMoved(event); + InteractiveCanvas::mouseMoved(event); if (mTracker.mouseDown()) { int freqChange = mTracker.getDeltaMouseX() * GetBandwidth(); @@ -226,12 +187,12 @@ void SpectrumCanvas::mouseMoved(wxMouseEvent& event) { waterfallCanvas->SetCenterFrequency(center_freq); } - int bw = (int)bandwidth; - int bwOfs = ((int)center_freq>freq)?((int)bandwidth/2):(-(int)bandwidth/2); - int freqEdge = ((int)center_freq+bwOfs); + int bw = (int) bandwidth; + int bwOfs = ((int) center_freq > freq) ? ((int) bandwidth / 2) : (-(int) bandwidth / 2); + int freqEdge = ((int) center_freq + bwOfs); - if (abs(freq-freqEdge) > (SRATE/2)) { - freqChange = -(((int)center_freq>freq)?(freqEdge-freq-(SRATE/2)):(freqEdge-freq+(SRATE/2))); + if (abs(freq - freqEdge) > (SRATE / 2)) { + freqChange = -(((int) center_freq > freq) ? (freqEdge - freq - (SRATE / 2)) : (freqEdge - freq + (SRATE / 2))); } else { freqChange = 0; } @@ -250,28 +211,25 @@ void SpectrumCanvas::mouseMoved(wxMouseEvent& event) { } void SpectrumCanvas::mouseDown(wxMouseEvent& event) { - mTracker.OnMouseDown(event); + InteractiveCanvas::mouseDown(event); SetCursor(wxCURSOR_CROSS); } void SpectrumCanvas::mouseWheelMoved(wxMouseEvent& event) { - mTracker.OnMouseWheelMoved(event); + InteractiveCanvas::mouseWheelMoved(event); } void SpectrumCanvas::mouseReleased(wxMouseEvent& event) { - mTracker.OnMouseReleased(event); + InteractiveCanvas::mouseReleased(event); SetCursor(wxCURSOR_SIZEWE); } void SpectrumCanvas::mouseLeftWindow(wxMouseEvent& event) { - mTracker.OnMouseLeftWindow(event); + InteractiveCanvas::mouseLeftWindow(event); SetCursor(wxCURSOR_SIZEWE); } void SpectrumCanvas::attachWaterfallCanvas(WaterfallCanvas* canvas_in) { waterfallCanvas = canvas_in; } -//void SpectrumCanvas::rightClick(wxMouseEvent& event) {} -//void SpectrumCanvas::keyPressed(wxKeyEvent& event) {} -//void SpectrumCanvas::keyReleased(wxKeyEvent& event) {} diff --git a/src/visual/SpectrumCanvas.h b/src/visual/SpectrumCanvas.h index 45e2d67..6a5cfe8 100644 --- a/src/visual/SpectrumCanvas.h +++ b/src/visual/SpectrumCanvas.h @@ -6,6 +6,7 @@ #include #include +#include "InteractiveCanvas.h" #include "SpectrumContext.h" #include "fftw3.h" @@ -13,7 +14,7 @@ class WaterfallCanvas; -class SpectrumCanvas: public wxGLCanvas { +class SpectrumCanvas: public InteractiveCanvas { public: std::vector spectrum_points; @@ -22,16 +23,6 @@ public: ~SpectrumCanvas(); void setData(DemodulatorThreadIQData *input); - - void SetView(int center_freq_in, int bandwidth_in); - void DisableView(); - - void SetCenterFrequency(unsigned int center_freq_in); - unsigned int GetCenterFrequency(); - - void SetBandwidth(unsigned int bandwidth_in); - unsigned int GetBandwidth(); - void attachWaterfallCanvas(WaterfallCanvas *canvas_in); private: @@ -47,8 +38,6 @@ private: // void rightClick(wxMouseEvent& event); void mouseLeftWindow(wxMouseEvent& event); - wxWindow *parent; - fftw_complex *in, *out; fftw_plan plan; @@ -62,13 +51,6 @@ private: SpectrumContext *glContext; WaterfallCanvas *waterfallCanvas; int fft_size; - - unsigned int center_freq; - unsigned int bandwidth; - - bool isView; - - MouseTracker mTracker; // event table wxDECLARE_EVENT_TABLE(); }; diff --git a/src/visual/WaterfallCanvas.cpp b/src/visual/WaterfallCanvas.cpp index 34cc9dd..06c889f 100644 --- a/src/visual/WaterfallCanvas.cpp +++ b/src/visual/WaterfallCanvas.cpp @@ -31,11 +31,9 @@ EVT_ENTER_WINDOW(WaterfallCanvas::mouseEnterWindow) wxEND_EVENT_TABLE() WaterfallCanvas::WaterfallCanvas(wxWindow *parent, int *attribList) : - wxGLCanvas(parent, wxID_ANY, attribList, wxDefaultPosition, wxDefaultSize, - wxFULL_REPAINT_ON_RESIZE), parent(parent), spectrumCanvas(NULL), activeDemodulatorBandwidth(0), activeDemodulatorFrequency(0), dragState( - WF_DRAG_NONE), nextDragState(WF_DRAG_NONE), shiftDown(false), altDown(false), ctrlDown(false), fft_size(0), waterfall_lines(0), plan( - NULL), in(NULL), out(NULL), center_freq(0), bandwidth(0), isView(false), resampler(NULL), resample_ratio(0), last_bandwidth(0), last_input_bandwidth( - 0), zoom(0) { + InteractiveCanvas(parent, attribList), spectrumCanvas(NULL), activeDemodulatorBandwidth(0), activeDemodulatorFrequency(0), dragState( + WF_DRAG_NONE), nextDragState(WF_DRAG_NONE), fft_size(0), waterfall_lines(0), plan( + NULL), in(NULL), out(NULL), resampler(NULL), resample_ratio(0), last_input_bandwidth(0), zoom(0) { glContext = new WaterfallContext(this, &wxGetApp().GetContext(this)); @@ -45,7 +43,6 @@ WaterfallCanvas::WaterfallCanvas(wxWindow *parent, int *attribList) : fft_ceil_ma = fft_ceil_maa = 100.0; fft_floor_ma = fft_floor_maa = 0.0; - mTracker.setTarget(this); SetCursor(wxCURSOR_CROSS); } @@ -53,20 +50,6 @@ WaterfallCanvas::~WaterfallCanvas() { nco_crcf_destroy(nco_shift); } -void WaterfallCanvas::SetView(int center_freq_in, int bandwidth_in) { - isView = true; - center_freq = center_freq_in; - bandwidth = bandwidth_in; - last_bandwidth = 0; -} - -void WaterfallCanvas::DisableView() { - isView = false; - center_freq = wxGetApp().getFrequency(); - bandwidth = SRATE; - last_bandwidth = 0; -} - void WaterfallCanvas::Setup(int fft_size_in, int waterfall_lines_in) { if (fft_size == fft_size_in && waterfall_lines_in == waterfall_lines) { return; @@ -90,38 +73,6 @@ void WaterfallCanvas::Setup(int fft_size_in, int waterfall_lines_in) { glContext->Setup(fft_size, waterfall_lines); } -int WaterfallCanvas::GetFrequencyAt(float x) { - int iqCenterFreq = GetCenterFrequency(); - int iqBandwidth = GetBandwidth(); - int freq = iqCenterFreq - (int) (0.5 * (float) iqBandwidth) + (int) ((float) x * (float) iqBandwidth); - - return freq; -} - -void WaterfallCanvas::SetCenterFrequency(unsigned int center_freq_in) { - center_freq = center_freq_in; -} - -unsigned int WaterfallCanvas::GetCenterFrequency() { - if (isView) { - return center_freq; - } else { - return (unsigned int) wxGetApp().getFrequency(); - } -} - -void WaterfallCanvas::SetBandwidth(unsigned int bandwidth_in) { - bandwidth = bandwidth_in; -} - -unsigned int WaterfallCanvas::GetBandwidth() { - if (isView) { - return bandwidth; - } else { - return SRATE; - } -} - WaterfallCanvas::DragState WaterfallCanvas::getDragState() { return dragState; } @@ -221,6 +172,7 @@ void WaterfallCanvas::OnPaint(wxPaintEvent& WXUNUSED(event)) { } void WaterfallCanvas::OnKeyUp(wxKeyEvent& event) { + InteractiveCanvas::OnKeyUp(event); shiftDown = event.ShiftDown(); altDown = event.AltDown(); ctrlDown = event.ControlDown(); @@ -235,12 +187,9 @@ void WaterfallCanvas::OnKeyUp(wxKeyEvent& event) { } void WaterfallCanvas::OnKeyDown(wxKeyEvent& event) { + InteractiveCanvas::OnKeyDown(event); float angle = 5.0; - shiftDown = event.ShiftDown(); - altDown = event.AltDown(); - ctrlDown = event.ControlDown(); - DemodulatorInstance *activeDemod = wxGetApp().getDemodMgr().getActiveDemodulator(); unsigned int freq; @@ -256,8 +205,20 @@ void WaterfallCanvas::OnKeyDown(wxKeyEvent& event) { freq = wxGetApp().getFrequency(); if (shiftDown) { freq += SRATE * 10; + if (isView) { + SetView(center_freq + SRATE * 10, GetBandwidth()); + if (spectrumCanvas) { + spectrumCanvas->SetView(GetCenterFrequency(), GetBandwidth()); + } + } } else { freq += SRATE / 2; + if (isView) { + SetView(center_freq + SRATE / 2, GetBandwidth()); + if (spectrumCanvas) { + spectrumCanvas->SetView(GetCenterFrequency(), GetBandwidth()); + } + } } wxGetApp().setFrequency(freq); ((wxFrame*) parent)->GetStatusBar()->SetStatusText(wxString::Format(wxT("Set center frequency: %i"), freq)); @@ -266,11 +227,23 @@ void WaterfallCanvas::OnKeyDown(wxKeyEvent& event) { freq = wxGetApp().getFrequency(); if (shiftDown) { freq -= SRATE * 10; + if (isView) { + SetView(center_freq - SRATE * 10, GetBandwidth()); + if (spectrumCanvas) { + spectrumCanvas->SetView(GetCenterFrequency(), GetBandwidth()); + } + } } else { freq -= SRATE / 2; + if (isView) { + SetView(center_freq - SRATE / 2, GetBandwidth()); + if (spectrumCanvas) { + spectrumCanvas->SetView(GetCenterFrequency(), GetBandwidth()); + } + } } wxGetApp().setFrequency(freq); - ((wxFrame*) parent)->GetStatusBar()->SetStatusText(wxString::Format(wxT("Set center frequency: %i"), freq)); + ((wxFrame*) parent)->GetStatusBar()->SetStatusText(wxString::Format(wxT("Set center frequenfcy: %i"), freq)); break; case 'D': case WXK_DELETE: @@ -542,12 +515,7 @@ void WaterfallCanvas::OnIdle(wxIdleEvent &event) { } void WaterfallCanvas::mouseMoved(wxMouseEvent& event) { - mTracker.OnMouseMoved(event); - - shiftDown = event.ShiftDown(); - altDown = event.AltDown(); - ctrlDown = event.ControlDown(); - + InteractiveCanvas::mouseMoved(event); DemodulatorInstance *demod = wxGetApp().getDemodMgr().getActiveDemodulator(); if (mTracker.mouseDown()) { @@ -670,12 +638,9 @@ void WaterfallCanvas::mouseMoved(wxMouseEvent& event) { } void WaterfallCanvas::mouseDown(wxMouseEvent& event) { - mTracker.OnMouseDown(event); - dragState = nextDragState; + InteractiveCanvas::mouseDown(event); - shiftDown = event.ShiftDown(); - altDown = event.AltDown(); - ctrlDown = event.ControlDown(); + dragState = nextDragState; if (dragState && dragState != WF_DRAG_RANGE) { wxGetApp().getDemodMgr().setActiveDemodulator(wxGetApp().getDemodMgr().getActiveDemodulator(), false); @@ -686,15 +651,11 @@ void WaterfallCanvas::mouseDown(wxMouseEvent& event) { } void WaterfallCanvas::mouseWheelMoved(wxMouseEvent& event) { - mTracker.OnMouseWheelMoved(event); + InteractiveCanvas::mouseWheelMoved(event); } void WaterfallCanvas::mouseReleased(wxMouseEvent& event) { - mTracker.OnMouseReleased(event); - - shiftDown = event.ShiftDown(); - altDown = event.AltDown(); - ctrlDown = event.ControlDown(); + InteractiveCanvas::mouseReleased(event); bool isNew = shiftDown || (wxGetApp().getDemodMgr().getLastActiveDemodulator() && !wxGetApp().getDemodMgr().getLastActiveDemodulator()->isActive()); @@ -819,13 +780,13 @@ void WaterfallCanvas::mouseReleased(wxMouseEvent& event) { } void WaterfallCanvas::mouseLeftWindow(wxMouseEvent& event) { - mTracker.OnMouseLeftWindow(event); + InteractiveCanvas::mouseLeftWindow(event); SetCursor(wxCURSOR_CROSS); wxGetApp().getDemodMgr().setActiveDemodulator(NULL); } void WaterfallCanvas::mouseEnterWindow(wxMouseEvent& event) { - mTracker.OnMouseEnterWindow(event); + InteractiveCanvas::mouseEnterWindow(event); SetCursor(wxCURSOR_CROSS); } diff --git a/src/visual/WaterfallCanvas.h b/src/visual/WaterfallCanvas.h index 582109c..1264103 100644 --- a/src/visual/WaterfallCanvas.h +++ b/src/visual/WaterfallCanvas.h @@ -6,13 +6,14 @@ #include #include +#include "InteractiveCanvas.h" #include "WaterfallContext.h" #include "MouseTracker.h" #include "SpectrumCanvas.h" #include "fftw3.h" -class WaterfallCanvas: public wxGLCanvas { +class WaterfallCanvas: public InteractiveCanvas { public: enum DragState { WF_DRAG_NONE, WF_DRAG_BANDWIDTH_LEFT, WF_DRAG_BANDWIDTH_RIGHT, WF_DRAG_FREQUENCY, WF_DRAG_RANGE @@ -23,16 +24,6 @@ public: ~WaterfallCanvas(); void setData(DemodulatorThreadIQData *input); - int GetFrequencyAt(float x); - - void SetView(int center_freq_in, int bandwidth_in); - void DisableView(); - - void SetCenterFrequency(unsigned int center_freq_in); - unsigned int GetCenterFrequency(); - - void SetBandwidth(unsigned int bandwidth_in); - unsigned int GetBandwidth(); DragState getDragState(); DragState getNextDragState(); @@ -53,7 +44,6 @@ private: void mouseEnterWindow(wxMouseEvent& event); void mouseLeftWindow(wxMouseEvent& event); - wxWindow *parent; SpectrumCanvas *spectrumCanvas; std::vector spectrum_points; @@ -68,7 +58,6 @@ private: std::vector fft_result_maa; WaterfallContext *glContext; - MouseTracker mTracker; int activeDemodulatorBandwidth; int activeDemodulatorFrequency; @@ -76,25 +65,15 @@ private: DragState dragState; DragState nextDragState; - bool shiftDown; - bool altDown; - bool ctrlDown; - int fft_size; int waterfall_lines; - unsigned int center_freq; - unsigned int bandwidth; - - bool isView; msresamp_crcf resampler; double resample_ratio; nco_crcf nco_shift; int shift_freq; int last_input_bandwidth; - int last_bandwidth; - int zoom; std::vector shift_buffer;