From 85e1c098fb61869cba7edf20a6281b2f87a7b9ed Mon Sep 17 00:00:00 2001 From: "Steinar H. Gunderson" Date: Sun, 16 Dec 2018 22:33:18 +0100 Subject: [PATCH] Make the UI programmatically dependent on NUM_CAMERAS. --- futatabi/clip_list.cpp | 49 ++++------ futatabi/clip_list.h | 12 ++- futatabi/main.cpp | 10 +- futatabi/mainwindow.cpp | 97 ++++++++++--------- futatabi/mainwindow.h | 15 ++- futatabi/mainwindow.ui | 200 +--------------------------------------- 6 files changed, 89 insertions(+), 294 deletions(-) diff --git a/futatabi/clip_list.cpp b/futatabi/clip_list.cpp index 9ccbb71..0321727 100644 --- a/futatabi/clip_list.cpp +++ b/futatabi/clip_list.cpp @@ -58,7 +58,7 @@ int ClipList::columnCount(const QModelIndex &parent) const { if (parent.isValid()) return 0; - return int(Column::NUM_COLUMNS); + return int(Column::NUM_NON_CAMERA_COLUMNS) + NUM_CAMERAS; } int PlayList::columnCount(const QModelIndex &parent) const @@ -105,15 +105,13 @@ QVariant ClipList::data(const QModelIndex &parent, int role) const } else { return QVariant(); } - case Column::CAMERA_1: - case Column::CAMERA_2: - case Column::CAMERA_3: - case Column::CAMERA_4: { - unsigned stream_idx = column - int(Column::CAMERA_1); - return QString::fromStdString(clips[row].descriptions[stream_idx]); - } default: - return ""; + if (is_camera_column(column)) { + unsigned stream_idx = column - int(Column::CAMERA_1); + return QString::fromStdString(clips[row].descriptions[stream_idx]); + } else { + return ""; + } } } @@ -213,16 +211,12 @@ QVariant ClipList::headerData(int section, Qt::Orientation orientation, int role return "Out"; case Column::DURATION: return "Duration"; - case Column::CAMERA_1: - return "Camera 1"; - case Column::CAMERA_2: - return "Camera 2"; - case Column::CAMERA_3: - return "Camera 3"; - case Column::CAMERA_4: - return "Camera 4"; default: - return ""; + if (section >= int(Column::CAMERA_1) && section < int(Column::CAMERA_1) + NUM_CAMERAS) { + return QString::fromStdString("Camera " + to_string(section - int(Column::CAMERA_1) + 1)); + } else { + return ""; + } } } @@ -261,13 +255,9 @@ Qt::ItemFlags ClipList::flags(const QModelIndex &index) const if (size_t(row) >= clips.size()) return Qt::ItemIsEnabled | Qt::ItemIsSelectable; - switch (Column(column)) { - case Column::CAMERA_1: - case Column::CAMERA_2: - case Column::CAMERA_3: - case Column::CAMERA_4: + if (is_camera_column(column)) { return Qt::ItemIsEnabled | Qt::ItemIsSelectable | Qt::ItemIsEditable | Qt::ItemIsDragEnabled; - default: + } else { return Qt::ItemIsEnabled | Qt::ItemIsSelectable; } } @@ -301,17 +291,12 @@ bool ClipList::setData(const QModelIndex &index, const QVariant &value, int role if (size_t(row) >= clips.size()) return false; - switch (Column(column)) { - case Column::CAMERA_1: - case Column::CAMERA_2: - case Column::CAMERA_3: - case Column::CAMERA_4: { + if (is_camera_column(column)) { unsigned stream_idx = column - int(Column::CAMERA_1); clips[row].descriptions[stream_idx] = value.toString().toStdString(); emit_data_changed(row); return true; - } - default: + } else { return false; } } @@ -405,7 +390,7 @@ void PlayList::move_clips(size_t first, size_t last, int delta) void ClipList::emit_data_changed(size_t row) { - emit dataChanged(index(row, 0), index(row, int(Column::NUM_COLUMNS))); + emit dataChanged(index(row, 0), index(row, int(Column::NUM_NON_CAMERA_COLUMNS) + NUM_CAMERAS)); emit any_content_changed(); } diff --git a/futatabi/clip_list.h b/futatabi/clip_list.h index 8dead83..d2c7f83 100644 --- a/futatabi/clip_list.h +++ b/futatabi/clip_list.h @@ -53,11 +53,8 @@ public: IN, OUT, DURATION, - CAMERA_1, - CAMERA_2, - CAMERA_3, - CAMERA_4, - NUM_COLUMNS + CAMERA_1, // Then CAMERA_2, CAMERA_3, etc. as needed. + NUM_NON_CAMERA_COLUMNS = CAMERA_1 }; int rowCount(const QModelIndex &parent) const override; @@ -81,6 +78,11 @@ public: void emit_data_changed(size_t row) override; + static bool is_camera_column(int column) + { + return (column >= int(Column::CAMERA_1) && column < int(Column::CAMERA_1) + NUM_CAMERAS); + } + signals: void any_content_changed(); diff --git a/futatabi/main.cpp b/futatabi/main.cpp index 7076230..7343df1 100644 --- a/futatabi/main.cpp +++ b/futatabi/main.cpp @@ -487,15 +487,7 @@ int record_thread_func() FrameOnDisk frame = write_frame(pkt.stream_index, pts, pkt.data, pkt.size, &db); post_to_main_thread([pkt, frame] { - if (pkt.stream_index == 0) { - global_mainwindow->ui->input1_display->setFrame(pkt.stream_index, frame); - } else if (pkt.stream_index == 1) { - global_mainwindow->ui->input2_display->setFrame(pkt.stream_index, frame); - } else if (pkt.stream_index == 2) { - global_mainwindow->ui->input3_display->setFrame(pkt.stream_index, frame); - } else if (pkt.stream_index == 3) { - global_mainwindow->ui->input4_display->setFrame(pkt.stream_index, frame); - } + global_mainwindow->display_frame(pkt.stream_index, frame); }); if (last_pts != -1 && global_flags.slow_down_input) { diff --git a/futatabi/mainwindow.cpp b/futatabi/mainwindow.cpp index 0c12b5c..8d52c06 100644 --- a/futatabi/mainwindow.cpp +++ b/futatabi/mainwindow.cpp @@ -138,30 +138,6 @@ MainWindow::MainWindow() connect(ui->stop_btn, &QPushButton::clicked, this, &MainWindow::stop_clicked); ui->stop_btn->setEnabled(false); - QShortcut *preview_1 = new QShortcut(QKeySequence(Qt::Key_1), this); - connect(preview_1, &QShortcut::activated, ui->preview_1_btn, &QPushButton::click); - connect(ui->input1_display, &JPEGFrameView::clicked, ui->preview_1_btn, &QPushButton::click); - connect(ui->preview_1_btn, &QPushButton::clicked, [this]{ preview_angle_clicked(0); }); - ui->input1_display->set_overlay("1"); - - QShortcut *preview_2 = new QShortcut(QKeySequence(Qt::Key_2), this); - connect(preview_2, &QShortcut::activated, ui->preview_2_btn, &QPushButton::click); - connect(ui->input2_display, &JPEGFrameView::clicked, ui->preview_2_btn, &QPushButton::click); - connect(ui->preview_2_btn, &QPushButton::clicked, [this]{ preview_angle_clicked(1); }); - ui->input2_display->set_overlay("2"); - - QShortcut *preview_3 = new QShortcut(QKeySequence(Qt::Key_3), this); - connect(preview_3, &QShortcut::activated, ui->preview_3_btn, &QPushButton::click); - connect(ui->input3_display, &JPEGFrameView::clicked, ui->preview_3_btn, &QPushButton::click); - connect(ui->preview_3_btn, &QPushButton::clicked, [this]{ preview_angle_clicked(2); }); - ui->input3_display->set_overlay("3"); - - QShortcut *preview_4 = new QShortcut(QKeySequence(Qt::Key_4), this); - connect(preview_4, &QShortcut::activated, ui->preview_4_btn, &QPushButton::click); - connect(ui->input4_display, &JPEGFrameView::clicked, ui->preview_4_btn, &QPushButton::click); - connect(ui->preview_4_btn, &QPushButton::clicked, [this]{ preview_angle_clicked(3); }); - ui->input4_display->set_overlay("4"); - connect(ui->playlist_duplicate_btn, &QPushButton::clicked, this, &MainWindow::playlist_duplicate); connect(ui->playlist_remove_btn, &QPushButton::clicked, this, &MainWindow::playlist_remove); @@ -202,6 +178,38 @@ MainWindow::MainWindow() connect(ui->clip_list->selectionModel(), &QItemSelectionModel::currentChanged, this, &MainWindow::clip_list_selection_changed); + + // Make the display rows. + unsigned display_rows = (NUM_CAMERAS + 1) / 2; + ui->video_displays->setStretch(1, display_rows); + for (unsigned i = 0; i < NUM_CAMERAS; ++i) { + QFrame *frame = new QFrame(this); + frame->setAutoFillBackground(true); + + QLayout *layout = new QGridLayout(frame); + frame->setLayout(layout); + layout->setContentsMargins(3, 3, 3, 3); + + JPEGFrameView *display = new JPEGFrameView(frame); + display->setAutoFillBackground(true); + layout->addWidget(display); + + ui->input_displays->addWidget(frame, i / 2, i % 2); + display->set_overlay(to_string(i + 1)); + + QPushButton *preview_btn = new QPushButton(this); + preview_btn->setMaximumSize(20, 17); + preview_btn->setText(QString::fromStdString(to_string(i + 1))); + ui->preview_layout->addWidget(preview_btn); + + displays.emplace_back(FrameAndDisplay{ frame, display, preview_btn }); + + connect(display, &JPEGFrameView::clicked, preview_btn, &QPushButton::click); + QShortcut *shortcut = new QShortcut(QKeySequence(Qt::Key_1 + i), this); + connect(shortcut, &QShortcut::activated, preview_btn, &QPushButton::click); + + connect(preview_btn, &QPushButton::clicked, [this, i]{ preview_angle_clicked(i); }); + } } MainWindow::~MainWindow() @@ -250,8 +258,7 @@ void MainWindow::queue_clicked() QModelIndex index = selected->currentIndex(); Clip clip = *cliplist_clips->clip(index.row()); - if (index.column() >= int(ClipList::Column::CAMERA_1) && - index.column() <= int(ClipList::Column::CAMERA_4)) { + if (ClipList::is_camera_column(index.column())) { clip.stream_idx = index.column() - int(ClipList::Column::CAMERA_1); } else { clip.stream_idx = ui->preview_display->get_stream_idx(); @@ -293,8 +300,7 @@ void MainWindow::preview_clicked() QModelIndex index = selected->currentIndex(); unsigned stream_idx; - if (index.column() >= int(ClipList::Column::CAMERA_1) && - index.column() <= int(ClipList::Column::CAMERA_4)) { + if (ClipList::is_camera_column(index.column())) { stream_idx = index.column() - int(ClipList::Column::CAMERA_1); } else { stream_idx = ui->preview_display->get_stream_idx(); @@ -799,8 +805,7 @@ void MainWindow::playlist_selection_changed() void MainWindow::clip_list_selection_changed(const QModelIndex ¤t, const QModelIndex &) { int camera_selected = -1; - if (current.column() >= int(ClipList::Column::CAMERA_1) && - current.column() <= int(ClipList::Column::CAMERA_4)) { + if (ClipList::is_camera_column(current.column())) { camera_selected = current.column() - int(ClipList::Column::CAMERA_1); } highlight_camera_input(camera_selected); @@ -978,25 +983,12 @@ void MainWindow::quality_toggled(int quality, bool checked) void MainWindow::highlight_camera_input(int stream_idx) { - if (stream_idx == 0) { - ui->input1_frame->setStyleSheet("background: rgb(0,255,0)"); - } else { - ui->input1_frame->setStyleSheet(""); - } - if (stream_idx == 1) { - ui->input2_frame->setStyleSheet("background: rgb(0,255,0)"); - } else { - ui->input2_frame->setStyleSheet(""); - } - if (stream_idx == 2) { - ui->input3_frame->setStyleSheet("background: rgb(0,255,0)"); - } else { - ui->input3_frame->setStyleSheet(""); - } - if (stream_idx == 3) { - ui->input4_frame->setStyleSheet("background: rgb(0,255,0)"); - } else { - ui->input4_frame->setStyleSheet(""); + for (unsigned i = 0; i < NUM_CAMERAS; ++i) { + if (stream_idx == i) { + displays[i].frame->setStyleSheet("background: rgb(0,255,0)"); + } else { + displays[i].frame->setStyleSheet(""); + } } } @@ -1013,6 +1005,13 @@ pair MainWindow::get_queue_status() const { return {queue_status, "text/plain"}; } +void MainWindow::display_frame(unsigned stream_idx, const FrameOnDisk &frame) +{ + if (stream_idx < NUM_CAMERAS) { + displays[stream_idx].display->setFrame(stream_idx, frame); + } +} + template void MainWindow::replace_model(QTableView *view, Model **model, Model *new_model) { diff --git a/futatabi/mainwindow.h b/futatabi/mainwindow.h index 7987456..97f0f29 100644 --- a/futatabi/mainwindow.h +++ b/futatabi/mainwindow.h @@ -19,7 +19,10 @@ namespace Ui { class MainWindow; } // namespace Ui +struct FrameOnDisk; +class JPEGFrameView; class Player; +class QPushButton; class QTableView; class MainWindow : public QMainWindow { @@ -32,10 +35,11 @@ public: // HTTP callback. TODO: Does perhaps not belong to MainWindow? std::pair get_queue_status() const; -//private: - Ui::MainWindow *ui; + void display_frame(unsigned stream_idx, const FrameOnDisk &frame); private: + Ui::MainWindow *ui; + QLabel *disk_free_label; std::unique_ptr preview_player, live_player; DB db; @@ -76,6 +80,13 @@ private: mutable std::mutex queue_status_mu; std::string queue_status; // Under queue_status_mu. + struct FrameAndDisplay { + QFrame *frame; + JPEGFrameView *display; + QPushButton *preview_btn; + }; + std::vector displays; + void cue_in_clicked(); void cue_out_clicked(); void queue_clicked(); diff --git a/futatabi/mainwindow.ui b/futatabi/mainwindow.ui index 288da89..212f3bd 100644 --- a/futatabi/mainwindow.ui +++ b/futatabi/mainwindow.ui @@ -159,7 +159,8 @@ Stop - + + .. @@ -188,7 +189,7 @@ - + 0 @@ -202,70 +203,6 @@ - - - - - 0 - 0 - - - - - 20 - 17 - - - - 1 - - - - - - - - 0 - 0 - - - - - 20 - 17 - - - - 2 - - - - - - - - 20 - 17 - - - - 3 - - - - - - - - 20 - 17 - - - - 4 - - - @@ -296,137 +233,6 @@ 0 - - - - QFrame::Box - - - QFrame::Plain - - - 0 - - - - 3 - - - 3 - - - 3 - - - 3 - - - - - true - - - - - - - - - - QFrame::Box - - - QFrame::Plain - - - 0 - - - - 3 - - - 3 - - - 3 - - - 3 - - - - - - - - - - - QFrame::Box - - - QFrame::Plain - - - 0 - - - - 3 - - - 3 - - - 3 - - - 3 - - - - - true - - - - - - - - - - true - - - QFrame::Box - - - QFrame::Plain - - - 0 - - - - 3 - - - 3 - - - 3 - - - 3 - - - - - - - -- 2.39.2