Merge pull request #649 from AlexandreRouma/backend_abstraction

Backend abstraction and android support
This commit is contained in:
AlexandreRouma
2022-03-28 22:27:38 +02:00
committed by GitHub
115 changed files with 5747 additions and 1969 deletions

View File

@ -8,8 +8,10 @@
namespace credits {
ImFont* bigFont;
ImVec2 imageSize(128.0f, 128.0f);
void init() {
imageSize = ImVec2(128.0f * style::uiScale, 128.0f * style::uiScale);
}
void show() {
@ -25,7 +27,7 @@ namespace credits {
ImGui::TextUnformatted("SDR++ ");
ImGui::PopFont();
ImGui::SameLine();
ImGui::Image(icons::LOGO, ImVec2(128, 128));
ImGui::Image(icons::LOGO, imageSize);
ImGui::Spacing();
ImGui::Spacing();
ImGui::Spacing();

View File

@ -1,26 +1,22 @@
#include <gui/dialogs/loading_screen.h>
#include <gui/main_window.h>
#include <imgui.h>
#include "imgui_impl_glfw.h"
#include "imgui_impl_opengl3.h"
#include <gui/icons.h>
#include <gui/style.h>
#include <credits.h>
#include <gui/gui.h>
#include <backend.h>
namespace LoadingScreen {
GLFWwindow* _win;
ImVec2 imageSize(128.0f, 128.0f);
void setWindow(GLFWwindow* win) {
_win = win;
void init() {
imageSize = ImVec2(128.0f * style::uiScale, 128.0f * style::uiScale);
}
void show(std::string msg) {
glfwPollEvents();
ImGui_ImplOpenGL3_NewFrame();
ImGui_ImplGlfw_NewFrame();
backend::beginFrame();
ImGui::NewFrame();
ImGui::Begin("Main", NULL, WINDOW_FLAGS);
@ -33,7 +29,7 @@ namespace LoadingScreen {
ImGui::TextUnformatted("SDR++ ");
ImGui::PopFont();
ImGui::SameLine();
ImGui::Image(icons::LOGO, ImVec2(128, 128));
ImGui::Image(icons::LOGO, imageSize);
ImVec2 origPos = ImGui::GetCursorPos();
ImGui::SetCursorPosY(origPos.y + 50);
@ -46,14 +42,6 @@ namespace LoadingScreen {
ImGui::End();
ImGui::Render();
int display_w, display_h;
glfwGetFramebufferSize(_win, &display_w, &display_h);
glViewport(0, 0, display_w, display_h);
glClearColor(gui::themeManager.clearColor.x, gui::themeManager.clearColor.y, gui::themeManager.clearColor.z, gui::themeManager.clearColor.w);
glClear(GL_COLOR_BUFFER_BIT);
ImGui_ImplOpenGL3_RenderDrawData(ImGui::GetDrawData());
glfwSwapBuffers(_win);
backend::render(false);
}
}

View File

@ -2,9 +2,8 @@
#include <thread>
#include <string>
#include <mutex>
#include <GLFW/glfw3.h>
namespace LoadingScreen {
void setWindow(GLFWwindow* win);
void init();
void show(std::string msg);
};

View File

@ -1,7 +1,6 @@
#include <gui/icons.h>
#include <stdint.h>
#include <config.h>
#include <options.h>
#define STB_IMAGE_IMPLEMENTATION
#include <imgui/stb_image.h>

View File

@ -1,10 +1,7 @@
#include <gui/main_window.h>
#include <gui/gui.h>
#include "imgui.h"
#include "imgui_impl_glfw.h"
#include "imgui_impl_opengl3.h"
#include <stdio.h>
#include <GLFW/glfw3.h>
#include <thread>
#include <complex>
#include <gui/widgets/waterfall.h>
@ -27,7 +24,6 @@
#include <filesystem>
#include <signal_path/source.h>
#include <gui/dialogs/loading_screen.h>
#include <options.h>
#include <gui/colormaps.h>
#include <gui/widgets/snr_meter.h>
#include <gui/tuner.h>
@ -126,10 +122,14 @@ void MainWindow::init() {
// Load additional modules specified through config
for (auto const& path : modules) {
#ifndef __ANDROID__
std::string apath = std::filesystem::absolute(path).string();
spdlog::info("Loading {0}", apath);
LoadingScreen::show("Loading " + std::filesystem::path(path).filename().string());
core::moduleManager.loadModule(apath);
#else
core::moduleManager.loadModule(path);
#endif
}
// Create module instances
@ -354,8 +354,10 @@ void MainWindow::draw() {
}
// To Bar
// ImGui::BeginChild("TopBarChild", ImVec2(0, 49.0f * style::uiScale), false, ImGuiWindowFlags_HorizontalScrollbar);
ImVec2 btnSize(30 * style::uiScale, 30 * style::uiScale);
ImGui::PushID(ImGui::GetID("sdrpp_menu_btn"));
if (ImGui::ImageButton(icons::MENU, ImVec2(30, 30), ImVec2(0, 0), ImVec2(1, 1), 5) || ImGui::IsKeyPressed(GLFW_KEY_MENU, false)) {
if (ImGui::ImageButton(icons::MENU, btnSize, ImVec2(0, 0), ImVec2(1, 1), 5) || ImGui::IsKeyPressed(ImGuiKey_Menu, false)) {
showMenu = !showMenu;
core::configManager.acquire();
core::configManager.conf["showMenu"] = showMenu;
@ -369,14 +371,14 @@ void MainWindow::draw() {
if (playButtonLocked && !tmpPlaySate) { style::beginDisabled(); }
if (playing) {
ImGui::PushID(ImGui::GetID("sdrpp_stop_btn"));
if (ImGui::ImageButton(icons::STOP, ImVec2(30, 30), ImVec2(0, 0), ImVec2(1, 1), 5) || ImGui::IsKeyPressed(GLFW_KEY_END, false)) {
if (ImGui::ImageButton(icons::STOP, btnSize, ImVec2(0, 0), ImVec2(1, 1), 5) || ImGui::IsKeyPressed(ImGuiKey_End, false)) {
setPlayState(false);
}
ImGui::PopID();
}
else { // TODO: Might need to check if there even is a device
ImGui::PushID(ImGui::GetID("sdrpp_play_btn"));
if (ImGui::ImageButton(icons::PLAY, ImVec2(30, 30), ImVec2(0, 0), ImVec2(1, 1), 5) || ImGui::IsKeyPressed(GLFW_KEY_END, false)) {
if (ImGui::ImageButton(icons::PLAY, btnSize, ImVec2(0, 0), ImVec2(1, 1), 5) || ImGui::IsKeyPressed(ImGuiKey_End, false)) {
setPlayState(true);
}
ImGui::PopID();
@ -384,20 +386,21 @@ void MainWindow::draw() {
if (playButtonLocked && !tmpPlaySate) { style::endDisabled(); }
ImGui::SameLine();
float origY = ImGui::GetCursorPosY();
//ImGui::SetCursorPosY(ImGui::GetCursorPosY() + 8);
sigpath::sinkManager.showVolumeSlider(gui::waterfall.selectedVFO, "##_sdrpp_main_volume_", 248, 30, 5, true);
sigpath::sinkManager.showVolumeSlider(gui::waterfall.selectedVFO, "##_sdrpp_main_volume_", 248 * style::uiScale, btnSize.x, 5, true);
ImGui::SameLine();
ImGui::SetCursorPosY(origY);
gui::freqSelect.draw();
ImGui::SameLine();
ImGui::SetCursorPosY(ImGui::GetCursorPosY() - 9);
ImGui::SetCursorPosY(origY);
if (tuningMode == tuner::TUNER_MODE_CENTER) {
ImGui::PushID(ImGui::GetID("sdrpp_ena_st_btn"));
if (ImGui::ImageButton(icons::CENTER_TUNING, ImVec2(30, 30), ImVec2(0, 0), ImVec2(1, 1), 5)) {
if (ImGui::ImageButton(icons::CENTER_TUNING, btnSize, ImVec2(0, 0), ImVec2(1, 1), 5)) {
tuningMode = tuner::TUNER_MODE_NORMAL;
gui::waterfall.VFOMoveSingleClick = false;
core::configManager.acquire();
@ -408,7 +411,7 @@ void MainWindow::draw() {
}
else { // TODO: Might need to check if there even is a device
ImGui::PushID(ImGui::GetID("sdrpp_dis_st_btn"));
if (ImGui::ImageButton(icons::NORMAL_TUNING, ImVec2(30, 30), ImVec2(0, 0), ImVec2(1, 1), 5)) {
if (ImGui::ImageButton(icons::NORMAL_TUNING, btnSize, ImVec2(0, 0), ImVec2(1, 1), 5)) {
tuningMode = tuner::TUNER_MODE_CENTER;
gui::waterfall.VFOMoveSingleClick = true;
tuner::tune(tuner::TUNER_MODE_CENTER, gui::waterfall.selectedVFO, gui::freqSelect.frequency);
@ -421,32 +424,37 @@ void MainWindow::draw() {
ImGui::SameLine();
int snrWidth = std::min<int>(300, ImGui::GetWindowSize().x - ImGui::GetCursorPosX() - 87);
int snrOffset = 87.0f * style::uiScale;
int snrWidth = std::clamp<int>(ImGui::GetWindowSize().x - ImGui::GetCursorPosX() - snrOffset, 100.0f * style::uiScale, 300.0f * style::uiScale);
int snrPos = std::max<int>(ImGui::GetWindowSize().x - (snrWidth + snrOffset), ImGui::GetCursorPosX());
ImGui::SetCursorPosX(ImGui::GetWindowSize().x - (snrWidth + 87));
ImGui::SetCursorPosY(ImGui::GetCursorPosY() + 5);
ImGui::SetCursorPosX(snrPos);
ImGui::SetCursorPosY(origY + (5.0f * style::uiScale));
ImGui::SetNextItemWidth(snrWidth);
ImGui::SNRMeter((vfo != NULL) ? gui::waterfall.selectedVFOSNR : 0);
// Note: this is what makes the vertical size correct, needs to be fixed
ImGui::SameLine();
// ImGui::EndChild();
// Logo button
ImGui::SetCursorPosX(ImGui::GetWindowSize().x - 48);
ImGui::SetCursorPosY(10);
if (ImGui::ImageButton(icons::LOGO, ImVec2(32, 32), ImVec2(0, 0), ImVec2(1, 1), 0)) {
ImGui::SetCursorPosX(ImGui::GetWindowSize().x - (48 * style::uiScale));
ImGui::SetCursorPosY(10.0f * style::uiScale);
if (ImGui::ImageButton(icons::LOGO, ImVec2(32 * style::uiScale, 32 * style::uiScale), ImVec2(0, 0), ImVec2(1, 1), 0)) {
showCredits = true;
}
if (ImGui::IsMouseDown(ImGuiMouseButton_Left)) {
showCredits = false;
}
if (ImGui::IsKeyPressed(GLFW_KEY_ESCAPE)) {
if (ImGui::IsKeyPressed(ImGuiKey_Escape)) {
showCredits = false;
}
// 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);
@ -455,7 +463,7 @@ void MainWindow::draw() {
newWidth = std::clamp<float>(newWidth, 250, winSize.x - 250);
ImGui::GetForegroundDrawList()->AddLine(ImVec2(newWidth, curY), ImVec2(newWidth, winSize.y - 10), ImGui::GetColorU32(ImGuiCol_SeparatorActive));
}
if (mousePos.x >= newWidth - 2 && mousePos.x <= newWidth + 2 && mousePos.y > curY) {
if (mousePos.x >= newWidth - (2.0f * style::uiScale) && mousePos.x <= newWidth + (2.0f * style::uiScale) && mousePos.y > curY) {
ImGui::SetMouseCursor(ImGuiMouseCursor_ResizeEW);
if (click) {
grabbingMenu = true;
@ -479,8 +487,8 @@ void MainWindow::draw() {
if (showMenu) {
ImGui::Columns(3, "WindowColumns", false);
ImGui::SetColumnWidth(0, menuWidth);
ImGui::SetColumnWidth(1, winSize.x - menuWidth - 60);
ImGui::SetColumnWidth(2, 60);
ImGui::SetColumnWidth(1, std::max<int>(winSize.x - menuWidth - (60.0f * style::uiScale), 100.0f * style::uiScale));
ImGui::SetColumnWidth(2, 60.0f * style::uiScale);
ImGui::BeginChild("Left Column");
if (gui::menu.draw(firstMenuRender)) {
@ -538,9 +546,9 @@ void MainWindow::draw() {
else {
// When hiding the menu bar
ImGui::Columns(3, "WindowColumns", false);
ImGui::SetColumnWidth(0, 8);
ImGui::SetColumnWidth(1, winSize.x - 8 - 60);
ImGui::SetColumnWidth(2, 60);
ImGui::SetColumnWidth(0, 8 * style::uiScale);
ImGui::SetColumnWidth(1, winSize.x - ((8 + 60) * style::uiScale));
ImGui::SetColumnWidth(2, 60.0f * style::uiScale);
}
// Right Column
@ -557,12 +565,12 @@ void MainWindow::draw() {
if (!lockWaterfallControls) {
// Handle arrow keys
if (vfo != NULL && (gui::waterfall.mouseInFFT || gui::waterfall.mouseInWaterfall)) {
if (ImGui::IsKeyPressed(GLFW_KEY_LEFT) && !gui::freqSelect.digitHovered) {
if (ImGui::IsKeyPressed(ImGuiKey_LeftArrow) && !gui::freqSelect.digitHovered) {
double nfreq = gui::waterfall.getCenterFrequency() + vfo->generalOffset - vfo->snapInterval;
nfreq = roundl(nfreq / vfo->snapInterval) * vfo->snapInterval;
tuner::tune(tuningMode, gui::waterfall.selectedVFO, nfreq);
}
if (ImGui::IsKeyPressed(GLFW_KEY_RIGHT) && !gui::freqSelect.digitHovered) {
if (ImGui::IsKeyPressed(ImGuiKey_RightArrow) && !gui::freqSelect.digitHovered) {
double nfreq = gui::waterfall.getCenterFrequency() + vfo->generalOffset + vfo->snapInterval;
nfreq = roundl(nfreq / vfo->snapInterval) * vfo->snapInterval;
tuner::tune(tuningMode, gui::waterfall.selectedVFO, nfreq);
@ -602,8 +610,9 @@ void MainWindow::draw() {
ImGui::SetCursorPosX((ImGui::GetWindowSize().x / 2.0) - (ImGui::CalcTextSize("Zoom").x / 2.0));
ImGui::TextUnformatted("Zoom");
ImGui::SetCursorPosX((ImGui::GetWindowSize().x / 2.0) - 10);
if (ImGui::VSliderFloat("##_7_", ImVec2(20.0, 150.0), &bw, 1.0, 0.0, "")) {
ImGui::SetCursorPosX((ImGui::GetWindowSize().x / 2.0) - 10 * style::uiScale);
ImVec2 wfSliderSize(20.0 * style::uiScale, 150.0 * style::uiScale);
if (ImGui::VSliderFloat("##_7_", wfSliderSize, &bw, 1.0, 0.0, "")) {
double factor = (double)bw * (double)bw;
// Map 0.0 -> 1.0 to 1000.0 -> bandwidth
@ -621,8 +630,8 @@ void MainWindow::draw() {
ImGui::SetCursorPosX((ImGui::GetWindowSize().x / 2.0) - (ImGui::CalcTextSize("Max").x / 2.0));
ImGui::TextUnformatted("Max");
ImGui::SetCursorPosX((ImGui::GetWindowSize().x / 2.0) - 10);
if (ImGui::VSliderFloat("##_8_", ImVec2(20.0, 150.0), &fftMax, 0.0, -160.0f, "")) {
ImGui::SetCursorPosX((ImGui::GetWindowSize().x / 2.0) - 10 * style::uiScale);
if (ImGui::VSliderFloat("##_8_", wfSliderSize, &fftMax, 0.0, -160.0f, "")) {
fftMax = std::max<float>(fftMax, fftMin + 10);
core::configManager.acquire();
core::configManager.conf["max"] = fftMax;
@ -633,8 +642,9 @@ 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);
if (ImGui::VSliderFloat("##_9_", ImVec2(20.0, 150.0), &fftMin, 0.0, -160.0f, "")) {
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();
core::configManager.conf["min"] = fftMin;
@ -707,4 +717,8 @@ void MainWindow::setFFTWindow(int win) {
bool MainWindow::isPlaying() {
return playing;
}
void MainWindow::setFirstMenuRender() {
firstMenuRender = true;
}

View File

@ -19,6 +19,7 @@ public:
bool sdrIsRunning();
void setFFTSize(int size);
void setFFTWindow(int win);
void setFirstMenuRender();
// TODO: Replace with it's own class
void setVFO(double freq);

View File

@ -35,7 +35,7 @@ namespace bandplanmenu {
}
void draw(void* ctx) {
float menuColumnWidth = ImGui::GetContentRegionAvailWidth();
float menuColumnWidth = ImGui::GetContentRegionAvail().x;
ImGui::PushItemWidth(menuColumnWidth);
if (ImGui::Combo("##_bandplan_name_", &bandplanId, bandplan::bandplanNameTxt.c_str())) {
gui::waterfall.bandplan = &bandplan::bandplans[bandplan::bandplanNames[bandplanId]];

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,11 +90,18 @@ 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(1.0f, "100%", 1.0f);
uiScales.define(2.0f, "200%", 2.0f);
uiScales.define(3.0f, "300%", 3.0f);
uiScales.define(4.0f, "400%", 4.0f);
uiScaleId = uiScales.valueId(style::uiScale);
}
void draw(void* ctx) {
float menuWidth = ImGui::GetContentRegionAvailWidth();
bool homePressed = ImGui::IsKeyPressed(GLFW_KEY_HOME, false);
float menuWidth = ImGui::GetContentRegionAvail().x;
bool homePressed = ImGui::IsKeyPressed(ImGuiKey_Home, false);
if (ImGui::Checkbox("Show Waterfall##_sdrpp", &showWaterfall) || homePressed) {
if (homePressed) { showWaterfall = !showWaterfall; }
showWaterfall ? gui::waterfall.showWaterfall() : gui::waterfall.hideWaterfall();
@ -112,6 +124,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 +174,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.");
}
}
}

View File

@ -30,15 +30,22 @@ namespace module_manager_menu {
void draw(void* ctx) {
bool modified = false;
// Calculate delete button size and cell size
ImVec2 cellpad = ImGui::GetStyle().CellPadding;
float lheight = ImGui::GetTextLineHeight();
float cellWidth = lheight - (2.0f * cellpad.y);
float hdiff = cellpad.x - cellpad.y;
ImVec2 btnSize = ImVec2(lheight, lheight - 1);
ImVec2 textOff = ImVec2(3.0f * style::uiScale, -5.0f * style::uiScale);
if (ImGui::BeginTable("Module Manager Table", 3, ImGuiTableFlags_Borders | ImGuiTableFlags_RowBg | ImGuiTableFlags_ScrollY, ImVec2(0, 200))) {
ImGui::TableSetupColumn("Name");
ImGui::TableSetupColumn("Type");
ImGui::TableSetupColumn("", ImGuiTableColumnFlags_WidthFixed, 10);
ImGui::TableSetupColumn("", ImGuiTableColumnFlags_WidthFixed, cellWidth);
ImGui::TableSetupScrollFreeze(3, 1);
ImGui::TableHeadersRow();
float height = ImGui::CalcTextSize("-").y;
for (auto& [name, inst] : core::moduleManager.instances) {
ImGui::TableNextRow();
@ -49,13 +56,13 @@ namespace module_manager_menu {
ImGui::TextUnformatted(inst.module.info->name);
ImGui::TableSetColumnIndex(2);
ImVec2 origPos = ImGui::GetCursorPos();
ImGui::SetCursorPos(ImVec2(origPos.x - 3, origPos.y));
if (ImGui::Button(("##module_mgr_" + name).c_str(), ImVec2(height, height))) {
ImVec2 cpos = ImGui::GetCursorPos();
ImGui::SetCursorPos(ImVec2(cpos.x - hdiff, cpos.y + 1));
if (ImGui::Button(("##module_mgr_" + name).c_str(), btnSize)) {
toBeRemoved = name;
confirmOpened = true;
}
ImGui::SetCursorPos(ImVec2(origPos.x + 2, origPos.y - 5));
ImGui::SetCursorPos(ImVec2(cpos.x + textOff.x, cpos.y + textOff.y));
ImGui::TextUnformatted("_");
}
ImGui::EndTable();
@ -73,34 +80,36 @@ namespace module_manager_menu {
});
// Add module row with slightly different settings
ImGui::BeginTable("Module Manager Add Table", 3);
ImGui::TableSetupColumn("Name");
ImGui::TableSetupColumn("Type");
ImGui::TableSetupColumn("", ImGuiTableColumnFlags_WidthFixed, 16);
ImGui::TableNextRow();
if (ImGui::BeginTable("Module Manager Add Table", 3)) {
ImGui::TableSetupColumn("Name");
ImGui::TableSetupColumn("Type");
ImGui::TableSetupColumn("", ImGuiTableColumnFlags_WidthFixed, cellWidth + cellpad.x);
ImGui::TableNextRow();
ImGui::TableSetColumnIndex(0);
ImGui::SetNextItemWidth(ImGui::GetContentRegionAvailWidth());
ImGui::InputText("##module_mod_name", modName, 1000);
ImGui::TableSetColumnIndex(0);
ImGui::SetNextItemWidth(ImGui::GetContentRegionAvail().x + cellpad.x);
ImGui::InputText("##module_mod_name", modName, 1000);
ImGui::TableSetColumnIndex(1);
ImGui::SetNextItemWidth(ImGui::GetContentRegionAvailWidth());
ImGui::Combo("##module_mgr_type", &modTypeId, modTypesTxt.c_str());
ImGui::TableSetColumnIndex(1);
ImGui::SetNextItemWidth(ImGui::GetContentRegionAvail().x + cellpad.x);
ImGui::Combo("##module_mgr_type", &modTypeId, modTypesTxt.c_str());
ImGui::TableSetColumnIndex(2);
if (strlen(modName) == 0) { style::beginDisabled(); }
if (ImGui::Button("+##module_mgr_add_btn", ImVec2(16, 0))) {
if (!core::moduleManager.createInstance(modName, modTypes[modTypeId])) {
core::moduleManager.postInit(modName);
modified = true;
}
else {
errorMessage = "Could not create new instance of " + modTypes[modTypeId];
errorOpen = true;
ImGui::TableSetColumnIndex(2);
if (strlen(modName) == 0) { style::beginDisabled(); }
if (ImGui::Button("+##module_mgr_add_btn", ImVec2(btnSize.x, 0))) {
if (!core::moduleManager.createInstance(modName, modTypes[modTypeId])) {
core::moduleManager.postInit(modName);
modified = true;
}
else {
errorMessage = "Could not create new instance of " + modTypes[modTypeId];
errorOpen = true;
}
}
if (strlen(modName) == 0) { style::endDisabled(); }
ImGui::EndTable();
}
if (strlen(modName) == 0) { style::endDisabled(); }
ImGui::EndTable();
if (modified) {
// Update enabled and disabled modules

View File

@ -156,7 +156,7 @@ namespace sourcemenu {
}
void draw(void* ctx) {
float itemWidth = ImGui::GetContentRegionAvailWidth();
float itemWidth = ImGui::GetContentRegionAvail().x;
bool running = gui::mainWindow.sdrIsRunning();
if (running) { style::beginDisabled(); }

View File

@ -1,6 +1,5 @@
#include <gui/menus/theme.h>
#include <gui/gui.h>
#include <options.h>
#include <core.h>
#include <gui/style.h>
@ -23,8 +22,11 @@ namespace thememenu {
it = std::find(themeNames.begin(), themeNames.end(), "Dark");
selectedThemeName = "Dark";
}
gui::themeManager.applyTheme(selectedThemeName);
themeId = std::distance(themeNames.begin(), it);
applyTheme();
// Apply scaling
ImGui::GetStyle().ScaleAllSizes(style::uiScale);
themeNamesTxt = "";
for (auto name : themeNames) {
@ -33,12 +35,16 @@ namespace thememenu {
}
}
void applyTheme() {
gui::themeManager.applyTheme(themeNames[themeId]);
}
void draw(void* ctx) {
float menuWidth = ImGui::GetContentRegionAvailWidth();
float menuWidth = ImGui::GetContentRegionAvail().x;
ImGui::LeftLabel("Theme");
ImGui::SetNextItemWidth(menuWidth - ImGui::GetCursorPosX());
if (ImGui::Combo("##theme_select_combo", &themeId, themeNamesTxt.c_str())) {
gui::themeManager.applyTheme(themeNames[themeId]);
applyTheme();
core::configManager.acquire();
core::configManager.conf["theme"] = themeNames[themeId];
core::configManager.release(true);

View File

@ -3,5 +3,6 @@
namespace thememenu {
void init(std::string resDir);
void applyTheme();
void draw(void* ctx);
}

View File

@ -81,7 +81,7 @@ namespace vfo_color_menu {
ImGui::TableNextRow();
ImGui::TableSetColumnIndex(0);
if (ImGui::Button("Auto Color##vfo_color", ImVec2(ImGui::GetContentRegionAvailWidth(), 0))) {
if (ImGui::Button("Auto Color##vfo_color", ImVec2(ImGui::GetContentRegionAvail().x, 0))) {
float delta = 1.0f / (float)gui::waterfall.vfos.size();
float hue = 0;
for (auto& [name, vfo] : gui::waterfall.vfos) {
@ -99,7 +99,7 @@ namespace vfo_color_menu {
}
ImGui::TableSetColumnIndex(1);
if (ImGui::Button("Clear All##vfo_color", ImVec2(ImGui::GetContentRegionAvailWidth(), 0))) {
if (ImGui::Button("Clear All##vfo_color", ImVec2(ImGui::GetContentRegionAvail().x, 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);

View File

@ -1,6 +1,5 @@
#include "smgui.h"
#include "style.h"
#include <options.h>
#include <gui/widgets/stepped_slider.h>
#include <gui/gui.h>
@ -25,6 +24,7 @@ namespace SmGui {
std::string diffId = "";
DrawListElem diffValue;
bool nextItemFillWidth = false;
bool serverMode = false;
std::string ImStrToString(const char* imstr) {
int len = 0;
@ -33,6 +33,10 @@ namespace SmGui {
return std::string(imstr, end);
}
void init(bool server) {
serverMode = server;
}
// Rec/Play functions
void setDiff(std::string id, SmGui::DrawListElem value) {
diffId = id;
@ -457,26 +461,26 @@ namespace SmGui {
// Format functions
void FillWidth() {
if (!options::opts.serverMode) {
if (!serverMode) {
nextItemFillWidth = true;
ImGui::SetNextItemWidth(ImGui::GetContentRegionAvailWidth());
ImGui::SetNextItemWidth(ImGui::GetContentRegionAvail().x);
return;
}
if (rdl) { rdl->pushStep(DRAW_STEP_FILL_WIDTH, false); }
}
void SameLine() {
if (!options::opts.serverMode) { ImGui::SameLine(); return; }
if (!serverMode) { ImGui::SameLine(); return; }
if (rdl) { rdl->pushStep(DRAW_STEP_SAME_LINE, false); }
}
void BeginDisabled() {
if (!options::opts.serverMode) { style::beginDisabled(); return; }
if (!serverMode) { style::beginDisabled(); return; }
if (rdl) { rdl->pushStep(DRAW_STEP_BEGIN_DISABLED, false); }
}
void EndDisabled() {
if (!options::opts.serverMode) { style::endDisabled(); return; }
if (!serverMode) { style::endDisabled(); return; }
if (rdl) { rdl->pushStep(DRAW_STEP_END_DISABLED, false); }
}
@ -484,7 +488,7 @@ namespace SmGui {
// Widget functions
bool Combo(const char *label, int *current_item, const char *items_separated_by_zeros, int popup_max_height_in_items) {
nextItemFillWidth = false;
if (!options::opts.serverMode) { return ImGui::Combo(label, current_item, items_separated_by_zeros, popup_max_height_in_items); }
if (!serverMode) { return ImGui::Combo(label, current_item, items_separated_by_zeros, popup_max_height_in_items); }
if (rdl) {
rdl->pushStep(DRAW_STEP_COMBO, forceSyncForNext);
rdl->pushString(label);
@ -501,10 +505,10 @@ namespace SmGui {
}
bool Button(const char *label, ImVec2 size) {
if (!options::opts.serverMode) {
if (!serverMode) {
if (nextItemFillWidth) {
nextItemFillWidth = false;
size.x = ImGui::GetContentRegionAvailWidth();
size.x = ImGui::GetContentRegionAvail().x;
}
return ImGui::Button(label, size);
}
@ -519,7 +523,7 @@ namespace SmGui {
}
void Columns(int count, const char *id, bool border) {
if (!options::opts.serverMode) { ImGui::Columns(count, id, border); return; }
if (!serverMode) { ImGui::Columns(count, id, border); return; }
if (rdl) {
rdl->pushStep(DRAW_STEP_COLUMNS, forceSyncForNext);
rdl->pushInt(count);
@ -530,12 +534,12 @@ namespace SmGui {
}
void NextColumn() {
if (!options::opts.serverMode) { ImGui::NextColumn(); return; }
if (!serverMode) { ImGui::NextColumn(); return; }
if (rdl) { rdl->pushStep(DRAW_STEP_NEXT_COLUMN, false); }
}
bool RadioButton(const char *label, bool active) {
if (!options::opts.serverMode) { return ImGui::RadioButton(label, active); }
if (!serverMode) { return ImGui::RadioButton(label, active); }
if (rdl) {
rdl->pushStep(DRAW_STEP_RADIO_BUTTON, forceSyncForNext);
rdl->pushString(label);
@ -546,17 +550,17 @@ namespace SmGui {
}
void BeginGroup() {
if (!options::opts.serverMode) { ImGui::BeginGroup(); return; }
if (!serverMode) { ImGui::BeginGroup(); return; }
if (rdl) { rdl->pushStep(DRAW_STEP_BEGIN_GROUP, false); }
}
void EndGroup() {
if (!options::opts.serverMode) { ImGui::EndGroup(); return; }
if (!serverMode) { ImGui::EndGroup(); return; }
if (rdl) { rdl->pushStep(DRAW_STEP_END_GROUP, false); }
}
void LeftLabel(const char *text) {
if (!options::opts.serverMode) { ImGui::LeftLabel(text); return; }
if (!serverMode) { ImGui::LeftLabel(text); return; }
if (rdl) {
rdl->pushStep(DRAW_STEP_LEFT_LABEL, forceSyncForNext);
rdl->pushString(text);
@ -566,7 +570,7 @@ namespace SmGui {
bool SliderInt(const char *label, int *v, int v_min, int v_max, FormatString format, ImGuiSliderFlags flags) {
nextItemFillWidth = false;
if (!options::opts.serverMode) { return ImGui::SliderInt(label, v, v_min, v_max, fmtStr[format], flags); }
if (!serverMode) { return ImGui::SliderInt(label, v, v_min, v_max, fmtStr[format], flags); }
if (rdl) {
rdl->pushStep(DRAW_STEP_SLIDER_INT, forceSyncForNext);
rdl->pushString(label);
@ -586,7 +590,7 @@ namespace SmGui {
bool SliderFloatWithSteps(const char *label, float *v, float v_min, float v_max, float v_step, FormatString display_format) {
nextItemFillWidth = false;
if (!options::opts.serverMode) { return ImGui::SliderFloatWithSteps(label, v, v_min, v_max, v_step, fmtStr[display_format]); }
if (!serverMode) { return ImGui::SliderFloatWithSteps(label, v, v_min, v_max, v_step, fmtStr[display_format]); }
if (rdl) {
rdl->pushStep(DRAW_STEP_SLIDER_FLOAT_WITH_STEPS, forceSyncForNext);
rdl->pushString(label);
@ -606,7 +610,7 @@ namespace SmGui {
bool InputInt(const char *label, int *v, int step, int step_fast, ImGuiInputTextFlags flags) {
nextItemFillWidth = false;
if (!options::opts.serverMode) { return ImGui::InputInt(label, v, step, step_fast, flags); }
if (!serverMode) { return ImGui::InputInt(label, v, step, step_fast, flags); }
if (rdl) {
rdl->pushStep(DRAW_STEP_INPUT_INT, forceSyncForNext);
rdl->pushString(label);
@ -624,7 +628,7 @@ namespace SmGui {
}
bool Checkbox(const char *label, bool *v) {
if (!options::opts.serverMode) { return ImGui::Checkbox(label, v); }
if (!serverMode) { return ImGui::Checkbox(label, v); }
if (rdl) {
rdl->pushStep(DRAW_STEP_CHECKBOX, forceSyncForNext);
rdl->pushString(label);
@ -640,7 +644,7 @@ namespace SmGui {
bool SliderFloat(const char *label, float *v, float v_min, float v_max, FormatString format, ImGuiSliderFlags flags) {
nextItemFillWidth = false;
if (!options::opts.serverMode) { return ImGui::SliderFloat(label, v, v_min, v_max, fmtStr[format], flags); }
if (!serverMode) { return ImGui::SliderFloat(label, v, v_min, v_max, fmtStr[format], flags); }
if (rdl) {
rdl->pushStep(DRAW_STEP_SLIDER_FLOAT, forceSyncForNext);
rdl->pushString(label);
@ -660,7 +664,7 @@ namespace SmGui {
bool InputText(const char *label, char *buf, size_t buf_size, ImGuiInputTextFlags flags) {
nextItemFillWidth = false;
if (!options::opts.serverMode) { return ImGui::InputText(label, buf, buf_size, flags); }
if (!serverMode) { return ImGui::InputText(label, buf, buf_size, flags); }
if (rdl) {
rdl->pushStep(DRAW_STEP_INPUT_TEXT, forceSyncForNext);
rdl->pushString(label);
@ -677,7 +681,7 @@ namespace SmGui {
}
void Text(const char* str) {
if (!options::opts.serverMode) { ImGui::TextUnformatted(str); return; }
if (!serverMode) { ImGui::TextUnformatted(str); return; }
if (rdl) {
rdl->pushStep(DRAW_STEP_TEXT, false);
rdl->pushString(str);
@ -685,7 +689,7 @@ namespace SmGui {
}
void TextColored(const ImVec4 &col, const char *str) {
if (!options::opts.serverMode) { ImGui::TextColored(col, "%s", str); return; }
if (!serverMode) { ImGui::TextColored(col, "%s", str); return; }
if (rdl) {
rdl->pushStep(DRAW_STEP_TEXT_COLORED, false);
rdl->pushFloat(col.x);
@ -697,7 +701,7 @@ namespace SmGui {
}
void OpenPopup(const char *str_id, ImGuiPopupFlags popup_flags) {
if (!options::opts.serverMode) { ImGui::OpenPopup(str_id, popup_flags); return; }
if (!serverMode) { ImGui::OpenPopup(str_id, popup_flags); return; }
if (rdl) {
rdl->pushStep(DRAW_STEP_OPEN_POPUP, false);
rdl->pushString(str_id);
@ -706,7 +710,7 @@ namespace SmGui {
}
bool BeginPopup(const char *str_id, ImGuiWindowFlags flags) {
if (!options::opts.serverMode) { return ImGui::BeginPopup(str_id, flags); }
if (!serverMode) { return ImGui::BeginPopup(str_id, flags); }
if (rdl) {
rdl->pushStep(DRAW_STEP_BEGIN_POPUP, false);
rdl->pushString(str_id);
@ -716,14 +720,14 @@ namespace SmGui {
}
void EndPopup() {
if (!options::opts.serverMode) { ImGui::EndPopup(); return; }
if (!serverMode) { ImGui::EndPopup(); return; }
if (rdl) {
rdl->pushStep(DRAW_STEP_END_POPUP, false);
}
}
bool BeginTable(const char *str_id, int column, ImGuiTableFlags flags, const ImVec2 &outer_size, float inner_width) {
if (!options::opts.serverMode) { return ImGui::BeginTable(str_id, column, flags, outer_size, inner_width); }
if (!serverMode) { return ImGui::BeginTable(str_id, column, flags, outer_size, inner_width); }
if (rdl) {
rdl->pushStep(DRAW_STEP_BEGIN_TABLE, false);
rdl->pushString(str_id);
@ -737,14 +741,14 @@ namespace SmGui {
}
void EndTable() {
if (!options::opts.serverMode) { ImGui::EndTable(); return; }
if (!serverMode) { ImGui::EndTable(); return; }
if (rdl) {
rdl->pushStep(DRAW_STEP_END_TABLE, false);
}
}
void TableNextRow(ImGuiTableRowFlags row_flags, float min_row_height) {
if (!options::opts.serverMode) { ImGui::TableNextRow(row_flags, min_row_height); return; }
if (!serverMode) { ImGui::TableNextRow(row_flags, min_row_height); return; }
if (rdl) {
rdl->pushStep(DRAW_STEP_TABLE_NEXT_ROW, false);
rdl->pushInt(row_flags);
@ -753,7 +757,7 @@ namespace SmGui {
}
void TableSetColumnIndex(int column_n) {
if (!options::opts.serverMode) { ImGui::TableSetColumnIndex(column_n); return; }
if (!serverMode) { ImGui::TableSetColumnIndex(column_n); return; }
if (rdl) {
rdl->pushStep(DRAW_STEP_TABLE_SET_COLUMN_INDEX, false);
rdl->pushInt(column_n);
@ -761,7 +765,7 @@ namespace SmGui {
}
void SetNextItemWidth(float item_width) {
if (!options::opts.serverMode) { ImGui::SetNextItemWidth(item_width); return; }
if (!serverMode) { ImGui::SetNextItemWidth(item_width); return; }
if (rdl) {
rdl->pushStep(DRAW_STEP_SET_NEXT_ITEM_WIDTH, false);
rdl->pushFloat(item_width);

View File

@ -100,6 +100,7 @@ namespace SmGui {
// Rec/Play functions
// TODO: Maybe move verification to the load function instead of checking in drawFrame
void init(bool server);
void setDiff(std::string id, SmGui::DrawListElem value);
void startRecord(DrawList* dl);
void stopRecord();

View File

@ -2,7 +2,6 @@
#include <imgui.h>
#include <imgui_internal.h>
#include <config.h>
#include <options.h>
#include <spdlog/spdlog.h>
#include <filesystem>
@ -10,6 +9,14 @@ namespace style {
ImFont* baseFont;
ImFont* bigFont;
ImFont* hugeFont;
ImVector<ImWchar> ranges;
ImFontGlyphRangesBuilder builder;
#ifndef __ANDROID__
float uiScale = 1.0f;
#else
float uiScale = 3.0f;
#endif
bool loadFonts(std::string resDir) {
if (!std::filesystem::is_directory(resDir)) {
@ -17,9 +24,16 @@ namespace style {
return false;
}
baseFont = ImGui::GetIO().Fonts->AddFontFromFileTTF(((std::string)(resDir + "/fonts/Roboto-Medium.ttf")).c_str(), 16.0f);
bigFont = ImGui::GetIO().Fonts->AddFontFromFileTTF(((std::string)(resDir + "/fonts/Roboto-Medium.ttf")).c_str(), 45.0f);
hugeFont = ImGui::GetIO().Fonts->AddFontFromFileTTF(((std::string)(resDir + "/fonts/Roboto-Medium.ttf")).c_str(), 128.0f);
// Create font range
ImFontAtlas* fonts = ImGui::GetIO().Fonts;
builder.AddRanges(fonts->GetGlyphRangesDefault());
builder.AddRanges(fonts->GetGlyphRangesCyrillic());
builder.BuildRanges(&ranges);
// Add bigger fonts for frequency select and title
baseFont = fonts->AddFontFromFileTTF(((std::string)(resDir + "/fonts/Roboto-Medium.ttf")).c_str(), 16.0f * uiScale, NULL, ranges.Data);
bigFont = fonts->AddFontFromFileTTF(((std::string)(resDir + "/fonts/Roboto-Medium.ttf")).c_str(), 45.0f * uiScale);
hugeFont = fonts->AddFontFromFileTTF(((std::string)(resDir + "/fonts/Roboto-Medium.ttf")).c_str(), 128.0f * uiScale);
return true;
}
@ -55,6 +69,6 @@ namespace ImGui {
}
void FillWidth() {
ImGui::SetNextItemWidth(ImGui::GetContentRegionAvailWidth());
ImGui::SetNextItemWidth(ImGui::GetContentRegionAvail().x);
}
}

View File

@ -7,6 +7,8 @@ namespace style {
extern ImFont* bigFont;
extern ImFont* hugeFont;
extern float uiScale;
bool setDefaultStyle(std::string resDir);
bool loadFonts(std::string resDir);
void beginDisabled();

View File

@ -1,17 +1,18 @@
#include <gui/widgets/file_select.h>
#include <regex>
#include <options.h>
#include <filesystem>
#include <gui/file_dialogs.h>
#include <core.h>
FileSelect::FileSelect(std::string defaultPath, std::vector<std::string> filter) {
_filter = filter;
root = (std::string)core::args["root"];
setPath(defaultPath);
}
bool FileSelect::render(std::string id) {
bool _pathChanged = false;
float menuColumnWidth = ImGui::GetContentRegionAvailWidth();
float menuColumnWidth = ImGui::GetContentRegionAvail().x;
float buttonWidth = ImGui::CalcTextSize("...").x + 20.0f;
bool lastPathValid = pathValid;
@ -54,7 +55,7 @@ void FileSelect::setPath(std::string path, bool markChanged) {
}
std::string FileSelect::expandString(std::string input) {
input = std::regex_replace(input, std::regex("%ROOT%"), options::opts.root);
input = std::regex_replace(input, std::regex("%ROOT%"), root);
return std::regex_replace(input, std::regex("//"), "/");
}

View File

@ -22,6 +22,7 @@ private:
void worker();
std::thread workerThread;
std::vector<std::string> _filter;
std::string root = "";
bool pathValid = false;
bool dialogOpen = false;

View File

@ -1,16 +1,17 @@
#include <gui/widgets/folder_select.h>
#include <regex>
#include <options.h>
#include <filesystem>
#include <gui/file_dialogs.h>
#include <core.h>
FolderSelect::FolderSelect(std::string defaultPath) {
root = (std::string)core::args["root"];
setPath(defaultPath);
}
bool FolderSelect::render(std::string id) {
bool _pathChanged = false;
float menuColumnWidth = ImGui::GetContentRegionAvailWidth();
float menuColumnWidth = ImGui::GetContentRegionAvail().x;
float buttonWidth = ImGui::CalcTextSize("...").x + 20.0f;
bool lastPathValid = pathValid;
@ -53,7 +54,7 @@ void FolderSelect::setPath(std::string path, bool markChanged) {
}
std::string FolderSelect::expandString(std::string input) {
input = std::regex_replace(input, std::regex("%ROOT%"), options::opts.root);
input = std::regex_replace(input, std::regex("%ROOT%"), root);
return std::regex_replace(input, std::regex("//"), "/");
}

View File

@ -20,6 +20,7 @@ public:
private:
void worker();
std::thread workerThread;
std::string root = "";
bool pathValid = false;
bool dialogOpen = false;

View File

@ -2,8 +2,7 @@
#include <config.h>
#include <gui/style.h>
#include <gui/gui.h>
#include <glfw_window.h>
#include <GLFW/glfw3.h>
#include <backend.h>
#ifndef IMGUI_DEFINE_MATH_OPERATORS
#define IMGUI_DEFINE_MATH_OPERATORS
@ -42,9 +41,6 @@ void FrequencySelect::onPosChange() {
}
}
void FrequencySelect::onResize() {
}
void FrequencySelect::incrementDigit(int i) {
if (i < 0) {
return;
@ -87,40 +83,33 @@ void FrequencySelect::decrementDigit(int i) {
void FrequencySelect::moveCursorToDigit(int i) {
double xpos, ypos;
glfwGetCursorPos(core::window, &xpos, &ypos);
float nxpos = (digitTopMaxs[i].x + digitTopMins[i].x) / 2.0f;
glfwSetCursorPos(core::window, nxpos, ypos);
backend::getMouseScreenPos(xpos, ypos);
double nxpos = (digitTopMaxs[i].x + digitTopMins[i].x) / 2.0;
backend::setMouseScreenPos(nxpos, ypos);
}
void FrequencySelect::draw() {
window = ImGui::GetCurrentWindow();
auto window = ImGui::GetCurrentWindow();
widgetPos = ImGui::GetWindowContentRegionMin();
widgetEndPos = ImGui::GetWindowContentRegionMax();
ImVec2 cursorPos = ImGui::GetCursorPos();
widgetPos.x += window->Pos.x + cursorPos.x;
widgetPos.y += window->Pos.y - 3;
widgetEndPos.x += window->Pos.x + cursorPos.x;
widgetEndPos.y += window->Pos.y - 3;
widgetSize = ImVec2(widgetEndPos.x - widgetPos.x, widgetEndPos.y - widgetPos.y);
ImGui::PushFont(style::bigFont);
ImVec2 digitSz = ImGui::CalcTextSize("0");
ImVec2 commaSz = ImGui::CalcTextSize(".");
widgetPos.y = window->Pos.y + cursorPos.y - ((digitSz.y / 2.0f) - ceilf(15 * style::uiScale) - 5);
if (widgetPos.x != lastWidgetPos.x || widgetPos.y != lastWidgetPos.y) {
lastWidgetPos = widgetPos;
onPosChange();
}
if (widgetSize.x != lastWidgetSize.x || widgetSize.y != lastWidgetSize.y) {
lastWidgetSize = widgetSize;
onResize();
}
ImU32 disabledColor = ImGui::GetColorU32(ImGuiCol_Text, 0.3f);
ImU32 textColor = ImGui::GetColorU32(ImGuiCol_Text);
ImVec2 digitSz = ImGui::CalcTextSize("0");
ImVec2 commaSz = ImGui::CalcTextSize(".");
int digitWidth = digitSz.x;
int commaOffset = 0;
float textOffset = 11.0f * style::uiScale;
bool zeros = true;
ImGui::ItemSize(ImRect(digitTopMins[0], ImVec2(digitBottomMaxs[11].x + 15, digitBottomMaxs[11].y)));
@ -134,7 +123,7 @@ void FrequencySelect::draw() {
zeros ? disabledColor : textColor, buf);
if ((i + 1) % 3 == 0 && i < 11) {
commaOffset += commaSz.x;
window->DrawList->AddText(ImVec2(widgetPos.x + (i * digitWidth) + commaOffset + 11, widgetPos.y),
window->DrawList->AddText(ImVec2(widgetPos.x + (i * digitWidth) + commaOffset + textOffset, widgetPos.y),
zeros ? disabledColor : textColor, ".");
}
}
@ -165,23 +154,23 @@ void FrequencySelect::draw() {
}
if (onDigit) {
hovered = true;
if (rightClick || (ImGui::IsKeyPressed(GLFW_KEY_DELETE) || ImGui::IsKeyPressed(GLFW_KEY_ENTER) || ImGui::IsKeyPressed(GLFW_KEY_KP_ENTER))) {
if (rightClick || (ImGui::IsKeyPressed(ImGuiKey_Delete) || ImGui::IsKeyPressed(ImGuiKey_Enter) || ImGui::IsKeyPressed(ImGuiKey_KeypadEnter))) {
for (int j = i; j < 12; j++) {
digits[j] = 0;
}
frequencyChanged = true;
}
if (ImGui::IsKeyPressed(GLFW_KEY_UP)) {
if (ImGui::IsKeyPressed(ImGuiKey_UpArrow)) {
incrementDigit(i);
}
if (ImGui::IsKeyPressed(GLFW_KEY_DOWN)) {
if (ImGui::IsKeyPressed(ImGuiKey_DownArrow)) {
decrementDigit(i);
}
if ((ImGui::IsKeyPressed(GLFW_KEY_LEFT) || ImGui::IsKeyPressed(GLFW_KEY_BACKSPACE)) && i > 0) {
if ((ImGui::IsKeyPressed(ImGuiKey_LeftArrow) || ImGui::IsKeyPressed(ImGuiKey_Backspace)) && i > 0) {
moveCursorToDigit(i - 1);
}
if (ImGui::IsKeyPressed(GLFW_KEY_RIGHT) && i < 11) {
if (ImGui::IsKeyPressed(ImGuiKey_RightArrow) && i < 11) {
moveCursorToDigit(i + 1);
}
@ -223,9 +212,7 @@ void FrequencySelect::draw() {
ImGui::PopFont();
ImGui::SetCursorPosX(digitBottomMaxs[11].x + 17);
//ImGui::NewLine();
ImGui::SetCursorPosX(digitBottomMaxs[11].x + (17.0f * style::uiScale));
}
void FrequencySelect::setFrequency(int64_t freq) {

View File

@ -26,13 +26,7 @@ private:
void moveCursorToDigit(int i);
ImVec2 widgetPos;
ImVec2 widgetEndPos;
ImVec2 widgetSize;
ImVec2 lastWidgetPos;
ImVec2 lastWidgetSize;
ImGuiWindow* window;
int digits[12];
ImVec2 digitBottomMins[12];

View File

@ -26,8 +26,9 @@ void Menu::removeEntry(std::string name) {
bool Menu::draw(bool updateStates) {
bool changed = false;
float menuWidth = ImGui::GetContentRegionAvailWidth();
float menuWidth = ImGui::GetContentRegionAvail().x;
ImGuiWindow* window = ImGui::GetCurrentWindow();
ImVec2 checkboxOffset = ImVec2(menuWidth - ImGui::GetTextLineHeight() - (6.0f * style::uiScale), - ImGui::GetTextLineHeight() - (10.0f * style::uiScale));
int displayedCount = 0;
int rawId = 0;
@ -46,6 +47,7 @@ bool Menu::draw(bool updateStates) {
continue;
}
// Draw dragged menu item
if (displayedCount == insertBefore && !draggedMenuName.empty()) {
if (updateStates) { ImGui::SetNextItemOpen(false); }
ImVec2 posMin = ImGui::GetCursorScreenPos();
@ -56,14 +58,14 @@ bool Menu::draw(bool updateStates) {
if (items[draggedOpt.name].inst != NULL) {
window->WorkRect = orignalRect;
ImVec2 pos = ImGui::GetCursorPos();
ImGui::SetCursorPosX(pos.x + menuWidth - ImGui::GetTextLineHeight() - 6);
ImGui::SetCursorPosY(pos.y - 10 - ImGui::GetTextLineHeight());
ImGui::SetCursorPosX(pos.x + checkboxOffset.x);
ImGui::SetCursorPosY(pos.y + checkboxOffset.y);
bool enabled = items[draggedOpt.name].inst->isEnabled();
ImGui::Checkbox(("##_menu_checkbox_" + draggedOpt.name).c_str(), &enabled);
ImGui::SetCursorPos(pos);
}
style::endDisabled();
window->DrawList->AddRect(posMin, posMax, textColor);
window->DrawList->AddRect(posMin, posMax, textColor, 0.0f, 0, style::uiScale);
}
displayedCount++;
@ -72,7 +74,7 @@ bool Menu::draw(bool updateStates) {
ImRect orginalRect = window->WorkRect;
if (item.inst != NULL) {
window->WorkRect = ImRect(orginalRect.Min, ImVec2(orginalRect.Max.x - ImGui::GetTextLineHeight() - 6, orginalRect.Max.y));
window->WorkRect = ImRect(orginalRect.Min, ImVec2(orginalRect.Max.x - ImGui::GetTextLineHeight() - (6.0f * style::uiScale), orginalRect.Max.y));
}
ImVec2 posMin = ImGui::GetCursorScreenPos();
@ -93,13 +95,14 @@ bool Menu::draw(bool updateStates) {
continue;
}
// Draw menu header and menu content. There is a lot of boilerplate because the checkbox has to be drawn before the menu, TODO: fix
if (updateStates) { ImGui::SetNextItemOpen(opt.open); }
if (ImGui::CollapsingHeader((opt.name + "##sdrpp_main_menu").c_str())) {
if (item.inst != NULL) {
window->WorkRect = orginalRect;
ImVec2 pos = ImGui::GetCursorPos();
ImGui::SetCursorPosX(pos.x + menuWidth - ImGui::GetTextLineHeight() - 6);
ImGui::SetCursorPosY(pos.y - 10 - ImGui::GetTextLineHeight());
ImGui::SetCursorPosX(pos.x + checkboxOffset.x);
ImGui::SetCursorPosY(pos.y + checkboxOffset.y);
bool enabled = item.inst->isEnabled();
if (ImGui::Checkbox(("##_menu_checkbox_" + opt.name).c_str(), &enabled)) {
enabled ? item.inst->enable() : item.inst->disable();
@ -120,8 +123,8 @@ bool Menu::draw(bool updateStates) {
else if (item.inst != NULL) {
window->WorkRect = orginalRect;
ImVec2 pos = ImGui::GetCursorPos();
ImGui::SetCursorPosX(pos.x + menuWidth - ImGui::GetTextLineHeight() - 6);
ImGui::SetCursorPosY(pos.y - 10 - ImGui::GetTextLineHeight());
ImGui::SetCursorPosX(pos.x + checkboxOffset.x);
ImGui::SetCursorPosY(pos.y + checkboxOffset.y);
bool enabled = item.inst->isEnabled();
if (ImGui::Checkbox(("##_menu_checkbox_" + opt.name).c_str(), &enabled)) {
enabled ? item.inst->enable() : item.inst->disable();
@ -168,7 +171,7 @@ bool Menu::draw(bool updateStates) {
insertBefore = -1;
}
// TODO: Figure out why the hell this is needed
if (insertBefore == displayedCount && !draggedMenuName.empty()) {
if (updateStates) { ImGui::SetNextItemOpen(false); }
ImVec2 posMin = ImGui::GetCursorScreenPos();
@ -179,14 +182,14 @@ bool Menu::draw(bool updateStates) {
if (items[draggedOpt.name].inst != NULL) {
window->WorkRect = orignalRect;
ImVec2 pos = ImGui::GetCursorPos();
ImGui::SetCursorPosX(pos.x + menuWidth - ImGui::GetTextLineHeight() - 6);
ImGui::SetCursorPosY(pos.y - 10 - ImGui::GetTextLineHeight());
ImGui::SetCursorPosX(pos.x + checkboxOffset.x);
ImGui::SetCursorPosY(pos.y + checkboxOffset.y);
bool enabled = items[draggedOpt.name].inst->isEnabled();
ImGui::Checkbox(("##_menu_checkbox_" + draggedOpt.name).c_str(), &enabled);
ImGui::SetCursorPos(pos);
}
style::endDisabled();
window->DrawList->AddRect(posMin, posMax, textColor);
window->DrawList->AddRect(posMin, posMax, textColor, 0.0f, 0, style::uiScale);
}
if (!draggedMenuName.empty()) {

View File

@ -1,5 +1,6 @@
#include <gui/widgets/volume_meter.h>
#include <algorithm>
#include <gui/style.h>
#ifndef IMGUI_DEFINE_MATH_OPERATORS
#define IMGUI_DEFINE_MATH_OPERATORS
@ -27,15 +28,15 @@ namespace ImGui {
float it = size.x / 9;
char buf[32];
window->DrawList->AddRectFilled(min + ImVec2(0, 1), min + ImVec2(roundf((float)val * ratio), 10), IM_COL32(0, 136, 255, 255));
window->DrawList->AddLine(min, min + ImVec2(0, 9), text);
window->DrawList->AddLine(min + ImVec2(0, 9), min + ImVec2(size.x + 1, 9), text);
window->DrawList->AddRectFilled(min + ImVec2(0, 1), min + ImVec2(roundf((float)val * ratio), 10 * style::uiScale), IM_COL32(0, 136, 255, 255));
window->DrawList->AddLine(min, min + ImVec2(0, (10.0f * style::uiScale) - 1), text, style::uiScale);
window->DrawList->AddLine(min + ImVec2(0, (10.0f * style::uiScale) - 1), min + ImVec2(size.x + 1, (10.0f * style::uiScale) - 1), text, style::uiScale);
for (int i = 0; i < 10; i++) {
window->DrawList->AddLine(min + ImVec2(roundf((float)i * it), 9), min + ImVec2(roundf((float)i * it), 14), text);
window->DrawList->AddLine(min + ImVec2(roundf((float)i * it), (10.0f * style::uiScale) - 1), min + ImVec2(roundf((float)i * it), (15.0f * style::uiScale) - 1), text, style::uiScale);
sprintf(buf, "%d", i * 10);
ImVec2 sz = ImGui::CalcTextSize(buf);
window->DrawList->AddText(min + ImVec2(roundf(((float)i * it) - (sz.x / 2.0)) + 1, 16), text, buf);
window->DrawList->AddText(min + ImVec2(roundf(((float)i * it) - (sz.x / 2.0)) + 1, 16.0f * style::uiScale), text, buf);
}
}
}

View File

@ -4,9 +4,9 @@
#include <imutils.h>
#include <algorithm>
#include <volk/volk.h>
#include <GLFW/glfw3.h>
#include <spdlog/spdlog.h>
#include <gui/gui.h>
#include <gui/style.h>
float DEFAULT_COLOR_MAP[][3] = {
{ 0x00, 0x00, 0x20 },
@ -99,51 +99,53 @@ namespace ImGui {
ImU32 trace = ImGui::GetColorU32(ImGuiCol_PlotLines);
ImU32 shadow = ImGui::GetColorU32(ImGuiCol_PlotLines, 0.2);
ImU32 text = ImGui::GetColorU32(ImGuiCol_Text);
float textVOffset = 10.0f * style::uiScale;
// Vertical scale
for (float line = startLine; line > fftMin; line -= vRange) {
float yPos = widgetPos.y + fftHeight + 10 - ((line - fftMin) * scaleFactor);
window->DrawList->AddLine(ImVec2(roundf(widgetPos.x + 50), roundf(yPos)),
ImVec2(roundf(widgetPos.x + dataWidth + 50), roundf(yPos)),
IM_COL32(50, 50, 50, 255), 1.0);
float yPos = fftAreaMax.y - ((line - fftMin) * scaleFactor);
window->DrawList->AddLine(ImVec2(fftAreaMin.x, roundf(yPos)),
ImVec2(fftAreaMax.x, roundf(yPos)),
IM_COL32(50, 50, 50, 255), style::uiScale);
sprintf(buf, "%d", (int)line);
ImVec2 txtSz = ImGui::CalcTextSize(buf);
window->DrawList->AddText(ImVec2(widgetPos.x + 40 - txtSz.x, roundf(yPos - (txtSz.y / 2.0))), text, buf);
window->DrawList->AddText(ImVec2(fftAreaMin.x - txtSz.x - textVOffset, roundf(yPos - (txtSz.y / 2.0))), text, buf);
}
// Horizontal scale
double startFreq = ceilf(lowerFreq / range) * range;
double horizScale = (double)dataWidth / viewBandwidth;
float scaleVOfsset = 7 * style::uiScale;
for (double freq = startFreq; freq < upperFreq; freq += range) {
double xPos = widgetPos.x + 50 + ((freq - lowerFreq) * horizScale);
window->DrawList->AddLine(ImVec2(roundf(xPos), widgetPos.y + 10),
ImVec2(roundf(xPos), widgetPos.y + fftHeight + 10),
IM_COL32(50, 50, 50, 255), 1.0);
window->DrawList->AddLine(ImVec2(roundf(xPos), widgetPos.y + fftHeight + 10),
ImVec2(roundf(xPos), widgetPos.y + fftHeight + 17),
text, 1.0);
double xPos = fftAreaMin.x + ((freq - lowerFreq) * horizScale);
window->DrawList->AddLine(ImVec2(roundf(xPos), fftAreaMin.y + 1),
ImVec2(roundf(xPos), fftAreaMax.y),
IM_COL32(50, 50, 50, 255), style::uiScale);
window->DrawList->AddLine(ImVec2(roundf(xPos), fftAreaMax.y),
ImVec2(roundf(xPos), fftAreaMax.y + scaleVOfsset),
text, style::uiScale);
printAndScale(freq, buf);
ImVec2 txtSz = ImGui::CalcTextSize(buf);
window->DrawList->AddText(ImVec2(roundf(xPos - (txtSz.x / 2.0)), widgetPos.y + fftHeight + 10 + txtSz.y), text, buf);
window->DrawList->AddText(ImVec2(roundf(xPos - (txtSz.x / 2.0)), fftAreaMax.y + txtSz.y), text, buf);
}
// Data
if (latestFFT != NULL && fftLines != 0) {
for (int i = 1; i < dataWidth; i++) {
double aPos = widgetPos.y + fftHeight + 10 - ((latestFFT[i - 1] - fftMin) * scaleFactor);
double bPos = widgetPos.y + fftHeight + 10 - ((latestFFT[i] - fftMin) * scaleFactor);
aPos = std::clamp<double>(aPos, widgetPos.y + 10, widgetPos.y + fftHeight + 10);
bPos = std::clamp<double>(bPos, widgetPos.y + 10, widgetPos.y + fftHeight + 10);
window->DrawList->AddLine(ImVec2(widgetPos.x + 49 + i, roundf(aPos)),
ImVec2(widgetPos.x + 50 + i, roundf(bPos)), trace, 1.0);
window->DrawList->AddLine(ImVec2(widgetPos.x + 50 + i, roundf(bPos)),
ImVec2(widgetPos.x + 50 + i, widgetPos.y + fftHeight + 10), shadow, 1.0);
double aPos = fftAreaMax.y - ((latestFFT[i - 1] - fftMin) * scaleFactor);
double bPos = fftAreaMax.y - ((latestFFT[i] - fftMin) * scaleFactor);
aPos = std::clamp<double>(aPos, fftAreaMin.y + 1, fftAreaMax.y);
bPos = std::clamp<double>(bPos, fftAreaMin.y + 1, fftAreaMax.y);
window->DrawList->AddLine(ImVec2(fftAreaMin.x + i - 1, roundf(aPos)),
ImVec2(fftAreaMin.x + i, roundf(bPos)), trace, 1.0);
window->DrawList->AddLine(ImVec2(fftAreaMin.x + i, roundf(bPos)),
ImVec2(fftAreaMin.x + i, fftAreaMax.y), shadow, 1.0);
}
}
FFTRedrawArgs args;
args.min = ImVec2(widgetPos.x + 50, widgetPos.y + 9);
args.max = ImVec2(widgetPos.x + dataWidth + 50, widgetPos.y + fftHeight + 10);
args.min = fftAreaMin;
args.max = fftAreaMax;
args.lowFreq = lowerFreq;
args.highFreq = upperFreq;
args.freqToPixelRatio = horizScale;
@ -152,13 +154,13 @@ namespace ImGui {
onFFTRedraw.emit(args);
// X Axis
window->DrawList->AddLine(ImVec2(widgetPos.x + 50, widgetPos.y + fftHeight + 10),
ImVec2(widgetPos.x + dataWidth + 50, widgetPos.y + fftHeight + 10),
text, 1.0);
window->DrawList->AddLine(ImVec2(fftAreaMin.x, fftAreaMax.y),
ImVec2(fftAreaMax.x, fftAreaMax.y),
text, style::uiScale);
// Y Axis
window->DrawList->AddLine(ImVec2(widgetPos.x + 50, widgetPos.y + 9),
ImVec2(widgetPos.x + 50, widgetPos.y + fftHeight + 9),
text, 1.0);
window->DrawList->AddLine(ImVec2(fftAreaMin.x, fftAreaMin.y),
ImVec2(fftAreaMin.x, fftAreaMax.y - 1),
text, style::uiScale);
}
void WaterFall::drawWaterfall() {
@ -173,7 +175,7 @@ namespace ImGui {
for (auto const& [name, vfo] : vfos) {
window->DrawList->AddRectFilled(vfo->wfRectMin, vfo->wfRectMax, vfo->color);
if (!vfo->lineVisible) { continue; }
window->DrawList->AddLine(vfo->wfLineMin, vfo->wfLineMax, (name == selectedVFO) ? IM_COL32(255, 0, 0, 255) : IM_COL32(255, 255, 0, 255));
window->DrawList->AddLine(vfo->wfLineMin, vfo->wfLineMax, (name == selectedVFO) ? IM_COL32(255, 0, 0, 255) : IM_COL32(255, 255, 0, 255), style::uiScale);
}
}
}
@ -212,7 +214,7 @@ namespace ImGui {
bool mouseClicked = ImGui::ButtonBehavior(ImRect(fftAreaMin, wfMax), GetID("WaterfallID"), &mouseHovered, &mouseHeld,
ImGuiButtonFlags_MouseButtonLeft | ImGuiButtonFlags_PressedOnClick);
mouseInFFTResize = (dragOrigin.x > widgetPos.x && dragOrigin.x < widgetPos.x + widgetSize.x && dragOrigin.y >= widgetPos.y + newFFTAreaHeight - 2 && dragOrigin.y <= widgetPos.y + newFFTAreaHeight + 2);
mouseInFFTResize = (dragOrigin.x > widgetPos.x && dragOrigin.x < widgetPos.x + widgetSize.x && dragOrigin.y >= widgetPos.y + newFFTAreaHeight - (2.0f * style::uiScale) && dragOrigin.y <= widgetPos.y + newFFTAreaHeight + (2.0f * style::uiScale));
mouseInFreq = IS_IN_AREA(dragOrigin, freqAreaMin, freqAreaMax);
mouseInFFT = IS_IN_AREA(dragOrigin, fftAreaMin, fftAreaMax);
mouseInWaterfall = IS_IN_AREA(dragOrigin, wfMin, wfMax);
@ -304,7 +306,7 @@ namespace ImGui {
newFFTAreaHeight = mousePos.y - widgetPos.y;
newFFTAreaHeight = std::clamp<float>(newFFTAreaHeight, 150, widgetSize.y - 50);
ImGui::GetForegroundDrawList()->AddLine(ImVec2(widgetPos.x, newFFTAreaHeight + widgetPos.y), ImVec2(widgetEndPos.x, newFFTAreaHeight + widgetPos.y),
ImGui::GetColorU32(ImGuiCol_SeparatorActive));
ImGui::GetColorU32(ImGuiCol_SeparatorActive), style::uiScale);
return;
}
@ -387,8 +389,8 @@ namespace ImGui {
}
// If the left and right keys are pressed while hovering the freq scale, move it too
bool leftKeyPressed = ImGui::IsKeyPressed(GLFW_KEY_LEFT);
if ((leftKeyPressed || ImGui::IsKeyPressed(GLFW_KEY_RIGHT)) && mouseInFreq) {
bool leftKeyPressed = ImGui::IsKeyPressed(ImGuiKey_LeftArrow);
if ((leftKeyPressed || ImGui::IsKeyPressed(ImGuiKey_RightArrow)) && mouseInFreq) {
viewOffset += leftKeyPressed ? (viewBandwidth / 20.0) : (-viewBandwidth / 20.0);
if (viewOffset + (viewBandwidth / 2.0) > wholeBandwidth / 2.0) {
@ -417,7 +419,7 @@ namespace ImGui {
// Finally, if nothing else was selected, just move the VFO
if ((VFOMoveSingleClick ? ImGui::IsMouseClicked(ImGuiMouseButton_Left) : ImGui::IsMouseDown(ImGuiMouseButton_Left)) && (mouseInFFT | mouseInWaterfall) && (mouseMoved || hoveredVFOName == "")) {
if (selVfo != NULL) {
int refCenter = mousePos.x - (widgetPos.x + 50);
int refCenter = mousePos.x - fftAreaMin.x;
if (refCenter >= 0 && refCenter < dataWidth) {
double off = ((((double)refCenter / ((double)dataWidth / 2.0)) - 1.0) * (viewBandwidth / 2.0)) + viewOffset;
off += centerFreq;
@ -435,7 +437,7 @@ namespace ImGui {
ImGui::TextUnformatted(name.c_str());
if (ImGui::IsKeyDown(GLFW_KEY_LEFT_CONTROL) || ImGui::IsKeyDown(GLFW_KEY_RIGHT_CONTROL)) {
if (ImGui::GetIO().KeyCtrl) {
ImGui::Separator();
printAndScale(_vfo->generalOffset + centerFreq, buf);
ImGui::Text("Frequency: %sHz", buf);
@ -461,7 +463,7 @@ namespace ImGui {
}
// Handle Page Up to cycle through VFOs
if (ImGui::IsKeyPressed(GLFW_KEY_PAGE_UP) && selVfo != NULL) {
if (ImGui::IsKeyPressed(ImGuiKey_PageUp) && selVfo != NULL) {
std::string next = (--vfos.end())->first;
std::string lowest = "";
double lowestOffset = INFINITY;
@ -484,7 +486,7 @@ namespace ImGui {
}
// Handle Page Down to cycle through VFOs
if (ImGui::IsKeyPressed(GLFW_KEY_PAGE_DOWN) && selVfo != NULL) {
if (ImGui::IsKeyPressed(ImGuiKey_PageDown) && selVfo != NULL) {
std::string next = (--vfos.end())->first;
std::string highest = "";
double highestOffset = -INFINITY;
@ -599,10 +601,10 @@ namespace ImGui {
float bpBottom;
if (bandPlanPos == BANDPLAN_POS_BOTTOM) {
bpBottom = widgetPos.y + fftHeight + 10;
bpBottom = fftAreaMax.y;
}
else {
bpBottom = widgetPos.y + height + 10;
bpBottom = fftAreaMin.y + height + 1;
}
@ -620,9 +622,9 @@ namespace ImGui {
start = std::clamp<double>(start, lowerFreq, upperFreq);
end = std::clamp<double>(end, lowerFreq, upperFreq);
center = (start + end) / 2.0;
aPos = widgetPos.x + 50 + ((start - lowerFreq) * horizScale);
bPos = widgetPos.x + 50 + ((end - lowerFreq) * horizScale);
cPos = widgetPos.x + 50 + ((center - lowerFreq) * horizScale);
aPos = fftAreaMin.x + ((start - lowerFreq) * horizScale);
bPos = fftAreaMin.x + ((end - lowerFreq) * horizScale);
cPos = fftAreaMin.x + ((center - lowerFreq) * horizScale);
width = bPos - aPos;
txtSz = ImGui::CalcTextSize(bandplan->bands[i].name.c_str());
if (bandplan::colorTable.find(bandplan->bands[i].type.c_str()) != bandplan::colorTable.end()) {
@ -633,22 +635,22 @@ namespace ImGui {
color = IM_COL32(255, 255, 255, 255);
colorTrans = IM_COL32(255, 255, 255, 100);
}
if (aPos <= widgetPos.x + 50) {
aPos = widgetPos.x + 51;
if (aPos <= fftAreaMin.x) {
aPos = fftAreaMin.x + 1;
}
if (bPos <= widgetPos.x + 50) {
bPos = widgetPos.x + 51;
if (bPos <= fftAreaMin.x) {
bPos = fftAreaMin.x + 1;
}
if (width >= 1.0) {
window->DrawList->AddRectFilled(ImVec2(roundf(aPos), bpBottom - height),
ImVec2(roundf(bPos), bpBottom), colorTrans);
if (startVis) {
window->DrawList->AddLine(ImVec2(roundf(aPos), bpBottom - height - 1),
ImVec2(roundf(aPos), bpBottom - 1), color);
ImVec2(roundf(aPos), bpBottom - 1), color, style::uiScale);
}
if (endVis) {
window->DrawList->AddLine(ImVec2(roundf(bPos), bpBottom - height - 1),
ImVec2(roundf(bPos), bpBottom - 1), color);
ImVec2(roundf(bPos), bpBottom - 1), color, style::uiScale);
}
}
if (txtSz.x <= width) {
@ -679,15 +681,15 @@ namespace ImGui {
int lastWaterfallHeight = waterfallHeight;
if (waterfallVisible) {
FFTAreaHeight = std::min<int>(FFTAreaHeight, widgetSize.y - 50);
FFTAreaHeight = std::min<int>(FFTAreaHeight, widgetSize.y - (50.0f * style::uiScale));
newFFTAreaHeight = FFTAreaHeight;
fftHeight = FFTAreaHeight - 50;
waterfallHeight = widgetSize.y - fftHeight - 52;
fftHeight = FFTAreaHeight - (50.0f * style::uiScale);
waterfallHeight = widgetSize.y - fftHeight - (50.0f * style::uiScale) - 2;
}
else {
fftHeight = widgetSize.y - 50;
fftHeight = widgetSize.y - (50.0f * style::uiScale);
}
dataWidth = widgetSize.x - 60.0;
dataWidth = widgetSize.x - (60.0f * style::uiScale);
if (waterfallVisible) {
// Raw FFT resize
@ -724,12 +726,14 @@ namespace ImGui {
latestFFT[i] = -1000.0; // Hide everything
}
fftAreaMin = ImVec2(widgetPos.x + 50, widgetPos.y + 9);
fftAreaMax = ImVec2(widgetPos.x + dataWidth + 50, widgetPos.y + fftHeight + 10);
freqAreaMin = ImVec2(widgetPos.x + 50, widgetPos.y + fftHeight + 11);
freqAreaMax = ImVec2(widgetPos.x + dataWidth + 50, widgetPos.y + fftHeight + 50);
wfMin = ImVec2(widgetPos.x + 50, widgetPos.y + fftHeight + 51);
wfMax = ImVec2(widgetPos.x + 50 + dataWidth, widgetPos.y + fftHeight + 51 + waterfallHeight);
fftAreaMin = ImVec2(widgetPos.x + (50.0f * style::uiScale), widgetPos.y + (9.0f * style::uiScale));
fftAreaMax = ImVec2(fftAreaMin.x + dataWidth, fftAreaMin.y + fftHeight + 1);
freqAreaMin = ImVec2(fftAreaMin.x, fftAreaMax.y + 1);
freqAreaMax = ImVec2(fftAreaMax.x, fftAreaMax.y + (40.0f * style::uiScale));
wfMin = ImVec2(fftAreaMin.x, freqAreaMax.y + 1);
wfMax = ImVec2(fftAreaMin.x + dataWidth, wfMin.y + waterfallHeight);
maxHSteps = dataWidth / (ImGui::CalcTextSize("000.000").x + 10);
maxVSteps = fftHeight / (ImGui::CalcTextSize("000.000").y);
@ -769,8 +773,8 @@ namespace ImGui {
//window->DrawList->AddRectFilled(widgetPos, widgetEndPos, IM_COL32( 0, 0, 0, 255 ));
ImU32 bg = ImGui::ColorConvertFloat4ToU32(gui::themeManager.waterfallBg);
window->DrawList->AddRectFilled(widgetPos, widgetEndPos, bg);
window->DrawList->AddRect(widgetPos, widgetEndPos, IM_COL32(50, 50, 50, 255));
window->DrawList->AddLine(ImVec2(widgetPos.x, widgetPos.y + fftHeight + 50), ImVec2(widgetPos.x + widgetSize.x, widgetPos.y + fftHeight + 50), IM_COL32(50, 50, 50, 255), 1.0);
window->DrawList->AddRect(widgetPos, widgetEndPos, IM_COL32(50, 50, 50, 255), 0.0, 0, style::uiScale);
window->DrawList->AddLine(ImVec2(widgetPos.x, freqAreaMax.y), ImVec2(widgetPos.x + widgetSize.x, freqAreaMax.y), IM_COL32(50, 50, 50, 255), style::uiScale);
if (!gui::mainWindow.lockWaterfallControls) {
inputHandled = false;
@ -1041,8 +1045,8 @@ namespace ImGui {
vfo->updateDrawingVars(viewBandwidth, dataWidth, viewOffset, widgetPos, fftHeight);
vfo->wfRectMin = ImVec2(vfo->rectMin.x, wfMin.y);
vfo->wfRectMax = ImVec2(vfo->rectMax.x, wfMax.y);
vfo->wfLineMin = ImVec2(vfo->lineMin.x, wfMin.y);
vfo->wfLineMax = ImVec2(vfo->lineMax.x, wfMax.y);
vfo->wfLineMin = ImVec2(vfo->lineMin.x, wfMin.y - 1);
vfo->wfLineMax = ImVec2(vfo->lineMax.x, wfMax.y - 1);
vfo->wfLbwSelMin = ImVec2(vfo->wfRectMin.x - 2, vfo->wfRectMin.y);
vfo->wfLbwSelMax = ImVec2(vfo->wfRectMin.x + 2, vfo->wfRectMax.y);
vfo->wfRbwSelMin = ImVec2(vfo->wfRectMax.x - 2, vfo->wfRectMin.y);
@ -1175,16 +1179,16 @@ namespace ImGui {
// Calculate the position of the line
if (reference == REF_LOWER) {
lineMin = ImVec2(widgetPos.x + 50 + left, widgetPos.y + 9);
lineMax = ImVec2(widgetPos.x + 50 + left, widgetPos.y + fftHeight + 9);
lineMin = ImVec2(gui::waterfall.fftAreaMin.x + left, gui::waterfall.fftAreaMin.y);
lineMax = ImVec2(gui::waterfall.fftAreaMin.x + left, gui::waterfall.fftAreaMax.y - 1);
}
else if (reference == REF_CENTER) {
lineMin = ImVec2(widgetPos.x + 50 + center, widgetPos.y + 9);
lineMax = ImVec2(widgetPos.x + 50 + center, widgetPos.y + fftHeight + 9);
lineMin = ImVec2(gui::waterfall.fftAreaMin.x + center, gui::waterfall.fftAreaMin.y);
lineMax = ImVec2(gui::waterfall.fftAreaMin.x + center, gui::waterfall.fftAreaMax.y - 1);
}
else if (reference == REF_UPPER) {
lineMin = ImVec2(widgetPos.x + 50 + right, widgetPos.y + 9);
lineMax = ImVec2(widgetPos.x + 50 + right, widgetPos.y + fftHeight + 9);
lineMin = ImVec2(gui::waterfall.fftAreaMin.x + right, gui::waterfall.fftAreaMin.y);
lineMax = ImVec2(gui::waterfall.fftAreaMin.x + right, gui::waterfall.fftAreaMax.y - 1);
}
int _left = left;
@ -1194,22 +1198,23 @@ namespace ImGui {
leftClamped = (left != _left);
rightClamped = (right != _right);
rectMin = ImVec2(widgetPos.x + 50 + left, widgetPos.y + 10);
rectMax = ImVec2(widgetPos.x + 51 + right, widgetPos.y + fftHeight + 10);
rectMin = ImVec2(gui::waterfall.fftAreaMin.x + left, gui::waterfall.fftAreaMin.y + 1);
rectMax = ImVec2(gui::waterfall.fftAreaMin.x + right + 1, gui::waterfall.fftAreaMax.y);
lbwSelMin = ImVec2(rectMin.x - 2, rectMin.y);
lbwSelMax = ImVec2(rectMin.x + 2, rectMax.y);
rbwSelMin = ImVec2(rectMax.x - 2, rectMin.y);
rbwSelMax = ImVec2(rectMax.x + 2, rectMax.y);
float gripSize = 2.0f * style::uiScale;
lbwSelMin = ImVec2(rectMin.x - gripSize, rectMin.y);
lbwSelMax = ImVec2(rectMin.x + gripSize, rectMax.y);
rbwSelMin = ImVec2(rectMax.x - gripSize, rectMin.y);
rbwSelMax = ImVec2(rectMax.x + gripSize, rectMax.y);
notchMin = ImVec2(widgetPos.x + 50 + notch - 2, widgetPos.y + 9);
notchMax = ImVec2(widgetPos.x + 50 + notch + 2, widgetPos.y + fftHeight + 9);
notchMin = ImVec2(gui::waterfall.fftAreaMin.x + notch - gripSize, gui::waterfall.fftAreaMin.y);
notchMax = ImVec2(gui::waterfall.fftAreaMin.x + notch + gripSize, gui::waterfall.fftAreaMax.y - 1);
}
void WaterfallVFO::draw(ImGuiWindow* window, bool selected) {
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));
window->DrawList->AddLine(lineMin, lineMax, selected ? IM_COL32(255, 0, 0, 255) : IM_COL32(255, 255, 0, 255), style::uiScale);
}
if (notchVisible) {

View File

@ -236,6 +236,13 @@ namespace ImGui {
_BANDPLAN_POS_COUNT
};
ImVec2 fftAreaMin;
ImVec2 fftAreaMax;
ImVec2 freqAreaMin;
ImVec2 freqAreaMax;
ImVec2 wfMin;
ImVec2 wfMax;
private:
void drawWaterfall();
void drawFFT();
@ -260,13 +267,6 @@ namespace ImGui {
ImVec2 lastWidgetPos;
ImVec2 lastWidgetSize;
ImVec2 fftAreaMin;
ImVec2 fftAreaMax;
ImVec2 freqAreaMin;
ImVec2 freqAreaMax;
ImVec2 wfMin;
ImVec2 wfMax;
ImGuiWindow* window;
GLuint textureId;