195 lines
7.5 KiB
C++
195 lines
7.5 KiB
C++
#pragma once
|
|
#include <cstddef>
|
|
#include <memory_resource>
|
|
#include <span>
|
|
#include <utility>
|
|
#include <vector>
|
|
#include "../architecture/Update_Completion.h"
|
|
#include "../base/Color.h"
|
|
#include "../base/Memory.h"
|
|
#include "../base/Style.h"
|
|
#include "../primitive/Curve.h"
|
|
#include "Hover_Tooltip.h"
|
|
#include "Interpolation.h"
|
|
namespace renderive {
|
|
struct Spectrum_Private;
|
|
class Label;
|
|
class Marker;
|
|
/// @brief 单条频谱线图元,支持可见范围裁剪和多种线插值策略。
|
|
class LIB_DECL Spectrum : public Renderable, public Hover_Tooltip_Mixin<Spectrum> {
|
|
public:
|
|
/// @brief 创建频谱线图元。
|
|
Spectrum();
|
|
/// @brief 绑定频率轴。
|
|
PROP(std::shared_ptr<Frequency_Axis>, frequency_axis)
|
|
/// @brief 绑定功率轴。
|
|
PROP(std::shared_ptr<Axis>, power_axis);
|
|
/// @brief 频率采样点数。
|
|
PROP(int, frequency_point_size);
|
|
/// @brief 频率数据范围。
|
|
PROP(Range, frequency_range);
|
|
/// @brief 中心扫频频率。
|
|
PROP(double, center_frequency);
|
|
/// @brief 扫频高亮频率范围。
|
|
PROP(Range, sweep_frequency_range);
|
|
/// @brief 是否绘制最大保持线。
|
|
PROP(bool, max_hold_visible);
|
|
/// @brief 是否绘制最小保持线。
|
|
PROP(bool, min_hold_visible);
|
|
/// @brief 是否显示最大值标记。
|
|
bool max_marker_visible();
|
|
void set_max_marker_visible(bool);
|
|
/// @brief 是否显示最小值标记。
|
|
PROP(bool, use_min_marker);
|
|
/// @brief 是否显示扫频高亮区域。
|
|
bool sweep_region_visible();
|
|
void set_sweep_region_visible(bool);
|
|
/// @brief 是否只生成当前可见频率范围。
|
|
PROP(bool, visible_range_only);
|
|
/// @brief 折线插值模式。
|
|
PROP(Line_Interpolation_Mode, interpolation_mode);
|
|
/// @brief 采样降采样模式。
|
|
PROP(Line_Sampling_Strategy, sample_mode);
|
|
/// @brief 最大保持线填充刷。
|
|
PROP(Brush, max_brush);
|
|
/// @brief 当前频谱线填充刷。
|
|
Brush current_brush();
|
|
void set_current_brush(Brush);
|
|
/// @brief 最小保持线填充刷。
|
|
PROP(Brush, min_brush);
|
|
/// @brief 最大保持线画笔。
|
|
PROP(Pen, max_pen);
|
|
/// @brief 当前频谱线画笔。
|
|
Pen current_pen();
|
|
void set_current_pen(Pen);
|
|
/// @brief 最小保持线画笔。
|
|
PROP(Pen, min_pen);
|
|
/// @brief 选中标记画笔。
|
|
Pen selected_marker_pen();
|
|
void set_selected_marker_pen(Pen);
|
|
/// @brief 普通标记画笔。
|
|
PROP(Pen, marker_pen);
|
|
/// @brief 中心频率线画笔。
|
|
PROP(Pen, middle_frequency_pen);
|
|
/// @brief 扫频区域填充刷。
|
|
Brush sweep_region_brush();
|
|
void set_sweep_region_brush(Brush);
|
|
/// @brief 写入一帧频谱线数据。
|
|
void update_samples(std::span<const double> line_data);
|
|
/// @brief 移动写入一帧频谱线数据。
|
|
void update_samples(std::pmr::vector<double>&& line_data);
|
|
/// @brief 提交一帧频谱线数据并返回完成票据。
|
|
Update_Ticket submit_data(std::span<const double> line_data);
|
|
/// @brief 移动提交一帧频谱线数据并返回完成票据。
|
|
Update_Ticket submit_data(std::pmr::vector<double>&& line_data);
|
|
/// @brief 用 writer 填充并写入一帧频谱线数据。
|
|
template <typename Writer>
|
|
void write_data(std::size_t count, Writer&& writer) {
|
|
std::pmr::vector<double> values(memory_resource(Memory_Domain::Spectrum));
|
|
values.resize(count);
|
|
std::forward<Writer>(writer)(std::span<double>(values.data(), values.size()));
|
|
update_samples(std::move(values));
|
|
}
|
|
/// 查询指定频率位置的功率值。
|
|
double power_at(double frequency, bool& ok);
|
|
/// 添加自定义频率标记。
|
|
void add_custom_marker(double frequency);
|
|
/// 添加自定义线标记。
|
|
void add_custom_line_marker(double frequency);
|
|
/// 删除指定频率附近的自定义标记。
|
|
void remove_custom_marker(double frequency);
|
|
/// 删除当前选中的标记。
|
|
void remove_selected_marker();
|
|
/// 清空所有自定义标记。
|
|
void clear_custom_markers();
|
|
/// 返回可选择线标记数量。
|
|
int selectable_line_marker_count();
|
|
/// 返回当前选中线标记索引。
|
|
int selected_marker_index();
|
|
/// 设置当前选中线标记索引。
|
|
void set_selected_marker_index(int marker_index);
|
|
/// 选择下一个线标记。
|
|
void select_next_marker();
|
|
/// 取消当前线标记选择。
|
|
void clear_marker_selection();
|
|
/// 选择上一个线标记。
|
|
void select_previous_marker();
|
|
/// 返回指定标记索引对应频率。
|
|
double marker_frequency(int mark_index);
|
|
/// 设置指定标记频率。
|
|
void set_marker_frequency(int marker_index, double frequency);
|
|
/// 设置当前选中标记频率。
|
|
void set_current_marker_frequency(double frequency);
|
|
struct Builder;
|
|
private:
|
|
Spectrum_Private* d();
|
|
Render_Object_Owner create_render_data() override;
|
|
Render_Object_Owner create_render_state() override;
|
|
Render_Object_Owner create_input_data() override;
|
|
};
|
|
struct Spectrum_Prop {
|
|
std::weak_ptr<Frequency_Axis> frequency_axis{};
|
|
std::weak_ptr<Axis> power_axis{};
|
|
int frequency_point_size{};
|
|
Range frequency_range{};
|
|
double center_frequency = 50;
|
|
Range sweep_frequency_range{40, 60};
|
|
bool max_hold_visible = false;
|
|
bool min_hold_visible = false;
|
|
bool max_marker_visible = false;
|
|
bool use_min_marker = false;
|
|
bool sweep_region_visible = false;
|
|
bool visible_range_only = true;
|
|
Line_Interpolation_Mode interpolation_mode = Line_Interpolation_Mode::Linear_Value;
|
|
Line_Sampling_Strategy sampling_strategy = Line_Sampling_Strategy::All_Samples;
|
|
Brush max_brush;
|
|
Brush current_brush;
|
|
Brush min_brush;
|
|
Pen max_pen = Pen{Color::red()};
|
|
Pen cur_pen = Pen{Color::green()};
|
|
Pen min_pen = Pen{Color::white()};
|
|
Pen selected_marker_pen = Pen{Color{0, 0, 139, 255}, 2.0};
|
|
Pen marker_pen = Pen{Color::red()};
|
|
Pen middle_frequency_pen = Pen{Color::red()};
|
|
Brush sweep_region_brush = Brush{Color{255, 255, 0, 100}, Brush_Style::Solid};
|
|
Spectrum_Prop() {
|
|
max_brush = Brush{};
|
|
current_brush = Brush{};
|
|
min_brush = Brush{};
|
|
}
|
|
};
|
|
/// @brief 频谱线构造器。
|
|
struct LIB_DECL Spectrum::Builder : Spectrum_Prop {
|
|
PROP_B(std::shared_ptr<Renderable>, parent)
|
|
PROP_B(std::shared_ptr<Frequency_Axis>, frequency_axis)
|
|
PROP_B(std::shared_ptr<Axis>, power_axis);
|
|
PROP_B(int, frequency_point_size);
|
|
PROP_B(Range, frequency_range);
|
|
PROP_B(double, center_frequency);
|
|
PROP_B(Range, sweep_frequency_range);
|
|
PROP_B(bool, max_hold_visible);
|
|
PROP_B(bool, min_hold_visible);
|
|
PROP_B(bool, max_marker_visible);
|
|
PROP_B(bool, use_min_marker);
|
|
PROP_B(bool, sweep_region_visible);
|
|
PROP_B(bool, visible_range_only);
|
|
PROP_B(Line_Interpolation_Mode, interpolation_mode);
|
|
PROP_B(Line_Sampling_Strategy, sampling_strategy);
|
|
PROP_B(Brush, max_brush);
|
|
PROP_B(Brush, current_brush);
|
|
PROP_B(Brush, min_brush);
|
|
PROP_B(Pen, max_pen);
|
|
PROP_B(Pen, cur_pen);
|
|
PROP_B(Pen, min_pen);
|
|
PROP_B(Pen, selected_marker_pen);
|
|
PROP_B(Pen, marker_pen);
|
|
PROP_B(Pen, middle_frequency_pen);
|
|
PROP_B(Brush, sweep_region_brush);
|
|
/// 创建频谱线构造器。
|
|
Builder(std::shared_ptr<Renderable> parent, std::shared_ptr<Frequency_Axis> frequency_axis, std::shared_ptr<Axis> axis);
|
|
/// 构建并返回频谱线对象。
|
|
std::shared_ptr<Spectrum> build();
|
|
std::shared_ptr<Renderable> parent{};
|
|
};
|
|
} // namespace renderive
|