mirror of
https://github.com/cjcliffe/CubicSDR.git
synced 2024-11-05 00:41:17 -05:00
Merge pull request #78 from cjcliffe/keyboard_freq_input
Keyboard frequency input
This commit is contained in:
commit
fdc45b32ef
@ -227,6 +227,7 @@ SET (cubicsdr_sources
|
||||
src/CubicSDR.cpp
|
||||
src/AppFrame.cpp
|
||||
src/AppConfig.cpp
|
||||
src/FrequencyDialog.cpp
|
||||
src/sdr/SDRThread.cpp
|
||||
src/sdr/SDRPostThread.cpp
|
||||
src/demod/DemodulatorPreThread.cpp
|
||||
@ -269,6 +270,7 @@ SET (cubicsdr_headers
|
||||
src/CubicSDR.h
|
||||
src/AppFrame.h
|
||||
src/AppConfig.h
|
||||
src/FrequencyDialog.h
|
||||
src/sdr/SDRThread.h
|
||||
src/sdr/SDRPostThread.h
|
||||
src/demod/DemodulatorPreThread.h
|
||||
|
@ -13,7 +13,7 @@
|
||||
#endif
|
||||
|
||||
#include "CubicSDR.h"
|
||||
#include "AppFrame.h"
|
||||
#include "FrequencyDialog.h"
|
||||
|
||||
#ifdef _OSX_APP_
|
||||
#include "CoreFoundation/CoreFoundation.h"
|
||||
@ -92,7 +92,7 @@ bool CubicSDR::OnInit() {
|
||||
t_PostSDR = new std::thread(&SDRPostThread::threadMain, sdrPostThread);
|
||||
t_SDR = new std::thread(&SDRThread::threadMain, sdrThread);
|
||||
|
||||
AppFrame *appframe = new AppFrame();
|
||||
appframe = new AppFrame();
|
||||
|
||||
#ifdef __APPLE__
|
||||
int main_policy;
|
||||
@ -271,3 +271,9 @@ int CubicSDR::getPPM() {
|
||||
return ppm;
|
||||
}
|
||||
|
||||
|
||||
void CubicSDR::showFrequencyInput() {
|
||||
FrequencyDialog fdialog(appframe, -1, demodMgr.getActiveDemodulator()?_("Set Demodulator Frequency"):_("Set Center Frequency"), demodMgr.getActiveDemodulator(), wxPoint(-100,-100), wxSize(320, 75 ));
|
||||
fdialog.ShowModal();
|
||||
}
|
||||
|
||||
|
@ -15,6 +15,7 @@
|
||||
#include "AudioThread.h"
|
||||
#include "DemodulatorMgr.h"
|
||||
#include "AppConfig.h"
|
||||
#include "AppFrame.h"
|
||||
|
||||
#define NUM_DEMODULATORS 1
|
||||
|
||||
@ -56,7 +57,10 @@ public:
|
||||
void setPPM(int ppm_in);
|
||||
int getPPM();
|
||||
|
||||
void showFrequencyInput();
|
||||
|
||||
private:
|
||||
AppFrame *appframe;
|
||||
AppConfig config;
|
||||
PrimaryGLContext *m_glContext;
|
||||
std::vector<SDRDeviceInfo *> devs;
|
||||
|
142
src/FrequencyDialog.cpp
Normal file
142
src/FrequencyDialog.cpp
Normal file
@ -0,0 +1,142 @@
|
||||
#include "FrequencyDialog.h"
|
||||
|
||||
#include "wx/clipbrd.h"
|
||||
#include <sstream>
|
||||
#include <iomanip>
|
||||
#include "CubicSDR.h"
|
||||
|
||||
wxBEGIN_EVENT_TABLE(FrequencyDialog, wxDialog) EVT_CHAR_HOOK(FrequencyDialog::OnChar)
|
||||
wxEND_EVENT_TABLE()
|
||||
|
||||
FrequencyDialog::FrequencyDialog(wxWindow * parent, wxWindowID id, const wxString & title, DemodulatorInstance *demod, const wxPoint & position,
|
||||
const wxSize & size, long style) :
|
||||
wxDialog(parent, id, title, position, size, style) {
|
||||
wxString freqStr;
|
||||
activeDemod = demod;
|
||||
|
||||
if (activeDemod) {
|
||||
freqStr = frequencyToStr(activeDemod->getFrequency());
|
||||
} else {
|
||||
freqStr = frequencyToStr(wxGetApp().getFrequency());
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
std::string& FrequencyDialog::filterChars(std::string& s, const std::string& allowed) {
|
||||
s.erase(remove_if(s.begin(), s.end(), [&allowed](const char& c) {
|
||||
return allowed.find(c) == std::string::npos;
|
||||
}), s.end());
|
||||
return s;
|
||||
}
|
||||
|
||||
std::string FrequencyDialog::frequencyToStr(long long freq) {
|
||||
long double freqTemp;
|
||||
|
||||
freqTemp = freq;
|
||||
std::string suffix("");
|
||||
std::stringstream freqStr;
|
||||
|
||||
if (freqTemp >= 1.0e9) {
|
||||
freqTemp /= 1.0e9;
|
||||
freqStr << std::setprecision(10);
|
||||
suffix = std::string("GHz");
|
||||
} else if (freqTemp >= 1.0e6) {
|
||||
freqTemp /= 1.0e6;
|
||||
freqStr << std::setprecision(7);
|
||||
suffix = std::string("MHz");
|
||||
} else if (freqTemp >= 1.0e3) {
|
||||
freqTemp /= 1.0e3;
|
||||
freqStr << std::setprecision(4);
|
||||
suffix = std::string("KHz");
|
||||
}
|
||||
|
||||
freqStr << freqTemp;
|
||||
freqStr << suffix;
|
||||
|
||||
return freqStr.str();
|
||||
}
|
||||
|
||||
long long FrequencyDialog::strToFrequency(std::string freqStr) {
|
||||
std::string filterStr = filterChars(freqStr, std::string("0123456789.MKGmkg"));
|
||||
|
||||
int numLen = filterStr.find_first_not_of("0123456789.");
|
||||
|
||||
if (numLen == std::string::npos) {
|
||||
numLen = freqStr.length();
|
||||
}
|
||||
|
||||
std::string numPartStr = freqStr.substr(0, numLen);
|
||||
std::string suffixStr = freqStr.substr(numLen);
|
||||
|
||||
std::stringstream numPartStream;
|
||||
numPartStream.str(numPartStr);
|
||||
|
||||
long double freqTemp = 0;
|
||||
|
||||
numPartStream >> freqTemp;
|
||||
|
||||
if (suffixStr.length()) {
|
||||
if (suffixStr.find_first_of("Gg") != std::string::npos) {
|
||||
freqTemp *= 1.0e9;
|
||||
} else if (suffixStr.find_first_of("Mm") != std::string::npos) {
|
||||
freqTemp *= 1.0e6;
|
||||
} else if (suffixStr.find_first_of("Kk") != std::string::npos) {
|
||||
freqTemp *= 1.0e3;
|
||||
}
|
||||
} else if (numPartStr.find_first_of(".") != std::string::npos) {
|
||||
freqTemp *= 1.0e6;
|
||||
}
|
||||
|
||||
return (long long) freqTemp;
|
||||
}
|
||||
|
||||
void FrequencyDialog::OnChar(wxKeyEvent& event) {
|
||||
wxChar c = event.GetKeyCode();
|
||||
long long freq;
|
||||
|
||||
switch (c) {
|
||||
case WXK_RETURN:
|
||||
case WXK_NUMPAD_ENTER:
|
||||
// Do Stuff
|
||||
freq = strToFrequency(dialogText->GetValue().ToStdString());
|
||||
if (activeDemod) {
|
||||
activeDemod->setTracking(true);
|
||||
activeDemod->setFollow(true);
|
||||
activeDemod->setFrequency(freq);
|
||||
activeDemod->updateLabel(freq);
|
||||
} else {
|
||||
wxGetApp().setFrequency(freq);
|
||||
}
|
||||
Close();
|
||||
break;
|
||||
case WXK_ESCAPE:
|
||||
Close();
|
||||
break;
|
||||
}
|
||||
|
||||
std::string allowed("0123456789.MKGHZmkghz");
|
||||
|
||||
if (allowed.find_first_of(c) != std::string::npos || c == WXK_DELETE || c == WXK_BACK || c == WXK_NUMPAD_DECIMAL
|
||||
|| (c >= WXK_NUMPAD0 && c <= WXK_NUMPAD9)) {
|
||||
event.DoAllowNextEvent();
|
||||
} else if (event.ControlDown() && c == 'V') {
|
||||
// Alter clipboard contents to remove unwanted chars
|
||||
wxTheClipboard->Open();
|
||||
wxTextDataObject data;
|
||||
wxTheClipboard->GetData(data);
|
||||
std::string clipText = data.GetText().ToStdString();
|
||||
std::string pasteText = filterChars(clipText, std::string(allowed));
|
||||
wxTheClipboard->SetData(new wxTextDataObject(pasteText));
|
||||
wxTheClipboard->Close();
|
||||
event.Skip();
|
||||
} else if (c == WXK_RIGHT || c == WXK_LEFT || event.ControlDown()) {
|
||||
event.Skip();
|
||||
}
|
||||
}
|
32
src/FrequencyDialog.h
Normal file
32
src/FrequencyDialog.h
Normal file
@ -0,0 +1,32 @@
|
||||
#pragma once
|
||||
|
||||
#include "wx/dialog.h"
|
||||
#include "wx/textctrl.h"
|
||||
#include "wx/string.h"
|
||||
#include "wx/button.h"
|
||||
#include "DemodulatorInstance.h"
|
||||
|
||||
#define wxID_FREQ_INPUT 3001
|
||||
|
||||
class FrequencyDialog: public wxDialog
|
||||
{
|
||||
public:
|
||||
|
||||
FrequencyDialog ( wxWindow * parent, wxWindowID id, const wxString & title,
|
||||
DemodulatorInstance *demod = NULL,
|
||||
const wxPoint & pos = wxDefaultPosition,
|
||||
const wxSize & size = wxDefaultSize,
|
||||
long style = wxDEFAULT_DIALOG_STYLE );
|
||||
|
||||
wxTextCtrl * dialogText;
|
||||
|
||||
long long strToFrequency(std::string freqStr);
|
||||
std::string frequencyToStr(long long freq);
|
||||
|
||||
private:
|
||||
DemodulatorInstance *activeDemod;
|
||||
void OnEnter ( wxCommandEvent &event );
|
||||
void OnChar ( wxKeyEvent &event );
|
||||
std::string& filterChars(std::string& s, const std::string& allowed);
|
||||
DECLARE_EVENT_TABLE()
|
||||
};
|
@ -271,21 +271,28 @@ void TuningCanvas::OnMouseMoved(wxMouseEvent& event) {
|
||||
} else {
|
||||
switch (hoverState) {
|
||||
case TUNING_HOVER_FREQ:
|
||||
setStatusText("Click, wheel or drag a digit to change frequency. Hold ALT to change PPM. Hold SHIFT to disable carry.");
|
||||
setStatusText("Click, wheel or drag a digit to change frequency; SPACE for direct input. 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. Hold SHIFT to disable carry.");
|
||||
break;
|
||||
case TUNING_HOVER_CENTER:
|
||||
setStatusText("Click, wheel or drag a digit to change center frequency. Hold SHIFT to disable carry.");
|
||||
setStatusText("Click, wheel or drag a digit to change center frequency; SPACE 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.");
|
||||
break;
|
||||
case TUNING_HOVER_NONE:
|
||||
setStatusText("");
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (hoverState == TUNING_HOVER_BW || hoverState == TUNING_HOVER_FREQ) {
|
||||
wxGetApp().getDemodMgr().setActiveDemodulator(wxGetApp().getDemodMgr().getLastActiveDemodulator());
|
||||
} else {
|
||||
wxGetApp().getDemodMgr().setActiveDemodulator(NULL);
|
||||
}
|
||||
}
|
||||
|
||||
void TuningCanvas::OnMouseDown(wxMouseEvent& event) {
|
||||
@ -339,6 +346,7 @@ void TuningCanvas::OnMouseLeftWindow(wxMouseEvent& event) {
|
||||
SetCursor(wxCURSOR_CROSS);
|
||||
hoverIndex = 0;
|
||||
hoverState = TUNING_HOVER_NONE;
|
||||
wxGetApp().getDemodMgr().setActiveDemodulator(NULL);
|
||||
|
||||
if (currentPPM != lastPPM) {
|
||||
wxGetApp().saveConfig();
|
||||
@ -359,6 +367,10 @@ void TuningCanvas::setHelpTip(std::string tip) {
|
||||
|
||||
void TuningCanvas::OnKeyDown(wxKeyEvent& event) {
|
||||
InteractiveCanvas::OnKeyDown(event);
|
||||
|
||||
if (event.GetKeyCode() == WXK_SPACE && (hoverState == TUNING_HOVER_CENTER || hoverState == TUNING_HOVER_FREQ)) {
|
||||
wxGetApp().showFrequencyInput();
|
||||
}
|
||||
}
|
||||
|
||||
void TuningCanvas::OnKeyUp(wxKeyEvent& event) {
|
||||
|
@ -141,7 +141,7 @@ void WaterfallCanvas::OnPaint(wxPaintEvent& WXUNUSED(event)) {
|
||||
ColorTheme *currentTheme = ThemeMgr::mgr.currentTheme;
|
||||
int last_type = wxGetApp().getDemodMgr().getLastDemodulatorType();
|
||||
|
||||
if (mouseTracker.mouseInView()) {
|
||||
if (mouseTracker.mouseInView() || wxGetApp().getDemodMgr().getActiveDemodulator()) {
|
||||
hoverAlpha += (1.0f-hoverAlpha)*0.1f;
|
||||
if (hoverAlpha > 1.5f) {
|
||||
hoverAlpha = 1.5f;
|
||||
@ -193,6 +193,8 @@ void WaterfallCanvas::OnPaint(wxPaintEvent& WXUNUSED(event)) {
|
||||
}
|
||||
}
|
||||
|
||||
glContext->setHoverAlpha(0);
|
||||
|
||||
for (int i = 0, iMax = demods.size(); i < iMax; i++) {
|
||||
if (activeDemodulator == demods[i] || lastActiveDemodulator == demods[i]) {
|
||||
continue;
|
||||
@ -299,16 +301,6 @@ void WaterfallCanvas::OnKeyDown(wxKeyEvent& event) {
|
||||
wxGetApp().getDemodMgr().deleteThread(activeDemod);
|
||||
break;
|
||||
case 'S':
|
||||
if (!activeDemod) {
|
||||
break;
|
||||
}
|
||||
if (activeDemod->isSquelchEnabled()) {
|
||||
activeDemod->setSquelchEnabled(false);
|
||||
} else {
|
||||
activeDemod->squelchAuto();
|
||||
}
|
||||
break;
|
||||
case WXK_SPACE:
|
||||
if (!activeDemod) {
|
||||
break;
|
||||
}
|
||||
@ -318,6 +310,9 @@ void WaterfallCanvas::OnKeyDown(wxKeyEvent& event) {
|
||||
activeDemod->setStereo(true);
|
||||
}
|
||||
break;
|
||||
case WXK_SPACE:
|
||||
wxGetApp().showFrequencyInput();
|
||||
break;
|
||||
default:
|
||||
event.Skip();
|
||||
return;
|
||||
@ -720,23 +715,23 @@ void WaterfallCanvas::OnMouseMoved(wxMouseEvent& event) {
|
||||
|
||||
mouseTracker.setVertDragLock(true);
|
||||
mouseTracker.setHorizDragLock(false);
|
||||
setStatusText("Click and drag to change demodulator bandwidth. D to delete, SPACE for stereo.");
|
||||
setStatusText("Click and drag to change demodulator bandwidth. SPACE for direct frequency input. D to delete, S for stereo.");
|
||||
} else {
|
||||
SetCursor(wxCURSOR_SIZING);
|
||||
nextDragState = WF_DRAG_FREQUENCY;
|
||||
|
||||
mouseTracker.setVertDragLock(true);
|
||||
mouseTracker.setHorizDragLock(false);
|
||||
setStatusText("Click and drag to change demodulator frequency. D to delete, SPACE for stereo.");
|
||||
setStatusText("Click and drag to change demodulator frequency; SPACE for direct input. D to delete, S for stereo.");
|
||||
}
|
||||
} else {
|
||||
SetCursor(wxCURSOR_CROSS);
|
||||
nextDragState = WF_DRAG_NONE;
|
||||
if (shiftDown) {
|
||||
setStatusText("Click to create a new demodulator or hold ALT to drag range.");
|
||||
setStatusText("Click to create a new demodulator or hold ALT to drag range, SPACE 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 A / Z to Zoom. Arrow keys (+SHIFT) to move center frequency.");
|
||||
"Click to move active demodulator frequency or hold ALT to drag range; hold SHIFT to create new. Right drag or A / Z to Zoom. Arrow keys (+SHIFT) to move center frequency; SPACE for direct input.");
|
||||
}
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user