名称优化

This commit is contained in:
2026-08-02 03:43:40 +08:00
parent cd45ffe6de
commit 0fc969c85d
7 changed files with 923 additions and 162 deletions
+13 -13
View File
@@ -52,24 +52,24 @@ void push_radio_data(Radio_Widget* rw) {
return;
{
auto r = rw->spectrogram_line->power_axis()->coord_range();
renderive::Range nr = {r.middle() - r.length() / 4, r.middle() + r.length() / 4};
renderive::Range nr = {r.center() - r.length() / 4, r.center() + r.length() / 4};
auto data = make_random_data(nr, rw->spectrogram_line->frequency_point_size(), renderive::Memory_Domain::Spectrum);
double middle_power = data.empty() ? nr.middle() : data[data.size() / 2];
rw->spectrogram_line->give_data(std::move(data));
double middle_power = data.empty() ? nr.center() : data[data.size() / 2];
rw->spectrogram_line->update_samples(std::move(data));
rw->progress_bar1->setValue(middle_power);
}
{
rw->water_fall->give_data(current_render_time(), make_random_data(rw->water_fall->power_range(), rw->water_fall->frequency_point_size(), renderive::Memory_Domain::Waterfall));
rw->water_fall->append_row(current_render_time(), make_random_data(rw->water_fall->power_range(), rw->water_fall->frequency_bin_count(), renderive::Memory_Domain::Waterfall));
}
{
renderive::Range r = rw->time_power->value_axis()->coord_range();
renderive::Range nr = {r.middle() - r.length() / 4, r.middle() + r.length() / 4};
rw->time_power->give_data(current_render_time(), make_random_value(nr));
renderive::Range nr = {r.center() - r.length() / 4, r.center() + r.length() / 4};
rw->time_power->append_sample(current_render_time(), make_random_value(nr));
}
{
auto r = rw->audio_spectrogram_plot->power_axis()->coord_range();
renderive::Range nr = {r.middle() - r.length() / 4, r.middle() + r.length() / 4};
rw->audio_spectrogram_plot->give_data(make_random_data(nr, rw->audio_spectrogram_plot->frequency_point_size(), renderive::Memory_Domain::Spectrum));
renderive::Range nr = {r.center() - r.length() / 4, r.center() + r.length() / 4};
rw->audio_spectrogram_plot->update_samples(make_random_data(nr, rw->audio_spectrogram_plot->frequency_point_size(), renderive::Memory_Domain::Spectrum));
}
rw->progress_bar2->setValue(make_random_value({1, 5}));
}
@@ -79,18 +79,18 @@ void push_radio_data_perf(Radio_Widget* rw) {
{
renderive::Range nr = {40, 120};
auto data = make_random_data(nr, 1024, renderive::Memory_Domain::Spectrum);
double middle_power = data.empty() ? nr.middle() : data[data.size() / 2];
rw->spectrogram_line->give_data(std::move(data));
double middle_power = data.empty() ? nr.center() : data[data.size() / 2];
rw->spectrogram_line->update_samples(std::move(data));
rw->progress_bar1->setValue(middle_power);
}
{
rw->water_fall->give_data(current_render_time(), make_random_data({0, 160}, 1024, renderive::Memory_Domain::Waterfall));
rw->water_fall->append_row(current_render_time(), make_random_data({0, 160}, 1024, renderive::Memory_Domain::Waterfall));
}
{
rw->time_power->give_data(current_render_time(), make_random_value({-6000, 6000}));
rw->time_power->append_sample(current_render_time(), make_random_value({-6000, 6000}));
}
{
rw->audio_spectrogram_plot->give_data(make_random_data({-6000, 6000}, 512, renderive::Memory_Domain::Spectrum));
rw->audio_spectrogram_plot->update_samples(make_random_data({-6000, 6000}, 512, renderive::Memory_Domain::Spectrum));
}
rw->progress_bar2->setValue(make_random_value({1, 5}));
}
@@ -11,7 +11,7 @@
#include "../BaseWidget.h"
#include "../menu/BaseWidgetMenu.h"
#include "../BackEnd/MainWidget.h"
#include "Demo_Gallery/base/export.h"
#include "../Tool.h"
static renderive::Range frequent_range = {-12000, 12000};
static double max = 160;
QWidget* Intermediate_Frequency_Widget::create_spectrogram_power_plot() {
@@ -19,16 +19,16 @@ QWidget* Intermediate_Frequency_Widget::create_spectrogram_power_plot() {
public:
std::shared_ptr<renderive::Frequency_Axis> x_axis{};
std::shared_ptr<renderive::Axis> y_axis{};
std::shared_ptr<renderive::Multi_Select_Rect> msr{};
std::shared_ptr<renderive::Selection_Rectangle_Overlay> msr{};
std::shared_ptr<renderive::Spectrum> sp{};
QMenu* menu{};
void init() override {
Latency_Eager_Plot::init();
object_name = "Spectrum_Plot";
auto data = create_renderable_node(get_root_renderable(), "Data_Renderable");
auto frequency_axis_cache = create_renderable_node(get_root_renderable(), "Frequency_Axis_Cache");
auto power_axis_cache = create_renderable_node(get_root_renderable(), "Power_Axis_Cache");
auto overlay = create_renderable_node(get_root_renderable(), "Overlay_Renderable");
auto data = create_renderable_node(root_renderable(), "Data_Renderable");
auto frequency_axis_cache = create_renderable_node(root_renderable(), "Frequency_Axis_Cache");
auto power_axis_cache = create_renderable_node(root_renderable(), "Power_Axis_Cache");
auto overlay = create_renderable_node(root_renderable(), "Overlay_Renderable");
frequency_axis_cache->set_cache_mode(renderive::Renderable_Cache_Mode::Local_Pixel);
power_axis_cache->set_cache_mode(renderive::Renderable_Cache_Mode::Local_Pixel);
x_axis = renderive::Frequency_Axis::Builder(frequency_axis_cache, renderive::Orientation::Horizontal)
@@ -43,19 +43,19 @@ QWidget* Intermediate_Frequency_Widget::create_spectrogram_power_plot() {
.build();
sp = renderive::Spectrum::Builder(data, x_axis, y_axis)
.set_frequency_range(frequent_range)
.set_use_sweep_frequency_rect(true)
.set_sweep_region_visible(true)
.set_frequency_point_size(1024)
.build();
msr = renderive::Multi_Select_Rect::Builder(overlay, x_axis, y_axis).build();
msr = renderive::Selection_Rectangle_Overlay::Builder(overlay, x_axis, y_axis).build();
}
protected:
void resizeEvent(QResizeEvent* event) override {
x_axis->set_x(0);
x_axis->set_y(height() - 1);
x_axis->set_pixel_size(width());
x_axis->set_pixel_length(width());
y_axis->set_x(0);
y_axis->set_y(0);
y_axis->set_pixel_size(height());
y_axis->set_pixel_length(height());
}
void contextMenuEvent(QContextMenuEvent* event) override {
if (!menu) {
@@ -73,9 +73,9 @@ QWidget* Intermediate_Frequency_Widget::create_spectrogram_power_plot() {
w->init();
spectrogram_line = w->sp;
progress_bar1->set_value = [this]() {
double middle_frequent = this->spectrogram_line->frequency_range().middle();
double middle_frequent = this->spectrogram_line->frequency_range().center();
bool ok = false;
double power = spectrogram_line->get_power(middle_frequent, ok);
double power = spectrogram_line->power_at(middle_frequent, ok);
if (ok)
this->progress_bar1->value = power;
};
@@ -87,15 +87,15 @@ QWidget* Intermediate_Frequency_Widget::create_Afterglow_Plot() {
std::shared_ptr<renderive::Frequency_Axis> x_axis{};
std::shared_ptr<renderive::Axis> y_axis{};
std::shared_ptr<renderive::Afterglow> ag{};
std::shared_ptr<renderive::Multi_Select_Rect> msr{};
std::shared_ptr<renderive::Selection_Rectangle_Overlay> msr{};
QMenu* menu{};
void init() override {
Latency_Eager_Plot::init();
object_name = "Afterglow_Plot";
auto data = create_renderable_node(get_root_renderable(), "Data_Renderable");
auto frequency_axis_cache = create_renderable_node(get_root_renderable(), "Frequency_Axis_Cache");
auto power_axis_cache = create_renderable_node(get_root_renderable(), "Power_Axis_Cache");
auto overlay = create_renderable_node(get_root_renderable(), "Overlay_Renderable");
auto data = create_renderable_node(root_renderable(), "Data_Renderable");
auto frequency_axis_cache = create_renderable_node(root_renderable(), "Frequency_Axis_Cache");
auto power_axis_cache = create_renderable_node(root_renderable(), "Power_Axis_Cache");
auto overlay = create_renderable_node(root_renderable(), "Overlay_Renderable");
frequency_axis_cache->set_cache_mode(renderive::Renderable_Cache_Mode::Local_Pixel);
power_axis_cache->set_cache_mode(renderive::Renderable_Cache_Mode::Local_Pixel);
x_axis = renderive::Frequency_Axis::Builder(frequency_axis_cache, renderive::Orientation::Horizontal)
@@ -111,19 +111,19 @@ QWidget* Intermediate_Frequency_Widget::create_Afterglow_Plot() {
ag = renderive::Afterglow::Builder(data, x_axis, y_axis)
.set_frequency_range(frequent_range)
.set_power_range({0, 160})
.set_frequency_point_size(1024)
.set_frequency_bin_count(1024)
.build();
msr = renderive::Multi_Select_Rect::Builder(overlay, x_axis, y_axis).build();
msr = renderive::Selection_Rectangle_Overlay::Builder(overlay, x_axis, y_axis).build();
}
protected:
void resizeEvent(QResizeEvent* event) override {
x_axis->set_x(0);
x_axis->set_y(height() - 1);
x_axis->set_pixel_size(width());
x_axis->set_pixel_length(width());
y_axis->set_x(0);
y_axis->set_y(0);
y_axis->set_pixel_size(height());
ag->set_power_point_size(ag->power_axis()->get_pixel_point_size());
y_axis->set_pixel_length(height());
ag->set_power_point_size(ag->power_axis()->pixel_sample_count());
}
void contextMenuEvent(QContextMenuEvent* event) override {
if (!menu) {
@@ -221,7 +221,7 @@ void Intermediate_Frequency_Widget::focusInEvent(QFocusEvent* event) {
void Intermediate_Frequency_Widget::init_menu() {
int font_size = 30;
auto btn1 = new Double_Text_Menu_Button("设置最大值标记", "取消最大值标记", font_size, [&](bool is_first) {
spectrogram_line->set_use_max_marker(is_first);
spectrogram_line->set_max_marker_visible(is_first);
base_widget_menu->hide();
Main_Widget::instance()->get_current_base_widget()->setFocus();
});
@@ -239,15 +239,15 @@ void Intermediate_Frequency_Widget::init_menu() {
that->setValue(new_frequent);
spectrogram_line->set_current_marker_frequency(new_frequent);
}, qMax(0.0, spectrogram_line->frequency_range().length() / 50.0));
auto btn_middle_frequent = new Value_Menu_Button("中频:%1 Hz", font_size, nullptr, spectrogram_line->middle_sweep_frequency());
auto btn_middle_frequent = new Value_Menu_Button("中频:%1 Hz", font_size, nullptr, spectrogram_line->center_frequency());
auto btn_frequent_width = new Value_Menu_Button("频宽:%1 Hz", font_size, [this, frequent_step2](Value_Menu_Button* that, bool add) {
that->setValue(that->value + (double)(add ? frequent_step2->value : -frequent_step2->value));
double middle_sweep_frequent = spectrogram_line->middle_sweep_frequency();
double middle_sweep_frequent = spectrogram_line->center_frequency();
spectrogram_line->set_sweep_frequency_range({middle_sweep_frequent - that->value, middle_sweep_frequent + that->value});
}, qAbs(spectrogram_line->sweep_frequency_range().length() / 2));
btn_middle_frequent->value_changed = [this, btn_frequent_width, frequent_step2](Value_Menu_Button* that, bool add) {
that->setValue(that->value + (double)(add ? frequent_step2->value : -frequent_step2->value));
spectrogram_line->set_middle_sweep_frequency(that->value);
spectrogram_line->set_center_frequency(that->value);
spectrogram_line->set_sweep_frequency_range({that->value - btn_frequent_width->value, that->value + btn_frequent_width->value});
};
auto btn2_2 = new Value_Menu_Button("参考增益:%1", font_size, [&](Value_Menu_Button* that, bool add) {
@@ -271,30 +271,30 @@ void Intermediate_Frequency_Widget::init_menu() {
that->setValue(new_frequent);
}, spectrogram_line->frequency_range().origin);
auto btn1_1 = new Value_Menu_Button("当前标记:%1", font_size, [&, mark_frequent](Value_Menu_Button* that, bool add) {
int index = ((int)that->value + (add ? 1 : -1)) % spectrogram_line->select_line_marker_size();
int index = ((int)that->value + (add ? 1 : -1)) % spectrogram_line->selectable_line_marker_count();
that->setValue(index);
spectrogram_line->set_selected_line_marker(index);
mark_frequent->setValue(spectrogram_line->get_mark_frequency(index));
spectrogram_line->set_selected_marker_index(index);
mark_frequent->setValue(spectrogram_line->marker_frequency(index));
}, -1);
auto btn1_2 = new Menu_Button("添加标记", font_size, [&, add_init_frequent]() {
spectrogram_line->add_custom_line_marker(add_init_frequent->value);
});
auto btn1_3 = new Menu_Button("删除标记", font_size, [&]() {
spectrogram_line->remove_current_marker();
int size = spectrogram_line->select_line_marker_size();
spectrogram_line->remove_selected_marker();
int size = spectrogram_line->selectable_line_marker_count();
if (size == 0) {
spectrogram_line->set_selected_line_marker(-1);
spectrogram_line->set_selected_marker_index(-1);
}
else {
spectrogram_line->set_selected_line_marker(0);
spectrogram_line->set_selected_marker_index(0);
}
});
connect(sub1, &Base_Widget_Menu::show_that, [&, mark_frequent]() {
spectrogram_line->set_selected_line_marker(0);
mark_frequent->setValue(spectrogram_line->get_mark_frequency(0));
spectrogram_line->set_selected_marker_index(0);
mark_frequent->setValue(spectrogram_line->marker_frequency(0));
});
connect(sub1, &Base_Widget_Menu::hide_that, [&]() {
spectrogram_line->un_select_marker();
spectrogram_line->clear_marker_selection();
});
sub1->add_menu_button_on_layout1({btn1_1, btn1_2, btn1_3}, 2);
sub1->add_menu_button_on_layout2({frequent_step, mark_frequent, add_init_frequent}, 2);
+36 -36
View File
@@ -10,8 +10,8 @@
#include "../menu/BaseWidgetMenu.h"
#include "BackEnd.h"
#include "../BackEnd/MainWidget.h"
#include "Demo_Gallery/base/export.h"
#include "Core/plottable/export.h"
#include "module/radio/Tool.h"
static double max = 160;
static renderive::Range frequent_range = {-12000, 12000};
static bool radio_mock_perf_mode() {
@@ -29,8 +29,8 @@ static void configure_radio_plot_perf(renderive::Latency_Eager_Plot* plot) {
return;
plot->set_max_render_fps(1000);
}
static renderive::Performance_Shower_Options radio_performance_options() {
renderive::Performance_Shower_Options options;
static renderive::Performance_Overlay_Options radio_performance_options() {
renderive::Performance_Overlay_Options options;
options.font.size = 11.0;
options.background = renderive::Color{20, 20, 20, 255};
options.foreground = renderive::Color::white();
@@ -47,12 +47,12 @@ static void apply_radio_performance_overlay(renderive::Latency_Eager_Plot* plot)
}
if (!plot || !plot->core())
return;
auto shower = renderive::attach_performance_shower(*plot->core(), radio_performance_options());
auto shower = renderive::attach_performance_overlay(*plot->core(), radio_performance_options());
if (!shower)
return;
shower->setEnabled(enabled);
shower->set_enabled(enabled);
if (enabled)
renderive::notify_performance_shower_viewport_changed(*plot->core());
renderive::notify_performance_overlay_viewport_changed(*plot->core());
}
struct Radio_Plot_Layout {
int left_axis_width{};
@@ -77,12 +77,12 @@ static void apply_radio_plot_layout(renderive::Abs_Axis* x_axis, renderive::Abs_
if (x_axis) {
x_axis->set_x(layout.content_x);
x_axis->set_y(layout.content_y + layout.content_height);
x_axis->set_pixel_size(static_cast<std::size_t>(layout.content_width));
x_axis->set_pixel_length(static_cast<std::size_t>(layout.content_width));
}
if (y_axis) {
y_axis->set_x(layout.content_x);
y_axis->set_y(layout.content_y);
y_axis->set_pixel_size(static_cast<std::size_t>(layout.content_height));
y_axis->set_pixel_length(static_cast<std::size_t>(layout.content_height));
}
}
QWidget* Radio_Widget::create_spectrogram_power_plot() {
@@ -90,21 +90,21 @@ QWidget* Radio_Widget::create_spectrogram_power_plot() {
public:
std::shared_ptr<renderive::Frequency_Axis> x_axis{};
std::shared_ptr<renderive::Axis> y_axis{};
std::shared_ptr<renderive::Multi_Select_Rect> msr{};
std::shared_ptr<renderive::Selection_Rectangle_Overlay> msr{};
std::shared_ptr<renderive::Spectrum> sp{};
QMenu* menu{};
void init() override {
Latency_Eager_Plot::init();
configure_radio_plot_perf(this);
object_name = "Spectrum_Plot";
auto data = create_renderable_node(get_root_renderable(), "Data_Renderable");
auto data = create_renderable_node(root_renderable(), "Data_Renderable");
// auto frequency_axis_cache = create_renderable_node(get_root_renderable(), "Frequency_Axis_Cache");
// auto power_axis_cache = create_renderable_node(get_root_renderable(), "Power_Axis_Cache");
// frequency_axis_cache->set_cache_mode(renderive::Renderable_Cache_Mode::Local_Pixel);
// power_axis_cache->set_cache_mode(renderive::Renderable_Cache_Mode::Local_Pixel);
auto axis_cache = create_renderable_node(get_root_renderable(), "Power_Axis_Cache");
auto axis_cache = create_renderable_node(root_renderable(), "Power_Axis_Cache");
axis_cache->set_cache_mode(renderive::Renderable_Cache_Mode::Local_Pixel);
auto overlay = create_renderable_node(get_root_renderable(), "Overlay_Renderable");
auto overlay = create_renderable_node(root_renderable(), "Overlay_Renderable");
x_axis = renderive::Frequency_Axis::Builder(axis_cache, renderive::Orientation::Horizontal)
.set_coord_range(frequent_range)
.set_tick_length(10)
@@ -119,7 +119,7 @@ QWidget* Radio_Widget::create_spectrogram_power_plot() {
.set_frequency_range(frequent_range)
.set_frequency_point_size(1024)
.build();
msr = renderive::Multi_Select_Rect::Builder(overlay, x_axis, y_axis).build();
msr = renderive::Selection_Rectangle_Overlay::Builder(overlay, x_axis, y_axis).build();
}
protected:
void resizeEvent(QResizeEvent* event) override {
@@ -143,9 +143,9 @@ QWidget* Radio_Widget::create_spectrogram_power_plot() {
spectrogram_line = w->sp;
if (!radio_mock_perf_mode()) {
progress_bar1->set_value = [this]() {
double middle_frequent = this->spectrogram_line->frequency_range().middle();
double middle_frequent = this->spectrogram_line->frequency_range().center();
bool ok = false;
double power = spectrogram_line->get_power(middle_frequent, ok);
double power = spectrogram_line->power_at(middle_frequent, ok);
if (ok)
this->progress_bar1->setValue(power);
};
@@ -157,18 +157,18 @@ QWidget* Radio_Widget::create_water_fall_plot() {
public:
std::shared_ptr<renderive::Frequency_Axis> x_axis{};
std::shared_ptr<renderive::Time_Axis> y_axis{};
std::shared_ptr<renderive::Multi_Select_Rect> msr{};
std::shared_ptr<renderive::Selection_Rectangle_Overlay> msr{};
std::shared_ptr<renderive::Waterfall> wf{};
QMenu* menu{};
void init() override {
Latency_Eager_Plot::init();
configure_radio_plot_perf(this);
object_name = "Water_Fall_Plot";
auto stream_cache = create_renderable_node(get_root_renderable(), "Waterfall_Stream_Cache");
auto stream_cache = create_renderable_node(root_renderable(), "Waterfall_Stream_Cache");
auto data = create_renderable_node(stream_cache, "Data_Renderable");
auto time_axis = create_renderable_node(stream_cache, "Time_Axis_Renderable");
auto frequency_axis_cache = create_renderable_node(get_root_renderable(), "Frequency_Axis_Cache");
auto overlay = create_renderable_node(get_root_renderable(), "Overlay_Renderable");
auto frequency_axis_cache = create_renderable_node(root_renderable(), "Frequency_Axis_Cache");
auto overlay = create_renderable_node(root_renderable(), "Overlay_Renderable");
stream_cache->set_cache_mode(renderive::Renderable_Cache_Mode::Local_Pixel);
frequency_axis_cache->set_cache_mode(renderive::Renderable_Cache_Mode::Local_Pixel);
x_axis = renderive::Frequency_Axis::Builder(frequency_axis_cache, renderive::Orientation::Horizontal)
@@ -179,14 +179,14 @@ QWidget* Radio_Widget::create_water_fall_plot() {
y_axis = renderive::Time_Axis::Builder(time_axis, renderive::Orientation::Vertical)
.set_tick_length(-10)
.set_sub_tick_length(-5)
.set_time_point_size(100)
.set_visible_time_point_count(100)
.build();
wf = renderive::Waterfall::Builder(data, x_axis, y_axis)
.set_frequency_range(frequent_range)
.set_frequency_point_size(1024)
.set_frequency_bin_count(1024)
.set_power_range({0, max})
.build();
msr = renderive::Multi_Select_Rect::Builder(overlay, x_axis, y_axis).build();
msr = renderive::Selection_Rectangle_Overlay::Builder(overlay, x_axis, y_axis).build();
}
protected:
void resizeEvent(QResizeEvent* event) override {
@@ -215,17 +215,17 @@ QWidget* Radio_Widget::create_audio_spectrogram_plot() {
public:
std::shared_ptr<renderive::Frequency_Axis> x_axis{};
std::shared_ptr<renderive::Axis> y_axis{};
std::shared_ptr<renderive::Multi_Select_Rect> msr{};
std::shared_ptr<renderive::Selection_Rectangle_Overlay> msr{};
std::shared_ptr<renderive::Spectrum> sp{};
QMenu* menu{};
void init() override {
Latency_Eager_Plot::init();
configure_radio_plot_perf(this);
object_name = "Spectrum_Plot";
auto data = create_renderable_node(get_root_renderable(), "Data_Renderable");
auto frequency_axis_cache = create_renderable_node(get_root_renderable(), "Frequency_Axis_Cache");
auto power_axis_cache = create_renderable_node(get_root_renderable(), "Power_Axis_Cache");
auto overlay = create_renderable_node(get_root_renderable(), "Overlay_Renderable");
auto data = create_renderable_node(root_renderable(), "Data_Renderable");
auto frequency_axis_cache = create_renderable_node(root_renderable(), "Frequency_Axis_Cache");
auto power_axis_cache = create_renderable_node(root_renderable(), "Power_Axis_Cache");
auto overlay = create_renderable_node(root_renderable(), "Overlay_Renderable");
frequency_axis_cache->set_cache_mode(renderive::Renderable_Cache_Mode::Local_Pixel);
power_axis_cache->set_cache_mode(renderive::Renderable_Cache_Mode::Local_Pixel);
x_axis = renderive::Frequency_Axis::Builder(frequency_axis_cache, renderive::Orientation::Horizontal)
@@ -242,7 +242,7 @@ QWidget* Radio_Widget::create_audio_spectrogram_plot() {
.set_frequency_range({-12000, 12000})
.set_frequency_point_size(512)
.build();
msr = renderive::Multi_Select_Rect::Builder(overlay, x_axis, y_axis).build();
msr = renderive::Selection_Rectangle_Overlay::Builder(overlay, x_axis, y_axis).build();
}
protected:
void resizeEvent(QResizeEvent* event) override {
@@ -271,18 +271,18 @@ QWidget* Radio_Widget::create_time_power_plot() {
public:
std::shared_ptr<renderive::Time_Axis> x_axis{};
std::shared_ptr<renderive::Axis> y_axis{};
std::shared_ptr<renderive::Audio_Frequency> audio{};
std::shared_ptr<renderive::Multi_Select_Rect> msr{};
std::shared_ptr<renderive::Frequency_Trace> audio{};
std::shared_ptr<renderive::Selection_Rectangle_Overlay> msr{};
QMenu* menu{};
void init() override {
Latency_Eager_Plot::init();
configure_radio_plot_perf(this);
object_name = "Audio_Plot";
auto stream_cache = create_renderable_node(get_root_renderable(), "Audio_Stream_Cache");
auto stream_cache = create_renderable_node(root_renderable(), "Audio_Stream_Cache");
auto data = create_renderable_node(stream_cache, "Data_Renderable");
auto time_axis = create_renderable_node(stream_cache, "Time_Axis_Renderable");
auto power_axis_cache = create_renderable_node(get_root_renderable(), "Power_Axis_Cache");
auto overlay = create_renderable_node(get_root_renderable(), "Overlay_Renderable");
auto power_axis_cache = create_renderable_node(root_renderable(), "Power_Axis_Cache");
auto overlay = create_renderable_node(root_renderable(), "Overlay_Renderable");
stream_cache->set_cache_mode(renderive::Renderable_Cache_Mode::Local_Pixel);
power_axis_cache->set_cache_mode(renderive::Renderable_Cache_Mode::Local_Pixel);
x_axis = renderive::Time_Axis::Builder(time_axis, renderive::Orientation::Horizontal)
@@ -294,14 +294,14 @@ QWidget* Radio_Widget::create_time_power_plot() {
.set_tick_length(-10)
.set_sub_tick_length(-5)
.build();
audio = renderive::Audio_Frequency::Builder(data, x_axis, y_axis)
audio = renderive::Frequency_Trace::Builder(data, x_axis, y_axis)
.build();
msr = renderive::Multi_Select_Rect::Builder(overlay, x_axis, y_axis).build();
msr = renderive::Selection_Rectangle_Overlay::Builder(overlay, x_axis, y_axis).build();
}
protected:
void resizeEvent(QResizeEvent* event) override {
apply_radio_plot_layout(x_axis.get(), y_axis.get(), width(), height());
x_axis->set_time_point_size(x_axis->get_pixel_point_size());
x_axis->set_time_point_size(x_axis->pixel_sample_count());
}
void contextMenuEvent(QContextMenuEvent* event) override {
if (!menu) {
+1 -1
View File
@@ -28,7 +28,7 @@ public:
QWidget* create_water_fall_plot();
std::shared_ptr<renderive::Spectrum> spectrogram_line{};
std::shared_ptr<renderive::Spectrum> audio_spectrogram_plot{};
std::shared_ptr<renderive::Audio_Frequency> time_power{};
std::shared_ptr<renderive::Frequency_Trace> time_power{};
std::shared_ptr<renderive::Waterfall> water_fall{};
protected:
void focusInEvent(QFocusEvent *event) override;
+14 -14
View File
@@ -9,22 +9,22 @@
#include "../component/ShowTime.h"
#include "../Global.h"
#include "../menu/BaseWidgetMenu.h"
#include "Demo_Gallery/base/export.h"
#include "module/radio/Tool.h"
QWidget* Sweep_Frequency_Widget::create_spectrogram_power_plot() {
class Sweep_Frequent_Plot : public renderive::Latency_Eager_Plot {
class Sweep_Frequency_Plot : public renderive::Latency_Eager_Plot {
public:
std::shared_ptr<renderive::Axis> x_axis{};
std::shared_ptr<renderive::Axis> y_axis{};
std::shared_ptr<renderive::Multi_Select_Rect> msr{};
std::shared_ptr<renderive::Sweep_Frequency> sf{};
std::shared_ptr<renderive::Selection_Rectangle_Overlay> msr{};
std::shared_ptr<renderive::Sweep_Spectrum> sf{};
QMenu* menu{};
void init() override {
Latency_Eager_Plot::init();
object_name = "Axis_Test_Plot";
auto data = create_renderable_node(get_root_renderable(), "Data_Renderable");
auto x_axis_cache = create_renderable_node(get_root_renderable(), "X_Axis_Cache");
auto y_axis_cache = create_renderable_node(get_root_renderable(), "Y_Axis_Cache");
auto overlay = create_renderable_node(get_root_renderable(), "Overlay_Renderable");
auto data = create_renderable_node(root_renderable(), "Data_Renderable");
auto x_axis_cache = create_renderable_node(root_renderable(), "X_Axis_Cache");
auto y_axis_cache = create_renderable_node(root_renderable(), "Y_Axis_Cache");
auto overlay = create_renderable_node(root_renderable(), "Overlay_Renderable");
x_axis_cache->set_cache_mode(renderive::Renderable_Cache_Mode::Local_Pixel);
y_axis_cache->set_cache_mode(renderive::Renderable_Cache_Mode::Local_Pixel);
x_axis = renderive::Axis::Builder(x_axis_cache, renderive::Orientation::Horizontal)
@@ -33,21 +33,21 @@ QWidget* Sweep_Frequency_Widget::create_spectrogram_power_plot() {
y_axis = renderive::Axis::Builder(y_axis_cache, renderive::Orientation::Vertical)
.set_coord_range({100, 0})
.set_tick_length(-10).build();
sf = renderive::Sweep_Frequency::Builder(data, x_axis, y_axis)
sf = renderive::Sweep_Spectrum::Builder(data, x_axis, y_axis)
.set_block_num(200)
.set_block_frequency_point_size(20)
.set_bins_per_block(20)
.set_frequency_range({0, 100})
.build();
msr = renderive::Multi_Select_Rect::Builder(overlay, x_axis, y_axis).build();
msr = renderive::Selection_Rectangle_Overlay::Builder(overlay, x_axis, y_axis).build();
}
protected:
void resizeEvent(QResizeEvent* event) override {
x_axis->set_x(0);
x_axis->set_y(height() - 1);
x_axis->set_pixel_size(width());
x_axis->set_pixel_length(width());
y_axis->set_x(0);
y_axis->set_y(0);
y_axis->set_pixel_size(height());
y_axis->set_pixel_length(height());
}
void contextMenuEvent(QContextMenuEvent* event) override {
if (!menu) {
@@ -61,7 +61,7 @@ QWidget* Sweep_Frequency_Widget::create_spectrogram_power_plot() {
menu->exec(event->globalPos());
}
};
auto w = new Sweep_Frequent_Plot;
auto w = new Sweep_Frequency_Plot;
w->init();
sweep_frequency_line = w->sf;
return w;
+1 -1
View File
@@ -23,7 +23,7 @@ public:
Frequent_Shower *select_value_widget;
Progress_Bar *progress_bar1, *progress_bar2;
void init_menu();
std::shared_ptr<renderive::Sweep_Frequency> sweep_frequency_line{};
std::shared_ptr<renderive::Sweep_Spectrum> sweep_frequency_line{};
QWidget* create_spectrogram_power_plot();
protected:
void focusInEvent(QFocusEvent *event) override;
+761
View File
@@ -0,0 +1,761 @@
#pragma once
#include <algorithm>
#include <QApplication>
#include <QColorDialog>
#include <QComboBox>
#include <QDebug>
#include <QFontMetrics>
#include <QHBoxLayout>
#include <QLabel>
#include <QLineEdit>
#include <QMenu>
#include <QPushButton>
#include <QRandomGenerator>
#include <QScrollArea>
#include <QWidgetAction>
namespace renderive {
static Time_Of_Day current_time_of_day() {
return renderive::qt_to_time_of_day(QTime::currentTime());
}
static QColor get_color(int lowest, int highest) {
int r = QRandomGenerator::global()->bounded(lowest, highest);
int g = QRandomGenerator::global()->bounded(lowest, highest);
int b = QRandomGenerator::global()->bounded(lowest, highest);
return {r, g, b};
}
static QString get_background_style_sheet() {
QString color = QString("background-color: %1;").arg(get_color(176, 256).name());
return color;
}
static QString get_button_style_sheet() {
QString color = QString("background-color: %1; color: #000000;").arg(get_color(200, 256).name());
return color;
}
template <typename T>
QString get_init_value(const T& value) {
return QString::number(value);
}
template <>
inline QString get_init_value<QString>(const QString& value) {
return value;
}
template <typename T>
T get_value_from_string(const QString& value) {
return value.toDouble();
}
template <>
inline QString get_value_from_string<QString>(const QString& value) {
return value;
}
template <typename T>
static QWidget* create_edit_widget_list(const QString& button_text,
const std::function<void(const std::vector<T>&)>& click, const std::vector<T>& init_values) {
auto container = new QWidget;
auto layout = new QHBoxLayout(container);
layout->setAlignment(Qt::AlignLeft);
layout->setContentsMargins(0, 0, 0, 0);
auto confirm = new QPushButton(button_text);
// QApplication* app = (QApplication*)QApplication::instance();
// qDebug() << "Global StyleSheet:" << app->styleSheet();
confirm->setStyleSheet(get_button_style_sheet());
// 清除 QSS
QFont font;
font.setFamily("Segoe UI");
confirm->setFont(font);
confirm->setMinimumWidth(QFontMetrics(confirm->font()).horizontalAdvance(button_text) + 8);
confirm->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Preferred);
layout->addWidget(confirm);
std::vector<QLineEdit*> lineEditList;
for (const T& init_value : init_values) {
QString init_value_str = get_init_value<T>(init_value);
auto cur_edit = new QLineEdit(init_value_str);
cur_edit->setStyleSheet(get_button_style_sheet());
// cur_edit->setMaximumWidth(50);
auto fm = QFontMetrics(QFont());
int width = fm.horizontalAdvance(init_value_str);
// cur_edit->setSizePolicy(QSizePolicy::MinimumExpanding, QSizePolicy::Preferred);
cur_edit->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Preferred);
int w = qMax((int)((double)width * 1.4) + 16, 50);
cur_edit->setMinimumWidth(w);
lineEditList.push_back(cur_edit);
layout->addWidget(cur_edit);
}
QObject::connect(confirm, &QPushButton::clicked, [lineEditList, click]() {
std::vector<T> values;
for (QLineEdit* line_edit : lineEditList) {
values.push_back(get_value_from_string<T>(line_edit->text()));
}
click(values);
});
return container;
}
template <typename T>
static QWidget* create_edit_widget(const QString& button_text,
const std::function<void(const T&)>& click, const T& init_values) {
return create_edit_widget_list<T>(button_text, [click](const std::vector<T>& data) {
click(data.front());
}, std::vector<T>{init_values});
}
static QWidget* create_range(Axis* axis, const QString& text = "更改轴范围") {
return create_edit_widget_list<double>(text, [axis](const std::vector<double>& values) {
axis->set_coord_range(Range{values[0], values[1]});
},
{axis->coord_range().origin, axis->coord_range().target});
}
static QMenu* find_parent_menu(QWidget* widget) {
// 从当前窗口开始,逐步检查父窗口
QWidget* parent = widget->parentWidget();
while (parent) {
if (QMenu* menu = qobject_cast<QMenu*>(parent)) {
return menu; // 找到第一个 QMenu 类型的父窗口
}
parent = parent->parentWidget();
}
return nullptr; // 如果没有找到 QMenu 类型的父窗口
}
static QWidget* create_select_color(const QString& text, const std::function<void(QColor)>& click, const QColor& color = QColor()) {
auto ret = new QWidget;
auto l = new QHBoxLayout(ret);
l->setContentsMargins(0, 0, 0, 0);
// l->setSpacing(0);
QString bs = get_button_style_sheet();
auto show_color = new QWidget;
show_color->setStyleSheet(QString("background-color: %1; border: 2px solid #000000;").arg(color.name(QColor::HexArgb)));
show_color->setFixedWidth(30);
static QPushButton* btn = nullptr;
// static auto dialog = new CustomColorDialog(Qt::white, QApplication::activeWindow());
static auto dialog = new Select_Color_Dialog;
dialog->resize(800, 600);
// dialog->adjustSize();
auto label = new QLineEdit(color.isValid() ? color.name(QColor::HexArgb) : "无效");
label->setAlignment(Qt::AlignCenter);
label->setStyleSheet("background-color: #ffffff; color: #000000;");
// label->setAlignment(Qt::AlignRight | Qt::AlignVCenter);
auto button = new QPushButton(text);
button->setStyleSheet(bs);
QObject::connect(button, &QPushButton::clicked, [button, label]() {
btn = button;
dialog->set_current_color(QColor(label->text()));
dialog->show();
});
QObject::connect(dialog, &QDialog::finished, [ret, button, click, label, show_color](int result) {
if (btn != button)
return;
if (result == QDialog::Accepted) {
QColor select_color = dialog->current_color();
click(select_color);
label->setText(select_color.name(QColor::HexArgb));
show_color->setStyleSheet(QString("background-color: %1; border: 2px solid #000000;")
.arg(select_color.name(QColor::HexArgb)));
}
else if (result == -1) {
click(QColor());
label->setText("无颜色");
show_color->setStyleSheet(QString("background-color: rgba(255, 255, 255, 0); border: 2px solid #000000;"));
}
QMenu* menu = find_parent_menu(ret);
if (menu) {
menu->show();
}
});
l->addWidget(button);
l->addWidget(label);
l->addWidget(show_color);
return ret;
}
static QPushButton* create_button(const QString& text, const std::function<void(void)>& click) {
auto button = new QPushButton(text);
button->setStyleSheet(get_button_style_sheet());
QObject::connect(button, &QPushButton::clicked, [click]() {
click();
});
return button;
}
static QPushButton* create_toggle_button(const QString& text, const QString& text2, const std::function<void()>& click, bool first_state) {
auto button = new QPushButton(first_state ? text : text2);
button->setStyleSheet(get_button_style_sheet());
QObject::connect(button, &QPushButton::clicked, [button, click, text, text2]() {
click();
if (button->text() == text2) {
button->setText(text);
}
else {
button->setText(text2);
}
});
return button;
}
static QLabel* create_label(const QString& text, int h = 50, const QColor& color = Qt::black) {
auto l = new QLabel(text);
QFont font;
font.setFamily("Segoe UI");
font.setBold(true);
l->setFont(font);
l->setFixedHeight(h);
l->setAlignment(Qt::AlignHCenter | Qt::AlignBottom);
l->setStyleSheet(QString("color: %1;").arg(color.name(QColor::HexArgb)));
return l;
}
} // namespace renderive
template <typename... Vectors>
static std::vector<QWidget*> concat_widgets(const Vectors&... vectors) {
std::vector<QWidget*> result;
result.reserve((vectors.size() + ... + 0));
(result.insert(result.end(), vectors.begin(), vectors.end()), ...);
return result;
}
static std::vector<QWidget*> bw(const std::vector<QWidget*>& widgets, const QString& name) {
if (widgets.empty())
return {};
auto ret = new QWidget;
ret->setStyleSheet(renderive::get_background_style_sheet());
auto l = new QVBoxLayout(ret);
auto label = new QLabel(name);
label->setAlignment(Qt::AlignHCenter | Qt::AlignVCenter);
QFontMetrics fm(label->font());
label->setFixedSize(fm.horizontalAdvance(name) + 16, fm.height() + 8);
label->setStyleSheet(QString("color: %1; background-color: %2; padding: 0px; margin: 0px;")
.arg(
QColor(Qt::white).name(QColor::HexArgb),
QColor(Qt::black).name(QColor::HexArgb)));
l->addWidget(label, 0, Qt::AlignHCenter | Qt::AlignBottom);
for (QWidget* w : widgets) {
l->addWidget(w);
}
return {ret};
}
template <typename T>
static QWidget* create_line_interpolation_combo(T* renderable) {
auto container = new QWidget;
auto layout = new QHBoxLayout(container);
layout->setContentsMargins(0, 0, 0, 0);
auto label = new QLabel("线图插值");
auto combo = new QComboBox;
label->setStyleSheet(renderive::get_button_style_sheet());
combo->setStyleSheet(renderive::get_button_style_sheet());
combo->addItem("Nearest_Bin", static_cast<int>(renderive::Line_Interpolation_Mode::Nearest_Sample));
combo->addItem("Linear_Display", static_cast<int>(renderive::Line_Interpolation_Mode::Linear_Value));
combo->addItem("Linear_Power", static_cast<int>(renderive::Line_Interpolation_Mode::Linear_Power_Domain));
combo->addItem("Step_Left", static_cast<int>(renderive::Line_Interpolation_Mode::Step_Left));
combo->addItem("Step_Right", static_cast<int>(renderive::Line_Interpolation_Mode::Step_Right));
combo->addItem("Cubic_Display", static_cast<int>(renderive::Line_Interpolation_Mode::Cubic_Value));
combo->setCurrentIndex(combo->findData(static_cast<int>(renderable->interpolation_mode())));
QObject::connect(combo, QOverload<int>::of(&QComboBox::currentIndexChanged), [renderable, combo](int index) {
renderable->set_interpolation_mode(static_cast<renderive::Line_Interpolation_Mode>(combo->itemData(index).toInt()));
});
layout->addWidget(label);
layout->addWidget(combo);
return container;
}
static QWidget* create_image_interpolation_combo(renderive::Waterfall* waterfall) {
auto container = new QWidget;
auto layout = new QHBoxLayout(container);
layout->setContentsMargins(0, 0, 0, 0);
auto label = new QLabel("二维插值");
auto combo = new QComboBox;
label->setStyleSheet(renderive::get_button_style_sheet());
combo->setStyleSheet(renderive::get_button_style_sheet());
combo->addItem("Nearest", static_cast<int>(renderive::Image_Interpolation_Mode::Nearest));
combo->addItem("Bilinear", static_cast<int>(renderive::Image_Interpolation_Mode::Bilinear));
combo->addItem("Bicubic", static_cast<int>(renderive::Image_Interpolation_Mode::Bicubic));
combo->setCurrentIndex(combo->findData(static_cast<int>(waterfall->interpolation_mode())));
QObject::connect(combo, QOverload<int>::of(&QComboBox::currentIndexChanged), [waterfall, combo](int index) {
waterfall->set_interpolation_mode(static_cast<renderive::Image_Interpolation_Mode>(combo->itemData(index).toInt()));
});
layout->addWidget(label);
layout->addWidget(combo);
return container;
}
static QWidget* create_control(renderive::Abs_Plot* plot, const std::vector<QWidget*>& widgets = {}) {
auto control = new QWidget;
auto l = new QVBoxLayout(control);
l->setAlignment(Qt::AlignTop);
l->setContentsMargins({0, 0, 0, 0});
l->setSpacing(0);
auto* core = renderive::plot_core(plot);
std::vector<QWidget*> ws = {
renderive::create_toggle_button("暂停渲染", "开始渲染", [plot]() {
plot->is_rendering() ? plot->pause_render() : plot->start_render();
}, plot->is_rendering()),
renderive::create_toggle_button("停止性能测试", "启动性能测试", [plot]() {
if (auto* current_core = renderive::plot_core(plot))
renderive::set_performance_overlay_enabled(*current_core, !renderive::performance_overlay_enabled(*current_core));
}, core ? renderive::performance_overlay_enabled(*core) : false),
renderive::create_select_color("更改背景色", [plot](const QColor& color) {
plot->set_background_color(color);
}, plot->background_color()),
};
if (auto latency_plot = dynamic_cast<renderive::Latency_Eager_Plot*>(plot)) {
ws.push_back(renderive::create_edit_widget_list<double>("最大渲染FPS", [latency_plot](std::vector<double> data) {
latency_plot->set_max_render_fps(data[0]);
}, {latency_plot->max_render_fps()}));
}
for (QWidget* cur : concat_widgets(bw(ws, "plot基础"), widgets)) {
l->addWidget(cur);
}
return control;
}
static std::vector<QWidget*> cw(renderive::Abs_Axis* it) {
if (it == nullptr)
return {};
auto t = std::vector<QWidget*>{
renderive::create_button("反转轴整体方向", [it]() {
it->set_orientation(it->orientation() == renderive::Orientation::Horizontal ? renderive::Orientation::Vertical : renderive::Orientation::Horizontal);
}),
renderive::create_edit_widget_list<int>("主刻度值", [it](const std::vector<int>& values) {
it->set_tick_length(values[0]);
},
{it->tick_length()}),
renderive::create_edit_widget_list<int>("子刻度值", [it](const std::vector<int>& values) {
it->set_sub_tick_length(values[0]);
},
{it->sub_tick_length()}),
renderive::create_select_color("更改轴颜色", [it](const QColor& color) {
it->set_color(renderive::qt_to_color(color));
}, renderive::to_qcolor(it->color())),
renderive::create_edit_widget_list<QString>("设置单位", [it](const std::vector<QString>& values) {
it->set_unit_text(renderive::qt_to_string(values[0]));
}, {renderive::to_qstring(it->unit_text())}),
renderive::create_select_color("更改UnitText颜色", [it](const QColor& color) {
it->set_unit_text_pen(renderive::qt_to_pen(color));
}, renderive::to_qcolor(it->unit_text_pen().color)),
renderive::create_select_color("更改UnitText背景色", [it](const QColor& color) {
it->set_unit_text_background_brush(renderive::qt_to_brush(color));
}, renderive::to_qcolor(it->unit_text_background_brush().color)),
renderive::create_edit_widget_list<int>("更改刻度斜度", [it](const std::vector<int>& values) {
it->set_label_rotation_degrees(values[0]);
}, {it->label_rotation_degrees()}),
};
return t;
}
static std::vector<QWidget*> cw(renderive::Axis* it) {
if (it == nullptr)
return {};
auto t = std::vector<QWidget*>{
renderive::create_range(it),
};
return concat_widgets(cw(dynamic_cast<renderive::Abs_Axis*>(it)), t);
}
static std::vector<QWidget*> cw(renderive::Frequency_Axis* it) {
if (it == nullptr)
return {};
auto t = std::vector<QWidget*>{};
return concat_widgets(cw(dynamic_cast<renderive::Axis*>(it)), t);
}
static std::vector<QWidget*> cw(renderive::Time_Axis* it, int num_pre_second = -1) {
if (it == nullptr)
return {};
auto t = std::vector<QWidget*>{
renderive::create_edit_widget_list<QString>("时间格式", [it](std::vector<QString> data) {
it->set_time_format(renderive::qt_to_string(data[0]));
},
{renderive::to_qstring(it->time_format())}),
renderive::create_edit_widget_list<int>("单位间隔pixel", [it](std::vector<int> data) {
it->set_tick_label_spacing_px(data[0]);
},
{it->tick_label_spacing_px()}),
};
auto timer = new QTimer(QApplication::instance());
if (num_pre_second > 0)
timer->start(static_cast<int>(1000.0 / static_cast<double>(num_pre_second)));
QObject::connect(timer, &QTimer::timeout, [it]() {
it->append_time(renderive::current_time_of_day());
});
t.push_back(renderive::create_edit_widget_list<double>("推数据Timer(次/s", [timer](std::vector<double> data) {
if (data[0] < 0) {
timer->stop();
}
else {
timer->start((int)(1000.0 / data[0]));
}
},
{timer->interval() > 0 ? 1000.0 / timer->interval() : -1}));
std::vector<QWidget*> axis_widgets = cw(dynamic_cast<renderive::Abs_Axis*>(it));
t.insert(t.end(), axis_widgets.begin(), axis_widgets.end());
return t;
}
static std::vector<QWidget*> cw(renderive::Selection_Rectangle_Overlay* it) {
if (it == nullptr)
return {};
auto t = std::vector<QWidget*>{
renderive::create_select_color("更改填充色", [it](const QColor& color) {
it->set_selection_brush(renderive::qt_to_brush(color));
}, renderive::to_qcolor(it->selection_brush().color)),
renderive::create_select_color("更改边框色", [it](const QColor& color) {
qDebug() << " color.isValid() == " << color.isValid();
auto pen = renderive::qt_to_pen(color);
pen.style = renderive::Line_Style::Dash;
it->set_selection_border_pen(pen);
qDebug() << " color.isValid() == " << renderive::to_qcolor(pen.color).isValid();
}, renderive::to_qcolor(it->selection_border_pen().color)),
renderive::create_select_color("更改字色", [it](const QColor& color) {
it->set_label_pen(renderive::qt_to_pen(color));
}, renderive::to_qcolor(it->label_pen().color))
};
return t;
}
template <typename T>
static std::vector<QWidget*> cw(renderive::Hover_Info_Renderable<T>* it) {
if (it == nullptr)
return {};
auto t = std::vector<QWidget*>{
renderive::create_label("悬浮信息"),
renderive::create_toggle_button("启动悬浮信息", "停止悬浮信息", [it]() {
it->set_use_hover_info(!it->hover_tooltip_enabled());
}, !it->hover_tooltip_enabled()),
renderive::create_select_color("设置文字颜色", [it](const QColor& c) {
it->set_tooltip_text_pen(renderive::qt_to_pen(c));
}, renderive::to_qcolor(it->tooltip_text_pen().color)),
renderive::create_select_color("设置背景颜色", [it](const QColor& c) {
it->set_hover_tooltip_background_brush(renderive::qt_to_brush(c));
}, renderive::to_qcolor(it->hover_info_background_brush().color))
};
return t;
}
static std::vector<QWidget*> cw(renderive::Waterfall* it, int num_pre_second = -1) {
if (it == nullptr)
return {};
auto timer = new QTimer(QApplication::instance());
if (num_pre_second > 0)
timer->start(static_cast<int>(1000.0 / static_cast<double>(num_pre_second)));
QObject::connect(timer, &QTimer::timeout, [it]() {
std::vector<double> d = renderive::get_data(it->power_range(), it->frequency_bin_count());
it->append_row(renderive::current_time_of_day(), d);
});
auto t = std::vector<QWidget*>{
renderive::create_toggle_button("关闭可见区裁剪", "开启可见区裁剪", [it]() {
it->set_visible_range_only(!it->visible_range_only());
}, it->visible_range_only()),
create_image_interpolation_combo(it),
renderive::create_edit_widget_list<double>("推数据Timer(次/s", [timer](std::vector<double> data) {
if (data[0] < 0) {
timer->stop();
}
else {
timer->start((int)(1000.0 / data[0]));
}
}, {timer->interval() > 0 ? 1000.0 / timer->interval() : -1}),
};
std::vector<QWidget*> hover_widgets = cw(static_cast<renderive::Hover_Info_Renderable<renderive::Waterfall>*>(it));
t.insert(t.end(), hover_widgets.begin(), hover_widgets.end());
return t;
}
static std::vector<QWidget*> cw(renderive::Frequency_Trace* it, int num_pre_second = -1) {
if (it == nullptr)
return {};
auto timer = new QTimer(QApplication::instance());
if (num_pre_second > 0)
timer->start(static_cast<int>(1000.0 / static_cast<double>(num_pre_second)));
QObject::connect(timer, &QTimer::timeout, [it]() {
it->append_sample(renderive::current_time_of_day(), renderive::get_data({0, 20}));
});
auto t = std::vector<QWidget*>{
renderive::create_edit_widget_list<double>("推数据Timer(次/s", [timer](std::vector<double> data) {
if (data[0] < 0) {
timer->stop();
}
else {
timer->start((int)(1000.0 / data[0]));
}
},
{timer->interval() > 0 ? 1000.0 / timer->interval() : -1}),
};
return t;
}
static std::vector<QWidget*> cw(renderive::Constellation_Diagram* it, int num_pre_second = -1) {
if (it == nullptr)
return {};
auto timer = new QTimer(QApplication::instance());
QObject::connect(timer, &QTimer::timeout, [it]() {
for (int i = 0; i < 10; ++i) {
double x = renderive::get_data(it->i_range());
double y = renderive::get_data(it->q_range());
it->append_point({x, y});
}
});
if (num_pre_second > 0)
timer->start(static_cast<int>(1000.0 / static_cast<double>(num_pre_second)));
auto t = std::vector<QWidget*>{
renderive::create_edit_widget_list<double>("推数据Timer(次/s", [timer](std::vector<double> data) {
if (data[0] < 0) {
timer->stop();
}
else {
timer->start((int)(1000.0 / data[0]));
}
},
{timer->interval() > 0 ? 1000.0 / timer->interval() : -1}),
renderive::create_edit_widget_list<int>("设置持续时间(ms)", [it](std::vector<int> data) {
it->set_point_lifetime_ms(data[0]);
},
{it->point_lifetime_ms()}),
renderive::create_select_color("更改IQ点颜色", [it](const QColor& color) {
it->set_point_color(renderive::qt_to_color(color));
}, renderive::to_qcolor(it->point_color())),
renderive::create_select_color("更改锚点颜色", [it](const QColor& color) {
it->set_anchor_color(renderive::qt_to_color(color));
}, renderive::to_qcolor(it->anchor_color())),
renderive::create_edit_widget_list<double>("I范围", [it](std::vector<double> data) {
it->set_i_range({data[0], data[1]});
}, {it->i_range().origin, it->i_range().target}),
renderive::create_edit_widget_list<double>("Q范围", [it](std::vector<double> data) {
it->set_q_range({data[0], data[1]});
}, {it->q_range().origin, it->q_range().target}),
renderive::create_button("设置到轴中心", [it]() {
it->fit_square_to_axes();
}),
};
return t;
}
static std::vector<QWidget*> cw(renderive::Afterglow* it, int num_pre_second = -1) {
if (it == nullptr)
return {};
static auto create_base_data = [it]() {
renderive::Range r = it->power_range();
std::vector<double> ret(it->frequency_point_size());
ret[0] = get_data(r);
for (int i = 1; i < it->frequency_point_size(); ++i) {
double rate;
if (i % 20 == 0) {
double that = qAbs(ret[i - 1] - r.origin) / r.size() - 0.5;
rate = (1.0 - that) * renderive::get_data({0.8, 1.2});
}
else {
rate = renderive::get_data({0.8, 1.2});
}
ret[i] = std::clamp(ret[i - 1] * rate, r.origin, r.target);
}
return ret;
};
static std::vector<double> base_data = create_base_data();
auto timer = new QTimer(QApplication::instance());
QObject::connect(timer, &QTimer::timeout, [it]() {
renderive::Range r = it->power_range();
int n = base_data.size();
std::vector<double> cur_data(n);
for (int i = 0; i < n; ++i) {
double rate = renderive::get_data({0.8, 1.2});
cur_data[i] = std::clamp(base_data[i] * rate, r.origin, r.target);
}
it->append_spectrum(cur_data);
});
if (num_pre_second > 0)
timer->start(static_cast<int>(1000.0 / static_cast<double>(num_pre_second)));
auto t = std::vector<QWidget*>{
renderive::create_edit_widget_list<double>("推数据Timer(次/s", [timer](std::vector<double> data) {
if (data[0] < 0) {
timer->stop();
}
else {
timer->start((int)(1000.0 / data[0]));
}
},
{timer->interval() > 0 ? 1000.0 / timer->interval() : -1}),
renderive::create_edit_widget_list<double>("频率范围", [it](std::vector<double> data) {
it->set_frequency_range({data[0], data[1]});
},
{it->frequency_range().origin, it->frequency_range().target}),
renderive::create_edit_widget_list<double>("功率概率范围", [it](std::vector<double> data) {
it->set_power_range({data[0], data[1]});
},
{it->power_range().origin, it->power_range().target}),
renderive::create_button("更改基础线", []() {
base_data = create_base_data();
}),
};
return t;
}
static std::vector<QWidget*> cw(renderive::Spectrum* it, int num_pre_second = -1) {
if (it == nullptr)
return {};
auto timer = new QTimer(QApplication::instance());
if (num_pre_second > 0)
timer->start(static_cast<int>(1000.0 / static_cast<double>(num_pre_second)));
QObject::connect(timer, &QTimer::timeout, [it]() {
it->update_samples(renderive::get_data(it->power_axis()->coord_range(), it->frequency_point_size()));
});
auto t = std::vector<QWidget*>{
renderive::create_toggle_button("关闭可见区裁剪", "开启可见区裁剪", [it]() {
it->set_visible_range_only(!it->visible_range_only());
}, it->visible_range_only()),
create_line_interpolation_combo(it),
renderive::create_edit_widget_list<double>("推数据Timer(次/s", [timer](std::vector<double> data) {
if (data[0] < 0) {
timer->stop();
}
else {
timer->start((int)(1000.0 / data[0]));
}
}, {timer->interval() > 0 ? 1000.0 / timer->interval() : -1}),
renderive::create_edit_widget_list<double>("频率范围", [it](std::vector<double> data) {
it->set_frequency_range({data[0], data[1]});
}, {it->frequency_range().origin, it->frequency_range().target}),
renderive::create_edit_widget_list<int>("设置频率点数", [it](std::vector<int> data) {
it->set_frequency_point_size(data[0]);
}, {it->frequency_point_size()}),
renderive::create_label("sweepRect"),
renderive::create_toggle_button("停止sweepRect", "启动sweepRect", [it]() {
it->set_sweep_region_visible(!it->sweep_region_visible());
}, it->sweep_region_visible()),
renderive::create_edit_widget_list<double>("sweepRect 范围", [it](std::vector<double> data) {
if (!it->sweep_region_visible()) it->set_sweep_region_visible(true);
it->set_sweep_frequency_range({data[0], data[1]});
}, {it->sweep_frequency_range().origin, it->sweep_frequency_range().target}),
renderive::create_edit_widget_list<double>("中频", [it](std::vector<double> data) {
if (!it->sweep_region_visible()) it->set_sweep_region_visible(true);
it->set_center_frequency(data[0]);
}, {it->center_frequency()}),
renderive::create_select_color("扫频矩形", [it](const QColor& c) {
it->set_sweep_region_brush(renderive::qt_to_brush(c));
}),
renderive::create_select_color("中频", [it](const QColor& c) {
if (!c.isValid()) {
it->set_middle_frequency_pen(renderive::Pen{.style = renderive::Line_Style::None});
return;
}
it->set_middle_frequency_pen(renderive::qt_to_pen(c));
}, renderive::to_qcolor(it->middle_frequency_pen().color)),
renderive::create_label("marker"),
renderive::create_toggle_button("停止最大值marker", "启动最大值marker", [it]() {
it->set_max_marker_visible(!it->max_marker_visible());
}, it->max_marker_visible()),
renderive::create_toggle_button("停止最小值marker", "启动最小值marker", [it]() {
it->set_use_min_marker(!it->use_min_marker());
}, it->use_min_marker()),
renderive::create_edit_widget_list<double>("添加自定义marker", [it](std::vector<double> data) {
it->add_custom_marker(data[0]);
}, {0}),
renderive::create_edit_widget_list<double>("添加自定义Linemarker", [it](std::vector<double> data) {
it->add_custom_line_marker(data[0]);
}, {0}),
renderive::create_edit_widget_list<double>("删除marker", [it](std::vector<double> data) {
it->remove_custom_marker(data[0]);
}, {0}),
renderive::create_edit_widget_list<double>("清楚所有marker", [it](std::vector<double> data) {
it->clear_custom_markers();
}, {}),
renderive::create_edit_widget_list<int>("选择当前marker", [it](std::vector<int> data) {
it->set_selected_marker_index(data[0]);
}, {0}),
renderive::create_edit_widget_list<double>("选择下一个marker", [it](std::vector<double> data) {
it->select_next_marker();
}, {}),
renderive::create_edit_widget_list<double>("选择上一个marker", [it](std::vector<double> data) {
it->select_previous_marker();
}, {}),
renderive::create_label("当前线"),
renderive::create_select_color("当前线色", [it](const QColor& c) {
if (!c.isValid()) {
it->set_current_pen(renderive::Pen{.style = renderive::Line_Style::None});
return;
}
it->set_current_pen(renderive::qt_to_pen(c));
}, renderive::to_qcolor(it->current_pen().color)),
renderive::create_select_color("当前线填充色", [it](const QColor& c) {
it->set_current_brush(renderive::qt_to_brush(c));
}, renderive::to_qcolor(it->current_brush().color)),
renderive::create_label("最大值线"),
renderive::create_toggle_button("停止最大值线", "启动最大值线", [it]() {
it->set_max_hold_visible(!it->max_hold_visible());
}, it->max_hold_visible()),
renderive::create_select_color("最大值线色", [it](const QColor& c) {
if (!c.isValid()) {
it->set_max_pen(renderive::Pen{.style = renderive::Line_Style::None});
return;
}
it->set_max_pen(renderive::qt_to_pen(c));
}, renderive::to_qcolor(it->max_pen().color)),
renderive::create_select_color("最大值线填充色", [it](const QColor& c) {
it->set_max_brush(renderive::qt_to_brush(c));
}, renderive::to_qcolor(it->max_brush().color)),
renderive::create_label("最小值线"),
renderive::create_toggle_button("停止最小值线", "启动最小值线", [it]() {
it->set_min_hold_visible(!it->min_hold_visible());
}, it->min_hold_visible()),
renderive::create_select_color("最小值线色", [it](const QColor& c) {
it->set_min_pen(renderive::qt_to_pen(c));
}, renderive::to_qcolor(it->min_pen().color)),
renderive::create_select_color("最小值线填充色", [it](const QColor& c) {
it->set_min_brush(renderive::qt_to_brush(c));
}, renderive::to_qcolor(it->min_brush().color)),
};
return concat_widgets(cw(static_cast<renderive::Hover_Info_Renderable<renderive::Spectrum>*>(it)), t);
}
static std::vector<QWidget*> cw(renderive::Sweep_Spectrum* it, int num_pre_second = -1) {
if (it == nullptr)
return {};
auto timer = new QTimer(QApplication::instance());
if (num_pre_second > 0)
timer->start(static_cast<int>(1000.0 / static_cast<double>(num_pre_second)));
QObject::connect(timer, &QTimer::timeout, [it]() {
it->append_block(renderive::get_data(it->power_axis()->coord_range(), it->bins_per_block()));
});
auto t = std::vector<QWidget*>{
renderive::create_toggle_button("关闭可见区裁剪", "开启可见区裁剪", [it]() {
it->set_visible_range_only(!it->visible_range_only());
}, it->visible_range_only()),
create_line_interpolation_combo(it), renderive::create_edit_widget_list<double>("推数据Timer(次/s", [timer](std::vector<double> data) {
if (data[0] < 0) {
timer->stop();
}
else {
timer->start((int)(1000.0 / data[0]));
}
}, {timer->interval() > 0 ? 1000.0 / timer->interval() : -1}),
renderive::create_select_color("线颜色", [it](const QColor& color) {
it->set_pen(renderive::qt_to_pen(color));
}, renderive::to_qcolor(it->pen().color)),
renderive::create_select_color("扫频线颜色", [it](const QColor& color) {
auto p = it->cur_frequency_pen();
p.color = renderive::qt_to_color(color);
it->set_cur_frequency_pen(p);
}, renderive::to_qcolor(it->cur_frequency_pen().color)),
renderive::create_edit_widget_list<double>("频率范围", [it](const std::vector<double>& data) {
it->set_frequency_range({data[0], data[1]});
}, {it->frequency_range().origin, it->frequency_range().target})
};
return t;
}
static QMenu* create_menu(renderive::Abs_Plot* plot, const std::vector<QWidget*>& widgets) {
auto menu = new QMenu(plot);
menu->setObjectName("memu");
// menu->setStyle(nullptr);
menu->hide();
menu->setContentsMargins(0, 0, 0, 0);
auto container = create_control(plot, widgets);
auto scroll_area = new QScrollArea;
scroll_area->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
scroll_area->setContentsMargins(0, 0, 0, 0);
scroll_area->setWidget(container);
scroll_area->setWidgetResizable(true);
scroll_area->setObjectName("scroll_area");
auto scrollAction = new QWidgetAction(menu);
scrollAction->setDefaultWidget(scroll_area);
menu->addAction(scrollAction);
return menu;
}
static QMenu* create_menu_normal(QWidget* w, const std::vector<QWidget*>& widgets) {
auto menu = new QMenu(w);
menu->setObjectName("memu_normal");
// menu->setStyle(nullptr);
menu->hide();
menu->setContentsMargins(0, 0, 0, 0);
auto container = new QWidget;
auto l = new QVBoxLayout(container);
l->setAlignment(Qt::AlignTop);
l->setContentsMargins({0, 0, 0, 0});
l->setSpacing(4);
for (auto widget : widgets) {
l->addWidget(widget);
}
auto scroll_area = new QScrollArea;
scroll_area->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
scroll_area->setContentsMargins(0, 0, 0, 0);
scroll_area->setWidget(container);
scroll_area->setWidgetResizable(true);
scroll_area->setObjectName("scrollArea2");
auto scrollAction = new QWidgetAction(menu);
scrollAction->setDefaultWidget(scroll_area);
menu->addAction(scrollAction);
return menu;
}