summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCarl Hetherington <cth@carlh.net>2025-04-18 23:56:56 +0200
committerCarl Hetherington <cth@carlh.net>2025-04-20 21:18:19 +0200
commit34e88d2353cc6976356e011f79dc5177b200941a (patch)
tree98d6031ca977ffa71b489086e0eb45943fad3f43
parent9a4ccc554f5c8784b7b34ccaa0f760b491e5a7ab (diff)
add scales
-rw-r--r--src/wx/simple_meters.cc79
-rw-r--r--src/wx/simple_meters.h3
-rw-r--r--src/wx/text_size_cache.cc47
-rw-r--r--src/wx/text_size_cache.h40
-rw-r--r--src/wx/wscript1
5 files changed, 138 insertions, 32 deletions
diff --git a/src/wx/simple_meters.cc b/src/wx/simple_meters.cc
index 06eabce8b..c4af8c0fe 100644
--- a/src/wx/simple_meters.cc
+++ b/src/wx/simple_meters.cc
@@ -32,9 +32,6 @@ LIBDCP_ENABLE_WARNINGS
#include <algorithm>
-static auto constexpr min_db = -70.0f;
-
-
using std::shared_ptr;
#if BOOST_VERSION >= 106100
using namespace boost::placeholders;
@@ -58,31 +55,34 @@ SimpleMeters::get() const
void
SimpleMeters::paint()
{
+ auto constexpr min_db = -70.0f;
+ auto constexpr border = 16;
+ auto constexpr scale_label_width = 28;
+
wxPaintDC dc(_panel);
dc.SetBackground(*wxBLACK_BRUSH);
dc.Clear();
- if (_peaks.empty()) {
- return;
- }
-
auto const scale = 1 / dpi_scale_factor(_panel);
- dc.SetLogicalScale(scale, scale);
-
auto const panel_size = dcp::Size(_panel->GetSize().GetWidth() / scale, _panel->GetSize().GetHeight() / scale);
+ auto const meter_height = panel_size.height - 24 - 2 * border;
+ dc.SetLogicalScale(scale, scale);
- auto const channel_width = panel_size.width / _peaks.size();
- auto const meter_height = panel_size.height - 24;
-
- int x = 0;
- dc.SetBrush(*wxGREEN_BRUSH);
- for (auto peak: _peaks) {
- auto const peak_db = std::max(min_db, 20 * log10(peak));
- auto const height = (peak_db - min_db) * meter_height / -min_db;
- dc.DrawRectangle(x, meter_height - height, channel_width, height);
- x += channel_width;
- }
+ auto db_to_y = [meter_height](float db) {
+ return border + meter_height - (db - min_db) * meter_height / -min_db;
+ };
+
+ static auto const scales = std::vector<std::pair<int, wxString>>{
+ { 0, wxT("0dB") },
+ { -10, wxT("-10dB") },
+ { -20, wxT("-20dB") },
+ { -30, wxT("-30dB") },
+ { -40, wxT("-40dB") },
+ { -50, wxT("-50dB") },
+ { -60, wxT("-60dB") },
+ { -70, wxT("-70dB") },
+ };
auto gc = wxGraphicsContext::Create(dc);
if (!gc) {
@@ -92,20 +92,37 @@ SimpleMeters::paint()
gc->SetAntialiasMode(wxANTIALIAS_DEFAULT);
gc->SetFont(gc->CreateFont(*wxSMALL_FONT, *wxWHITE));
- if (_label_widths.empty()) {
- _label_widths.resize(MAX_DCP_AUDIO_CHANNELS);
- for (auto i = 0; i < MAX_DCP_AUDIO_CHANNELS; ++i) {
- wxDouble label_width;
- wxDouble label_height;
- wxDouble label_descent;
- wxDouble label_leading;
- gc->GetTextExtent(std_to_wx(short_audio_channel_name(i)), &label_width, &label_height, &label_descent, &label_leading);
- _label_widths[i] = label_width;
- }
+ /* Scale lines and labels (0dB, -10dB etc.) */
+ dc.SetPen(*wxGREY_PEN);
+ for (auto const& scale: scales) {
+ auto const y = static_cast<int>(std::round(db_to_y(scale.first)));
+ dc.DrawLine({ border + scale_label_width, y }, { panel_size.width - border, y });
+ auto const size = _sizes.get(gc, scale.second);
+ gc->DrawText(scale.second, border + scale_label_width - size.width - 4, y - size.height / 2);
+ }
+
+ if (_peaks.empty()) {
+ delete gc;
+ return;
+ }
+
+ auto const channel_width = (panel_size.width - 2 * border - scale_label_width) / _peaks.size();
+
+ /* Meter bars */
+ int x = border + scale_label_width;
+ dc.SetBrush(*wxGREEN_BRUSH);
+ dc.SetPen(*wxBLACK_PEN);
+ for (auto peak: _peaks) {
+ auto const peak_db = std::max(min_db, 20 * log10(peak));
+ auto const y = db_to_y(peak_db);
+ dc.DrawRectangle(x, y, channel_width, meter_height - y + border);
+ x += channel_width;
}
+ /* Channel name labels */
for (auto i = 0; i < MAX_DCP_AUDIO_CHANNELS; ++i) {
- gc->DrawText(std_to_wx(short_audio_channel_name(i)), i * channel_width + (channel_width - _label_widths[i]) / 2, panel_size.height - 24);
+ auto name = std_to_wx(short_audio_channel_name(i));
+ gc->DrawText(name, border + scale_label_width + i * channel_width + (channel_width - _sizes.get(gc, name).width) / 2, panel_size.height - 24);
}
delete gc;
diff --git a/src/wx/simple_meters.h b/src/wx/simple_meters.h
index 779a12b9b..fc96dd8cb 100644
--- a/src/wx/simple_meters.h
+++ b/src/wx/simple_meters.h
@@ -24,6 +24,7 @@
#include "lib/dcpomatic_time.h"
+#include "text_size_cache.h"
#include <memory>
#include <vector>
@@ -57,7 +58,7 @@ private:
std::weak_ptr<LevelCalculator> _level_calculator;
- std::vector<float> _label_widths;
+ TextSizeCache _sizes;
};
diff --git a/src/wx/text_size_cache.cc b/src/wx/text_size_cache.cc
new file mode 100644
index 000000000..03b7e62ff
--- /dev/null
+++ b/src/wx/text_size_cache.cc
@@ -0,0 +1,47 @@
+/*
+ Copyright (C) 2025 Carl Hetherington <cth@carlh.net>
+
+ This file is part of DCP-o-matic.
+
+ DCP-o-matic is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ DCP-o-matic is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with DCP-o-matic. If not, see <http://www.gnu.org/licenses/>.
+
+*/
+
+
+#include "text_size_cache.h"
+LIBDCP_DISABLE_WARNINGS
+#include <wx/graphics.h>
+LIBDCP_ENABLE_WARNINGS
+#include <wx/wx.h>
+
+
+dcp::Size
+TextSizeCache::get(wxGraphicsContext* gc, wxString const& text)
+{
+ auto iter = _known.find(text);
+ if (iter != _known.end()) {
+ return iter->second;
+ }
+
+ wxDouble width;
+ wxDouble height;
+ wxDouble descent;
+ wxDouble leading;
+ gc->GetTextExtent(text, &width, &height, &descent, &leading);
+ auto size = dcp::Size{static_cast<int>(std::round(width)), static_cast<int>(std::round(height))};
+ _known[text] = size;
+
+ return size;
+}
+
diff --git a/src/wx/text_size_cache.h b/src/wx/text_size_cache.h
new file mode 100644
index 000000000..58fb9c82a
--- /dev/null
+++ b/src/wx/text_size_cache.h
@@ -0,0 +1,40 @@
+/*
+ Copyright (C) 2025 Carl Hetherington <cth@carlh.net>
+
+ This file is part of DCP-o-matic.
+
+ DCP-o-matic is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ DCP-o-matic is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with DCP-o-matic. If not, see <http://www.gnu.org/licenses/>.
+
+*/
+
+
+#include <dcp/types.h>
+#include <wx/wx.h>
+#include <unordered_map>
+
+
+class wxGraphicsContext;
+class wxString;
+
+
+class TextSizeCache
+{
+public:
+ TextSizeCache() = default;
+
+ dcp::Size get(wxGraphicsContext* gc, wxString const& text);
+
+private:
+ std::unordered_map<wxString, dcp::Size> _known;
+};
diff --git a/src/wx/wscript b/src/wx/wscript
index 9a9a79d9c..a2939adb1 100644
--- a/src/wx/wscript
+++ b/src/wx/wscript
@@ -176,6 +176,7 @@ sources = """
tall_kdm_output_panel.cc
templates_dialog.cc
text_panel.cc
+ text_size_cache.cc
text_view.cc
time_picker.cc
timer_display.cc