Use one capture widget for all screens instead of one per screen
This commit is contained in:
parent
178c954124
commit
2874177bc4
@ -6,7 +6,6 @@
|
|||||||
|
|
||||||
#include <QMouseEvent>
|
#include <QMouseEvent>
|
||||||
#include <QPainter>
|
#include <QPainter>
|
||||||
#include <QScreen>
|
|
||||||
|
|
||||||
CaptureAreaSelector::CaptureAreaSelector(Capturer &capturer,
|
CaptureAreaSelector::CaptureAreaSelector(Capturer &capturer,
|
||||||
const Settings &settings)
|
const Settings &settings)
|
||||||
@ -19,27 +18,37 @@ CaptureAreaSelector::CaptureAreaSelector(Capturer &capturer,
|
|||||||
setMouseTracking(true);
|
setMouseTracking(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
void CaptureAreaSelector::setScreen(QScreen &screen)
|
void CaptureAreaSelector::activate()
|
||||||
{
|
{
|
||||||
const auto geometry = screen.availableGeometry();
|
show();
|
||||||
#if QT_VERSION >= QT_VERSION_CHECK(5, 10, 0)
|
activateWindow();
|
||||||
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;
|
|
||||||
|
|
||||||
|
void CaptureAreaSelector::setPixmap(const QPixmap &pixmap)
|
||||||
|
{
|
||||||
|
pixmap_ = pixmap;
|
||||||
auto palette = this->palette();
|
auto palette = this->palette();
|
||||||
palette.setBrush(backgroundRole(), pixmap);
|
palette.setBrush(backgroundRole(), pixmap);
|
||||||
setPalette(palette);
|
setPalette(palette);
|
||||||
setGeometry(geometry);
|
setGeometry(pixmap_.rect());
|
||||||
|
|
||||||
updateHelp();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void CaptureAreaSelector::updateHelp()
|
void CaptureAreaSelector::setScreenRects(const std::vector<QRect> &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<QRect>(2, helpRect);
|
||||||
|
possible[0].moveTopLeft(screen.topLeft());
|
||||||
|
possible[1].moveTopRight(screen.topRight());
|
||||||
|
helpRects_.push_back({possible[0], possible});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void CaptureAreaSelector::updateSettings()
|
||||||
{
|
{
|
||||||
LanguageCodes languages;
|
LanguageCodes languages;
|
||||||
const auto source = languages.findById(settings_.sourceLanguage);
|
const auto source = languages.findById(settings_.sourceLanguage);
|
||||||
@ -52,14 +61,6 @@ void CaptureAreaSelector::updateHelp()
|
|||||||
help_ = tr(R"(Recognition language: %1
|
help_ = tr(R"(Recognition language: %1
|
||||||
Translation language: %2)")
|
Translation language: %2)")
|
||||||
.arg(sourceName, targetName);
|
.arg(sourceName, targetName);
|
||||||
|
|
||||||
const auto rect = this->rect();
|
|
||||||
auto helpRect = fontMetrics().boundingRect({}, 0, help_);
|
|
||||||
helpRect.setSize(helpRect.size() * 1.4);
|
|
||||||
helpRects_ = std::vector<QRect>(2, helpRect);
|
|
||||||
helpRects_[0].moveTopLeft(rect.topLeft());
|
|
||||||
helpRects_[1].moveTopRight(rect.topRight());
|
|
||||||
currentHelpRect_ = helpRects_[0];
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void CaptureAreaSelector::showEvent(QShowEvent * /*event*/)
|
void CaptureAreaSelector::showEvent(QShowEvent * /*event*/)
|
||||||
@ -77,22 +78,15 @@ void CaptureAreaSelector::paintEvent(QPaintEvent * /*event*/)
|
|||||||
{
|
{
|
||||||
QPainter painter(this);
|
QPainter painter(this);
|
||||||
|
|
||||||
const auto cursor = mapFromGlobal(QCursor::pos());
|
for (auto &screenHelp : helpRects_) {
|
||||||
if (currentHelpRect_.contains(cursor)) {
|
painter.setBrush(QBrush(QColor(200, 200, 200, 200)));
|
||||||
for (const auto &rect : helpRects_) {
|
painter.setPen(Qt::NoPen);
|
||||||
if (!rect.contains(cursor)) {
|
painter.drawRect(screenHelp.current);
|
||||||
currentHelpRect_ = rect;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
painter.setBrush(QBrush(QColor(200, 200, 200, 200)));
|
painter.setBrush({});
|
||||||
painter.setPen(Qt::NoPen);
|
painter.setPen(Qt::black);
|
||||||
painter.drawRect(currentHelpRect_);
|
painter.drawText(screenHelp.current, Qt::AlignCenter, help_);
|
||||||
painter.setBrush({});
|
}
|
||||||
painter.setPen(Qt::black);
|
|
||||||
painter.drawText(currentHelpRect_, Qt::AlignCenter, help_);
|
|
||||||
|
|
||||||
auto selection = QRect(startSelectPos_, currentSelectPos_).normalized();
|
auto selection = QRect(startSelectPos_, currentSelectPos_).normalized();
|
||||||
if (!selection.isValid())
|
if (!selection.isValid())
|
||||||
@ -103,6 +97,28 @@ void CaptureAreaSelector::paintEvent(QPaintEvent * /*event*/)
|
|||||||
painter.drawRect(selection);
|
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)
|
void CaptureAreaSelector::mousePressEvent(QMouseEvent *event)
|
||||||
{
|
{
|
||||||
if (startSelectPos_.isNull())
|
if (startSelectPos_.isNull())
|
||||||
@ -112,12 +128,13 @@ void CaptureAreaSelector::mousePressEvent(QMouseEvent *event)
|
|||||||
void CaptureAreaSelector::mouseMoveEvent(QMouseEvent *event)
|
void CaptureAreaSelector::mouseMoveEvent(QMouseEvent *event)
|
||||||
{
|
{
|
||||||
if (startSelectPos_.isNull()) {
|
if (startSelectPos_.isNull()) {
|
||||||
if (currentHelpRect_.contains(event->pos()))
|
if (updateCurrentHelpRects())
|
||||||
update();
|
update();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
currentSelectPos_ = event->pos();
|
currentSelectPos_ = event->pos();
|
||||||
|
updateCurrentHelpRects();
|
||||||
update();
|
update();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -4,8 +4,6 @@
|
|||||||
|
|
||||||
#include <QWidget>
|
#include <QWidget>
|
||||||
|
|
||||||
class QScreen;
|
|
||||||
|
|
||||||
class CaptureAreaSelector : public QWidget
|
class CaptureAreaSelector : public QWidget
|
||||||
{
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
@ -13,7 +11,10 @@ class CaptureAreaSelector : public QWidget
|
|||||||
public:
|
public:
|
||||||
CaptureAreaSelector(Capturer &capturer, const Settings &settings);
|
CaptureAreaSelector(Capturer &capturer, const Settings &settings);
|
||||||
|
|
||||||
void setScreen(QScreen &screen);
|
void activate();
|
||||||
|
void setPixmap(const QPixmap &pixmap);
|
||||||
|
void setScreenRects(const std::vector<QRect> &screens);
|
||||||
|
void updateSettings();
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
void showEvent(QShowEvent *event) override;
|
void showEvent(QShowEvent *event) override;
|
||||||
@ -24,7 +25,12 @@ protected:
|
|||||||
void paintEvent(QPaintEvent *event) override;
|
void paintEvent(QPaintEvent *event) override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void updateHelp();
|
struct HelpRect {
|
||||||
|
QRect current;
|
||||||
|
std::vector<QRect> possible;
|
||||||
|
};
|
||||||
|
|
||||||
|
bool updateCurrentHelpRects();
|
||||||
|
|
||||||
Capturer &capturer_;
|
Capturer &capturer_;
|
||||||
const Settings &settings_;
|
const Settings &settings_;
|
||||||
@ -32,6 +38,5 @@ private:
|
|||||||
QPoint startSelectPos_;
|
QPoint startSelectPos_;
|
||||||
QPoint currentSelectPos_;
|
QPoint currentSelectPos_;
|
||||||
QString help_;
|
QString help_;
|
||||||
QRect currentHelpRect_;
|
std::vector<HelpRect> helpRects_;
|
||||||
std::vector<QRect> helpRects_;
|
|
||||||
};
|
};
|
||||||
|
@ -1,36 +1,75 @@
|
|||||||
#include "capturer.h"
|
#include "capturer.h"
|
||||||
#include "captureareaselector.h"
|
#include "captureareaselector.h"
|
||||||
|
#include "debug.h"
|
||||||
#include "manager.h"
|
#include "manager.h"
|
||||||
#include "settings.h"
|
#include "settings.h"
|
||||||
#include "task.h"
|
#include "task.h"
|
||||||
|
|
||||||
#include <QApplication>
|
#include <QApplication>
|
||||||
|
#include <QPainter>
|
||||||
|
#include <QScreen>
|
||||||
|
|
||||||
Capturer::Capturer(Manager &manager, const Settings &settings)
|
Capturer::Capturer(Manager &manager, const Settings &settings)
|
||||||
: manager_(manager)
|
: manager_(manager)
|
||||||
, settings_(settings)
|
, settings_(settings)
|
||||||
|
, selector_(std::make_unique<CaptureAreaSelector>(*this, settings_))
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Capturer::~Capturer() = default;
|
||||||
|
|
||||||
void Capturer::capture()
|
void Capturer::capture()
|
||||||
{
|
{
|
||||||
showOverlays(true);
|
updatePixmap();
|
||||||
|
SOFT_ASSERT(selector_, return );
|
||||||
|
selector_->activate();
|
||||||
|
}
|
||||||
|
|
||||||
|
void Capturer::updatePixmap()
|
||||||
|
{
|
||||||
|
const auto screens = QApplication::screens();
|
||||||
|
std::vector<QRect> 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()
|
void Capturer::repeatCapture()
|
||||||
{
|
{
|
||||||
showOverlays(false);
|
SOFT_ASSERT(selector_, return );
|
||||||
|
selector_->activate();
|
||||||
}
|
}
|
||||||
|
|
||||||
void Capturer::updateSettings()
|
void Capturer::updateSettings()
|
||||||
{
|
{
|
||||||
|
SOFT_ASSERT(selector_, return );
|
||||||
|
selector_->updateSettings();
|
||||||
}
|
}
|
||||||
|
|
||||||
void Capturer::captured(const TaskPtr &task)
|
void Capturer::captured(const TaskPtr &task)
|
||||||
{
|
{
|
||||||
hideOverlays();
|
SOFT_ASSERT(selector_, return );
|
||||||
// TODO respect more overlay's options
|
selector_->hide();
|
||||||
// TODO process modifiers
|
|
||||||
task->translators = settings_.translators;
|
task->translators = settings_.translators;
|
||||||
task->sourceLanguage = settings_.sourceLanguage;
|
task->sourceLanguage = settings_.sourceLanguage;
|
||||||
if (settings_.doTranslation)
|
if (settings_.doTranslation)
|
||||||
@ -40,40 +79,7 @@ void Capturer::captured(const TaskPtr &task)
|
|||||||
|
|
||||||
void Capturer::canceled()
|
void Capturer::canceled()
|
||||||
{
|
{
|
||||||
hideOverlays();
|
SOFT_ASSERT(selector_, return );
|
||||||
|
selector_->hide();
|
||||||
manager_.captureCanceled();
|
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();
|
|
||||||
}
|
|
||||||
|
@ -8,6 +8,7 @@ class Capturer
|
|||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
Capturer(Manager &manager, const Settings &settings);
|
Capturer(Manager &manager, const Settings &settings);
|
||||||
|
~Capturer();
|
||||||
|
|
||||||
void capture();
|
void capture();
|
||||||
void repeatCapture();
|
void repeatCapture();
|
||||||
@ -17,10 +18,9 @@ public:
|
|||||||
void canceled();
|
void canceled();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void showOverlays(bool capturePixmap);
|
void updatePixmap();
|
||||||
void hideOverlays();
|
|
||||||
|
|
||||||
Manager &manager_;
|
Manager &manager_;
|
||||||
const Settings &settings_;
|
const Settings &settings_;
|
||||||
std::vector<CaptureAreaSelector *> selectors_;
|
std::unique_ptr<CaptureAreaSelector> selector_;
|
||||||
};
|
};
|
||||||
|
Loading…
Reference in New Issue
Block a user