Skip to content

Commit 507951d

Browse files
committed
GPSDR++ V1.0.8
Improved map zooming: center of map view will not move when zooming; The button on top will move (previous) GPS locked location (instead of the map tile it belongs to) to the center of map view. Improved ADS-B mode: prevent changing frequency and tuning mode when ADS-B mode is in used. Fixed bug: with map view activated, volume control stays disabled, demodulation modes are missing, and frequency meter not updated after quitting the ADS-B mode, until waterfall view gets activated.
1 parent 8a20ae5 commit 507951d

File tree

7 files changed

+138
-65
lines changed

7 files changed

+138
-65
lines changed

core/src/gui/main_window.cpp

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -428,11 +428,14 @@ void MainWindow::draw() {
428428
sigpath::sinkManager.showVolumeSlider(gui::waterfall.selectedVFO, "##_sdrpp_main_volume_", 238 * style::uiScale, btnSize.y, 5, true);
429429

430430
// Frequency select
431+
if (freqSelectLocked) { style::beginDisabled();}
431432
ImGui::SameLine();
432433
ImGui::SetCursorPosY(origY);
433434
gui::freqSelect.draw();
435+
if (freqSelectLocked) { style::endDisabled();}
434436

435437
// Tuning mode button
438+
if (tuningModeLocked) { style::beginDisabled();}
436439
ImGui::SameLine();
437440
ImGui::SetCursorPosY(origY);
438441
if (tuningMode == tuner::TUNER_MODE_CENTER) {
@@ -458,6 +461,7 @@ void MainWindow::draw() {
458461
}
459462
ImGui::PopID();
460463
}
464+
if (tuningModeLocked) { style::endDisabled(); }
461465

462466
// SNR meter
463467
ImGui::SameLine();
@@ -600,4 +604,8 @@ void MainWindow::setFirstMenuRender() {
600604

601605
int MainWindow::getTuningMode() {
602606
return tuningMode;
603-
}
607+
}
608+
609+
void MainWindow::setTuningMode(int mode) {
610+
tuningMode = mode;
611+
}

core/src/gui/main_window.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,10 +30,14 @@ class MainWindow {
3030

3131
bool lockWaterfallControls = false;
3232
bool playButtonLocked = false;
33+
bool freqSelectLocked = false;
34+
bool tuningModeLocked = false;
35+
bool waterfallLocked = false;
3336

3437
Event<bool> onPlayStateChange;
3538

3639
int getTuningMode();
40+
void setTuningMode(int mode);
3741

3842
private:
3943
static void vfoAddedHandler(VFOManager::VFO* vfo, void* ctx);

core/src/gui/widgets/frequency_select.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -132,7 +132,7 @@ void FrequencySelect::draw() {
132132
}
133133
}
134134

135-
if (!gui::mainWindow.lockWaterfallControls) {
135+
if (!gui::mainWindow.lockWaterfallControls && !gui::mainWindow.freqSelectLocked) {
136136
ImVec2 mousePos = ImGui::GetMousePos();
137137
bool leftClick = ImGui::IsMouseClicked(ImGuiMouseButton_Left);
138138
bool rightClick = ImGui::IsMouseClicked(ImGuiMouseButton_Right);

core/src/gui/widgets/map_view.cpp

Lines changed: 69 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -466,30 +466,76 @@ void MapView::draw() {
466466
ImVec2 btnSize(CONTROL_BUTTON_SIZE, CONTROL_BUTTON_SIZE);
467467
ImVec2 ctrlPos = ImVec2(availableRegion.x - CONTROL_BUTTON_SIZE - CONTROL_BUTTON_MARGIN, CONTROL_BUTTON_MARGIN);
468468
ImGui::SetCursorPos(ctrlPos);
469-
if (ImGui::ImageButton(icons::LOCATE, btnSize, ImVec2(0, 0), ImVec2(1, 1), 5, ImVec4(0, 0, 0, 0))) {
470-
prevPanLon = panLon = 0.0f;
471-
prevPanLat = panLat = 0.0f;
472-
}
473-
ctrlPos.y += CONTROL_BUTTON_SIZE + CONTROL_BUTTON_MARGIN;
474-
ImGui::SetCursorPos(ctrlPos);
475-
if (ImGui::ImageButton(icons::ZOOM_IN, btnSize, ImVec2(0, 0), ImVec2(1, 1), 5, ImVec4(0, 0, 0, 0), zoom < 19 ? ImVec4(0, 0, 0, 1) : ImVec4(0, 0, 0, 0.3))) {
476-
if (zoom < 19) {
477-
zoom ++;
478-
core::configManager.acquire();
479-
core::configManager.conf["zoom"] = zoom;
480-
core::configManager.release(true);
481-
}
482-
}
483-
ctrlPos.y += CONTROL_BUTTON_SIZE + CONTROL_BUTTON_MARGIN;
484-
ImGui::SetCursorPos(ctrlPos);
485-
if (ImGui::ImageButton(icons::ZOOM_OUT, btnSize, ImVec2(0, 0), ImVec2(1, 1), 5, ImVec4(0, 0, 0, 0), zoom > 1 ? ImVec4(0, 0, 0, 1) : ImVec4(0, 0, 0, 0.3))) {
486-
if (zoom > 1) {
487-
zoom --;
488-
core::configManager.acquire();
489-
core::configManager.conf["zoom"] = zoom;
490-
core::configManager.release(true);
491-
}
469+
470+
// Center location
471+
if (ImGui::ImageButton(icons::LOCATE, btnSize, ImVec2(0, 0), ImVec2(1, 1), 5, ImVec4(0, 0, 0, 0))) {
472+
ImVec2 availableRegion = ImGui::GetContentRegionAvail();
473+
ImVec2 screenCenter = ImVec2(availableRegion.x * 0.5f, availableRegion.y * 0.5f);
474+
panLon = screenCenter.x - ((availableRegion.x - TILE_WIDTH) * 0.5f) - pxOffsetX;
475+
panLat = screenCenter.y - ((availableRegion.y - TILE_HEIGHT) * 0.5f) - pxOffsetY;
476+
prevPanLon = panLon;
477+
prevPanLat = panLat;
478+
core::configManager.acquire();
479+
core::configManager.conf["panLon"] = panLon;
480+
core::configManager.conf["panLat"] = panLat;
481+
core::configManager.release(true);
492482
}
483+
484+
// Zoom in
485+
ctrlPos.y += CONTROL_BUTTON_SIZE + CONTROL_BUTTON_MARGIN;
486+
ImGui::SetCursorPos(ctrlPos);
487+
if (ImGui::ImageButton(icons::ZOOM_IN, btnSize, ImVec2(0, 0), ImVec2(1, 1), 5, ImVec4(0, 0, 0, 0), zoom < 19 ? ImVec4(0, 0, 0, 1) : ImVec4(0, 0, 0, 0.3))) {
488+
if (zoom < 19) {
489+
ImVec2 screenCenter = ImVec2(availableRegion.x * 0.5f, availableRegion.y * 0.5f);
490+
ImVec2 tileScreenPos = ImVec2(offsetX, offsetY);
491+
float centerOffsetFromGPSX = screenCenter.x - (tileScreenPos.x + pxOffsetX);
492+
float centerOffsetFromGPSY = screenCenter.y - (tileScreenPos.y + pxOffsetY);
493+
zoom++;
494+
centerOffsetFromGPSX *= 2.0f;
495+
centerOffsetFromGPSY *= 2.0f;
496+
int newTileX, newTileY, newPxOffsetX, newPxOffsetY;
497+
latLonToTilePixel(latitude, longitude, newTileX, newTileY, newPxOffsetX, newPxOffsetY);
498+
float newTileDefaultX = (availableRegion.x - TILE_WIDTH) * 0.5f;
499+
float newTileDefaultY = (availableRegion.y - TILE_HEIGHT) * 0.5f;
500+
panLon = screenCenter.x - newTileDefaultX - newPxOffsetX - centerOffsetFromGPSX;
501+
panLat = screenCenter.y - newTileDefaultY - newPxOffsetY - centerOffsetFromGPSY;
502+
prevPanLon = panLon;
503+
prevPanLat = panLat;
504+
core::configManager.acquire();
505+
core::configManager.conf["zoom"] = zoom;
506+
core::configManager.conf["panLon"] = panLon;
507+
core::configManager.conf["panLat"] = panLat;
508+
core::configManager.release(true);
509+
}
510+
}
511+
512+
// Zoom out
513+
ctrlPos.y += CONTROL_BUTTON_SIZE + CONTROL_BUTTON_MARGIN;
514+
ImGui::SetCursorPos(ctrlPos);
515+
if (ImGui::ImageButton(icons::ZOOM_OUT, btnSize, ImVec2(0, 0), ImVec2(1, 1), 5, ImVec4(0, 0, 0, 0), zoom > 1 ? ImVec4(0, 0, 0, 1) : ImVec4(0, 0, 0, 0.3))) {
516+
if (zoom > 1) {
517+
ImVec2 screenCenter = ImVec2(availableRegion.x * 0.5f, availableRegion.y * 0.5f);
518+
ImVec2 tileScreenPos = ImVec2(offsetX, offsetY);
519+
float centerOffsetFromGPSX = screenCenter.x - (tileScreenPos.x + pxOffsetX);
520+
float centerOffsetFromGPSY = screenCenter.y - (tileScreenPos.y + pxOffsetY);
521+
zoom--;
522+
centerOffsetFromGPSX *= 0.5f;
523+
centerOffsetFromGPSY *= 0.5f;
524+
int newTileX, newTileY, newPxOffsetX, newPxOffsetY;
525+
latLonToTilePixel(latitude, longitude, newTileX, newTileY, newPxOffsetX, newPxOffsetY);
526+
float newTileDefaultX = (availableRegion.x - TILE_WIDTH) * 0.5f;
527+
float newTileDefaultY = (availableRegion.y - TILE_HEIGHT) * 0.5f;
528+
panLon = screenCenter.x - newTileDefaultX - newPxOffsetX - centerOffsetFromGPSX;
529+
panLat = screenCenter.y - newTileDefaultY - newPxOffsetY - centerOffsetFromGPSY;
530+
prevPanLon = panLon;
531+
prevPanLat = panLat;
532+
core::configManager.acquire();
533+
core::configManager.conf["zoom"] = zoom;
534+
core::configManager.conf["panLon"] = panLon;
535+
core::configManager.conf["panLat"] = panLat;
536+
core::configManager.release(true);
537+
}
538+
}
493539

494540
// OpenStreetMap attribution
495541
ImGui::PushStyleColor(ImGuiCol_Button, ImVec4(0, 0, 0, 0));

core/src/gui/widgets/waterfall.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -887,7 +887,7 @@ namespace ImGui {
887887
window->DrawList->AddRect(widgetPos, widgetEndPos, IM_COL32(50, 50, 50, 255), 0.0, 0, style::uiScale);
888888
//window->DrawList->AddLine(ImVec2(widgetPos.x, freqAreaMax.y), ImVec2(widgetPos.x + widgetSize.x, freqAreaMax.y), IM_COL32(50, 50, 50, 255), style::uiScale);
889889

890-
if (!gui::mainWindow.lockWaterfallControls) {
890+
if (!gui::mainWindow.lockWaterfallControls && !gui::mainWindow.waterfallLocked) {
891891
inputHandled = false;
892892
InputHandlerArgs args;
893893
args.fftRectMin = fftAreaMin;

core/src/version.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,3 @@
11
#pragma once
22

3-
#define VERSION_STR "1.0.7"
3+
#define VERSION_STR "1.0.8"

decoder_modules/mode_s_decoder/src/main.cpp

Lines changed: 53 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -73,61 +73,73 @@ class ModeSDecoderModule : public ModuleManager::Instance {
7373
private:
7474
static void onStart(ModeSDecoderModule* _this) {
7575
_this->rtlSdrWasRunning = gui::mainWindow.isPlaying();
76-
if (_this->rtlSdrWasRunning) {
77-
gui::mainWindow.setPlayState(false);
78-
}
79-
80-
if (sigpath::vfoManager.vfoExists("Radio")) {
81-
_this->radioWasEnabled = true;
82-
core::moduleManager.disableInstance("Radio");
83-
}
8476

85-
core::modComManager.callInterface("RTL-SDR", RTL_SDR_SOURCE_IFACE_CMD_GET_SAMPLE_RATE_INDEX, NULL, &_this->oldSampleRateId);
77+
core::modComManager.callInterface("RTL-SDR", RTL_SDR_SOURCE_IFACE_CMD_GET_SAMPLE_RATE_INDEX, NULL, &_this->savedSampleRateId);
8678
int newSampleRateId = 5; // Index for 2MHz in RTLSDRSource's sampleRates
8779
core::modComManager.callInterface("RTL-SDR", RTL_SDR_SOURCE_IFACE_CMD_SET_SAMPLE_RATE_INDEX, &newSampleRateId, NULL);
8880

89-
_this->oldTuningFreq = gui::waterfall.getCenterFrequency();
90-
gui::waterfall.setCenterFrequency(MODE_S_DEFAULT_FREQ);
91-
gui::waterfall.centerFreqMoved = true;
81+
_this->savedSelectedVFO = gui::waterfall.selectedVFO;
82+
_this->savedFreq = gui::freqSelect.frequency;
83+
_this->savedTuningMode = gui::mainWindow.getTuningMode();
84+
if (gui::waterfall.selectedVFO != "") {
85+
ImGui::WaterfallVFO* vfo = gui::waterfall.vfos[gui::waterfall.selectedVFO];
86+
_this->savedSelectedVFOOffset = vfo->generalOffset;
87+
}
9288

93-
_this->decoder.init(ModeSPage::getInstance().getContext(), sigpath::sourceManager.getSelectedSource()->stream);
94-
_this->decoder.start();
89+
gui::mainWindow.setTuningMode(tuner::TUNER_MODE_CENTER);
90+
gui::mainWindow.waterfallLocked = true;
91+
gui::mainWindow.freqSelectLocked = true;
92+
gui::mainWindow.tuningModeLocked = true;
9593

96-
gui::mainWindow.setPlayState(true);
97-
98-
ModeSPage::getInstance().addLog("Start");
94+
if (_this->rtlSdrWasRunning) {
95+
gui::mainWindow.setPlayState(false);
96+
}
97+
98+
if (sigpath::vfoManager.vfoExists("Radio")) {
99+
_this->radioWasEnabled = true;
100+
core::moduleManager.disableInstance("Radio");
101+
}
102+
103+
tuner::tune(tuner::TUNER_MODE_CENTER, gui::waterfall.selectedVFO, MODE_S_DEFAULT_FREQ);
104+
105+
_this->decoder.init(ModeSPage::getInstance().getContext(), sigpath::sourceManager.getSelectedSource()->stream);
106+
_this->decoder.start();
107+
108+
gui::mainWindow.setPlayState(true);
109+
110+
ModeSPage::getInstance().addLog("Start");
99111
}
100112

101113
static void onStop(ModeSDecoderModule* _this) {
102114
// If stop decoder here, pressing the "Play" button later will freeze the GUI, why?
103115
//_this->decoder.stop();
104116

105117
gui::mainWindow.setPlayState(false);
106-
107-
gui::waterfall.setCenterFrequency(_this->oldTuningFreq);
108-
109-
core::modComManager.callInterface("RTL-SDR", RTL_SDR_SOURCE_IFACE_CMD_SET_SAMPLE_RATE_INDEX, &_this->oldSampleRateId, NULL);
110-
111-
if (_this->radioWasEnabled) {
118+
119+
if (_this->radioWasEnabled) {
112120
core::moduleManager.enableInstance("Radio");
113121
}
114122

123+
core::modComManager.callInterface("RTL-SDR", RTL_SDR_SOURCE_IFACE_CMD_SET_SAMPLE_RATE_INDEX, &_this->savedSampleRateId, NULL);
124+
125+
gui::waterfall.selectedVFO = _this->savedSelectedVFO;
126+
127+
if (gui::waterfall.selectedVFO != "") {
128+
ImGui::WaterfallVFO* vfo = gui::waterfall.vfos[gui::waterfall.selectedVFO];
129+
vfo->generalOffset = _this->savedSelectedVFOOffset;
130+
}
131+
132+
gui::mainWindow.setTuningMode(_this->savedTuningMode);
133+
tuner::tune(_this->savedTuningMode, gui::waterfall.selectedVFO, _this->savedFreq);
134+
115135
if (_this->rtlSdrWasRunning) {
116136
gui::mainWindow.setPlayState(true);
117137
}
118-
119-
// Save restored frequency here
120-
core::configManager.acquire();
121-
core::configManager.conf["frequency"] = gui::waterfall.getCenterFrequency();
122-
ImGui::WaterfallVFO* vfo = NULL;
123-
if (gui::waterfall.selectedVFO != "") {
124-
vfo = gui::waterfall.vfos[gui::waterfall.selectedVFO];
125-
}
126-
if (vfo != NULL) {
127-
core::configManager.conf["vfoOffsets"][gui::waterfall.selectedVFO] = vfo->generalOffset;
128-
}
129-
core::configManager.release(true);
130-
138+
139+
gui::mainWindow.waterfallLocked = false;
140+
gui::mainWindow.freqSelectLocked = false;
141+
gui::mainWindow.tuningModeLocked = false;
142+
131143
ModeSPage::getInstance().addLog("Stop");
132144
}
133145

@@ -170,8 +182,11 @@ class ModeSDecoderModule : public ModuleManager::Instance {
170182
bool run = false;
171183
bool radioWasEnabled = false;
172184
bool rtlSdrWasRunning = false;
173-
int oldSampleRateId = 0;
174-
double oldTuningFreq = 0;
185+
int savedSampleRateId = 0;
186+
double savedFreq = 0;
187+
int savedTuningMode;
188+
std::string savedSelectedVFO;
189+
double savedSelectedVFOOffset = 0.0f;
175190

176191
dsp::ModeSDecoder decoder;
177192
};

0 commit comments

Comments
 (0)