1
0
mirror of https://github.com/qTox/qTox.git synced 2024-03-22 14:00:36 +08:00
qTox/src/widget/tool/screenshotgrabber.cpp
Stefan Merettig 04dc650596 Screen grabber: Flyout menu for the screenshot button
When hovering over the "attach file" button in the chat form, an
additional button for the screenshot functionality will 'fly out'
to the left, showing a computer monitor as icon. Leaving the attach
file or the take screenshot button will collapse the fly out again.

Bug: Moving the mouse over the fly out and then back again to the
attach button collapses the fly out. Will sort this out later.

Also used the opportunity to rename headers from hpp -> h extension
I added earlier.
2015-05-07 20:00:20 +02:00

184 lines
5.7 KiB
C++

/*
Copyright (C) 2015 by Project Tox <https://tox.im>
This file is part of qTox, a Qt-based graphical interface for Tox.
This program is libre software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
See the COPYING file for more details.
*/
#include "screenshotgrabber.h"
#include <QGraphicsSceneMouseEvent>
#include <QGraphicsPixmapItem>
#include <QGraphicsRectItem>
#include <QDesktopWidget>
#include <QGraphicsView>
#include <QApplication>
#include <QMouseEvent>
#include <QScreen>
#include <QDebug>
#include "screengrabberchooserrectitem.h"
#include "screengrabberoverlayitem.h"
#include "toolboxgraphicsitem.h"
ScreenshotGrabber::ScreenshotGrabber(QWidget* parent)
: QWidget(parent)
{
QGraphicsScene* scene = new QGraphicsScene;
this->window = new QGraphicsView (scene); // Top-level widget
setupWindow();
setupScene(scene);
installEventFilter(this);
}
ScreenshotGrabber::~ScreenshotGrabber()
{
}
bool ScreenshotGrabber::eventFilter(QObject* object, QEvent* event)
{
if (event->type() == QEvent::KeyPress)
return handleKeyPress(static_cast<QKeyEvent*>(event));
return QWidget::eventFilter(object, event);
}
void ScreenshotGrabber::showGrabber()
{
this->screenGrab = grabScreen();
this->screenGrabDisplay->setPixmap(this->screenGrab);
this->window->show();
this->window->setFocus();
this->window->grabKeyboard();
adjustWindowSize();
adjustTooltipPosition();
}
bool ScreenshotGrabber::handleKeyPress(QKeyEvent* event)
{
if (event->key() == Qt::Key_Escape)
reject();
else if (event->key() == Qt::Key_Return || event->key() == Qt::Key_Enter)
acceptRegion();
else
return false;
return true;
}
void ScreenshotGrabber::acceptRegion()
{
QRect rect = this->chooserRect->chosenRect();
if (rect.width() < 1 || rect.height() < 1)
return;
//
qDebug() << "Screenshot accepted, chosen region" << rect;
emit screenshotTaken(this->screenGrab.copy(rect));
this->window->close();
}
void ScreenshotGrabber::setupWindow()
{
this->window->setWindowFlags(Qt::FramelessWindowHint | Qt::X11BypassWindowManagerHint);
this->window->setAttribute(Qt::WA_DeleteOnClose);
this->window->setContentsMargins(0, 0, 0, 0);
this->window->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
this->window->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
this->window->setFrameShape(QFrame::NoFrame);
connect(this->window, &QObject::destroyed, this, &QObject::deleteLater);
this->window->installEventFilter(this);
}
void ScreenshotGrabber::setupScene(QGraphicsScene* scene)
{
this->overlay = new ScreenGrabberOverlayItem(this);
this->helperToolbox = new ToolBoxGraphicsItem;
this->screenGrabDisplay = scene->addPixmap(this->screenGrab);
this->helperTooltip = scene->addText(QString());
scene->addItem(this->overlay);
this->chooserRect = new ScreenGrabberChooserRectItem(scene);
scene->addItem(this->helperToolbox);
this->helperToolbox->addToGroup(this->helperTooltip);
this->helperTooltip->setDefaultTextColor(Qt::black);
useNothingSelectedTooltip();
connect(this->chooserRect, &ScreenGrabberChooserRectItem::doubleClicked, this, &ScreenshotGrabber::acceptRegion);
connect(this->chooserRect, &ScreenGrabberChooserRectItem::regionChosen, this, &ScreenshotGrabber::useRegionSelectedTooltip);
connect(this->chooserRect, &ScreenGrabberChooserRectItem::regionChosen, this->overlay, &ScreenGrabberOverlayItem::setChosenRect);
}
void ScreenshotGrabber::useNothingSelectedTooltip()
{
this->helperTooltip->setHtml(tr("Click and drag to select a region to select it. Press <b>ESC</b> to cancel.",
"Help text shown when no region has been selected yet"));
adjustTooltipPosition();
}
void ScreenshotGrabber::useRegionSelectedTooltip()
{
this->helperTooltip->setHtml(tr("Press <b>Return</b> to accept, or move and resize the selected region.",
"Help text shown when a region has been selected"));
adjustTooltipPosition();
}
void ScreenshotGrabber::adjustTooltipPosition()
{
QRectF size = this->helperToolbox->childrenBoundingRect();
QRect screenRect = QApplication::desktop()->screen()->rect();
// Align the toolbox center-top.
this->helperToolbox->setX(screenRect.x() + (screenRect.width() - size.width() + size.x()) / 2);
this->helperToolbox->setY(screenRect.y());
}
void ScreenshotGrabber::reject()
{
qDebug() << "Rejected screenshot";
this->window->close();
}
QRect ScreenshotGrabber::getSystemScreenRect()
{
return QApplication::primaryScreen()->virtualGeometry();
}
void ScreenshotGrabber::adjustWindowSize()
{
QRect systemScreenRect = getSystemScreenRect();
qDebug() << "adjusting grabber size to" << systemScreenRect;
this->window->setGeometry(systemScreenRect);
this->window->scene()->setSceneRect(systemScreenRect);
this->overlay->setRect(systemScreenRect);
}
QPixmap ScreenshotGrabber::grabScreen() {
return QApplication::primaryScreen()->grabWindow(QApplication::desktop()->winId());
}
void ScreenshotGrabber::beginRectChooser(QGraphicsSceneMouseEvent* event)
{
QPointF pos = event->scenePos();
this->chooserRect->setX(pos.x());
this->chooserRect->setY(pos.y());
this->chooserRect->beginResize();
}