bugfix + part of the new command arg system

This commit is contained in:
AlexandreRouma 2022-02-18 19:21:02 +01:00
parent f46fa2157b
commit a87aedabb8
5 changed files with 265 additions and 1 deletions

103
core/src/command_args.cpp Normal file
View File

@ -0,0 +1,103 @@
#include "command_args.h"
int CommandArgsParser::parse(int argc, char* argv[]) {
for (int i = 1; i < argc; i++) {
std::string arg = argv[i];
// Check for long and short name arguments
if (!arg.rfind("--", 0)) {
arg = arg.substr(2);
}
else if (!arg.rfind("-", 0)) {
if (aliases.find(arg[1]) == aliases.end()) {
printf("Unknown argument\n");
showHelp();
return -1;
}
arg = aliases[arg[1]];
}
else {
printf("Invalid argument\n");
showHelp();
return -1;
}
// Make sure the argument exists
if (args.find(arg) == args.end()) {
printf("Unknown argument\n");
showHelp();
return -1;
}
// Parse depending on type
CLIArg& carg = args[arg];
// If not void, make sure an argument is available and retrieve it
if (carg.type != CLI_ARG_TYPE_VOID && i + 1 >= argc) {
printf("Missing argument\n");
showHelp();
return -1;
}
// Parse void since arg won't be needed
if (carg.type == CLI_ARG_TYPE_VOID) {
carg.bval = true;
continue;
}
// Parse types that require parsing
arg = argv[++i];
if (carg.type == CLI_ARG_TYPE_BOOL) {
// Enforce lower case
for (int i = 0; i < arg.size(); i++) { arg[i] = std::tolower(arg[i]); }
if (arg == "true" || arg == "on" || arg == "1") {
carg.bval = true;
}
else if (arg == "false" || arg == "off" || arg == "0") {
carg.bval = true;
}
else {
printf("Invald argument, expected bool (true, false, on, off, 1, 0)\n");
showHelp();
return -1;
}
}
else if (carg.type == CLI_ARG_TYPE_INT) {
try {
carg.ival = std::stoi(arg);
}
catch (std::exception e) {
printf("Invald argument, failed to parse integer\n");
showHelp();
return -1;
}
}
else if (carg.type == CLI_ARG_TYPE_FLOAT) {
try {
carg.fval = std::stod(arg);
}
catch (std::exception e) {
printf("Invald argument, failed to parse float\n");
showHelp();
return -1;
}
}
else if (carg.type == CLI_ARG_TYPE_STRING) {
carg.sval = arg;
}
}
return 0;
}
void CommandArgsParser::showHelp() {
for (auto const& [ln, arg] : args) {
if (arg.alias) {
printf("-%c\t--%s\t\t%s\n", arg.alias, ln.c_str(), arg.description.c_str());
}
else {
printf(" \t--%s\t\t%s\n", ln.c_str(), arg.description.c_str());
}
}
}

127
core/src/command_args.h Normal file
View File

@ -0,0 +1,127 @@
#pragma once
#include <string>
#include <map>
#include <stdexcept>
enum CLIArgType {
CLI_ARG_TYPE_INVALID,
CLI_ARG_TYPE_VOID,
CLI_ARG_TYPE_BOOL,
CLI_ARG_TYPE_INT,
CLI_ARG_TYPE_FLOAT,
CLI_ARG_TYPE_STRING
};
class CommandArgsParser;
class CLIArg {
public:
CLIArg() {
type = CLI_ARG_TYPE_INVALID;
}
CLIArg(char al, std::string desc) {
alias = al;
description = desc;
type = CLI_ARG_TYPE_VOID;
}
CLIArg(char al, std::string desc, bool b) {
alias = al;
description = desc;
type = CLI_ARG_TYPE_BOOL;
bval = b;
}
CLIArg(char al, std::string desc, int i) {
alias = al;
description = desc;
type = CLI_ARG_TYPE_INT;
ival = i;
}
CLIArg(char al, std::string desc, double f) {
alias = al;
description = desc;
type = CLI_ARG_TYPE_FLOAT;
fval = f;
}
CLIArg(char al, std::string desc, std::string s) {
printf("String const called\n");
alias = al;
description = desc;
type = CLI_ARG_TYPE_STRING;
sval = s;
}
CLIArg(char al, std::string desc, const char* s) {
printf("String const called\n");
alias = al;
description = desc;
type = CLI_ARG_TYPE_STRING;
sval = s;
}
operator bool() const {
if (type != CLI_ARG_TYPE_BOOL && type != CLI_ARG_TYPE_VOID) { throw std::runtime_error("Not a bool"); }
return bval;
}
operator int() const {
if (type != CLI_ARG_TYPE_INT) { throw std::runtime_error("Not an int"); }
return ival;
}
operator float() const {
if (type != CLI_ARG_TYPE_FLOAT) { throw std::runtime_error("Not a float"); }
return (float)fval;
}
operator double() const {
if (type != CLI_ARG_TYPE_FLOAT) { throw std::runtime_error("Not a float"); }
return fval;
}
operator std::string() const {
if (type != CLI_ARG_TYPE_STRING) { throw std::runtime_error("Not a string"); }
return sval;
}
friend CommandArgsParser;
CLIArgType type;
char alias;
std::string description;
private:
bool bval;
int ival;
std::string sval;
double fval;
};
class CommandArgsParser {
public:
void define(char shortName, std::string name, std::string desc) {
args[name] = CLIArg(shortName, desc);
aliases[shortName] = name;
}
template<class T>
void define(char shortName, std::string name, std::string desc, T defValue) {
args[name] = CLIArg(shortName, desc, defValue);
aliases[shortName] = name;
}
int parse(int argc, char* argv[]);
void showHelp();
CLIArg operator[](std::string name) {
return args[name];
}
private:
std::map<std::string, CLIArg> args;
std::map<char, std::string> aliases;
};

View File

@ -184,6 +184,7 @@ int sdrpp_main(int argc, char* argv[]) {
// Themes
defConfig["theme"] = "Dark";
defConfig["uiScale"] = 1.0f;
defConfig["modules"] = json::array();
@ -279,6 +280,9 @@ int sdrpp_main(int argc, char* argv[]) {
core::configManager.conf["moduleInstances"][_name] = newMod;
}
// Load UI scaling
style::uiScale = core::configManager.conf["uiScale"];
core::configManager.release(true);
if (options::opts.serverMode) { return server::main(); }

View File

@ -450,7 +450,7 @@ void MainWindow::draw() {
// Handle menu resize
ImVec2 winSize = ImGui::GetWindowSize();
ImVec2 mousePos = ImGui::GetMousePos();
if (!lockWaterfallControls) {
if (!lockWaterfallControls && showMenu) {
float curY = ImGui::GetCursorPosY();
bool click = ImGui::IsMouseClicked(ImGuiMouseButton_Left);
bool down = ImGui::IsMouseDown(ImGuiMouseButton_Left);
@ -639,6 +639,7 @@ void MainWindow::draw() {
ImGui::SetCursorPosX((ImGui::GetWindowSize().x / 2.0) - (ImGui::CalcTextSize("Min").x / 2.0));
ImGui::TextUnformatted("Min");
ImGui::SetCursorPosX((ImGui::GetWindowSize().x / 2.0) - 10 * style::uiScale);
ImGui::SetItemUsingMouseWheel();
if (ImGui::VSliderFloat("##_9_", wfSliderSize, &fftMin, 0.0, -160.0f, "")) {
fftMin = std::min<float>(fftMax - 10, fftMin);
core::configManager.acquire();

View File

@ -7,6 +7,7 @@
#include <gui/main_window.h>
#include <signal_path/signal_path.h>
#include <gui/style.h>
#include <utils/optionlist.h>
namespace displaymenu {
bool showWaterfall;
@ -18,6 +19,10 @@ namespace displaymenu {
std::string colorMapAuthor = "";
int selectedWindow = 0;
int fftRate = 20;
int uiScaleId = 0;
bool restartRequired = false;
OptionList<float, float> uiScales;
const int FFTSizes[] = {
524288,
@ -85,6 +90,17 @@ namespace displaymenu {
selectedWindow = std::clamp<int>((int)core::configManager.conf["fftWindow"], 0, _FFT_WINDOW_COUNT - 1);
gui::mainWindow.setFFTWindow(selectedWindow);
// Define and load UI scales
uiScales.define(0.5f, "50%", 0.5f);
uiScales.define(1.0f, "100%", 1.0f);
uiScales.define(1.5f, "150%", 1.5f);
uiScales.define(2.0f, "200%", 2.0f);
uiScales.define(2.5f, "250%", 2.5f);
uiScales.define(3.0f, "300%", 3.0f);
uiScales.define(3.5f, "350%", 3.5f);
uiScales.define(4.0f, "400%", 4.0f);
uiScaleId = uiScales.valueId(style::uiScale);
}
void draw(void* ctx) {
@ -112,6 +128,15 @@ namespace displaymenu {
core::configManager.release(true);
}
ImGui::LeftLabel("High-DPI Scaling");
ImGui::FillWidth();
if (ImGui::Combo("##sdrpp_ui_scale", &uiScaleId, uiScales.txt)) {
core::configManager.acquire();
core::configManager.conf["uiScale"] = uiScales[uiScaleId];
core::configManager.release(true);
restartRequired = true;
}
ImGui::LeftLabel("FFT Framerate");
ImGui::SetNextItemWidth(menuWidth - ImGui::GetCursorPosX());
if (ImGui::InputInt("##sdrpp_fft_rate", &fftRate, 1, 10)) {
@ -153,5 +178,9 @@ namespace displaymenu {
}
ImGui::Text("Color map Author: %s", colorMapAuthor.c_str());
}
if (restartRequired) {
ImGui::TextColored(ImVec4(1.0f, 1.0f, 0.0f, 1.0f), "Restart required.");
}
}
}