diff --git a/src/capture/captureareaselector.cpp b/src/capture/captureareaselector.cpp index 6015a2f..3c28f94 100644 --- a/src/capture/captureareaselector.cpp +++ b/src/capture/captureareaselector.cpp @@ -6,7 +6,6 @@ #include #include -#include CaptureAreaSelector::CaptureAreaSelector(Capturer &capturer, const Settings &settings) @@ -19,27 +18,37 @@ CaptureAreaSelector::CaptureAreaSelector(Capturer &capturer, setMouseTracking(true); } -void CaptureAreaSelector::setScreen(QScreen &screen) +void CaptureAreaSelector::activate() { - const auto geometry = screen.availableGeometry(); -#if QT_VERSION >= QT_VERSION_CHECK(5, 10, 0) - const auto pixmap = - screen.grabWindow(0, 0, 0, geometry.width(), geometry.height()); -#else - const auto pixmap = screen.grabWindow(0, geometry.x(), geometry.y(), - geometry.width(), geometry.height()); -#endif - pixmap_ = pixmap; + show(); + activateWindow(); +} +void CaptureAreaSelector::setPixmap(const QPixmap &pixmap) +{ + pixmap_ = pixmap; auto palette = this->palette(); palette.setBrush(backgroundRole(), pixmap); setPalette(palette); - setGeometry(geometry); - - updateHelp(); + setGeometry(pixmap_.rect()); } -void CaptureAreaSelector::updateHelp() +void CaptureAreaSelector::setScreenRects(const std::vector &screens) +{ + auto helpRect = fontMetrics().boundingRect({}, 0, help_); + helpRect.setSize(helpRect.size() * 1.4); + + helpRects_.clear(); + helpRects_.reserve(screens.size()); + for (const auto &screen : screens) { + auto possible = std::vector(2, helpRect); + possible[0].moveTopLeft(screen.topLeft()); + possible[1].moveTopRight(screen.topRight()); + helpRects_.push_back({possible[0], possible}); + } +} + +void CaptureAreaSelector::updateSettings() { LanguageCodes languages; const auto source = languages.findById(settings_.sourceLanguage); @@ -52,14 +61,6 @@ void CaptureAreaSelector::updateHelp() help_ = tr(R"(Recognition language: %1 Translation language: %2)") .arg(sourceName, targetName); - - const auto rect = this->rect(); - auto helpRect = fontMetrics().boundingRect({}, 0, help_); - helpRect.setSize(helpRect.size() * 1.4); - helpRects_ = std::vector(2, helpRect); - helpRects_[0].moveTopLeft(rect.topLeft()); - helpRects_[1].moveTopRight(rect.topRight()); - currentHelpRect_ = helpRects_[0]; } void CaptureAreaSelector::showEvent(QShowEvent * /*event*/) @@ -77,22 +78,15 @@ void CaptureAreaSelector::paintEvent(QPaintEvent * /*event*/) { QPainter painter(this); - const auto cursor = mapFromGlobal(QCursor::pos()); - if (currentHelpRect_.contains(cursor)) { - for (const auto &rect : helpRects_) { - if (!rect.contains(cursor)) { - currentHelpRect_ = rect; - break; - } - } - } + for (auto &screenHelp : helpRects_) { + painter.setBrush(QBrush(QColor(200, 200, 200, 200))); + painter.setPen(Qt::NoPen); + painter.drawRect(screenHelp.current); - painter.setBrush(QBrush(QColor(200, 200, 200, 200))); - painter.setPen(Qt::NoPen); - painter.drawRect(currentHelpRect_); - painter.setBrush({}); - painter.setPen(Qt::black); - painter.drawText(currentHelpRect_, Qt::AlignCenter, help_); + painter.setBrush({}); + painter.setPen(Qt::black); + painter.drawText(screenHelp.current, Qt::AlignCenter, help_); + } auto selection = QRect(startSelectPos_, currentSelectPos_).normalized(); if (!selection.isValid()) @@ -103,6 +97,28 @@ void CaptureAreaSelector::paintEvent(QPaintEvent * /*event*/) painter.drawRect(selection); } +bool CaptureAreaSelector::updateCurrentHelpRects() +{ + const auto cursor = mapFromGlobal(QCursor::pos()); + auto changed = false; + + for (auto &screenHelp : helpRects_) { + if (!screenHelp.current.contains(cursor)) + continue; + + for (const auto &screenPossible : screenHelp.possible) { + if (screenPossible.contains(cursor)) + continue; + + screenHelp.current = screenPossible; + changed = true; + break; + } + } + + return changed; +} + void CaptureAreaSelector::mousePressEvent(QMouseEvent *event) { if (startSelectPos_.isNull()) @@ -112,12 +128,13 @@ void CaptureAreaSelector::mousePressEvent(QMouseEvent *event) void CaptureAreaSelector::mouseMoveEvent(QMouseEvent *event) { if (startSelectPos_.isNull()) { - if (currentHelpRect_.contains(event->pos())) + if (updateCurrentHelpRects()) update(); return; } currentSelectPos_ = event->pos(); + updateCurrentHelpRects(); update(); } diff --git a/src/capture/captureareaselector.h b/src/capture/captureareaselector.h index 9eade25..52d3fe9 100644 --- a/src/capture/captureareaselector.h +++ b/src/capture/captureareaselector.h @@ -4,8 +4,6 @@ #include -class QScreen; - class CaptureAreaSelector : public QWidget { Q_OBJECT @@ -13,7 +11,10 @@ class CaptureAreaSelector : public QWidget public: CaptureAreaSelector(Capturer &capturer, const Settings &settings); - void setScreen(QScreen &screen); + void activate(); + void setPixmap(const QPixmap &pixmap); + void setScreenRects(const std::vector &screens); + void updateSettings(); protected: void showEvent(QShowEvent *event) override; @@ -24,7 +25,12 @@ protected: void paintEvent(QPaintEvent *event) override; private: - void updateHelp(); + struct HelpRect { + QRect current; + std::vector possible; + }; + + bool updateCurrentHelpRects(); Capturer &capturer_; const Settings &settings_; @@ -32,6 +38,5 @@ private: QPoint startSelectPos_; QPoint currentSelectPos_; QString help_; - QRect currentHelpRect_; - std::vector helpRects_; + std::vector helpRects_; }; diff --git a/src/capture/capturer.cpp b/src/capture/capturer.cpp index 59f6b3a..e1a7535 100644 --- a/src/capture/capturer.cpp +++ b/src/capture/capturer.cpp @@ -1,36 +1,75 @@ #include "capturer.h" #include "captureareaselector.h" +#include "debug.h" #include "manager.h" #include "settings.h" #include "task.h" #include +#include +#include Capturer::Capturer(Manager &manager, const Settings &settings) : manager_(manager) , settings_(settings) + , selector_(std::make_unique(*this, settings_)) { } +Capturer::~Capturer() = default; + void Capturer::capture() { - showOverlays(true); + updatePixmap(); + SOFT_ASSERT(selector_, return ); + selector_->activate(); +} + +void Capturer::updatePixmap() +{ + const auto screens = QApplication::screens(); + std::vector screenRects; + screenRects.reserve(screens.size()); + QRect rect; + + for (const auto screen : screens) { + const auto geometry = screen->geometry(); + screenRects.push_back(geometry); + rect |= geometry; + } + + QPixmap combined(rect.size()); + QPainter p(&combined); + + for (const auto screen : screens) { + const auto geometry = screen->geometry(); + const auto pixmap = + screen->grabWindow(0, 0, 0, geometry.width(), geometry.height()); + p.drawPixmap(geometry, pixmap); + } + + SOFT_ASSERT(selector_, return ); + selector_->setPixmap(combined); + selector_->setScreenRects(screenRects); } void Capturer::repeatCapture() { - showOverlays(false); + SOFT_ASSERT(selector_, return ); + selector_->activate(); } void Capturer::updateSettings() { + SOFT_ASSERT(selector_, return ); + selector_->updateSettings(); } void Capturer::captured(const TaskPtr &task) { - hideOverlays(); - // TODO respect more overlay's options - // TODO process modifiers + SOFT_ASSERT(selector_, return ); + selector_->hide(); + task->translators = settings_.translators; task->sourceLanguage = settings_.sourceLanguage; if (settings_.doTranslation) @@ -40,40 +79,7 @@ void Capturer::captured(const TaskPtr &task) void Capturer::canceled() { - hideOverlays(); + SOFT_ASSERT(selector_, return ); + selector_->hide(); manager_.captureCanceled(); } - -void Capturer::showOverlays(bool capturePixmap) -{ - const auto screens = QApplication::screens(); - const auto screensSize = screens.size(); - int overlaysSize = selectors_.size(); - if (screensSize > overlaysSize) - selectors_.reserve(screensSize); - - for (auto i = 0, end = screensSize; i < end; ++i) { - if (i == overlaysSize) { - selectors_.push_back(new CaptureAreaSelector(*this, settings_)); - ++overlaysSize; - } - - const auto screen = screens[i]; - auto &overlay = selectors_[i]; - overlay->hide(); - if (capturePixmap) - overlay->setScreen(*screen); - overlay->show(); - overlay->activateWindow(); - } - - if (screensSize < overlaysSize) { - for (auto i = overlaysSize - 1; i >= screensSize; --i) - selectors_[i]->deleteLater(); - } -} - -void Capturer::hideOverlays() -{ - for (const auto &overlay : selectors_) overlay->hide(); -} diff --git a/src/capture/capturer.h b/src/capture/capturer.h index 4899b75..78ac2e1 100644 --- a/src/capture/capturer.h +++ b/src/capture/capturer.h @@ -8,6 +8,7 @@ class Capturer { public: Capturer(Manager &manager, const Settings &settings); + ~Capturer(); void capture(); void repeatCapture(); @@ -17,10 +18,9 @@ public: void canceled(); private: - void showOverlays(bool capturePixmap); - void hideOverlays(); + void updatePixmap(); Manager &manager_; const Settings &settings_; - std::vector selectors_; + std::unique_ptr selector_; };