Move audio out choice to modem props, save modem props collapse state, shift rig menu over

This commit is contained in:
Charles J. Cliffe 2016-07-28 22:50:02 -04:00
parent 9ea5d704c0
commit c36ca29111
6 changed files with 175 additions and 44 deletions

View File

@ -289,6 +289,7 @@ AppConfig::AppConfig() : configName("") {
centerFreq.store(100000000); centerFreq.store(100000000);
waterfallLinesPerSec.store(DEFAULT_WATERFALL_LPS); waterfallLinesPerSec.store(DEFAULT_WATERFALL_LPS);
spectrumAvgSpeed.store(0.65f); spectrumAvgSpeed.store(0.65f);
modemPropsCollapsed.store(false);
#ifdef USE_HAMLIB #ifdef USE_HAMLIB
rigEnabled.store(false); rigEnabled.store(false);
rigModel.store(1); rigModel.store(1);
@ -342,6 +343,14 @@ bool AppConfig::getWindowMaximized() {
return winMax.load(); return winMax.load();
} }
void AppConfig::setModemPropsCollapsed(bool collapse) {
modemPropsCollapsed.store(collapse);
}
bool AppConfig::getModemPropsCollapsed() {
return modemPropsCollapsed.load();
}
void AppConfig::setShowTips(bool show) { void AppConfig::setShowTips(bool show) {
showTips.store(show); showTips.store(show);
} }
@ -468,6 +477,7 @@ bool AppConfig::save() {
*window_node->newChild("center_freq") = centerFreq.load(); *window_node->newChild("center_freq") = centerFreq.load();
*window_node->newChild("waterfall_lps") = waterfallLinesPerSec.load(); *window_node->newChild("waterfall_lps") = waterfallLinesPerSec.load();
*window_node->newChild("spectrum_avg") = spectrumAvgSpeed.load(); *window_node->newChild("spectrum_avg") = spectrumAvgSpeed.load();
*window_node->newChild("modemprops_collapsed") = modemPropsCollapsed.load();;
} }
DataNode *devices_node = cfg.rootNode()->newChild("devices"); DataNode *devices_node = cfg.rootNode()->newChild("devices");
@ -547,7 +557,7 @@ bool AppConfig::load() {
if (cfg.rootNode()->hasAnother("window")) { if (cfg.rootNode()->hasAnother("window")) {
int x,y,w,h; int x,y,w,h;
int max,tips,lpm; int max,tips,lpm,mpc;
DataNode *win_node = cfg.rootNode()->getNext("window"); DataNode *win_node = cfg.rootNode()->getNext("window");
@ -613,6 +623,11 @@ bool AppConfig::load() {
win_node->getNext("spectrum_avg")->element()->get(avgVal); win_node->getNext("spectrum_avg")->element()->get(avgVal);
spectrumAvgSpeed.store(avgVal); spectrumAvgSpeed.store(avgVal);
} }
if (win_node->hasAnother("modemprops_collapsed")) {
win_node->getNext("modemprops_collapsed")->element()->get(mpc);
modemPropsCollapsed.store(mpc?true:false);
}
} }
if (cfg.rootNode()->hasAnother("devices")) { if (cfg.rootNode()->hasAnother("devices")) {

View File

@ -85,6 +85,9 @@ public:
void setWindowMaximized(bool max); void setWindowMaximized(bool max);
bool getWindowMaximized(); bool getWindowMaximized();
void setModemPropsCollapsed(bool collapse);
bool getModemPropsCollapsed();
void setShowTips(bool show); void setShowTips(bool show);
bool getShowTips(); bool getShowTips();
@ -148,7 +151,7 @@ private:
std::string configName; std::string configName;
std::map<std::string, DeviceConfig *> deviceConfig; std::map<std::string, DeviceConfig *> deviceConfig;
std::atomic_int winX,winY,winW,winH; std::atomic_int winX,winY,winW,winH;
std::atomic_bool winMax, showTips, lowPerfMode; std::atomic_bool winMax, showTips, lowPerfMode, modemPropsCollapsed;
std::atomic_int themeId; std::atomic_int themeId;
std::atomic_int fontScale; std::atomic_int fontScale;
std::atomic_llong snap; std::atomic_llong snap;

View File

@ -42,6 +42,8 @@ wxEND_EVENT_TABLE()
#include "RigThread.h" #include "RigThread.h"
#endif #endif
#define APPFRAME_MODEMPROPS_SIZE 240
AppFrame::AppFrame() : AppFrame::AppFrame() :
wxFrame(NULL, wxID_ANY, CUBICSDR_TITLE), activeDemodulator(NULL) { wxFrame(NULL, wxID_ANY, CUBICSDR_TITLE), activeDemodulator(NULL) {
@ -110,8 +112,8 @@ AppFrame::AppFrame() :
modemPropertiesUpdated.store(false); modemPropertiesUpdated.store(false);
modemProps = new ModemProperties(demodPanel, wxID_ANY); modemProps = new ModemProperties(demodPanel, wxID_ANY);
modemProps->SetMinSize(wxSize(200,-1)); modemProps->SetMinSize(wxSize(APPFRAME_MODEMPROPS_SIZE,-1));
modemProps->SetMaxSize(wxSize(200,-1)); modemProps->SetMaxSize(wxSize(APPFRAME_MODEMPROPS_SIZE,-1));
modemProps->Hide(); modemProps->Hide();
demodTray->Add(modemProps, 15, wxEXPAND | wxALL, 0); demodTray->Add(modemProps, 15, wxEXPAND | wxALL, 0);
@ -367,17 +369,17 @@ AppFrame::AppFrame() :
} }
i++; i++;
} }
//
for (mdevices_i = outputDevices.begin(); mdevices_i != outputDevices.end(); mdevices_i++) { // for (mdevices_i = outputDevices.begin(); mdevices_i != outputDevices.end(); mdevices_i++) {
wxMenuItem *itm = menu->AppendRadioItem(wxID_RT_AUDIO_DEVICE + mdevices_i->first, mdevices_i->second.name, wxT("Description?")); // wxMenuItem *itm = menu->AppendRadioItem(wxID_RT_AUDIO_DEVICE + mdevices_i->first, mdevices_i->second.name, wxT("Description?"));
itm->SetId(wxID_RT_AUDIO_DEVICE + mdevices_i->first); // itm->SetId(wxID_RT_AUDIO_DEVICE + mdevices_i->first);
if (mdevices_i->second.isDefaultOutput) { // if (mdevices_i->second.isDefaultOutput) {
itm->Check(true); // itm->Check(true);
} // }
outputDeviceMenuItems[mdevices_i->first] = itm; // outputDeviceMenuItems[mdevices_i->first] = itm;
} // }
//
menuBar->Append(menu, wxT("Audio &Output")); // menuBar->Append(menu, wxT("Audio &Output"));
sampleRateMenu = new wxMenu; sampleRateMenu = new wxMenu;
menuBar->Append(sampleRateMenu, wxT("Sample &Rate")); menuBar->Append(sampleRateMenu, wxT("Sample &Rate"));
@ -460,8 +462,6 @@ AppFrame::AppFrame() :
displayMenu->AppendSubMenu(themeMenu, wxT("&Color Scheme")); displayMenu->AppendSubMenu(themeMenu, wxT("&Color Scheme"));
menuBar->Append(displayMenu, wxT("&Display"));
GLFont::setScale((GLFont::GLFontScale)fontScale); GLFont::setScale((GLFont::GLFontScale)fontScale);
#ifdef USE_HAMLIB #ifdef USE_HAMLIB
@ -543,7 +543,9 @@ AppFrame::AppFrame() :
menuBar->Append(rigMenu, wxT("&Rig Control")); menuBar->Append(rigMenu, wxT("&Rig Control"));
#endif #endif
menuBar->Append(displayMenu, wxT("&Display"));
SetMenuBar(menuBar); SetMenuBar(menuBar);
CreateStatusBar(); CreateStatusBar();
@ -578,6 +580,12 @@ AppFrame::AppFrame() :
ThemeMgr::mgr.setTheme(wxGetApp().getConfig()->getTheme()); ThemeMgr::mgr.setTheme(wxGetApp().getConfig()->getTheme());
int mpc =wxGetApp().getConfig()->getModemPropsCollapsed();
if (mpc) {
modemProps->setCollapsed(true);
}
Show(); Show();
#ifdef _WIN32 #ifdef _WIN32
@ -725,7 +733,7 @@ void AppFrame::updateDeviceParams() {
sampleRateMenuItems[wxID_BANDWIDTH_MANUAL]->Check(true); sampleRateMenuItems[wxID_BANDWIDTH_MANUAL]->Check(true);
} }
menuBar->Replace(3, newSampleRateMenu, wxT("Sample &Rate")); menuBar->Replace(2, newSampleRateMenu, wxT("Sample &Rate"));
sampleRateMenu = newSampleRateMenu; sampleRateMenu = newSampleRateMenu;
if (!wxGetApp().getAGCMode()) { if (!wxGetApp().getAGCMode()) {
@ -796,19 +804,23 @@ void AppFrame::disableRig() {
void AppFrame::OnMenu(wxCommandEvent& event) { void AppFrame::OnMenu(wxCommandEvent& event) {
if (event.GetId() >= wxID_RT_AUDIO_DEVICE && event.GetId() < wxID_RT_AUDIO_DEVICE + (int)devices.size()) { // if (event.GetId() >= wxID_RT_AUDIO_DEVICE && event.GetId() < wxID_RT_AUDIO_DEVICE + (int)devices.size()) {
if (activeDemodulator) { // if (activeDemodulator) {
activeDemodulator->setOutputDevice(event.GetId() - wxID_RT_AUDIO_DEVICE); // activeDemodulator->setOutputDevice(event.GetId() - wxID_RT_AUDIO_DEVICE);
activeDemodulator = NULL; // activeDemodulator = NULL;
} // }
} // return;
// }
#ifdef __APPLE__ #ifdef __APPLE__
else if (event.GetId() == wxApp::s_macAboutMenuItemId) { if (event.GetId() == wxApp::s_macAboutMenuItemId) {
wxMessageDialog *aboutDlg = new wxMessageDialog(NULL, wxT("CubicSDR v" CUBICSDR_VERSION "\nby Charles J. Cliffe (@ccliffe)\nwww.cubicsdr.com"), wxT("CubicSDR v" CUBICSDR_VERSION), wxOK); wxMessageDialog *aboutDlg = new wxMessageDialog(NULL, wxT("CubicSDR v" CUBICSDR_VERSION "\nby Charles J. Cliffe (@ccliffe)\nwww.cubicsdr.com"), wxT("CubicSDR v" CUBICSDR_VERSION), wxOK);
aboutDlg->ShowModal(); aboutDlg->ShowModal();
return;
} }
#endif #endif
else if (event.GetId() == wxID_SDR_START_STOP) {
if (event.GetId() == wxID_SDR_START_STOP) {
if (!wxGetApp().getSDRThread()->isTerminated()) { if (!wxGetApp().getSDRThread()->isTerminated()) {
wxGetApp().stopDevice(true, 2000); wxGetApp().stopDevice(true, 2000);
} else { } else {
@ -1204,6 +1216,7 @@ void AppFrame::OnClose(wxCloseEvent& event) {
wxGetApp().getConfig()->setSpectrumAvgSpeed(wxGetApp().getSpectrumProcessor()->getFFTAverageRate()); wxGetApp().getConfig()->setSpectrumAvgSpeed(wxGetApp().getSpectrumProcessor()->getFFTAverageRate());
wxGetApp().getConfig()->setWaterfallLinesPerSec(waterfallDataThread->getLinesPerSecond()); wxGetApp().getConfig()->setWaterfallLinesPerSec(waterfallDataThread->getLinesPerSecond());
wxGetApp().getConfig()->setManualDevices(SDREnumerator::getManuals()); wxGetApp().getConfig()->setManualDevices(SDREnumerator::getManuals());
wxGetApp().getConfig()->setModemPropsCollapsed(modemProps->isCollapsed());
#ifdef USE_HAMLIB #ifdef USE_HAMLIB
wxGetApp().getConfig()->setRigEnabled(rigEnableMenuItem->IsChecked()); wxGetApp().getConfig()->setRigEnabled(rigEnableMenuItem->IsChecked());
wxGetApp().getConfig()->setRigModel(rigModel); wxGetApp().getConfig()->setRigModel(rigModel);
@ -1263,7 +1276,7 @@ void AppFrame::OnIdle(wxIdleEvent& event) {
wxGetApp().getDemodMgr().setLastGain(demod->getGain()); wxGetApp().getDemodMgr().setLastGain(demod->getGain());
int outputDevice = demod->getOutputDevice(); int outputDevice = demod->getOutputDevice();
scopeCanvas->setDeviceName(outputDevices[outputDevice].name); scopeCanvas->setDeviceName(outputDevices[outputDevice].name);
outputDeviceMenuItems[outputDevice]->Check(true); // outputDeviceMenuItems[outputDevice]->Check(true);
std::string dType = demod->getDemodulatorType(); std::string dType = demod->getDemodulatorType();
demodModeSelector->setSelection(dType); demodModeSelector->setSelection(dType);
#ifdef ENABLE_DIGITAL_LAB #ifdef ENABLE_DIGITAL_LAB
@ -1504,7 +1517,7 @@ void AppFrame::OnIdle(wxIdleEvent& event) {
//reset notification flag //reset notification flag
modemPropertiesUpdated.store(false); modemPropertiesUpdated.store(false);
modemProps->initProperties(demod->getModemArgs()); modemProps->initProperties(demod->getModemArgs(), demod);
demodTray->Layout(); demodTray->Layout();
modemProps->fitColumns(); modemProps->fitColumns();
@ -1517,17 +1530,20 @@ void AppFrame::OnIdle(wxIdleEvent& event) {
} }
demod->showOutput(); demod->showOutput();
} }
#endif #endif
} else if (!demod) {
modemProps->Hide();
demodTray->Layout();
} }
if (modemProps->isCollapsed() && modemProps->GetMinWidth() > 22) { if (modemProps->IsShown() && modemProps->isCollapsed() && modemProps->GetMinWidth() > 22) {
modemProps->SetMinSize(wxSize(22,-1)); modemProps->SetMinSize(wxSize(22,-1));
modemProps->SetMaxSize(wxSize(22,-1)); modemProps->SetMaxSize(wxSize(22,-1));
demodTray->Layout(); demodTray->Layout();
modemProps->fitColumns(); modemProps->fitColumns();
} else if (!modemProps->isCollapsed() && modemProps->GetMinWidth() < 200) { } else if (modemProps->IsShown() && !modemProps->isCollapsed() && modemProps->GetMinWidth() < 200) {
modemProps->SetMinSize(wxSize(200,-1)); modemProps->SetMinSize(wxSize(APPFRAME_MODEMPROPS_SIZE,-1));
modemProps->SetMaxSize(wxSize(200,-1)); modemProps->SetMaxSize(wxSize(APPFRAME_MODEMPROPS_SIZE,-1));
demodTray->Layout(); demodTray->Layout();
modemProps->fitColumns(); modemProps->fitColumns();
} }
@ -1893,6 +1909,10 @@ void AppFrame::setMainWaterfallFFTSize(int fftSize) {
waterfallCanvas->setFFTSize(fftSize); waterfallCanvas->setFFTSize(fftSize);
} }
void AppFrame::setScopeDeviceName(std::string deviceName) {
scopeCanvas->setDeviceName(deviceName);
}
void AppFrame::refreshGainUI() { void AppFrame::refreshGainUI() {
gainCanvas->updateGainUI(); gainCanvas->updateGainUI();

View File

@ -85,6 +85,7 @@ public:
void notifyUpdateModemProperties(); void notifyUpdateModemProperties();
void setMainWaterfallFFTSize(int fftSize); void setMainWaterfallFFTSize(int fftSize);
void setScopeDeviceName(std::string deviceName);
void gkNudgeLeft(DemodulatorInstance *demod, int snap); void gkNudgeLeft(DemodulatorInstance *demod, int snap);
void gkNudgeRight(DemodulatorInstance *demod, int snap); void gkNudgeRight(DemodulatorInstance *demod, int snap);

View File

@ -66,20 +66,72 @@ ModemProperties::~ModemProperties() {
} }
void ModemProperties::initProperties(ModemArgInfoList newArgs) {
args = newArgs;
void ModemProperties::initDefaultProperties() {
if (!audioOutputDevices.size()) {
std::vector<string> outputOpts;
std::vector<string> outputOptNames;
AudioThread::enumerateDevices(audioDevices);
int i = 0;
for (auto aDev : audioDevices) {
if (aDev.inputChannels) {
audioInputDevices[i] = aDev;
}
if (aDev.outputChannels) {
audioOutputDevices[i] = aDev;
}
i++;
}
int defaultDevice = 0;
int dc = 0;
for (auto mdevices_i : audioOutputDevices) {
outputOpts.push_back(std::to_string(mdevices_i.first));
outputOptNames.push_back(mdevices_i.second.name);
if (mdevices_i.second.isDefaultOutput) {
defaultDevice = dc;
}
dc++;
}
outputArg.key ="._audio_output";
outputArg.name = "Audio Out";
outputArg.description = "Set the current modem's audio output device.";
outputArg.type = ModemArgInfo::STRING;
outputArg.options = outputOpts;
outputArg.optionNames = outputOptNames;
}
int currentOutput = demodContext->getOutputDevice();
outputArg.value = std::to_string(currentOutput);
defaultProps["._audio_output"] = addArgInfoProperty(m_propertyGrid, outputArg);
}
void ModemProperties::initProperties(ModemArgInfoList newArgs, DemodulatorInstance *demodInstance) {
args = newArgs;
demodContext = demodInstance;
bSizer->Layout(); bSizer->Layout();
m_propertyGrid->Clear(); m_propertyGrid->Clear();
if (newArgs.size() == 0) { if (!demodInstance) {
Hide(); Hide();
return; return;
} else { } else {
Show(); Show();
} }
m_propertyGrid->Append(new wxPropertyCategory("Modem Settings")); m_propertyGrid->Append(new wxPropertyCategory(demodInstance->getDemodulatorType() + " Settings"));
initDefaultProperties();
ModemArgInfoList::const_iterator args_i; ModemArgInfoList::const_iterator args_i;
@ -161,7 +213,7 @@ wxPGProperty *ModemProperties::addArgInfoProperty(wxPropertyGrid *pg, ModemArgIn
} }
if (prop != NULL) { if (prop != NULL) {
prop->SetHelpString(arg.key + ": " + arg.description); prop->SetHelpString(arg.name + ": " + arg.description);
} }
return prop; return prop;
@ -191,18 +243,35 @@ std::string ModemProperties::readProperty(std::string key) {
} }
void ModemProperties::OnChange(wxPropertyGridEvent &event) { void ModemProperties::OnChange(wxPropertyGridEvent &event) {
DemodulatorInstance *inst = wxGetApp().getDemodMgr().getLastActiveDemodulator(); if (!demodContext || !demodContext->isActive()) {
if (!inst) {
return; return;
} }
std::map<std::string, wxPGProperty *>::const_iterator prop_i; std::map<std::string, wxPGProperty *>::const_iterator prop_i;
if (event.m_property == defaultProps["._audio_output"]) {
int sel = event.m_property->GetChoiceSelection();
outputArg.value = outputArg.options[sel];
if (demodContext) {
try {
demodContext->setOutputDevice(std::stoi(outputArg.value));
} catch (exception e) {
// .. this should never happen ;)
}
wxGetApp().getAppFrame()->setScopeDeviceName(outputArg.optionNames[sel]);
}
return;
}
for (prop_i = props.begin(); prop_i != props.end(); prop_i++) { for (prop_i = props.begin(); prop_i != props.end(); prop_i++) {
if (prop_i->second == event.m_property) { if (prop_i->second == event.m_property) {
std::string key = prop_i->first; std::string key = prop_i->first;
std::string value = readProperty(prop_i->first); std::string value = readProperty(prop_i->first);
inst->writeModemSetting(key, value); demodContext->writeModemSetting(key, value);
return; return;
} }
} }
@ -228,6 +297,17 @@ bool ModemProperties::isMouseInView() {
return mouseInView || (m_propertyGrid && m_propertyGrid->IsEditorFocused()); return mouseInView || (m_propertyGrid && m_propertyGrid->IsEditorFocused());
} }
void ModemProperties::setCollapsed(bool state) {
collapsed = state;
if (m_propertyGrid) {
if (state) {
m_propertyGrid->CollapseAll();
} else {
m_propertyGrid->ExpandAll();
}
}
}
bool ModemProperties::isCollapsed() { bool ModemProperties::isCollapsed() {
return collapsed; return collapsed;
} }

View File

@ -5,6 +5,7 @@
#include <wx/propgrid/propgrid.h> #include <wx/propgrid/propgrid.h>
#include <wx/propgrid/advprops.h> #include <wx/propgrid/advprops.h>
#include "DemodulatorInstance.h"
#include "Modem.h" #include "Modem.h"
class ModemProperties : public wxPanel { class ModemProperties : public wxPanel {
@ -19,8 +20,10 @@ public:
); );
~ModemProperties(); ~ModemProperties();
void initProperties(ModemArgInfoList newArgs); void initDefaultProperties();
void initProperties(ModemArgInfoList newArgs, DemodulatorInstance *demodInstance);
bool isMouseInView(); bool isMouseInView();
void setCollapsed(bool state);
bool isCollapsed(); bool isCollapsed();
void fitColumns(); void fitColumns();
@ -40,6 +43,15 @@ private:
wxBoxSizer* bSizer; wxBoxSizer* bSizer;
wxPropertyGrid* m_propertyGrid; wxPropertyGrid* m_propertyGrid;
ModemArgInfoList args; ModemArgInfoList args;
DemodulatorInstance *demodContext;
std::map<std::string, wxPGProperty *> props; std::map<std::string, wxPGProperty *> props;
bool mouseInView, collapsed; bool mouseInView, collapsed;
ModemArgInfoList defaultArgs;
ModemArgInfo outputArg;
std::map<std::string, wxPGProperty *> defaultProps;
std::vector<RtAudio::DeviceInfo> audioDevices;
std::map<int,RtAudio::DeviceInfo> audioInputDevices;
std::map<int,RtAudio::DeviceInfo> audioOutputDevices;
}; };