diff --git a/src/AppConfig.cpp b/src/AppConfig.cpp index 42d3b6a..63d7eb1 100644 --- a/src/AppConfig.cpp +++ b/src/AppConfig.cpp @@ -198,6 +198,7 @@ AppConfig::AppConfig() : configName("") { winW.store(0); winH.store(0); winMax.store(false); + showTips.store(true); themeId.store(0); snap.store(1); centerFreq.store(100000000); @@ -253,6 +254,14 @@ bool AppConfig::getWindowMaximized() { return winMax.load(); } +void AppConfig::setShowTips(bool show) { + showTips.store(show); +} + +bool AppConfig::getShowTips() { + return showTips.load(); +} + wxRect *AppConfig::getWindow() { wxRect *r = NULL; if (winH.load() && winW.load()) { @@ -347,6 +356,7 @@ bool AppConfig::save() { *window_node->newChild("h") = winH.load(); *window_node->newChild("max") = winMax.load(); + *window_node->newChild("tips") = showTips.load(); *window_node->newChild("theme") = themeId.load(); *window_node->newChild("snap") = snap.load(); *window_node->newChild("center_freq") = centerFreq.load(); @@ -426,7 +436,7 @@ bool AppConfig::load() { if (cfg.rootNode()->hasAnother("window")) { int x,y,w,h; - int max; + int max,tips; DataNode *win_node = cfg.rootNode()->getNext("window"); @@ -447,6 +457,11 @@ bool AppConfig::load() { winMax.store(max?true:false); } + if (win_node->hasAnother("tips")) { + win_node->getNext("tips")->element()->get(tips); + showTips.store(tips?true:false); + } + if (win_node->hasAnother("theme")) { int theme; win_node->getNext("theme")->element()->get(theme); diff --git a/src/AppConfig.h b/src/AppConfig.h index b40ec12..8227c3b 100644 --- a/src/AppConfig.h +++ b/src/AppConfig.h @@ -70,6 +70,9 @@ public: void setWindowMaximized(bool max); bool getWindowMaximized(); + void setShowTips(bool show); + bool getShowTips(); + void setTheme(int themeId); int getTheme(); @@ -109,7 +112,7 @@ private: std::string configName; std::map deviceConfig; std::atomic_int winX,winY,winW,winH; - std::atomic_bool winMax; + std::atomic_bool winMax, showTips; std::atomic_int themeId; std::atomic_llong snap; std::atomic_llong centerFreq; diff --git a/src/AppFrame.cpp b/src/AppFrame.cpp index cdc68ea..205f6d6 100644 --- a/src/AppFrame.cpp +++ b/src/AppFrame.cpp @@ -78,7 +78,7 @@ AppFrame::AppFrame() : demodModeSelector->addChoice("DSB"); demodModeSelector->addChoice("I/Q"); demodModeSelector->setSelection("FM"); - demodModeSelector->setHelpTip("Choose modulation type: Frequency Modulation, Amplitude Modulation and Lower, Upper or Double Side-Band."); + demodModeSelector->setHelpTip("Choose modulation type: Frequency Modulation (Hotkey F), Amplitude Modulation (A) and Lower (L), Upper (U), Double Side-Band and more."); demodModeSelector->SetMinSize(wxSize(40,-1)); demodModeSelector->SetMaxSize(wxSize(40,-1)); demodTray->Add(demodModeSelector, 2, wxEXPAND | wxALL, 0); @@ -287,9 +287,6 @@ AppFrame::AppFrame() : this->SetSizer(vbox); - // waterfallCanvas->SetFocusFromKbd(); - waterfallCanvas->SetFocus(); - // SetIcon(wxICON(sample)); // Make a menubar @@ -555,6 +552,10 @@ void AppFrame::updateDeviceParams() { // Build settings menu wxMenu *newSettingsMenu = new wxMenu; + showTipMenuItem = newSettingsMenu->AppendCheckItem(wxID_SET_TIPS, "Show Hover Tips"); + if (wxGetApp().getConfig()->getShowTips()) { + showTipMenuItem->Check(); + } newSettingsMenu->Append(wxID_SET_FREQ_OFFSET, "Frequency Offset"); if (devInfo->hasCORR(SOAPY_SDR_RX, 0)) { newSettingsMenu->Append(wxID_SET_PPM, "Device PPM"); @@ -676,6 +677,12 @@ void AppFrame::OnMenu(wxCommandEvent& event) { activeDemodulator->setOutputDevice(event.GetId() - wxID_RT_AUDIO_DEVICE); activeDemodulator = NULL; } + } else if (event.GetId() == wxID_SET_TIPS ) { + if (wxGetApp().getConfig()->getShowTips()) { + wxGetApp().getConfig()->setShowTips(false); + } else { + wxGetApp().getConfig()->setShowTips(true); + } } else if (event.GetId() == wxID_SET_FREQ_OFFSET) { long ofs = wxGetNumberFromUser("Shift the displayed frequency by this amount.\ni.e. -125000000 for -125 MHz", "Frequency (Hz)", "Frequency Offset", wxGetApp().getOffset(), -2000000000, 2000000000, this); @@ -1196,16 +1203,6 @@ void AppFrame::OnIdle(wxIdleEvent& event) { } } - if (demodTuner->getMouseTracker()->mouseInView()) { - if (!demodTuner->HasFocus()) { - demodTuner->SetFocus(); - } - } else if (!wxGetApp().isDeviceSelectorOpen() && (!modemProps || !modemProps->isMouseInView())) { - if (!waterfallCanvas->HasFocus()) { - waterfallCanvas->SetFocus(); - } - } - scopeCanvas->setPPMMode(demodTuner->isAltDown()); scopeCanvas->setShowDb(spectrumCanvas->getShowDb()); @@ -1276,6 +1273,8 @@ void AppFrame::OnIdle(wxIdleEvent& event) { if (!this->IsActive()) { std::this_thread::sleep_for(std::chrono::milliseconds(25)); + } else { + std::this_thread::sleep_for(std::chrono::milliseconds(1)); } event.RequestMore(); @@ -1540,3 +1539,151 @@ void AppFrame::setMainWaterfallFFTSize(int fftSize) { waterfallDataThread->getProcessor()->setFFTSize(fftSize); waterfallCanvas->setFFTSize(fftSize); } + + +void AppFrame::refreshGainUI() { + gainCanvas->updateGainUI(); + gainCanvas->Refresh(); +} + + +FrequencyDialog::FrequencyDialogTarget AppFrame::getFrequencyDialogTarget() { + FrequencyDialog::FrequencyDialogTarget target = FrequencyDialog::FrequencyDialogTarget::FDIALOG_TARGET_DEFAULT; + + if (waterfallSpeedMeter->getMouseTracker()->mouseInView()) { + target = FrequencyDialog::FrequencyDialogTarget::FDIALOG_TARGET_WATERFALL_LPS; + } + else if (spectrumAvgMeter->getMouseTracker()->mouseInView()) { + target = FrequencyDialog::FrequencyDialogTarget::FDIALOG_TARGET_SPECTRUM_AVG; + } + else if (demodTuner->getMouseTracker()->mouseInView()) { + switch (demodTuner->getHoverState()) { + case TuningCanvas::ActiveState::TUNING_HOVER_BW: + target = FrequencyDialog::FrequencyDialogTarget::FDIALOG_TARGET_BANDWIDTH; + break; + case TuningCanvas::ActiveState::TUNING_HOVER_FREQ: + target = FrequencyDialog::FrequencyDialogTarget::FDIALOG_TARGET_FREQ; + break; + case TuningCanvas::ActiveState::TUNING_HOVER_CENTER: + default: + target = FrequencyDialog::FrequencyDialogTarget::FDIALOG_TARGET_DEFAULT; + break; + + } + } + else if (gainCanvas->getMouseTracker()->mouseInView()) { + target = FrequencyDialog::FrequencyDialogTarget::FDIALOG_TARGET_GAIN; + } + return target; +} + +int AppFrame::OnGlobalKeyDown(wxKeyEvent &event) { + if (!this->IsActive()) { + return -1; + } + + switch (event.GetKeyCode()) { + case WXK_UP: + case WXK_NUMPAD_UP: + case WXK_DOWN: + case WXK_NUMPAD_DOWN: + case WXK_LEFT: + case WXK_NUMPAD_LEFT: + case WXK_RIGHT: + case WXK_NUMPAD_RIGHT: + waterfallCanvas->OnKeyDown(event); + return 1; + case 'A': + case 'F': + case 'L': + case 'U': + return 1; + case '0': + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + case '8': + case '9': + wxGetApp().showFrequencyInput(getFrequencyDialogTarget(), std::to_string(event.GetKeyCode() - '0')); + return 1; + break; + default: + break; + } + + if (demodTuner->getMouseTracker()->mouseInView()) { + demodTuner->OnKeyDown(event); + } else if (waterfallCanvas->getMouseTracker()->mouseInView()) { + waterfallCanvas->OnKeyDown(event); + } + + return 1; +} + +int AppFrame::OnGlobalKeyUp(wxKeyEvent &event) { + if (!this->IsActive()) { + return -1; + } + + switch (event.GetKeyCode()) { + case WXK_SPACE: + if (!demodTuner->getMouseTracker()->mouseInView()) { + wxGetApp().showFrequencyInput(getFrequencyDialogTarget()); + return 1; + } + break; + case WXK_UP: + case WXK_NUMPAD_UP: + case WXK_DOWN: + case WXK_NUMPAD_DOWN: + case WXK_LEFT: + case WXK_NUMPAD_LEFT: + case WXK_RIGHT: + case WXK_NUMPAD_RIGHT: + waterfallCanvas->OnKeyUp(event); + return 1; + case 'A': + demodModeSelector->setSelection("AM"); + break; + case 'F': + if (demodModeSelector->getSelectionLabel() == "FM") { + demodModeSelector->setSelection("FMS"); + } else { + demodModeSelector->setSelection("FM"); + } + break; + case 'L': + demodModeSelector->setSelection("LSB"); + break; + case 'U': + demodModeSelector->setSelection("USB"); + break; + default: + break; + } + + if (demodTuner->getMouseTracker()->mouseInView()) { + demodTuner->OnKeyUp(event); + } else if (waterfallCanvas->getMouseTracker()->mouseInView()) { + waterfallCanvas->OnKeyUp(event); + } + + + // TODO: Catch key-ups outside of original target + + return 1; +} + + +void AppFrame::setWaterfallLinesPerSecond(int lps) { + waterfallSpeedMeter->setUserInputValue(sqrt(lps)); +} + +void AppFrame::setSpectrumAvgSpeed(double avg) { + spectrumAvgMeter->setUserInputValue(avg); +} + diff --git a/src/AppFrame.h b/src/AppFrame.h index cfa549c..cbe6367 100644 --- a/src/AppFrame.h +++ b/src/AppFrame.h @@ -18,6 +18,7 @@ #include "SDRDeviceInfo.h" #include "ModemProperties.h" //#include "UITestCanvas.h" +#include "FrequencyDialog.h" #include @@ -25,6 +26,7 @@ #define wxID_SET_FREQ_OFFSET 2001 #define wxID_RESET 2002 #define wxID_SET_PPM 2003 +#define wxID_SET_TIPS 2004 #define wxID_SDR_DEVICES 2008 #define wxID_AGC_CONTROL 2009 @@ -75,6 +77,15 @@ public: void updateModemProperties(ModemArgInfoList args); void setMainWaterfallFFTSize(int fftSize); + int OnGlobalKeyDown(wxKeyEvent &event); + int OnGlobalKeyUp(wxKeyEvent &event); + + void setWaterfallLinesPerSecond(int lps); + void setSpectrumAvgSpeed(double avg); + + FrequencyDialog::FrequencyDialogTarget getFrequencyDialogTarget(); + void refreshGainUI(); + private: void OnMenu(wxCommandEvent& event); void OnClose(wxCloseEvent& event); @@ -132,6 +143,7 @@ private: ModemProperties *modemProps; std::atomic_bool modemPropertiesUpdated; ModemArgInfoList newModemArgs; + wxMenuItem *showTipMenuItem; #ifdef USE_HAMLIB wxMenu *rigMenu; diff --git a/src/CubicSDR.cpp b/src/CubicSDR.cpp index d023ad1..836f41a 100644 --- a/src/CubicSDR.cpp +++ b/src/CubicSDR.cpp @@ -134,6 +134,7 @@ CubicSDR::CubicSDR() : appframe(NULL), m_glContext(NULL), frequency(0), offset(0 sdrThread(NULL), sdrPostThread(NULL), spectrumVisualThread(NULL), demodVisualThread(NULL), pipeSDRIQData(NULL), pipeIQVisualData(NULL), pipeAudioVisualData(NULL), t_SDR(NULL), t_PostSDR(NULL) { sampleRateInitialized.store(false); agcMode.store(true); + fdlgTarget = FrequencyDialog::FDIALOG_TARGET_DEFAULT; } bool CubicSDR::OnInit() { @@ -649,11 +650,13 @@ int CubicSDR::getPPM() { return ppm; } - -void CubicSDR::showFrequencyInput(FrequencyDialog::FrequencyDialogTarget targetMode) { +void CubicSDR::showFrequencyInput(FrequencyDialog::FrequencyDialogTarget targetMode, wxString initString) { const wxString demodTitle("Set Demodulator Frequency"); const wxString freqTitle("Set Center Frequency"); - const wxString bwTitle("Set Demodulator Bandwidth"); + const wxString bwTitle("Modem Bandwidth (150Hz - 500KHz)"); + const wxString lpsTitle("Lines-Per-Second (1-1024)"); + const wxString avgTitle("Average Rate (0.1 - 0.99)"); + const wxString gainTitle("Gain Entry: "+wxGetApp().getActiveGainEntry()); wxString title; @@ -664,11 +667,23 @@ void CubicSDR::showFrequencyInput(FrequencyDialog::FrequencyDialogTarget targetM case FrequencyDialog::FDIALOG_TARGET_BANDWIDTH: title = bwTitle; break; + case FrequencyDialog::FDIALOG_TARGET_WATERFALL_LPS: + title = lpsTitle; + break; + case FrequencyDialog::FDIALOG_TARGET_SPECTRUM_AVG: + title = avgTitle; + break; + case FrequencyDialog::FDIALOG_TARGET_GAIN: + title = gainTitle; + if (wxGetApp().getActiveGainEntry() == "") { + return; + } + break; default: break; } - FrequencyDialog fdialog(appframe, -1, title, demodMgr.getActiveDemodulator(), wxPoint(-100,-100), wxSize(320, 75 ), wxDEFAULT_DIALOG_STYLE, targetMode); + FrequencyDialog fdialog(appframe, -1, title, demodMgr.getActiveDemodulator(), wxPoint(-100,-100), wxSize(350, 75), wxDEFAULT_DIALOG_STYLE, targetMode, initString); fdialog.ShowModal(); } @@ -749,6 +764,30 @@ std::string CubicSDR::getModulePath() { return modulePath; } +void CubicSDR::setActiveGainEntry(std::string gainName) { + activeGain = gainName; +} + +std::string CubicSDR::getActiveGainEntry() { + return activeGain; +} + +int CubicSDR::FilterEvent(wxEvent& event) { + if (!appframe) { + return -1; + } + + if (event.GetEventType() == wxEVT_KEY_DOWN) { + return appframe->OnGlobalKeyDown((wxKeyEvent&)event); + } + + if (event.GetEventType() == wxEVT_KEY_UP) { + return appframe->OnGlobalKeyUp((wxKeyEvent&)event); + } + + return -1; // process normally +} + #ifdef USE_HAMLIB RigThread *CubicSDR::getRigThread() { return rigThread; diff --git a/src/CubicSDR.h b/src/CubicSDR.h index caa997f..4cc4f7e 100644 --- a/src/CubicSDR.h +++ b/src/CubicSDR.h @@ -125,7 +125,7 @@ public: void setPPM(int ppm_in); int getPPM(); - void showFrequencyInput(FrequencyDialog::FrequencyDialogTarget targetMode = FrequencyDialog::FDIALOG_TARGET_DEFAULT); + void showFrequencyInput(FrequencyDialog::FrequencyDialogTarget targetMode = FrequencyDialog::FDIALOG_TARGET_DEFAULT, wxString initString = ""); AppFrame *getAppFrame(); bool areDevicesReady(); @@ -153,6 +153,9 @@ public: bool getUseLocalMod(); std::string getModulePath(); + void setActiveGainEntry(std::string gainName); + std::string getActiveGainEntry(); + #ifdef USE_HAMLIB RigThread *getRigThread(); void initRig(int rigModel, std::string rigPort, int rigSerialRate); @@ -161,6 +164,8 @@ public: #endif private: + int FilterEvent(wxEvent& event); + AppFrame *appframe; AppConfig config; PrimaryGLContext *m_glContext; @@ -205,6 +210,8 @@ private: std::mutex notify_busy; std::atomic_bool frequency_locked; std::atomic_llong lock_freq; + FrequencyDialog::FrequencyDialogTarget fdlgTarget; + std::string activeGain; #ifdef USE_HAMLIB RigThread *rigThread; std::thread *t_Rig; diff --git a/src/FrequencyDialog.cpp b/src/FrequencyDialog.cpp index 6d4b848..1d6fb04 100644 --- a/src/FrequencyDialog.cpp +++ b/src/FrequencyDialog.cpp @@ -6,14 +6,16 @@ wxBEGIN_EVENT_TABLE(FrequencyDialog, wxDialog) EVT_CHAR_HOOK(FrequencyDialog::OnChar) +EVT_SHOW(FrequencyDialog::OnShow) wxEND_EVENT_TABLE() FrequencyDialog::FrequencyDialog(wxWindow * parent, wxWindowID id, const wxString & title, DemodulatorInstance *demod, const wxPoint & position, - const wxSize & size, long style, FrequencyDialogTarget targetMode) : + const wxSize & size, long style, FrequencyDialogTarget targetMode, wxString initString) : wxDialog(parent, id, title, position, size, style) { wxString freqStr; activeDemod = demod; this->targetMode = targetMode; + this->initialString = initString; if (targetMode == FDIALOG_TARGET_DEFAULT) { if (activeDemod) { @@ -31,29 +33,54 @@ FrequencyDialog::FrequencyDialog(wxWindow * parent, wxWindowID id, const wxStrin freqStr = frequencyToStr(wxGetApp().getDemodMgr().getLastBandwidth()); } } + + if (targetMode == FDIALOG_TARGET_WATERFALL_LPS) { + freqStr = std::to_string(wxGetApp().getAppFrame()->getWaterfallDataThread()->getLinesPerSecond()); + } + if (targetMode == FDIALOG_TARGET_SPECTRUM_AVG) { + freqStr = std::to_string(wxGetApp().getSpectrumProcessor()->getFFTAverageRate()); + } + + if (targetMode == FDIALOG_TARGET_GAIN) { + if (wxGetApp().getActiveGainEntry() != "") { + freqStr = std::to_string((int)wxGetApp().getGain(wxGetApp().getActiveGainEntry())); + } + } + dialogText = new wxTextCtrl(this, wxID_FREQ_INPUT, freqStr, wxPoint(6, 1), wxSize(size.GetWidth() - 20, size.GetHeight() - 70), wxTE_PROCESS_ENTER); dialogText->SetFont(wxFont(20, wxFONTFAMILY_TELETYPE, wxFONTSTYLE_NORMAL, wxFONTWEIGHT_BOLD)); Centre(); - dialogText->SetSelection(-1, -1); + if (initString != "" && initString.length() == 1) { + dialogText->SetValue(initString); + dialogText->SetSelection(2, 2); + dialogText->SetFocus(); + } else { + if (initString != "") { + dialogText->SetValue(initString); + } + dialogText->SetSelection(-1, -1); + } } void FrequencyDialog::OnChar(wxKeyEvent& event) { int c = event.GetKeyCode(); long long freq; + double dblval; std::string lastDemodType = activeDemod?activeDemod->getDemodulatorType():wxGetApp().getDemodMgr().getLastDemodulatorType(); - + std::string strValue = dialogText->GetValue().ToStdString(); + switch (c) { case WXK_RETURN: case WXK_NUMPAD_ENTER: // Do Stuff - freq = strToFrequency(dialogText->GetValue().ToStdString()); if (targetMode == FDIALOG_TARGET_DEFAULT) { + freq = strToFrequency(strValue); if (activeDemod) { activeDemod->setTracking(true); activeDemod->setFollow(true); @@ -64,6 +91,7 @@ void FrequencyDialog::OnChar(wxKeyEvent& event) { } } if (targetMode == FDIALOG_TARGET_BANDWIDTH) { + freq = strToFrequency(strValue); if (lastDemodType == "USB" || lastDemodType == "LSB") { freq *= 2; } @@ -73,6 +101,59 @@ void FrequencyDialog::OnChar(wxKeyEvent& event) { wxGetApp().getDemodMgr().setLastBandwidth(freq); } } + if (targetMode == FDIALOG_TARGET_WATERFALL_LPS) { + try { + freq = std::stoi(strValue); + } catch (exception e) { + Close(); + break; + } + if (freq > 1024) { + freq = 1024; + } + if (freq < 1) { + freq = 1; + } + wxGetApp().getAppFrame()->setWaterfallLinesPerSecond(freq); + } + if (targetMode == FDIALOG_TARGET_SPECTRUM_AVG) { + try { + dblval = std::stod(strValue); + } catch (exception e) { + Close(); + break; + } + if (dblval > 0.99) { + dblval = 0.99; + } + if (dblval < 0.1) { + dblval = 0.1; + } + wxGetApp().getAppFrame()->setSpectrumAvgSpeed(dblval); + } + + if (targetMode == FDIALOG_TARGET_GAIN) { + try { + freq = std::stoi(strValue); + } catch (exception e) { + break; + } + SDRDeviceInfo *devInfo = wxGetApp().getDevice(); + std::string gainName = wxGetApp().getActiveGainEntry(); + if (gainName == "") { + break; + } + SDRRangeMap gains = devInfo->getGains(SOAPY_SDR_RX, 0); + if (freq > gains[gainName].maximum()) { + freq = gains[gainName].maximum(); + } + if (freq < gains[gainName].minimum()) { + freq = gains[gainName].minimum(); + } + wxGetApp().setGain(gainName, freq); + wxGetApp().getAppFrame()->refreshGainUI(); + } + Close(); break; case WXK_ESCAPE: @@ -104,3 +185,11 @@ void FrequencyDialog::OnChar(wxKeyEvent& event) { event.Skip(); } } + +void FrequencyDialog::OnShow(wxShowEvent &event) { + if (initialString.length() == 1) { + dialogText->SetFocus(); + dialogText->SetSelection(2, 2); + } + event.Skip(); +} diff --git a/src/FrequencyDialog.h b/src/FrequencyDialog.h index d0c57b0..6353c39 100644 --- a/src/FrequencyDialog.h +++ b/src/FrequencyDialog.h @@ -11,13 +11,22 @@ class FrequencyDialog: public wxDialog { public: - typedef enum FrequencyDialogTarget { FDIALOG_TARGET_DEFAULT, FDIALOG_TARGET_CENTERFREQ, FDIALOG_TARGET_FREQ, FDIALOG_TARGET_BANDWIDTH } FrequencyDialogTarget; + typedef enum FrequencyDialogTarget { + FDIALOG_TARGET_DEFAULT, + FDIALOG_TARGET_CENTERFREQ, + FDIALOG_TARGET_FREQ, + FDIALOG_TARGET_BANDWIDTH, + FDIALOG_TARGET_WATERFALL_LPS, + FDIALOG_TARGET_SPECTRUM_AVG, + FDIALOG_TARGET_GAIN + } FrequencyDialogTarget; FrequencyDialog ( wxWindow * parent, wxWindowID id, const wxString & title, DemodulatorInstance *demod = NULL, const wxPoint & pos = wxDefaultPosition, const wxSize & size = wxDefaultSize, long style = wxDEFAULT_DIALOG_STYLE, - FrequencyDialogTarget targetMode = FDIALOG_TARGET_DEFAULT); + FrequencyDialogTarget targetMode = FDIALOG_TARGET_DEFAULT, + wxString initString = ""); wxTextCtrl * dialogText; @@ -25,6 +34,8 @@ private: DemodulatorInstance *activeDemod; void OnEnter ( wxCommandEvent &event ); void OnChar ( wxKeyEvent &event ); + void OnShow(wxShowEvent &event); FrequencyDialogTarget targetMode; + std::string initialString; DECLARE_EVENT_TABLE() }; diff --git a/src/visual/GainCanvas.cpp b/src/visual/GainCanvas.cpp index 3b82e82..33badba 100644 --- a/src/visual/GainCanvas.cpp +++ b/src/visual/GainCanvas.cpp @@ -132,6 +132,9 @@ void GainCanvas::OnMouseMoved(wxMouseEvent& event) { int i = 0; for (std::vector::iterator gi = gainInfo.begin(); gi != gainInfo.end(); gi++) { (*gi)->highlightPanel.visible = (i==panelHit); + if (i==panelHit) { + wxGetApp().setActiveGainEntry((*gi)->name); + } i++; } diff --git a/src/visual/InteractiveCanvas.cpp b/src/visual/InteractiveCanvas.cpp index 228277f..d4fe77c 100644 --- a/src/visual/InteractiveCanvas.cpp +++ b/src/visual/InteractiveCanvas.cpp @@ -19,7 +19,7 @@ InteractiveCanvas::InteractiveCanvas(wxWindow *parent, int *attribList) : wxGLCanvas(parent, wxID_ANY, attribList, wxDefaultPosition, wxDefaultSize, - wxFULL_REPAINT_ON_RESIZE| wxWANTS_CHARS), parent(parent), shiftDown(false), altDown(false), ctrlDown(false), centerFreq(0), bandwidth(0), lastBandwidth(0), isView( + wxFULL_REPAINT_ON_RESIZE), parent(parent), shiftDown(false), altDown(false), ctrlDown(false), centerFreq(0), bandwidth(0), lastBandwidth(0), isView( false) { mouseTracker.setTarget(this); } @@ -157,6 +157,17 @@ void InteractiveCanvas::OnMouseEnterWindow(wxMouseEvent& event) { void InteractiveCanvas::setStatusText(std::string statusText) { wxGetApp().getAppFrame()->GetStatusBar()->SetStatusText(statusText); + if (wxGetApp().getConfig()->getShowTips()) { + if (statusText != lastToolTip) { + wxToolTip::Enable(false); + this->SetToolTip(statusText); + lastToolTip = statusText; + wxToolTip::SetDelay(1000); + wxToolTip::Enable(true); + } + } else { + this->SetToolTip(""); + } } void InteractiveCanvas::setStatusText(std::string statusText, int value) { diff --git a/src/visual/InteractiveCanvas.h b/src/visual/InteractiveCanvas.h index f310918..3fdb2be 100644 --- a/src/visual/InteractiveCanvas.h +++ b/src/visual/InteractiveCanvas.h @@ -58,5 +58,6 @@ protected: unsigned int lastBandwidth; bool isView; + std::string lastToolTip; }; diff --git a/src/visual/MeterCanvas.cpp b/src/visual/MeterCanvas.cpp index e696421..d5b6037 100644 --- a/src/visual/MeterCanvas.cpp +++ b/src/visual/MeterCanvas.cpp @@ -52,6 +52,11 @@ void MeterCanvas::setMin(float min_in) { Refresh(); } +void MeterCanvas::setUserInputValue(float slider_in) { + userInputValue = slider_in; + Refresh(); +} + void MeterCanvas::setInputValue(float slider_in) { userInputValue = inputValue = slider_in; Refresh(); diff --git a/src/visual/MeterCanvas.h b/src/visual/MeterCanvas.h index 12577b2..7da390e 100644 --- a/src/visual/MeterCanvas.h +++ b/src/visual/MeterCanvas.h @@ -24,6 +24,7 @@ public: void setMax(float max_in); void setMin(float max_in); + void setUserInputValue(float slider_in); void setInputValue(float slider_in); bool inputChanged(); float getInputValue(); diff --git a/src/visual/TuningCanvas.cpp b/src/visual/TuningCanvas.cpp index 3616463..709eaff 100644 --- a/src/visual/TuningCanvas.cpp +++ b/src/visual/TuningCanvas.cpp @@ -26,8 +26,8 @@ EVT_RIGHT_UP(TuningCanvas::OnMouseRightReleased) EVT_LEAVE_WINDOW(TuningCanvas::OnMouseLeftWindow) EVT_ENTER_WINDOW(TuningCanvas::OnMouseEnterWindow) EVT_MOUSEWHEEL(TuningCanvas::OnMouseWheelMoved) -EVT_KEY_DOWN(TuningCanvas::OnKeyDown) -EVT_KEY_UP(TuningCanvas::OnKeyUp) +//EVT_KEY_DOWN(TuningCanvas::OnKeyDown) +//EVT_KEY_UP(TuningCanvas::OnKeyUp) wxEND_EVENT_TABLE() TuningCanvas::TuningCanvas(wxWindow *parent, int *attribList) : @@ -303,13 +303,13 @@ void TuningCanvas::OnMouseMoved(wxMouseEvent& event) { } else { switch (hoverState) { case TUNING_HOVER_FREQ: - setStatusText("Click, wheel or drag a digit to change frequency; SPACE for direct input. Right click to set/clear snap. Hold ALT to change PPM. Hold SHIFT to disable carry."); + setStatusText("Click, wheel or drag a digit to change frequency; SPACE or numeric key for direct input. Right click to set/clear snap. Hold ALT to change PPM. Hold SHIFT to disable carry."); break; case TUNING_HOVER_BW: - setStatusText("Click, wheel or drag a digit to change bandwidth; SPACE for direct input. Hold SHIFT to disable carry."); + setStatusText("Click, wheel or drag a digit to change bandwidth; SPACE or numeric key for direct input. Hold SHIFT to disable carry."); break; case TUNING_HOVER_CENTER: - setStatusText("Click, wheel or drag a digit to change center frequency; SPACE for direct input. Hold SHIFT to disable carry."); + setStatusText("Click, wheel or drag a digit to change center frequency; SPACE or numeric key for direct input. Hold SHIFT to disable carry."); break; case TUNING_HOVER_PPM: setStatusText("Click, wheel or drag a digit to change device PPM offset. Hold SHIFT to disable carry."); @@ -428,3 +428,7 @@ void TuningCanvas::OnKeyDown(wxKeyEvent& event) { void TuningCanvas::OnKeyUp(wxKeyEvent& event) { InteractiveCanvas::OnKeyUp(event); } + +TuningCanvas::ActiveState TuningCanvas::getHoverState() { + return hoverState; +} diff --git a/src/visual/TuningCanvas.h b/src/visual/TuningCanvas.h index daf41ff..403181f 100644 --- a/src/visual/TuningCanvas.h +++ b/src/visual/TuningCanvas.h @@ -25,6 +25,10 @@ public: bool changed(); void setHalfBand(bool hb); + void OnKeyDown(wxKeyEvent& event); + void OnKeyUp(wxKeyEvent& event); + + ActiveState getHoverState(); private: void OnPaint(wxPaintEvent& event); @@ -36,8 +40,6 @@ private: void OnMouseReleased(wxMouseEvent& event); void OnMouseEnterWindow(wxMouseEvent& event); void OnMouseLeftWindow(wxMouseEvent& event); - void OnKeyDown(wxKeyEvent& event); - void OnKeyUp(wxKeyEvent& event); void OnMouseRightDown(wxMouseEvent& event); void OnMouseRightReleased(wxMouseEvent& event); diff --git a/src/visual/WaterfallCanvas.cpp b/src/visual/WaterfallCanvas.cpp index 6d5b5c9..6f7e8ce 100644 --- a/src/visual/WaterfallCanvas.cpp +++ b/src/visual/WaterfallCanvas.cpp @@ -19,8 +19,6 @@ wxBEGIN_EVENT_TABLE(WaterfallCanvas, wxGLCanvas) EVT_PAINT(WaterfallCanvas::OnPaint) -EVT_KEY_DOWN(WaterfallCanvas::OnKeyDown) -EVT_KEY_UP(WaterfallCanvas::OnKeyUp) EVT_IDLE(WaterfallCanvas::OnIdle) EVT_MOTION(WaterfallCanvas::OnMouseMoved) EVT_LEFT_DOWN(WaterfallCanvas::OnMouseDown) @@ -345,7 +343,6 @@ void WaterfallCanvas::OnKeyUp(wxKeyEvent& event) { altDown = event.AltDown(); ctrlDown = event.ControlDown(); switch (event.GetKeyCode()) { - case 'A': case WXK_UP: case WXK_NUMPAD_UP: scaleMove = 0.0; @@ -354,7 +351,6 @@ void WaterfallCanvas::OnKeyUp(wxKeyEvent& event) { mouseZoom = 0.95; } break; - case 'Z': case WXK_DOWN: case WXK_NUMPAD_DOWN: scaleMove = 0.0; @@ -381,7 +377,6 @@ void WaterfallCanvas::OnKeyDown(wxKeyEvent& event) { long long freq = originalFreq; switch (event.GetKeyCode()) { - case 'A': case WXK_UP: case WXK_NUMPAD_UP: if (!shiftDown) { @@ -391,7 +386,6 @@ void WaterfallCanvas::OnKeyDown(wxKeyEvent& event) { scaleMove = 1.0; } break; - case 'Z': case WXK_DOWN: case WXK_NUMPAD_DOWN: if (!shiftDown) { @@ -601,20 +595,20 @@ void WaterfallCanvas::OnMouseMoved(wxMouseEvent& event) { mouseTracker.setVertDragLock(true); mouseTracker.setHorizDragLock(false); - setStatusText("Click and drag to change demodulator bandwidth. SPACE for direct frequency input. M for mute, D to delete, C to center."); + setStatusText("Click and drag to change demodulator bandwidth. SPACE or numeric key for direct frequency input. M for mute, D to delete, C to center."); } else { SetCursor(wxCURSOR_SIZING); nextDragState = WF_DRAG_FREQUENCY; mouseTracker.setVertDragLock(true); mouseTracker.setHorizDragLock(false); - setStatusText("Click and drag to change demodulator frequency; SPACE for direct input. M for mute, D to delete, C to center."); + setStatusText("Click and drag to change demodulator frequency; SPACE or numeric key for direct input. M for mute, D to delete, C to center."); } } else { SetCursor(wxCURSOR_CROSS); nextDragState = WF_DRAG_NONE; if (shiftDown) { - setStatusText("Click to create a new demodulator or hold ALT to drag range, SPACE for direct center frequency input."); + setStatusText("Click to create a new demodulator or hold ALT to drag range, SPACE or numeric key for direct center frequency input."); } else { setStatusText( "Click to move active demodulator frequency or hold ALT to drag range; hold SHIFT to create new. Right drag or wheel to Zoom. Arrow keys to navigate/zoom, C to center."); diff --git a/src/visual/WaterfallCanvas.h b/src/visual/WaterfallCanvas.h index 013e3fc..9aff56b 100644 --- a/src/visual/WaterfallCanvas.h +++ b/src/visual/WaterfallCanvas.h @@ -33,11 +33,11 @@ public: void setLinesPerSecond(int lps); void setMinBandwidth(int min); -private: - void OnPaint(wxPaintEvent& event); void OnKeyDown(wxKeyEvent& event); void OnKeyUp(wxKeyEvent& event); +private: + void OnPaint(wxPaintEvent& event); void OnIdle(wxIdleEvent &event); void OnMouseMoved(wxMouseEvent& event);