diff --git a/firmware/application/ui/ui_spectrum.cpp b/firmware/application/ui/ui_spectrum.cpp index 93bca6278..533d9529b 100644 --- a/firmware/application/ui/ui_spectrum.cpp +++ b/firmware/application/ui/ui_spectrum.cpp @@ -1,5 +1,6 @@ /* * Copyright (C) 2015 Jared Boone, ShareBrained Technology, Inc. + * Copyleft Mr. Robot 2025 * * This file is part of PortaPack. * @@ -100,6 +101,15 @@ void FrequencyScale::set_channel_filter( } } +void FrequencyScale::set_cursor_position(const int32_t position) { + cursor_position = position; + + cursor_position = std::min(cursor_position, 119); + cursor_position = std::max(cursor_position, -120); + + set_dirty(); +} + void FrequencyScale::paint(Painter& painter) { const auto r = screen_rect(); @@ -240,6 +250,15 @@ bool FrequencyScale::on_key(const KeyEvent key) { return false; } +bool FrequencyScale::on_touch(const TouchEvent touch) { + if (touch.type == TouchEvent::Type::Start) { + if (on_select) { + on_select((touch.point.x() * spectrum_sampling_rate) / 240); + } + } + return true; +} + void FrequencyScale::on_tick_second() { set_dirty(); _blink = !_blink; @@ -285,6 +304,15 @@ void WaterfallWidget::on_channel_spectrum( pixel_row); } +bool WaterfallWidget::on_touch(const TouchEvent event) { + if (event.type == TouchEvent::Type::Start) { + if (on_touch_select) { + on_touch_select(event.point.x(), event.point.y()); + } + } + return true; +} + void WaterfallWidget::clear() { display.fill_rectangle( screen_rect(), @@ -304,6 +332,18 @@ WaterfallView::WaterfallView(const bool cursor) { if (on_select) on_select(offset); }; + waterfall_widget.on_touch_select = [this](int32_t x, int32_t y) { + if (y > screen_height - screen_height * 0.1) return; // prevent ghost touch + + frequency_scale.focus(); // focus on frequency scale to show cursor + + if (sampling_rate) { + // screen x to frequency scale x, NB we need two widgets align + int32_t cursor_position = x - (screen_width / 2); + frequency_scale.set_cursor_position(cursor_position); + } + }; + if (!waterfall_widget.gradient.load_file(default_gradient_file)) { waterfall_widget.gradient.set_default(); } diff --git a/firmware/application/ui/ui_spectrum.hpp b/firmware/application/ui/ui_spectrum.hpp index 398e419ca..1714a6c7e 100644 --- a/firmware/application/ui/ui_spectrum.hpp +++ b/firmware/application/ui/ui_spectrum.hpp @@ -1,5 +1,6 @@ /* * Copyright (C) 2015 Jared Boone, ShareBrained Technology, Inc. + * Copyleft Mr. Robot 2025 * * This file is part of PortaPack. * @@ -79,9 +80,11 @@ class FrequencyScale : public Widget { bool on_encoder(const EncoderEvent delta) override; bool on_key(const KeyEvent key) override; + bool on_touch(const TouchEvent touch) override; void set_spectrum_sampling_rate(const int new_sampling_rate); void set_channel_filter(const int low_frequency, const int high_frequency, const int transition); + void set_cursor_position(const int32_t position); void paint(Painter& painter) override; @@ -112,11 +115,14 @@ class FrequencyScale : public Widget { class WaterfallWidget : public Widget { public: + std::function on_touch_select{}; + Gradient gradient{}; void on_show() override; void on_hide() override; void paint(Painter&) override {} + bool on_touch(const TouchEvent event) override; void on_channel_spectrum(const ChannelSpectrum& spectrum);