优化volume_bar效果
This commit is contained in:
parent
fa0b169dde
commit
080d0986f5
@ -120,12 +120,9 @@ void draw_mixer_track(uint32_t delta_sample_count, mixer_track* track, int32_t i
|
||||
});
|
||||
sample_t peak = std::abs(*peak_it);
|
||||
|
||||
float peak_db = sample_to_db(peak);
|
||||
float peak_db_percent = db_to_percent(peak_db);
|
||||
|
||||
// update peak
|
||||
if (peak_db_percent > peak_info.peak) {
|
||||
peak_info.peak = peak_db_percent;
|
||||
if (peak > peak_info.peak) {
|
||||
peak_info.peak = peak;
|
||||
peak_info.left_time = volume_bar_peak_duration;
|
||||
} else {
|
||||
peak_info.left_time -= delta_time;
|
||||
@ -135,7 +132,7 @@ void draw_mixer_track(uint32_t delta_sample_count, mixer_track* track, int32_t i
|
||||
}
|
||||
}
|
||||
|
||||
sample_value.push_back(peak_db_percent);
|
||||
sample_value.push_back(peak);
|
||||
sample_peak.push_back(peak_info.peak);
|
||||
}
|
||||
draw_volume_bar(volume_bar_id.c_str(), widget_height, sample_value, sample_peak);
|
||||
@ -152,8 +149,6 @@ void draw_mixer_track(uint32_t delta_sample_count, mixer_track* track, int32_t i
|
||||
}
|
||||
|
||||
void draw_volume_bar(const char* id, float height, std::vector<float> sample_value, std::vector<float> sample_peak) {
|
||||
// draw a 2d box
|
||||
// calculate the size
|
||||
#if BUILD_DEBUG
|
||||
if (sample_value.size() != sample_peak.size()) {
|
||||
spdlog::error("sample_value size is not equal to sample_peak size");
|
||||
@ -164,7 +159,7 @@ void draw_volume_bar(const char* id, float height, std::vector<float> sample_val
|
||||
|
||||
const ImGuiStyle& style = ImGui::GetStyle();
|
||||
int32_t channel_count = sample_value.size();
|
||||
float channel_width = 6.0f;
|
||||
float channel_width = 9.0f;
|
||||
float widget_width = channel_width * channel_count;
|
||||
float widget_height = height; // TODO: calculate the height
|
||||
ImVec2 size_arg = ImVec2(widget_width, widget_height);
|
||||
@ -186,38 +181,44 @@ void draw_volume_bar(const char* id, float height, std::vector<float> sample_val
|
||||
const ImColor safe_color = ImColor(0, 255, 0, 255); // green
|
||||
const ImColor warning_color = ImColor(255, 255, 0, 255); // yellow
|
||||
const ImColor danger_color = ImColor(255, 0, 0, 255); // red
|
||||
const ImColor bar_split_color = ImColor(0, 0, 0, 255); // white
|
||||
const ImColor boarder_color = ImColor(0, 140, 120, 255); // black
|
||||
|
||||
window->DrawList->PushClipRect(bb.Min, bb.Max, true);
|
||||
ImVec2 temp_pos = pos;
|
||||
// 坐标系原点在左上角
|
||||
for (int32_t i = 0; i < channel_count; ++i) {
|
||||
float value = sample_value.at(i);
|
||||
float peak = sample_peak.at(i);
|
||||
float value_db = sample_to_db(sample_value.at(i));
|
||||
float value = db_to_percent(value_db);
|
||||
|
||||
float peak_db = sample_to_db(sample_peak.at(i));
|
||||
float peak = db_to_percent(peak_db);
|
||||
|
||||
// 绘制矩形(60%以下的部分绘制绿色,80%以下的部分绘制黄色,100%以下的部分绘制红色)
|
||||
if (value > volume_bar_inf) {
|
||||
ImVec2 clip_bar_start = ImVec2(pos.x, pos.y + widget_height * (1.0f - value));
|
||||
ImVec2 clip_bar_end = ImVec2(pos.x + channel_width, pos.y + widget_height);
|
||||
ImVec2 clip_bar_start = ImVec2(temp_pos.x, temp_pos.y + widget_height * (1.0f - value));
|
||||
ImVec2 clip_bar_end = ImVec2(temp_pos.x + channel_width, temp_pos.y + widget_height);
|
||||
ImRect bar_rect(clip_bar_start, clip_bar_end);
|
||||
window->DrawList->PushClipRect(bar_rect.Min, bar_rect.Max, true);
|
||||
// 绘制100%的部分
|
||||
{
|
||||
float bar_height = widget_height * danger_level;
|
||||
ImVec2 bar_start = ImVec2(pos.x, pos.y + widget_height - bar_height);
|
||||
ImVec2 bar_end = ImVec2(pos.x + channel_width, pos.y + widget_height);
|
||||
ImVec2 bar_start = ImVec2(temp_pos.x, temp_pos.y + widget_height - bar_height);
|
||||
ImVec2 bar_end = ImVec2(temp_pos.x + channel_width, temp_pos.y + widget_height);
|
||||
window->DrawList->AddRectFilled(bar_start, bar_end, danger_color);
|
||||
}
|
||||
// 绘制80%的部分
|
||||
{
|
||||
float bar_height = widget_height * warning_level;
|
||||
ImVec2 bar_start = ImVec2(pos.x, pos.y + widget_height - bar_height);
|
||||
ImVec2 bar_end = ImVec2(pos.x + channel_width, pos.y + widget_height);
|
||||
ImVec2 bar_start = ImVec2(temp_pos.x, temp_pos.y + widget_height - bar_height);
|
||||
ImVec2 bar_end = ImVec2(temp_pos.x + channel_width, temp_pos.y + widget_height);
|
||||
window->DrawList->AddRectFilled(bar_start, bar_end, warning_color);
|
||||
}
|
||||
// 绘制60%以下的部分
|
||||
{
|
||||
float bar_height = widget_height * safe_level;
|
||||
ImVec2 bar_start = ImVec2(pos.x, pos.y + widget_height - bar_height);
|
||||
ImVec2 bar_end = ImVec2(pos.x + channel_width, pos.y + widget_height);
|
||||
ImVec2 bar_start = ImVec2(temp_pos.x, temp_pos.y + widget_height - bar_height);
|
||||
ImVec2 bar_end = ImVec2(temp_pos.x + channel_width, temp_pos.y + widget_height);
|
||||
window->DrawList->AddRectFilled(bar_start, bar_end, safe_color);
|
||||
}
|
||||
window->DrawList->PopClipRect();
|
||||
@ -226,20 +227,27 @@ void draw_volume_bar(const char* id, float height, std::vector<float> sample_val
|
||||
// 绘制Peak
|
||||
if (peak > volume_bar_inf) {
|
||||
const ImColor peak_color = peak <= safe_level ? safe_color : peak <= warning_level ? warning_color : danger_color;
|
||||
float peak_height = pos.y + widget_height * (1 - peak);
|
||||
ImVec2 peak_start = ImVec2(pos.x, peak_height);
|
||||
ImVec2 peak_end = ImVec2(pos.x + channel_width, peak_height + 1);
|
||||
float peak_height = temp_pos.y + widget_height * (1 - peak);
|
||||
ImVec2 peak_start = ImVec2(temp_pos.x, peak_height);
|
||||
ImVec2 peak_end = ImVec2(temp_pos.x + channel_width, peak_height + 1);
|
||||
window->DrawList->AddRectFilled(peak_start, peak_end, peak_color);
|
||||
}
|
||||
|
||||
// 绘制垂直分割线
|
||||
if (i != channel_count - 1) {
|
||||
ImVec2 line_start = ImVec2(pos.x + channel_width, pos.y);
|
||||
ImVec2 line_end = ImVec2(pos.x + channel_width, pos.y + widget_height);
|
||||
window->DrawList->AddLine(line_start, line_end, ImGui::GetColorU32(ImGuiCol_Header));
|
||||
}
|
||||
|
||||
pos.x += channel_width;
|
||||
temp_pos.x += channel_width;
|
||||
}
|
||||
temp_pos = pos;
|
||||
|
||||
// 绘制垂直分割线
|
||||
for (int32_t i = 0; i < channel_count; ++i) {
|
||||
if (i != channel_count - 1) {
|
||||
ImVec2 line_start = ImVec2(temp_pos.x + channel_width - 0.5f, temp_pos.y);
|
||||
ImVec2 line_end = ImVec2(temp_pos.x + channel_width - 0.5f, temp_pos.y + widget_height);
|
||||
window->DrawList->AddLine(line_start, line_end, bar_split_color);
|
||||
}
|
||||
}
|
||||
|
||||
// 绘制边框
|
||||
window->DrawList->AddRect(bb.Min, bb.Max, boarder_color);
|
||||
|
||||
window->DrawList->PopClipRect();
|
||||
}
|
||||
|
@ -22,6 +22,6 @@ void draw_mixer();
|
||||
void draw_mixer_track(uint32_t delta_sample_count, mixer_track* track, int32_t index);
|
||||
void draw_volume_bar(const char* id, float height, std::vector<float> sample_value, std::vector<float> sample_peak);
|
||||
|
||||
inline float volume_bar_peak_duration = 0.5f;
|
||||
inline float volume_bar_peak_decay = 0.1f;
|
||||
inline float volume_bar_peak_duration = 1.0f;
|
||||
inline float volume_bar_peak_decay = 0.2f;
|
||||
inline constexpr float volume_bar_inf = 0.0001f;
|
||||
|
Loading…
x
Reference in New Issue
Block a user