From: Steinar H. Gunderson Date: Mon, 17 Feb 2020 22:13:29 +0000 (+0100) Subject: In Futatabi, make it possible to set custom source labels. X-Git-Tag: 1.9.2~28 X-Git-Url: https://git.sesse.net/?p=nageru;a=commitdiff_plain;h=04738b0cecf5f7b6d988822c1d7595fdd52a496e In Futatabi, make it possible to set custom source labels. An operator was consistently confused by having 3 on a left camera and 4 on a right camera, and wanted L3 and R4 labels, so here goes :-) There's no auto-import from Nageru at this point; it needs to be set using --source-label NUM:LABEL (or -l NUM:LABEL) from the command line. --- diff --git a/futatabi/flags.cpp b/futatabi/flags.cpp index fa1fe6e..a8ae958 100644 --- a/futatabi/flags.cpp +++ b/futatabi/flags.cpp @@ -44,6 +44,7 @@ void usage() fprintf(stderr, " --http-port PORT which port to listen on for output\n"); fprintf(stderr, " --tally-url URL URL to get tally color from (polled every 100 ms)\n"); fprintf(stderr, " --midi-mapping=FILE start with the given MIDI controller mapping\n"); + fprintf(stderr, " -l --source-label NUM:LABEL label source NUM as LABEL, if visible\n"); } void parse_flags(int argc, char *const argv[]) @@ -61,11 +62,12 @@ void parse_flags(int argc, char *const argv[]) { "cue-in-point-padding", required_argument, 0, OPTION_CUE_IN_POINT_PADDING }, { "cue-out-point-padding", required_argument, 0, OPTION_CUE_OUT_POINT_PADDING }, { "midi-mapping", required_argument, 0, OPTION_MIDI_MAPPING }, + { "source-label", required_argument, 0, 'l' }, { 0, 0, 0, 0 } }; for (;;) { int option_index = 0; - int c = getopt_long(argc, argv, "w:h:r:q:d:", long_options, &option_index); + int c = getopt_long(argc, argv, "w:h:r:q:d:l:", long_options, &option_index); if (c == -1) { break; @@ -99,6 +101,18 @@ void parse_flags(int argc, char *const argv[]) case 'd': global_flags.working_directory = optarg; break; + case 'l': { + int prefix_len; + unsigned channel_idx; + if (sscanf(optarg, "%u:%n", &channel_idx, &prefix_len) == 1) { + const char *label = optarg + prefix_len; + global_flags.source_labels[channel_idx] = label; + } else { + fprintf(stderr, "Invalid source label format (must be on the form NUM:LABEL)\n"); + exit(1); + } + break; + } case OPTION_HTTP_PORT: global_flags.http_port = atoi(optarg); break; diff --git a/futatabi/flags.h b/futatabi/flags.h index 88379b5..6e59d9d 100644 --- a/futatabi/flags.h +++ b/futatabi/flags.h @@ -4,6 +4,7 @@ #include "defs.h" #include +#include struct Flags { int width = 1280, height = 720; @@ -20,6 +21,7 @@ struct Flags { double cue_out_point_padding_seconds = 0.0; // Can be changed in the menus. bool cue_out_point_padding_set = false; std::string midi_mapping_filename; // Empty for none. + std::unordered_map source_labels; }; extern Flags global_flags; diff --git a/futatabi/jpeg_frame_view.cpp b/futatabi/jpeg_frame_view.cpp index adc3764..eb0ed09 100644 --- a/futatabi/jpeg_frame_view.cpp +++ b/futatabi/jpeg_frame_view.cpp @@ -465,10 +465,25 @@ void JPEGFrameView::set_overlay(const string &text) return; } + // Figure out how large the texture needs to be. + { + QImage img(overlay_width, overlay_height, QImage::Format_Grayscale8); + QPainter painter(&img); + QFont font = painter.font(); + font.setPointSize(12); + QFontMetrics metrics(font); + overlay_base_width = lrint(metrics.boundingRect(QString::fromStdString(text)).width() + 8.0); + overlay_base_height = lrint(metrics.height()); + } + float dpr = QGuiApplication::primaryScreen()->devicePixelRatio(); overlay_width = lrint(overlay_base_width * dpr); overlay_height = lrint(overlay_base_height * dpr); + // Work around OpenGL alignment issues. + while (overlay_width % 4 != 0) ++overlay_width; + + // Now do the actual drawing. overlay_image.reset(new QImage(overlay_width, overlay_height, QImage::Format_Grayscale8)); overlay_image->setDevicePixelRatio(dpr); overlay_image->fill(0); diff --git a/futatabi/jpeg_frame_view.h b/futatabi/jpeg_frame_view.h index b66e265..108aa73 100644 --- a/futatabi/jpeg_frame_view.h +++ b/futatabi/jpeg_frame_view.h @@ -65,7 +65,7 @@ private: std::shared_ptr current_frame; // So that we hold on to the pixels. std::shared_ptr current_secondary_frame; // Same. - static constexpr int overlay_base_width = 16, overlay_base_height = 16; + int overlay_base_width = 16, overlay_base_height = 16; int overlay_width = overlay_base_width, overlay_height = overlay_base_height; std::unique_ptr overlay_image; // If nullptr, no overlay. std::unique_ptr overlay_chain; // Just to get the overlay on screen in the easiest way possible. diff --git a/futatabi/mainwindow.cpp b/futatabi/mainwindow.cpp index 0ebb75c..49581e5 100644 --- a/futatabi/mainwindow.cpp +++ b/futatabi/mainwindow.cpp @@ -324,7 +324,11 @@ void MainWindow::change_num_cameras() display->setAutoFillBackground(true); layout->addWidget(display); - display->set_overlay(to_string(i + 1)); + if (global_flags.source_labels.count(i + 1)) { + display->set_overlay(global_flags.source_labels[i + 1]); + } else { + display->set_overlay(to_string(i + 1)); + } QPushButton *preview_btn = new QPushButton(this); preview_btn->setMaximumSize(20, 17);