From a3a33eb3fe54b01728143560a1c8703726b6654d Mon Sep 17 00:00:00 2001 From: "Charles J. Cliffe" Date: Wed, 22 Apr 2015 22:54:48 -0400 Subject: [PATCH] Set PPM via Tuning bar by holding ALT --- src/AppFrame.cpp | 3 ++ src/CubicSDR.cpp | 4 +++ src/CubicSDR.h | 1 + src/visual/InteractiveCanvas.cpp | 22 ++++++++++-- src/visual/InteractiveCanvas.h | 4 +++ src/visual/ScopeCanvas.cpp | 12 +++++-- src/visual/ScopeCanvas.h | 4 +++ src/visual/ScopeContext.cpp | 4 +-- src/visual/ScopeContext.h | 2 +- src/visual/TuningCanvas.cpp | 60 ++++++++++++++++++++++++++++---- src/visual/TuningCanvas.h | 8 ++++- 11 files changed, 109 insertions(+), 15 deletions(-) diff --git a/src/AppFrame.cpp b/src/AppFrame.cpp index f2b0fad..cd64321 100644 --- a/src/AppFrame.cpp +++ b/src/AppFrame.cpp @@ -323,6 +323,7 @@ void AppFrame::OnMenu(wxCommandEvent& event) { long ofs = wxGetNumberFromUser("Frequency correction for device in PPM.\ni.e. -51 for -51 PPM", "Parts per million (PPM)", "Frequency Correction", wxGetApp().getPPM(), -1000, 1000, this); wxGetApp().setPPM(ofs); + wxGetApp().saveConfig(); } else if (event.GetId() == wxID_SAVE) { if (!currentSessionFile.empty()) { saveSession(currentSessionFile); @@ -531,6 +532,8 @@ void AppFrame::OnIdle(wxIdleEvent& event) { waterfallCanvas->SetFocus(); } + scopeCanvas->setPPMMode(demodTuner->isAltDown()); + event.Skip(); } diff --git a/src/CubicSDR.cpp b/src/CubicSDR.cpp index 7966ae0..be24cd5 100644 --- a/src/CubicSDR.cpp +++ b/src/CubicSDR.cpp @@ -239,6 +239,10 @@ AppConfig *CubicSDR::getConfig() { return &config; } +void CubicSDR::saveConfig() { + config.save(); +} + void CubicSDR::setPPM(int ppm_in) { if (sdrThread->getDeviceId() < 0) { return; diff --git a/src/CubicSDR.h b/src/CubicSDR.h index 1c6da6a..38975c3 100644 --- a/src/CubicSDR.h +++ b/src/CubicSDR.h @@ -51,6 +51,7 @@ public: void removeDemodulator(DemodulatorInstance *demod); AppConfig *getConfig(); + void saveConfig(); void setPPM(int ppm_in); int getPPM(); diff --git a/src/visual/InteractiveCanvas.cpp b/src/visual/InteractiveCanvas.cpp index 9a24165..19cc0bc 100644 --- a/src/visual/InteractiveCanvas.cpp +++ b/src/visual/InteractiveCanvas.cpp @@ -81,6 +81,18 @@ MouseTracker *InteractiveCanvas::getMouseTracker() { return &mouseTracker; } +bool InteractiveCanvas::isAltDown() { + return altDown; +} + +bool InteractiveCanvas::isCtrlDown() { + return ctrlDown; +} + +bool InteractiveCanvas::isShiftDown() { + return shiftDown; +} + void InteractiveCanvas::OnKeyUp(wxKeyEvent& event) { shiftDown = event.ShiftDown(); altDown = event.AltDown(); @@ -88,8 +100,6 @@ void InteractiveCanvas::OnKeyUp(wxKeyEvent& event) { } void InteractiveCanvas::OnKeyDown(wxKeyEvent& event) { - float angle = 5.0; - shiftDown = event.ShiftDown(); altDown = event.AltDown(); ctrlDown = event.ControlDown(); @@ -125,10 +135,18 @@ void InteractiveCanvas::OnMouseReleased(wxMouseEvent& event) { void InteractiveCanvas::OnMouseLeftWindow(wxMouseEvent& event) { mouseTracker.OnMouseLeftWindow(event); + + shiftDown = false; + altDown = false; + ctrlDown = false; } void InteractiveCanvas::OnMouseEnterWindow(wxMouseEvent& event) { mouseTracker.OnMouseEnterWindow(event); + + shiftDown = event.ShiftDown(); + altDown = event.AltDown(); + ctrlDown = event.ControlDown(); } void InteractiveCanvas::setStatusText(std::string statusText) { diff --git a/src/visual/InteractiveCanvas.h b/src/visual/InteractiveCanvas.h index 055dcc9..bbc4024 100644 --- a/src/visual/InteractiveCanvas.h +++ b/src/visual/InteractiveCanvas.h @@ -25,6 +25,10 @@ public: MouseTracker *getMouseTracker(); + bool isAltDown(); + bool isCtrlDown(); + bool isShiftDown(); + protected: void OnKeyDown(wxKeyEvent& event); void OnKeyUp(wxKeyEvent& event); diff --git a/src/visual/ScopeCanvas.cpp b/src/visual/ScopeCanvas.cpp index cc8c000..2b01de8 100644 --- a/src/visual/ScopeCanvas.cpp +++ b/src/visual/ScopeCanvas.cpp @@ -21,7 +21,7 @@ wxEND_EVENT_TABLE() ScopeCanvas::ScopeCanvas(wxWindow *parent, int *attribList) : wxGLCanvas(parent, wxID_ANY, attribList, wxDefaultPosition, wxDefaultSize, - wxFULL_REPAINT_ON_RESIZE), parent(parent), stereo(false) { + wxFULL_REPAINT_ON_RESIZE), parent(parent), stereo(false), ppmMode(false) { glContext = new ScopeContext(this, &wxGetApp().GetContext(this)); } @@ -43,6 +43,14 @@ void ScopeCanvas::setDeviceName(std::string device_name) { deviceName.append(" "); } +void ScopeCanvas::setPPMMode(bool ppmMode) { + this->ppmMode = ppmMode; +} + +bool ScopeCanvas::getPPMMode() { + return ppmMode; +} + void ScopeCanvas::OnPaint(wxPaintEvent& WXUNUSED(event)) { wxPaintDC dc(this); #ifdef __APPLE__ // force half-rate? @@ -75,7 +83,7 @@ void ScopeCanvas::OnPaint(wxPaintEvent& WXUNUSED(event)) { glViewport(0, 0, ClientSize.x, ClientSize.y); glContext->DrawBegin(); - glContext->Plot(waveform_points, stereo); + glContext->Plot(waveform_points, stereo, ppmMode); if (!deviceName.empty()) { glContext->DrawDeviceName(deviceName); } diff --git a/src/visual/ScopeCanvas.h b/src/visual/ScopeCanvas.h index 94f3328..cb24fee 100644 --- a/src/visual/ScopeCanvas.h +++ b/src/visual/ScopeCanvas.h @@ -19,6 +19,9 @@ public: void setWaveformPoints(std::vector &waveform_points_in); void setStereo(bool state); void setDeviceName(std::string device_name); + void setPPMMode(bool ppmMode); + bool getPPMMode(); + private: void OnPaint(wxPaintEvent& event); @@ -29,6 +32,7 @@ private: ScopeContext *glContext; std::string deviceName; bool stereo; + bool ppmMode; // event table wxDECLARE_EVENT_TABLE(); }; diff --git a/src/visual/ScopeContext.cpp b/src/visual/ScopeContext.cpp index 6b72c4a..b90f19e 100644 --- a/src/visual/ScopeContext.cpp +++ b/src/visual/ScopeContext.cpp @@ -23,7 +23,7 @@ void ScopeContext::DrawBegin() { glDisable (GL_TEXTURE_2D); } -void ScopeContext::Plot(std::vector &points, bool stereo) { +void ScopeContext::Plot(std::vector &points, bool stereo, bool ppmMode) { if (stereo) { glBegin(GL_QUADS); glColor3f(ThemeMgr::mgr.currentTheme->scopeBackground.r, ThemeMgr::mgr.currentTheme->scopeBackground.g, ThemeMgr::mgr.currentTheme->scopeBackground.b); @@ -81,7 +81,7 @@ void ScopeContext::Plot(std::vector &points, bool stereo) { glColor3f(0.65, 0.65, 0.65); - getFont(PrimaryGLContext::GLFONT_SIZE12).drawString("Frequency", -0.66, -1.0+hPos, 12, GLFont::GLFONT_ALIGN_CENTER, GLFont::GLFONT_ALIGN_CENTER); + getFont(PrimaryGLContext::GLFONT_SIZE12).drawString(ppmMode?"Device PPM":"Frequency", -0.66, -1.0+hPos, 12, GLFont::GLFONT_ALIGN_CENTER, GLFont::GLFONT_ALIGN_CENTER); getFont(PrimaryGLContext::GLFONT_SIZE12).drawString("Bandwidth", 0.0, -1.0+hPos, 12, GLFont::GLFONT_ALIGN_CENTER, GLFont::GLFONT_ALIGN_CENTER); getFont(PrimaryGLContext::GLFONT_SIZE12).drawString("Center Frequency", 0.66, -1.0+hPos, 12, GLFont::GLFONT_ALIGN_CENTER, GLFont::GLFONT_ALIGN_CENTER); diff --git a/src/visual/ScopeContext.h b/src/visual/ScopeContext.h index d4fa1a0..4afc6ad 100644 --- a/src/visual/ScopeContext.h +++ b/src/visual/ScopeContext.h @@ -12,7 +12,7 @@ public: ScopeContext(ScopeCanvas *canvas, wxGLContext *sharedContext); void DrawBegin(); - void Plot(std::vector &points, bool stereo=false); + void Plot(std::vector &points, bool stereo=false, bool ppmMode=false); void DrawDeviceName(std::string deviceName); void DrawDivider(); void DrawEnd(); diff --git a/src/visual/TuningCanvas.cpp b/src/visual/TuningCanvas.cpp index 30e8479..a7e5416 100644 --- a/src/visual/TuningCanvas.cpp +++ b/src/visual/TuningCanvas.cpp @@ -23,6 +23,8 @@ EVT_LEFT_UP(TuningCanvas::OnMouseReleased) EVT_LEAVE_WINDOW(TuningCanvas::OnMouseLeftWindow) EVT_ENTER_WINDOW(TuningCanvas::OnMouseEnterWindow) EVT_MOUSEWHEEL(TuningCanvas::OnMouseWheelMoved) +EVT_KEY_DOWN(TuningCanvas::OnKeyDown) +EVT_KEY_UP(TuningCanvas::OnKeyUp) wxEND_EVENT_TABLE() TuningCanvas::TuningCanvas(wxWindow *parent, int *attribList) : @@ -44,6 +46,8 @@ TuningCanvas::TuningCanvas(wxWindow *parent, int *attribList) : centerDP = -1.0 + (2.0 / 3.0) * 2.0; centerW = (1.0 / 3.0) * 2.0; + + currentPPM = lastPPM = 0; } TuningCanvas::~TuningCanvas() { @@ -110,10 +114,17 @@ void TuningCanvas::OnPaint(wxPaintEvent& WXUNUSED(event)) { break; case TUNING_HOVER_NONE: break; - } + case TUNING_HOVER_PPM: + glContext->DrawTunerBarIndexed(hoverIndex, hoverIndex, 11, freqDP, freqW, clr, 0.25, top, bottom); // freq + break; + } } - glContext->DrawTuner(freq, 11, freqDP, freqW); + if (altDown) { + glContext->DrawTuner(currentPPM, 11, freqDP, freqW); + } else { + glContext->DrawTuner(freq, 11, freqDP, freqW); + } glContext->DrawTuner(bw, 7, bwDP, bwW); glContext->DrawTuner(center, 11, centerDP, centerW); @@ -179,6 +190,25 @@ void TuningCanvas::StepTuner(ActiveState state, int exponent, bool up) { wxGetApp().setFrequency(ctr); } + + if (state == TUNING_HOVER_PPM) { + if (shiftDown) { + bool carried = (long long)((currentPPM) / (exp * 10)) != (long long)((currentPPM + amount) / (exp * 10)) || (bottom && currentPPM < exp); + currentPPM += carried?(9*-amount):amount; + } else { + currentPPM += amount; + } + + if (currentPPM > 2000) { + currentPPM = 2000; + } + + if (currentPPM < -2000) { + currentPPM = -2000; + } + + wxGetApp().setPPM(currentPPM); + } } void TuningCanvas::OnIdle(wxIdleEvent &event) { @@ -215,7 +245,7 @@ void TuningCanvas::OnMouseMoved(wxMouseEvent& event) { index = glContext->GetTunerDigitIndex(mouseTracker.getMouseX(), 11, freqDP, freqW); // freq if (index > 0) { hoverIndex = index; - hoverState = TUNING_HOVER_FREQ; + hoverState = altDown?TUNING_HOVER_PPM:TUNING_HOVER_FREQ; } if (!index) { @@ -240,15 +270,18 @@ void TuningCanvas::OnMouseMoved(wxMouseEvent& event) { } else { switch (hoverState) { case TUNING_HOVER_FREQ: - setStatusText("Click or drag a digit to change frequency. Hold shift to disable carry."); + setStatusText("Click or drag a digit to change frequency. Hold ALT to change PPM. Hold SHIFT to disable carry."); break; case TUNING_HOVER_BW: - setStatusText("Click or drag a digit to change bandwidth. Hold shift to disable carry."); + setStatusText("Click or drag a digit to change bandwidth. Hold SHIFT to disable carry."); break; case TUNING_HOVER_CENTER: - setStatusText("Click or drag a digit to change center frequency. Hold shift to disable carry."); + setStatusText("Click or drag a digit to change center frequency. Hold SHIFT to disable carry."); break; - } + case TUNING_HOVER_PPM: + setStatusText("Click or drag a digit to change device PPM offset. Hold SHIFT to disable carry."); + break; + } } @@ -305,6 +338,10 @@ void TuningCanvas::OnMouseLeftWindow(wxMouseEvent& event) { SetCursor(wxCURSOR_CROSS); hoverIndex = 0; hoverState = TUNING_HOVER_NONE; + + if (currentPPM != lastPPM) { + wxGetApp().saveConfig(); + } } void TuningCanvas::OnMouseEnterWindow(wxMouseEvent& event) { @@ -312,8 +349,17 @@ void TuningCanvas::OnMouseEnterWindow(wxMouseEvent& event) { SetCursor(wxCURSOR_ARROW); hoverIndex = 0; hoverState = TUNING_HOVER_NONE; + lastPPM = currentPPM = wxGetApp().getPPM(); } void TuningCanvas::setHelpTip(std::string tip) { helpTip = tip; } + +void TuningCanvas::OnKeyDown(wxKeyEvent& event) { + InteractiveCanvas::OnKeyDown(event); +} + +void TuningCanvas::OnKeyUp(wxKeyEvent& event) { + InteractiveCanvas::OnKeyUp(event); +} diff --git a/src/visual/TuningCanvas.h b/src/visual/TuningCanvas.h index 21b22c5..d6e2cee 100644 --- a/src/visual/TuningCanvas.h +++ b/src/visual/TuningCanvas.h @@ -16,7 +16,7 @@ class TuningCanvas: public InteractiveCanvas { public: enum ActiveState { - TUNING_HOVER_NONE, TUNING_HOVER_FREQ, TUNING_HOVER_BW, TUNING_HOVER_CENTER + TUNING_HOVER_NONE, TUNING_HOVER_FREQ, TUNING_HOVER_BW, TUNING_HOVER_PPM, TUNING_HOVER_CENTER }; TuningCanvas(wxWindow *parent, int *attribList = NULL); ~TuningCanvas(); @@ -33,6 +33,9 @@ private: void OnMouseReleased(wxMouseEvent& event); void OnMouseEnterWindow(wxMouseEvent& event); void OnMouseLeftWindow(wxMouseEvent& event); + void OnKeyDown(wxKeyEvent& event); + void OnKeyUp(wxKeyEvent& event); + void StepTuner(ActiveState state, int factor, bool up = true); TuningContext *glContext; @@ -58,6 +61,9 @@ private: bool top; bool bottom; + int currentPPM; + int lastPPM; + // wxDECLARE_EVENT_TABLE(); };