Merge pull request #418 from cjcliffe/menu_refactor

Menu Refactoring
This commit is contained in:
Charles J. Cliffe 2016-07-28 21:53:39 -05:00 committed by GitHub
commit 4169186914
6 changed files with 199 additions and 64 deletions

View File

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

View File

@ -85,6 +85,9 @@ public:
void setWindowMaximized(bool max);
bool getWindowMaximized();
void setModemPropsCollapsed(bool collapse);
bool getModemPropsCollapsed();
void setShowTips(bool show);
bool getShowTips();
@ -148,7 +151,7 @@ private:
std::string configName;
std::map<std::string, DeviceConfig *> deviceConfig;
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 fontScale;
std::atomic_llong snap;

View File

@ -42,6 +42,8 @@ wxEND_EVENT_TABLE()
#include "RigThread.h"
#endif
#define APPFRAME_MODEMPROPS_SIZE 240
AppFrame::AppFrame() :
wxFrame(NULL, wxID_ANY, CUBICSDR_TITLE), activeDemodulator(NULL) {
@ -110,8 +112,8 @@ AppFrame::AppFrame() :
modemPropertiesUpdated.store(false);
modemProps = new ModemProperties(demodPanel, wxID_ANY);
modemProps->SetMinSize(wxSize(200,-1));
modemProps->SetMaxSize(wxSize(200,-1));
modemProps->SetMinSize(wxSize(APPFRAME_MODEMPROPS_SIZE,-1));
modemProps->SetMaxSize(wxSize(APPFRAME_MODEMPROPS_SIZE,-1));
modemProps->Hide();
demodTray->Add(modemProps, 15, wxEXPAND | wxALL, 0);
@ -367,32 +369,22 @@ AppFrame::AppFrame() :
}
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?"));
itm->SetId(wxID_RT_AUDIO_DEVICE + mdevices_i->first);
if (mdevices_i->second.isDefaultOutput) {
itm->Check(true);
}
outputDeviceMenuItems[mdevices_i->first] = itm;
}
menuBar->Append(menu, wxT("Audio &Output"));
menu = new wxMenu;
int themeId = wxGetApp().getConfig()->getTheme();
//
// 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?"));
// itm->SetId(wxID_RT_AUDIO_DEVICE + mdevices_i->first);
// if (mdevices_i->second.isDefaultOutput) {
// itm->Check(true);
// }
// outputDeviceMenuItems[mdevices_i->first] = itm;
// }
//
// menuBar->Append(menu, wxT("Audio &Output"));
menu->AppendRadioItem(wxID_THEME_DEFAULT, "Default")->Check(themeId==COLOR_THEME_DEFAULT);
menu->AppendRadioItem(wxID_THEME_RADAR, "RADAR")->Check(themeId==COLOR_THEME_RADAR);
menu->AppendRadioItem(wxID_THEME_BW, "Black & White")->Check(themeId==COLOR_THEME_BW);
menu->AppendRadioItem(wxID_THEME_SHARP, "Sharp")->Check(themeId==COLOR_THEME_SHARP);
menu->AppendRadioItem(wxID_THEME_RAD, "Rad")->Check(themeId==COLOR_THEME_RAD);
menu->AppendRadioItem(wxID_THEME_TOUCH, "Touch")->Check(themeId==COLOR_THEME_TOUCH);
menu->AppendRadioItem(wxID_THEME_HD, "HD")->Check(themeId==COLOR_THEME_HD);
menuBar->Append(menu, wxT("&Color Scheme"));
sampleRateMenu = new wxMenu;
menuBar->Append(sampleRateMenu, wxT("Sample &Rate"));
// Audio Sample Rates
menu = new wxMenu;
#define NUM_RATES_DEFAULT 4
@ -441,23 +433,35 @@ AppFrame::AppFrame() :
}
}
sampleRateMenu = new wxMenu;
menuBar->Append(sampleRateMenu, wxT("Sample &Rate"));
menuBar->Append(menu, wxT("Audio &Sample Rate"));
//Add Display menu
displayMenu = new wxMenu;
wxMenu *fontMenu = new wxMenu;
menuBar->Append(displayMenu, wxT("&Display"));
int fontScale = wxGetApp().getConfig()->getFontScale();
displayMenu->AppendRadioItem(wxID_DISPLAY_BASE, "Text Size: Normal")->Check(GLFont::GLFONT_SCALE_NORMAL == fontScale);
displayMenu->AppendRadioItem(wxID_DISPLAY_BASE + 1, "Text Size: 1.5x")->Check(GLFont::GLFONT_SCALE_MEDIUM == fontScale);
displayMenu->AppendRadioItem(wxID_DISPLAY_BASE + 2, "Text Size: 2.0x")->Check(GLFont::GLFONT_SCALE_LARGE == fontScale);
fontMenu->AppendRadioItem(wxID_DISPLAY_BASE, "Normal")->Check(GLFont::GLFONT_SCALE_NORMAL == fontScale);
fontMenu->AppendRadioItem(wxID_DISPLAY_BASE + 1, "1.5x")->Check(GLFont::GLFONT_SCALE_MEDIUM == fontScale);
fontMenu->AppendRadioItem(wxID_DISPLAY_BASE + 2, "2.0x")->Check(GLFont::GLFONT_SCALE_LARGE == fontScale);
displayMenu->AppendSubMenu(fontMenu, "&Text Size");
wxMenu *themeMenu = new wxMenu;
int themeId = wxGetApp().getConfig()->getTheme();
themeMenu->AppendRadioItem(wxID_THEME_DEFAULT, "Default")->Check(themeId==COLOR_THEME_DEFAULT);
themeMenu->AppendRadioItem(wxID_THEME_RADAR, "RADAR")->Check(themeId==COLOR_THEME_RADAR);
themeMenu->AppendRadioItem(wxID_THEME_BW, "Black & White")->Check(themeId==COLOR_THEME_BW);
themeMenu->AppendRadioItem(wxID_THEME_SHARP, "Sharp")->Check(themeId==COLOR_THEME_SHARP);
themeMenu->AppendRadioItem(wxID_THEME_RAD, "Rad")->Check(themeId==COLOR_THEME_RAD);
themeMenu->AppendRadioItem(wxID_THEME_TOUCH, "Touch")->Check(themeId==COLOR_THEME_TOUCH);
themeMenu->AppendRadioItem(wxID_THEME_HD, "HD")->Check(themeId==COLOR_THEME_HD);
displayMenu->AppendSubMenu(themeMenu, wxT("&Color Scheme"));
GLFont::setScale((GLFont::GLFontScale)fontScale);
#ifdef USE_HAMLIB
@ -539,7 +543,9 @@ AppFrame::AppFrame() :
menuBar->Append(rigMenu, wxT("&Rig Control"));
#endif
menuBar->Append(displayMenu, wxT("&Display"));
SetMenuBar(menuBar);
CreateStatusBar();
@ -574,6 +580,12 @@ AppFrame::AppFrame() :
ThemeMgr::mgr.setTheme(wxGetApp().getConfig()->getTheme());
int mpc =wxGetApp().getConfig()->getModemPropsCollapsed();
if (mpc) {
modemProps->setCollapsed(true);
}
Show();
#ifdef _WIN32
@ -721,7 +733,7 @@ void AppFrame::updateDeviceParams() {
sampleRateMenuItems[wxID_BANDWIDTH_MANUAL]->Check(true);
}
menuBar->Replace(4, newSampleRateMenu, wxT("Sample &Rate"));
menuBar->Replace(2, newSampleRateMenu, wxT("Sample &Rate"));
sampleRateMenu = newSampleRateMenu;
if (!wxGetApp().getAGCMode()) {
@ -792,19 +804,23 @@ void AppFrame::disableRig() {
void AppFrame::OnMenu(wxCommandEvent& event) {
if (event.GetId() >= wxID_RT_AUDIO_DEVICE && event.GetId() < wxID_RT_AUDIO_DEVICE + (int)devices.size()) {
if (activeDemodulator) {
activeDemodulator->setOutputDevice(event.GetId() - wxID_RT_AUDIO_DEVICE);
activeDemodulator = NULL;
}
}
// if (event.GetId() >= wxID_RT_AUDIO_DEVICE && event.GetId() < wxID_RT_AUDIO_DEVICE + (int)devices.size()) {
// if (activeDemodulator) {
// activeDemodulator->setOutputDevice(event.GetId() - wxID_RT_AUDIO_DEVICE);
// activeDemodulator = NULL;
// }
// return;
// }
#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);
aboutDlg->ShowModal();
return;
}
#endif
else if (event.GetId() == wxID_SDR_START_STOP) {
if (event.GetId() == wxID_SDR_START_STOP) {
if (!wxGetApp().getSDRThread()->isTerminated()) {
wxGetApp().stopDevice(true, 2000);
} else {
@ -1200,6 +1216,7 @@ void AppFrame::OnClose(wxCloseEvent& event) {
wxGetApp().getConfig()->setSpectrumAvgSpeed(wxGetApp().getSpectrumProcessor()->getFFTAverageRate());
wxGetApp().getConfig()->setWaterfallLinesPerSec(waterfallDataThread->getLinesPerSecond());
wxGetApp().getConfig()->setManualDevices(SDREnumerator::getManuals());
wxGetApp().getConfig()->setModemPropsCollapsed(modemProps->isCollapsed());
#ifdef USE_HAMLIB
wxGetApp().getConfig()->setRigEnabled(rigEnableMenuItem->IsChecked());
wxGetApp().getConfig()->setRigModel(rigModel);
@ -1259,7 +1276,7 @@ void AppFrame::OnIdle(wxIdleEvent& event) {
wxGetApp().getDemodMgr().setLastGain(demod->getGain());
int outputDevice = demod->getOutputDevice();
scopeCanvas->setDeviceName(outputDevices[outputDevice].name);
outputDeviceMenuItems[outputDevice]->Check(true);
// outputDeviceMenuItems[outputDevice]->Check(true);
std::string dType = demod->getDemodulatorType();
demodModeSelector->setSelection(dType);
#ifdef ENABLE_DIGITAL_LAB
@ -1500,7 +1517,7 @@ void AppFrame::OnIdle(wxIdleEvent& event) {
//reset notification flag
modemPropertiesUpdated.store(false);
modemProps->initProperties(demod->getModemArgs());
modemProps->initProperties(demod->getModemArgs(), demod);
demodTray->Layout();
modemProps->fitColumns();
@ -1513,17 +1530,20 @@ void AppFrame::OnIdle(wxIdleEvent& event) {
}
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->SetMaxSize(wxSize(22,-1));
demodTray->Layout();
modemProps->fitColumns();
} else if (!modemProps->isCollapsed() && modemProps->GetMinWidth() < 200) {
modemProps->SetMinSize(wxSize(200,-1));
modemProps->SetMaxSize(wxSize(200,-1));
} else if (modemProps->IsShown() && !modemProps->isCollapsed() && modemProps->GetMinWidth() < 200) {
modemProps->SetMinSize(wxSize(APPFRAME_MODEMPROPS_SIZE,-1));
modemProps->SetMaxSize(wxSize(APPFRAME_MODEMPROPS_SIZE,-1));
demodTray->Layout();
modemProps->fitColumns();
}
@ -1889,6 +1909,10 @@ void AppFrame::setMainWaterfallFFTSize(int fftSize) {
waterfallCanvas->setFFTSize(fftSize);
}
void AppFrame::setScopeDeviceName(std::string deviceName) {
scopeCanvas->setDeviceName(deviceName);
}
void AppFrame::refreshGainUI() {
gainCanvas->updateGainUI();

View File

@ -85,6 +85,7 @@ public:
void notifyUpdateModemProperties();
void setMainWaterfallFFTSize(int fftSize);
void setScopeDeviceName(std::string deviceName);
void gkNudgeLeft(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();
m_propertyGrid->Clear();
if (newArgs.size() == 0) {
if (!demodInstance) {
Hide();
return;
} else {
Show();
}
m_propertyGrid->Append(new wxPropertyCategory("Modem Settings"));
m_propertyGrid->Append(new wxPropertyCategory(demodInstance->getDemodulatorType() + " Settings"));
initDefaultProperties();
ModemArgInfoList::const_iterator args_i;
@ -161,7 +213,7 @@ wxPGProperty *ModemProperties::addArgInfoProperty(wxPropertyGrid *pg, ModemArgIn
}
if (prop != NULL) {
prop->SetHelpString(arg.key + ": " + arg.description);
prop->SetHelpString(arg.name + ": " + arg.description);
}
return prop;
@ -191,18 +243,35 @@ std::string ModemProperties::readProperty(std::string key) {
}
void ModemProperties::OnChange(wxPropertyGridEvent &event) {
DemodulatorInstance *inst = wxGetApp().getDemodMgr().getLastActiveDemodulator();
if (!inst) {
if (!demodContext || !demodContext->isActive()) {
return;
}
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++) {
if (prop_i->second == event.m_property) {
std::string key = prop_i->first;
std::string value = readProperty(prop_i->first);
inst->writeModemSetting(key, value);
demodContext->writeModemSetting(key, value);
return;
}
}
@ -228,6 +297,17 @@ bool ModemProperties::isMouseInView() {
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() {
return collapsed;
}

View File

@ -5,6 +5,7 @@
#include <wx/propgrid/propgrid.h>
#include <wx/propgrid/advprops.h>
#include "DemodulatorInstance.h"
#include "Modem.h"
class ModemProperties : public wxPanel {
@ -19,8 +20,10 @@ public:
);
~ModemProperties();
void initProperties(ModemArgInfoList newArgs);
void initDefaultProperties();
void initProperties(ModemArgInfoList newArgs, DemodulatorInstance *demodInstance);
bool isMouseInView();
void setCollapsed(bool state);
bool isCollapsed();
void fitColumns();
@ -40,6 +43,15 @@ private:
wxBoxSizer* bSizer;
wxPropertyGrid* m_propertyGrid;
ModemArgInfoList args;
DemodulatorInstance *demodContext;
std::map<std::string, wxPGProperty *> props;
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;
};