#pragma once #include #include #include #include #include #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 { public: /// @brief 创建频谱线图元。 Spectrum(); /// @brief 绑定频率轴。 PROP(std::shared_ptr, frequency_axis) /// @brief 绑定功率轴。 PROP(std::shared_ptr, 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 line_data); /// @brief 移动写入一帧频谱线数据。 void update_samples(std::pmr::vector&& line_data); /// @brief 提交一帧频谱线数据并返回完成票据。 Update_Ticket submit_data(std::span line_data); /// @brief 移动提交一帧频谱线数据并返回完成票据。 Update_Ticket submit_data(std::pmr::vector&& line_data); /// @brief 用 writer 填充并写入一帧频谱线数据。 template void write_data(std::size_t count, Writer&& writer) { std::pmr::vector values(memory_resource(Memory_Domain::Spectrum)); values.resize(count); std::forward(writer)(std::span(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{}; std::weak_ptr 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, parent) PROP_B(std::shared_ptr, frequency_axis) PROP_B(std::shared_ptr, 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 parent, std::shared_ptr frequency_axis, std::shared_ptr axis); /// 构建并返回频谱线对象。 std::shared_ptr build(); std::shared_ptr parent{}; }; } // namespace renderive