Added VFO coloring option

pull/133/head
Ryzerth 2021-05-04 20:41:23 +02:00
rodzic 9a1850bd61
commit 1eca58605c
10 zmienionych plików z 200 dodań i 10 usunięć

Wyświetl plik

@ -195,7 +195,8 @@ private:
// Setup device parameters
bladerf_set_sample_rate(_this->openDev, BLADERF_CHANNEL_RX(0), _this->sampleRate, NULL);
bladerf_set_frequency(_this->openDev, BLADERF_CHANNEL_RX(0), _this->freq);
bladerf_set_bandwidth(_this->openDev, BLADERF_CHANNEL_RX(0), (_this->bwId == _this->bandwidths.size()) ? _this->sampleRate : _this->bandwidths[_this->bwId], NULL);
bladerf_set_bandwidth(_this->openDev, BLADERF_CHANNEL_RX(0), (_this->bwId == _this->bandwidths.size()) ?
std::clamp<uint64_t>(_this->sampleRate, _this->bwRange->min, _this->bwRange->max) : _this->bandwidths[_this->bwId], NULL);
bladerf_set_gain_mode(_this->openDev, BLADERF_CHANNEL_RX(0), BLADERF_GAIN_MANUAL);
bladerf_set_gain(_this->openDev, BLADERF_CHANNEL_RX(0), _this->testGain);
@ -280,7 +281,8 @@ private:
ImGui::SetNextItemWidth(menuWidth - ImGui::GetCursorPosX());
if (ImGui::Combo(CONCAT("##_balderf_bw_sel_", _this->name), &_this->bwId, _this->bandwidthsTxt.c_str())) {
if (_this->running) {
bladerf_set_bandwidth(_this->openDev, BLADERF_CHANNEL_RX(0), (_this->bwId == _this->bandwidths.size()) ? _this->sampleRate : _this->bandwidths[_this->bwId], NULL);
bladerf_set_bandwidth(_this->openDev, BLADERF_CHANNEL_RX(0), (_this->bwId == _this->bandwidths.size()) ?
std::clamp<uint64_t>(_this->sampleRate, _this->bwRange->min, _this->bwRange->max) : _this->bandwidths[_this->bwId], NULL);
}
// Save config
}

Wyświetl plik

@ -174,6 +174,8 @@ int sdrpp_main(int argc, char *argv[]) {
defConfig["vfoOffsets"] = json::object();
defConfig["vfoColors"]["Radio"] = "#FFFFFF";
#ifdef _WIN32
defConfig["modulesDirectory"] = "./modules";
defConfig["resourcesDirectory"] = "./res";
@ -193,7 +195,7 @@ int sdrpp_main(int argc, char *argv[]) {
// Fix missing elements in config
for (auto const& item : defConfig.items()) {
if (!core::configManager.conf.contains(item.key())) {
spdlog::warn("Missing key in config {0}, repairing", item.key());
spdlog::info("Missing key in config {0}, repairing", item.key());
core::configManager.conf[item.key()] = defConfig[item.key()];
}
}
@ -202,7 +204,7 @@ int sdrpp_main(int argc, char *argv[]) {
auto items = core::configManager.conf.items();
for (auto const& item : items) {
if (!defConfig.contains(item.key())) {
spdlog::warn("Unused key in config {0}, repairing", item.key());
spdlog::info("Unused key in config {0}, repairing", item.key());
core::configManager.conf.erase(item.key());
}
}

Wyświetl plik

@ -32,6 +32,7 @@
#include <options.h>
#include <gui/colormaps.h>
#include <gui/widgets/snr_meter.h>
#include <gui/menus/vfo_color.h>
int fftSize = 8192 * 8;
@ -135,6 +136,7 @@ void windowInit() {
gui::menu.registerEntry("Scripting", scriptingmenu::draw, NULL);
gui::menu.registerEntry("Band Plan", bandplanmenu::draw, NULL);
gui::menu.registerEntry("Display", displaymenu::draw, NULL);
gui::menu.registerEntry("VFO Color", vfo_color_menu::draw, NULL);
gui::freqSelect.init();
@ -214,6 +216,7 @@ void windowInit() {
scriptingmenu::init();
bandplanmenu::init();
displaymenu::init();
vfo_color_menu::init();
// TODO for 0.2.5
// Add "select file" option for the file source

Wyświetl plik

@ -0,0 +1,137 @@
#include <gui/menus/vfo_color.h>
#include <gui/gui.h>
#include <gui/widgets/waterfall.h>
#include <signal_path/signal_path.h>
#include <string>
#include <core.h>
#include <map>
namespace vfo_color_menu {
std::map<std::string, ImVec4> vfoColors;
std::string openName = "";
EventHandler<VFOManager::VFO*> vfoAddHndl;
void vfoAddHandler(VFOManager::VFO* vfo, void* ctx) {
std::string name = vfo->getName();
if (vfoColors.find(name) != vfoColors.end()) {
ImVec4 col = vfoColors[name];
vfo->setColor(IM_COL32((int)roundf(col.x * 255), (int)roundf(col.y * 255), (int)roundf(col.z * 255), 50));
return;
}
vfo->setColor(IM_COL32(255, 255, 255, 50));
vfoColors[name] = ImVec4(1.0f, 1.0f, 1.0f, 1.0f);
}
void init() {
// Load colors from config
bool modified = false;
core::configManager.aquire();
json conf = core::configManager.conf["vfoColors"];
for (auto& [name, val] : conf.items()) {
// If not a string, repair with default
if (!val.is_string()) {
core::configManager.conf["vfoColors"][name] = "#FFFFFF";
vfoColors[name] = ImVec4(1.0f, 1.0f, 1.0f, 1.0f);
modified = true;
if (sigpath::vfoManager.vfoExists(name)) {
sigpath::vfoManager.setColor(name, IM_COL32(255, 255, 255, 50));
}
continue;
}
// If not a valid hex color, repair with default
std::string col = val;
if (col[0] != '#' || !std::all_of(col.begin() + 1, col.end(), ::isxdigit)) {
core::configManager.conf["vfoColors"][name] = "#FFFFFF";
vfoColors[name] = ImVec4(1.0f, 1.0f, 1.0f, 1.0f);
modified = true;
if (sigpath::vfoManager.vfoExists(name)) {
sigpath::vfoManager.setColor(name, IM_COL32(255, 255, 255, 50));
}
continue;
}
// Since the color is valid, decode it and set the vfo's color
float r, g, b;
r = std::stoi(col.substr(1, 2), NULL, 16);
g = std::stoi(col.substr(3, 2), NULL, 16);
b = std::stoi(col.substr(5, 2), NULL, 16);
vfoColors[name] = ImVec4(r / 255.0f, g / 255.0f, b / 255.0f, 1.0f);
if (sigpath::vfoManager.vfoExists(name)) {
sigpath::vfoManager.setColor(name, IM_COL32((int)roundf(r), (int)roundf(g), (int)roundf(b), 50));
}
}
// Iterate existing VFOs and set their color if in the config, if not set to default
for (auto& [name, vfo] : gui::waterfall.vfos) {
if (vfoColors.find(name) == vfoColors.end()) {
vfoColors[name] = ImVec4(1.0f, 1.0f, 1.0f, 1.0f);
vfo->color = IM_COL32(255, 255, 255, 50);
modified = true;
}
}
vfoAddHndl.handler = vfoAddHandler;
sigpath::vfoManager.vfoCreatedEvent.bindHandler(vfoAddHndl);
core::configManager.release(modified);
}
void draw(void* ctx) {
ImGui::BeginTable("VFO Color Buttons Table", 2);
ImGui::TableNextRow();
ImGui::TableSetColumnIndex(0);
if (ImGui::Button("Auto Color##vfo_color", ImVec2(ImGui::GetContentRegionAvailWidth(), 0))) {
float delta = 1.0f / (float)gui::waterfall.vfos.size();
float hue = 0;
for (auto& [name, vfo] : gui::waterfall.vfos) {
float r, g, b;
ImGui::ColorConvertHSVtoRGB(hue, 0.5f, 1.0f, r, g, b);
vfoColors[name] = ImVec4(r, g, b, 1.0f);
vfo->color = IM_COL32((int)roundf(r * 255), (int)roundf(g * 255), (int)roundf(b * 255), 50);
hue += delta;
core::configManager.aquire();
char buf[16];
sprintf(buf, "#%02X%02X%02X", (int)roundf(r * 255), (int)roundf(g * 255), (int)roundf(b * 255));
core::configManager.conf["vfoColors"][name] = buf;
core::configManager.release(true);
}
}
ImGui::TableSetColumnIndex(1);
if (ImGui::Button("Clear All##vfo_color", ImVec2(ImGui::GetContentRegionAvailWidth(), 0))) {
for (auto& [name, vfo] : gui::waterfall.vfos) {
vfoColors[name] = ImVec4(1.0f, 1.0f, 1.0f, 1.0f);
vfo->color = IM_COL32(255, 255, 255, 50);
core::configManager.aquire();
char buf[16];
core::configManager.conf["vfoColors"][name] = "#FFFFFF";
core::configManager.release(true);
}
}
ImGui::EndTable();
ImGui::BeginTable("VFO Color table", 1, ImGuiTableFlags_RowBg | ImGuiTableFlags_Borders);
for (auto& [name, vfo] : gui::waterfall.vfos) {
ImGui::TableNextRow();
ImGui::TableSetColumnIndex(0);
ImVec4 col(1.0f, 1.0f, 1.0f, 1.0f);
if (vfoColors.find(name) != vfoColors.end()) {
col = vfoColors[name];
}
if (ImGui::ColorEdit3(("##vfo_color_"+name).c_str(), (float*)&col, ImGuiColorEditFlags_NoInputs | ImGuiColorEditFlags_NoLabel)) {
vfoColors[name] = col;
vfo->color = IM_COL32((int)roundf(col.x * 255), (int)roundf(col.y * 255), (int)roundf(col.z * 255), 50);
core::configManager.aquire();
char buf[16];
sprintf(buf, "#%02X%02X%02X", (int)roundf(col.x * 255), (int)roundf(col.y * 255), (int)roundf(col.z * 255));
core::configManager.conf["vfoColors"][name] = buf;
core::configManager.release(true);
}
ImGui::SameLine();
ImGui::Text(name.c_str());
}
ImGui::EndTable();
}
}

Wyświetl plik

@ -0,0 +1,6 @@
#pragma once
namespace vfo_color_menu {
void init();
void draw(void* ctx);
}

Wyświetl plik

@ -194,7 +194,7 @@ namespace ImGui {
if (IS_IN_AREA(mPos, wfMin, wfMax)) {
for (auto const& [name, vfo] : vfos) {
window->DrawList->AddRectFilled(vfo->wfRectMin, vfo->wfRectMax, IM_COL32(255, 255, 255, 50));
window->DrawList->AddRectFilled(vfo->wfRectMin, vfo->wfRectMax, vfo->color);
window->DrawList->AddLine(vfo->wfLineMin, vfo->wfLineMax, (name == selectedVFO) ? IM_COL32(255, 0, 0, 255) : IM_COL32(255, 255, 0, 255));
}
}
@ -1115,7 +1115,7 @@ namespace ImGui {
}
void WaterfallVFO::draw(ImGuiWindow* window, bool selected) {
window->DrawList->AddRectFilled(rectMin, rectMax, IM_COL32(255, 255, 255, 50));
window->DrawList->AddRectFilled(rectMin, rectMax, color);
if (lineVisible) {
window->DrawList->AddLine(lineMin, lineMax, selected ? IM_COL32(255, 0, 0, 255) : IM_COL32(255, 255, 0, 255));
}
@ -1128,7 +1128,7 @@ namespace ImGui {
if (reference != REF_UPPER && !bandwidthLocked) {
if (IS_IN_AREA(mousePos, rbwSelMin, rbwSelMax)) { ImGui::SetMouseCursor(ImGuiMouseCursor_ResizeEW); }
else if (IS_IN_AREA(mousePos, wfRbwSelMin, wfRbwSelMax)) { ImGui::SetMouseCursor(ImGuiMouseCursor_ResizeEW); }
}
}
};
void WaterFall::showWaterfall() {

Wyświetl plik

@ -61,6 +61,8 @@ namespace ImGui {
double minBandwidth;
double maxBandwidth;
bool bandwidthLocked;
ImU32 color = IM_COL32(255, 255, 255, 50);
};
class WaterFall {

Wyświetl plik

@ -73,6 +73,14 @@ double VFOManager::VFO::getBandwidth() {
return wtfVFO->bandwidth;
}
void VFOManager::VFO::setColor(ImU32 color) {
wtfVFO->color = color;
}
std::string VFOManager::VFO::getName() {
return name;
}
VFOManager::VFOManager() {
}
@ -83,6 +91,7 @@ VFOManager::VFO* VFOManager::createVFO(std::string name, int reference, double o
}
VFOManager::VFO* vfo = new VFO(name, reference, offset, bandwidth, sampleRate, minBandwidth, maxBandwidth, bandwidthLocked);
vfos[name] = vfo;
vfoCreatedEvent.emit(vfo);
return vfo;
}
@ -97,6 +106,7 @@ void VFOManager::deleteVFO(VFOManager::VFO* vfo) {
if (name == "") {
return;
}
vfoDeletedEvent.emit(vfo);
vfos.erase(name);
delete vfo;
}
@ -164,6 +174,17 @@ double VFOManager::getBandwidth(std::string name) {
return vfos[name]->getBandwidth();
}
void VFOManager::setColor(std::string name, ImU32 color) {
if (vfos.find(name) == vfos.end()) {
return;
}
return vfos[name]->setColor(color);
}
bool VFOManager::vfoExists(std::string name) {
return (vfos.find(name) != vfos.end());
}
void VFOManager::updateFromWaterfall(ImGui::WaterFall* wtf) {
for (auto const& [name, vfo] : vfos) {
if (vfo->wtfVFO->centerOffsetChanged) {
@ -171,4 +192,4 @@ void VFOManager::updateFromWaterfall(ImGui::WaterFall* wtf) {
vfo->dspVFO->setOffset(vfo->wtfVFO->centerOffset);
}
}
}
}

Wyświetl plik

@ -2,6 +2,7 @@
#include <dsp/vfo.h>
#include <gui/widgets/waterfall.h>
#include <gui/gui.h>
#include <utils/event.h>
class VFOManager {
public:
@ -22,6 +23,8 @@ public:
void setBandwidthLimits(double minBandwidth, double maxBandwidth, bool bandwidthLocked);
bool getBandwidthChanged(bool erase = true);
double getBandwidth();
void setColor(ImU32 color);
std::string getName();
dsp::stream<dsp::complex_t>* output;
@ -46,9 +49,15 @@ public:
void setBandwidthLimits(std::string name, double minBandwidth, double maxBandwidth, bool bandwidthLocked);
bool getBandwidthChanged(std::string name, bool erase = true);
double getBandwidth(std::string name);
void setColor(std::string name, ImU32 color);
std::string getName();
bool vfoExists(std::string name);
void updateFromWaterfall(ImGui::WaterFall* wtf);
Event<VFOManager::VFO*> vfoCreatedEvent;
Event<VFOManager::VFO*> vfoDeletedEvent;
private:
std::map<std::string, VFO*> vfos;
};

Wyświetl plik

@ -161,10 +161,18 @@ private:
if (_this->running) { style::beginDisabled(); }
ImGui::SetNextItemWidth(menuWidth - portWidth);
ImGui::InputText(CONCAT("##_ip_select_", _this->name), _this->ip, 1024);
if (ImGui::InputText(CONCAT("##_ip_select_", _this->name), _this->ip, 1024)) {
config.aquire();
config.conf["host"] = std::string(_this->ip);
config.release(true);
}
ImGui::SameLine();
ImGui::SetNextItemWidth(portWidth);
ImGui::InputInt(CONCAT("##_port_select_", _this->name), &_this->port, 0);
if (ImGui::InputInt(CONCAT("##_port_select_", _this->name), &_this->port, 0)) {
config.aquire();
config.conf["port"] = _this->port;
config.release(true);
}
ImGui::SetNextItemWidth(menuWidth);
if (ImGui::Combo(CONCAT("##_rtltcp_sr_", _this->name), &_this->srId, _this->srTxt.c_str())) {