From 0536e4a60bdcb1a0c2e4b9aa2aa877b462275f63 Mon Sep 17 00:00:00 2001 From: WarmUpTill <19472752+WarmUpTill@users.noreply.github.com> Date: Sun, 22 Sep 2024 10:09:21 +0200 Subject: [PATCH] Add option to trim screenshot created in Video condition --- data/locale/en-US.ini | 1 + plugins/video/CMakeLists.txt | 4 +- plugins/video/macro-condition-video.cpp | 4 +- plugins/video/screenshot-dialog.cpp | 113 ++++++++++++++++++++++++ plugins/video/screenshot-dialog.hpp | 41 +++++++++ 5 files changed, 160 insertions(+), 3 deletions(-) create mode 100644 plugins/video/screenshot-dialog.cpp create mode 100644 plugins/video/screenshot-dialog.hpp diff --git a/data/locale/en-US.ini b/data/locale/en-US.ini index 9c9f9891..b6310975 100644 --- a/data/locale/en-US.ini +++ b/data/locale/en-US.ini @@ -407,6 +407,7 @@ AdvSceneSwitcher.condition.video.selectArea="Select area" AdvSceneSwitcher.condition.video.selectArea.status="Only highlighted area will be checked" AdvSceneSwitcher.condition.video.width="Width" AdvSceneSwitcher.condition.video.height="Height" +AdvSceneSwitcher.condition.video.screenshot.selectArea="Highlight the area of the screenshot you want to keep:" AdvSceneSwitcher.condition.stream="Streaming" AdvSceneSwitcher.condition.stream.state.start="Stream running" AdvSceneSwitcher.condition.stream.state.stop="Stream stopped" diff --git a/plugins/video/CMakeLists.txt b/plugins/video/CMakeLists.txt index b487a118..219c5fc3 100644 --- a/plugins/video/CMakeLists.txt +++ b/plugins/video/CMakeLists.txt @@ -50,7 +50,9 @@ target_sources( paramerter-wrappers.cpp paramerter-wrappers.hpp preview-dialog.cpp - preview-dialog.hpp) + preview-dialog.hpp + screenshot-dialog.cpp + screenshot-dialog.hpp) setup_advss_plugin(${PROJECT_NAME}) set_target_properties(${PROJECT_NAME} PROPERTIES PREFIX "") diff --git a/plugins/video/macro-condition-video.cpp b/plugins/video/macro-condition-video.cpp index c087fa19..06a5e527 100644 --- a/plugins/video/macro-condition-video.cpp +++ b/plugins/video/macro-condition-video.cpp @@ -1433,8 +1433,8 @@ void MacroConditionVideoEdit::ImageBrowseButtonClicked() return; } - auto source = OBSGetStrongRef(_entryData->_video.GetVideo()); - auto screenshot = ScreenshotDialog::AskForScreenshot(source); + auto screenshot = + ScreenshotDialog::AskForScreenshot(_entryData->_video); if (!screenshot) { return; } diff --git a/plugins/video/screenshot-dialog.cpp b/plugins/video/screenshot-dialog.cpp new file mode 100644 index 00000000..613168d3 --- /dev/null +++ b/plugins/video/screenshot-dialog.cpp @@ -0,0 +1,113 @@ +#include "screenshot-dialog.hpp" +#include "obs-module-helper.hpp" +#include "ui-helpers.hpp" + +#include +#include + +namespace advss { + +ScreenshotDialog::ScreenshotDialog(obs_source_t *source) + : QDialog(GetSettingsWindow()), + _scrollArea(new QScrollArea), + _imageLabel(new QLabel(this)), + _rubberBand(new QRubberBand(QRubberBand::Rectangle, this)), + _buttonbox(new QDialogButtonBox(QDialogButtonBox::Ok | + QDialogButtonBox::Cancel)), + _screenshot(source, {}, true) +{ + setWindowTitle(obs_module_text("AdvSceneSwitcher.windowTitle")); + setWindowFlags(windowFlags() | Qt::WindowMaximizeButtonHint | + Qt::WindowCloseButtonHint); + + QWidget::connect(_buttonbox, &QDialogButtonBox::accepted, this, + &QDialog::accept); + QWidget::connect(_buttonbox, &QDialogButtonBox::rejected, this, + &QDialog::reject); + + _imageLabel->setPixmap(QPixmap::fromImage(_screenshot.GetImage())); + _imageLabel->adjustSize(); + _imageLabel->updateGeometry(); + + // Center image + auto wrapper = new QWidget(); + auto wrapperHLayout = new QHBoxLayout(); + wrapperHLayout->addStretch(); + wrapperHLayout->addWidget(_imageLabel); + wrapperHLayout->addStretch(); + auto wrapperVLayout = new QVBoxLayout(); + wrapperVLayout->addStretch(); + wrapperVLayout->addLayout(wrapperHLayout); + wrapperVLayout->addStretch(); + wrapper->setLayout(wrapperVLayout); + + _scrollArea->setBackgroundRole(QPalette::Dark); + _scrollArea->setWidget(wrapper); + _scrollArea->setWidgetResizable(true); + QVBoxLayout *layout = new QVBoxLayout; + layout->addWidget(new QLabel(obs_module_text( + "AdvSceneSwitcher.condition.video.screenshot.selectArea"))); + layout->addWidget(_scrollArea); + layout->addWidget(_buttonbox); + setLayout(layout); + + _result = _screenshot.GetImage(); + + if (!_screenshot.IsDone() || _screenshot.GetImage().isNull()) { + DisplayMessage(obs_module_text( + "AdvSceneSwitcher.condition.video.screenshotFail")); + close(); + } +} + +void ScreenshotDialog::mousePressEvent(QMouseEvent *event) +{ + _origin = event->pos(); + _rubberBand->setGeometry(QRect(_origin, QSize())); + _rubberBand->show(); +} + +void ScreenshotDialog::mouseMoveEvent(QMouseEvent *event) +{ + _rubberBand->setGeometry(QRect(_origin, event->pos()).normalized()); +} + +void ScreenshotDialog::mouseReleaseEvent(QMouseEvent *) +{ + auto selectionStart = + _rubberBand->mapToGlobal(_rubberBand->rect().topLeft()); + QRect selectionArea(selectionStart, _rubberBand->size()); + + auto imageStart = + _imageLabel->mapToGlobal(_imageLabel->rect().topLeft()); + QRect imageArea(imageStart, _imageLabel->size()); + + auto intersected = imageArea.intersected(selectionArea); + QRect checksize(QPoint(intersected.topLeft() - imageStart), + intersected.size()); + if (checksize.x() >= 0 && checksize.y() >= 0 && checksize.width() > 0 && + checksize.height() > 0) { + _result = _screenshot.GetImage().copy(checksize.x(), + checksize.y(), + checksize.width(), + checksize.height()); + } +} + +std::optional +ScreenshotDialog::AskForScreenshot(const VideoInput &input) +{ + if (!input.ValidSelection()) { + return {}; + } + + auto source = OBSGetStrongRef(input.GetVideo()); + ScreenshotDialog dialog(source); + if (dialog.exec() != DialogCode::Accepted) { + return {}; + } + + return dialog._result; +} + +} // namespace advss diff --git a/plugins/video/screenshot-dialog.hpp b/plugins/video/screenshot-dialog.hpp new file mode 100644 index 00000000..8b185bec --- /dev/null +++ b/plugins/video/screenshot-dialog.hpp @@ -0,0 +1,41 @@ +#pragma once +#include "screenshot-helper.hpp" +#include "paramerter-wrappers.hpp" + +#include +#include +#include +#include +#include +#include +#include +#include + +namespace advss { + +class ScreenshotDialog : public QDialog { + Q_OBJECT + +public: + static std::optional AskForScreenshot(const VideoInput &); + +private: + ScreenshotDialog(obs_source_t *source); + + void mousePressEvent(QMouseEvent *event); + void mouseMoveEvent(QMouseEvent *event); + void mouseReleaseEvent(QMouseEvent *event); + + QScrollArea *_scrollArea; + QLabel *_imageLabel; + + QPoint _origin; + QRubberBand *_rubberBand = nullptr; + + QDialogButtonBox *_buttonbox; + + QImage _result; + Screenshot _screenshot; +}; + +} // namespace advss