mirror of
https://github.com/qTox/qTox.git
synced 2024-03-22 14:00:36 +08:00
WIP: KSnapshot-like screenshot grabber
WIP of a screenshot grabber accessible from the chat form to allow users to easily send a part of a screenshot
This commit is contained in:
parent
4e1dd74269
commit
c6d5b4cc55
13
qtox.pro
13
qtox.pro
|
@ -407,7 +407,6 @@ contains(ENABLE_SYSTRAY_GTK_BACKEND, NO) {
|
|||
src/offlinemsgengine.cpp \
|
||||
src/misc/qrwidget.cpp \
|
||||
src/widget/genericchatroomwidget.cpp
|
||||
|
||||
}
|
||||
|
||||
SOURCES += \
|
||||
|
@ -434,6 +433,11 @@ SOURCES += \
|
|||
src/core/corestructs.cpp \
|
||||
src/profilelocker.cpp \
|
||||
src/avatarbroadcaster.cpp
|
||||
src/widget/tool/screenshotgrabber.cpp \
|
||||
src/widget/tool/screengrabberchooserrectitem.cpp \
|
||||
src/widget/tool/screengrabberoverlayitem.cpp \
|
||||
src/widget/tool/toolboxgraphicsitem.cpp
|
||||
|
||||
|
||||
HEADERS += \
|
||||
src/audio.h \
|
||||
|
@ -458,4 +462,9 @@ HEADERS += \
|
|||
src/widget/gui.h \
|
||||
src/toxme.h \
|
||||
src/profilelocker.h \
|
||||
src/avatarbroadcaster.h
|
||||
src/avatarbroadcaster.h \
|
||||
src/widget/tool/screenshotgrabber.h \
|
||||
src/widget/tool/screengrabberchooserrectitem.hpp \
|
||||
src/widget/tool/screengrabberoverlayitem.hpp \
|
||||
src/widget/tool/toolboxgraphicsitem.hpp
|
||||
|
||||
|
|
|
@ -23,6 +23,9 @@
|
|||
#include <QFileInfo>
|
||||
#include <QDragEnterEvent>
|
||||
#include <QBitmap>
|
||||
#include <QScreen>
|
||||
#include <QTemporaryFile>
|
||||
#include <QGuiApplication>
|
||||
#include "chatform.h"
|
||||
#include "src/core/core.h"
|
||||
#include "src/friend.h"
|
||||
|
@ -44,6 +47,7 @@
|
|||
#include "src/chatlog/content/text.h"
|
||||
#include "src/chatlog/chatlog.h"
|
||||
#include "src/offlinemsgengine.h"
|
||||
#include "src/widget/tool/screenshotgrabber.h"
|
||||
|
||||
ChatForm::ChatForm(Friend* chatFriend)
|
||||
: f(chatFriend)
|
||||
|
@ -81,6 +85,9 @@ ChatForm::ChatForm(Friend* chatFriend)
|
|||
connect(Core::getInstance(), &Core::fileSendStarted, this, &ChatForm::startFileSend);
|
||||
connect(sendButton, &QPushButton::clicked, this, &ChatForm::onSendTriggered);
|
||||
connect(fileButton, &QPushButton::clicked, this, &ChatForm::onAttachClicked);
|
||||
fileButton->setContextMenuPolicy(Qt::CustomContextMenu);
|
||||
connect(fileButton, &QPushButton::customContextMenuRequested, this, &ChatForm::onAttachContext);
|
||||
connect(screenshotAction, &QAction::triggered, this, &ChatForm::onScreenshotCreate);
|
||||
connect(callButton, &QPushButton::clicked, this, &ChatForm::onCallTriggered);
|
||||
connect(videoButton, &QPushButton::clicked, this, &ChatForm::onVideoCallTriggered);
|
||||
connect(msgEdit, &ChatTextEdit::enterPressed, this, &ChatForm::onSendTriggered);
|
||||
|
@ -858,6 +865,45 @@ void ChatForm::loadHistory(QDateTime since, bool processUndelivered)
|
|||
chatWidget->verticalScrollBar()->setValue(savedSliderPos);
|
||||
}
|
||||
|
||||
void ChatForm::onScreenshotCreate()
|
||||
{
|
||||
ScreenshotGrabber *screenshotGrabber = new ScreenshotGrabber (this);
|
||||
connect(screenshotGrabber, &ScreenshotGrabber::screenshotTaken, this, &ChatForm::onScreenshotTaken);
|
||||
|
||||
// Try to not grab the context-menu
|
||||
QTimer::singleShot(200, screenshotGrabber, &ScreenshotGrabber::showGrabber);
|
||||
}
|
||||
|
||||
void ChatForm::onScreenshotTaken (const QPixmap &pixmap) {
|
||||
QTemporaryFile file("qTox-Screenshot-XXXXXXXX.png");
|
||||
|
||||
if (!file.open())
|
||||
{
|
||||
QMessageBox::warning(this, tr("Failed to open temporary file", "Temporary file for screenshot"),
|
||||
tr("qTox wasn't able to save the screenshot"));
|
||||
return;
|
||||
}
|
||||
|
||||
file.setAutoRemove(false);
|
||||
|
||||
pixmap.save(&file, "PNG");
|
||||
|
||||
long long filesize = file.size();
|
||||
file.close();
|
||||
QFileInfo fi(file);
|
||||
|
||||
emit sendFile(f->getFriendID(), fi.fileName(), fi.filePath(), filesize);
|
||||
|
||||
}
|
||||
|
||||
void ChatForm::onAttachContext(const QPoint &pos)
|
||||
{
|
||||
QMenu* context = new QMenu(fileButton);
|
||||
context->addAction(screenshotAction);
|
||||
|
||||
context->exec(fileButton->mapToGlobal(pos));
|
||||
}
|
||||
|
||||
void ChatForm::onLoadHistory()
|
||||
{
|
||||
LoadHistoryDialog dlg;
|
||||
|
|
|
@ -79,6 +79,7 @@ public slots:
|
|||
void onVolMuteToggle();
|
||||
void onAvatarChange(uint32_t FriendId, const QPixmap& pic);
|
||||
void onAvatarRemoved(uint32_t FriendId);
|
||||
void onAttachContext(const QPoint &pos);
|
||||
|
||||
private slots:
|
||||
void onSendTriggered();
|
||||
|
@ -94,6 +95,8 @@ private slots:
|
|||
void onLoadHistory();
|
||||
void onUpdateTime();
|
||||
void onEnableCallButtons();
|
||||
void onScreenshotCreate();
|
||||
void onScreenshotTaken(const QPixmap &pixmap);
|
||||
|
||||
protected:
|
||||
// drag & drop
|
||||
|
|
|
@ -90,6 +90,8 @@ GenericChatForm::GenericChatForm(QWidget *parent)
|
|||
// micButton->setFixedSize(25,20);
|
||||
micButton->setToolTip("");
|
||||
|
||||
screenshotAction = new QAction(tr("Send screenshot"), nullptr);
|
||||
|
||||
footButtonsSmall->setSpacing(2);
|
||||
|
||||
msgEdit->setStyleSheet(Style::getStylesheet(":/ui/msgEdit/msgEdit.css"));
|
||||
|
|
|
@ -90,6 +90,7 @@ protected:
|
|||
MaskablePixmapWidget *avatar;
|
||||
QWidget *headWidget;
|
||||
QPushButton *fileButton, *emoteButton, *callButton, *videoButton, *volButton, *micButton;
|
||||
QAction *screenshotAction;
|
||||
QVBoxLayout *headTextLayout;
|
||||
ChatTextEdit *msgEdit;
|
||||
QPushButton *sendButton;
|
||||
|
|
316
src/widget/tool/screengrabberchooserrectitem.cpp
Normal file
316
src/widget/tool/screengrabberchooserrectitem.cpp
Normal file
|
@ -0,0 +1,316 @@
|
|||
/*
|
||||
Copyright (C) 2014 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 "screengrabberchooserrectitem.hpp"
|
||||
|
||||
#include <QGraphicsSceneMouseEvent>
|
||||
#include <QGraphicsScene>
|
||||
#include <QPainter>
|
||||
#include <QCursor>
|
||||
|
||||
enum { HandleSize = 10 };
|
||||
|
||||
ScreenGrabberChooserRectItem::ScreenGrabberChooserRectItem(QGraphicsScene* scene)
|
||||
{
|
||||
scene->addItem(this);
|
||||
setCursor(QCursor(Qt::OpenHandCursor));
|
||||
|
||||
this->mainRect = createHandleItem(scene);
|
||||
this->topLeft = createHandleItem(scene);
|
||||
this->topCenter = createHandleItem(scene);
|
||||
this->topRight = createHandleItem(scene);
|
||||
this->rightCenter = createHandleItem(scene);
|
||||
this->bottomRight = createHandleItem(scene);
|
||||
this->bottomCenter = createHandleItem(scene);
|
||||
this->bottomLeft = createHandleItem(scene);
|
||||
this->leftCenter = createHandleItem(scene);
|
||||
|
||||
this->topLeft->setCursor(QCursor(Qt::SizeFDiagCursor));
|
||||
this->bottomRight->setCursor(QCursor(Qt::SizeFDiagCursor));
|
||||
this->topRight->setCursor(QCursor(Qt::SizeBDiagCursor));
|
||||
this->bottomLeft->setCursor(QCursor(Qt::SizeBDiagCursor));
|
||||
this->leftCenter->setCursor(QCursor(Qt::SizeHorCursor));
|
||||
this->rightCenter->setCursor(QCursor(Qt::SizeHorCursor));
|
||||
this->topCenter->setCursor(QCursor(Qt::SizeVerCursor));
|
||||
this->bottomCenter->setCursor(QCursor(Qt::SizeVerCursor));
|
||||
|
||||
this->mainRect->setRect(QRect());
|
||||
hideHandles();
|
||||
|
||||
}
|
||||
|
||||
ScreenGrabberChooserRectItem::~ScreenGrabberChooserRectItem()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
QRectF ScreenGrabberChooserRectItem::boundingRect() const
|
||||
{
|
||||
return QRectF(0, 0, this->rectWidth, this->rectHeight);
|
||||
}
|
||||
|
||||
void ScreenGrabberChooserRectItem::beginResize()
|
||||
{
|
||||
this->rectWidth = this->rectHeight = 0;
|
||||
this->state = Resizing;
|
||||
setCursor(QCursor(Qt::CrossCursor));
|
||||
hideHandles();
|
||||
this->mainRect->grabMouse();
|
||||
}
|
||||
|
||||
QRect ScreenGrabberChooserRectItem::chosenRect() const
|
||||
{
|
||||
QRect rect (x(), y(), this->rectWidth, this->rectHeight);
|
||||
return rect.normalized();
|
||||
}
|
||||
|
||||
void ScreenGrabberChooserRectItem::showHandles()
|
||||
{
|
||||
this->topLeft->show();
|
||||
this->topCenter->show();
|
||||
this->topRight->show();
|
||||
this->rightCenter->show();
|
||||
this->bottomRight->show();
|
||||
this->bottomCenter->show();
|
||||
this->bottomLeft->show();
|
||||
this->leftCenter->show();
|
||||
}
|
||||
|
||||
void ScreenGrabberChooserRectItem::hideHandles()
|
||||
{
|
||||
this->topLeft->hide();
|
||||
this->topCenter->hide();
|
||||
this->topRight->hide();
|
||||
this->rightCenter->hide();
|
||||
this->bottomRight->hide();
|
||||
this->bottomCenter->hide();
|
||||
this->bottomLeft->hide();
|
||||
this->leftCenter->hide();
|
||||
}
|
||||
|
||||
void ScreenGrabberChooserRectItem::mousePress(QGraphicsSceneMouseEvent* event)
|
||||
{
|
||||
if (event->button() == Qt::LeftButton)
|
||||
{
|
||||
this->state = Moving;
|
||||
setCursor(QCursor(Qt::ClosedHandCursor));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void ScreenGrabberChooserRectItem::mouseMove(QGraphicsSceneMouseEvent* event)
|
||||
{
|
||||
if (this->state == Moving)
|
||||
{
|
||||
QPointF delta = event->scenePos() - event->lastScenePos();
|
||||
moveBy (delta.x(), delta.y());
|
||||
}
|
||||
else if (this->state == Resizing)
|
||||
{
|
||||
prepareGeometryChange();
|
||||
QPointF size = event->scenePos() - scenePos();
|
||||
this->mainRect->setRect (0, 0, size.x(), size.y());
|
||||
this->rectWidth = size.x();
|
||||
this->rectHeight = size.y();
|
||||
|
||||
updateHandlePositions();
|
||||
}
|
||||
else
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
emit regionChosen(chosenRect());
|
||||
scene()->update();
|
||||
}
|
||||
|
||||
void ScreenGrabberChooserRectItem::mouseRelease(QGraphicsSceneMouseEvent* event)
|
||||
{
|
||||
if (event->button() == Qt::LeftButton)
|
||||
{
|
||||
setCursor(QCursor(Qt::OpenHandCursor));
|
||||
emit regionChosen(chosenRect());
|
||||
this->state = None;
|
||||
this->mainRect->ungrabMouse();
|
||||
showHandles();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void ScreenGrabberChooserRectItem::mouseDoubleClick(QGraphicsSceneMouseEvent* event)
|
||||
{
|
||||
Q_UNUSED(event);
|
||||
emit doubleClicked();
|
||||
}
|
||||
|
||||
void ScreenGrabberChooserRectItem::mousePressHandle(int x, int y, QGraphicsSceneMouseEvent* event)
|
||||
{
|
||||
Q_UNUSED(x);
|
||||
Q_UNUSED(y);
|
||||
|
||||
if(event->button() == Qt::LeftButton)
|
||||
this->state = HandleResizing;
|
||||
|
||||
}
|
||||
|
||||
void ScreenGrabberChooserRectItem::mouseMoveHandle(int x, int y, QGraphicsSceneMouseEvent* event)
|
||||
{
|
||||
if (this->state != HandleResizing)
|
||||
return;
|
||||
|
||||
QPointF delta = event->scenePos() - event->lastScenePos();
|
||||
delta.rx() *= qreal(std::abs(x));
|
||||
delta.ry() *= qreal(std::abs(y));
|
||||
|
||||
// We increase if the multiplier and the delta have the same sign
|
||||
bool increaseX = ((x < 0) == (delta.x() < 0));
|
||||
bool increaseY = ((y < 0) == (delta.y() < 0));
|
||||
|
||||
if((delta.x() < 0 && increaseX) || (delta.x() >= 0 && !increaseX))
|
||||
{
|
||||
moveBy(delta.x(), 0);
|
||||
delta.rx() *= -1;
|
||||
}
|
||||
|
||||
if((delta.y() < 0 && increaseY) || (delta.y() >= 0 && !increaseY))
|
||||
{
|
||||
moveBy(0, delta.y());
|
||||
delta.ry() *= -1;
|
||||
}
|
||||
|
||||
//
|
||||
this->rectWidth += delta.x();
|
||||
this->rectHeight += delta.y();
|
||||
this->mainRect->setRect (0, 0, this->rectWidth, this->rectHeight);
|
||||
updateHandlePositions();
|
||||
emit regionChosen(chosenRect());
|
||||
}
|
||||
|
||||
void ScreenGrabberChooserRectItem::mouseReleaseHandle(int x, int y, QGraphicsSceneMouseEvent* event)
|
||||
{
|
||||
Q_UNUSED(x);
|
||||
Q_UNUSED(y);
|
||||
|
||||
if (event->button() == Qt::LeftButton)
|
||||
this->state = None;
|
||||
|
||||
}
|
||||
|
||||
QPoint ScreenGrabberChooserRectItem::getHandleMultiplier(QGraphicsItem* handle)
|
||||
{
|
||||
if (handle == this->topLeft)
|
||||
return QPoint(-1, -1);
|
||||
|
||||
if (handle == this->topCenter)
|
||||
return QPoint(0, -1);
|
||||
|
||||
if (handle == this->topRight)
|
||||
return QPoint(1, -1);
|
||||
|
||||
if (handle == this->rightCenter)
|
||||
return QPoint(1, 0);
|
||||
|
||||
if (handle == this->bottomRight)
|
||||
return QPoint(1, 1);
|
||||
|
||||
if (handle == this->bottomCenter)
|
||||
return QPoint(0, 1);
|
||||
|
||||
if (handle == this->bottomLeft)
|
||||
return QPoint(-1, 1);
|
||||
|
||||
if (handle == this->leftCenter)
|
||||
return QPoint(-1, 0);
|
||||
|
||||
return QPoint();
|
||||
}
|
||||
|
||||
void ScreenGrabberChooserRectItem::updateHandlePositions()
|
||||
{
|
||||
this->topLeft->setPos(-HandleSize, -HandleSize);
|
||||
this->topCenter->setPos((this->rectWidth - HandleSize) / 2, -HandleSize);
|
||||
this->topRight->setPos(this->rectWidth, -HandleSize);
|
||||
this->rightCenter->setPos(this->rectWidth, (this->rectHeight - HandleSize) / 2);
|
||||
this->bottomRight->setPos(this->rectWidth, this->rectHeight);
|
||||
this->bottomCenter->setPos((this->rectWidth - HandleSize) / 2, this->rectHeight);
|
||||
this->bottomLeft->setPos(-HandleSize, this->rectHeight);
|
||||
this->leftCenter->setPos(-HandleSize, (this->rectHeight - HandleSize) / 2);
|
||||
}
|
||||
|
||||
QGraphicsRectItem* ScreenGrabberChooserRectItem::createHandleItem(QGraphicsScene* scene)
|
||||
{
|
||||
QGraphicsRectItem* handle = new QGraphicsRectItem(0, 0, HandleSize, HandleSize);
|
||||
handle->setPen(QPen(Qt::blue));
|
||||
handle->setBrush(Qt::NoBrush);
|
||||
|
||||
scene->addItem(handle);
|
||||
addToGroup(handle);
|
||||
|
||||
handle->installSceneEventFilter(this);
|
||||
return handle;
|
||||
}
|
||||
|
||||
bool ScreenGrabberChooserRectItem::sceneEventFilter(QGraphicsItem* watched, QEvent* event)
|
||||
{
|
||||
if (watched == this->mainRect)
|
||||
forwardMainRectEvent(event);
|
||||
else
|
||||
forwardHandleEvent(watched, event);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void ScreenGrabberChooserRectItem::forwardMainRectEvent(QEvent* event)
|
||||
{
|
||||
QGraphicsSceneMouseEvent* mouseEvent = static_cast<QGraphicsSceneMouseEvent*>(event);
|
||||
|
||||
switch(event->type())
|
||||
{
|
||||
case QEvent::GraphicsSceneMousePress:
|
||||
return mousePress(mouseEvent);
|
||||
case QEvent::GraphicsSceneMouseMove:
|
||||
return mouseMove(mouseEvent);
|
||||
case QEvent::GraphicsSceneMouseRelease:
|
||||
return mouseRelease(mouseEvent);
|
||||
case QEvent::GraphicsSceneMouseDoubleClick:
|
||||
return mouseDoubleClick(mouseEvent);
|
||||
default:
|
||||
return;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void ScreenGrabberChooserRectItem::forwardHandleEvent(QGraphicsItem* watched, QEvent* event)
|
||||
{
|
||||
QGraphicsSceneMouseEvent* mouseEvent = static_cast<QGraphicsSceneMouseEvent*>(event);
|
||||
QPoint multiplier = getHandleMultiplier(watched);
|
||||
|
||||
if (multiplier.isNull())
|
||||
return;
|
||||
|
||||
switch(event->type())
|
||||
{
|
||||
case QEvent::GraphicsSceneMousePress:
|
||||
return mousePressHandle(multiplier.x(), multiplier.y(), mouseEvent);
|
||||
case QEvent::GraphicsSceneMouseMove:
|
||||
return mouseMoveHandle(multiplier.x(), multiplier.y(), mouseEvent);
|
||||
case QEvent::GraphicsSceneMouseRelease:
|
||||
return mouseReleaseHandle(multiplier.x(), multiplier.y(), mouseEvent);
|
||||
default:
|
||||
return;
|
||||
}
|
||||
|
||||
}
|
89
src/widget/tool/screengrabberchooserrectitem.hpp
Normal file
89
src/widget/tool/screengrabberchooserrectitem.hpp
Normal file
|
@ -0,0 +1,89 @@
|
|||
/*
|
||||
Copyright (C) 2014 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.
|
||||
*/
|
||||
|
||||
#ifndef SCREENGRABBERCHOOSERRECTITEM_HPP
|
||||
#define SCREENGRABBERCHOOSERRECTITEM_HPP
|
||||
|
||||
#include <QGraphicsItemGroup>
|
||||
|
||||
class ScreenGrabberChooserRectItem : public QObject, public QGraphicsItemGroup
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
ScreenGrabberChooserRectItem(QGraphicsScene* scene);
|
||||
~ScreenGrabberChooserRectItem();
|
||||
|
||||
QRectF boundingRect() const;
|
||||
void beginResize();
|
||||
|
||||
QRect chosenRect() const;
|
||||
|
||||
void showHandles();
|
||||
void hideHandles();
|
||||
|
||||
signals:
|
||||
|
||||
void doubleClicked();
|
||||
void regionChosen(QRect rect);
|
||||
|
||||
protected:
|
||||
bool sceneEventFilter(QGraphicsItem* watched, QEvent* event);
|
||||
|
||||
private:
|
||||
|
||||
enum State {
|
||||
None,
|
||||
Resizing,
|
||||
HandleResizing,
|
||||
Moving,
|
||||
};
|
||||
|
||||
State state = None;
|
||||
int rectWidth = 0;
|
||||
int rectHeight = 0;
|
||||
|
||||
void forwardMainRectEvent(QEvent* event);
|
||||
void forwardHandleEvent(QGraphicsItem* watched, QEvent* event);
|
||||
|
||||
void mousePress(QGraphicsSceneMouseEvent* event);
|
||||
void mouseMove(QGraphicsSceneMouseEvent* event);
|
||||
void mouseRelease(QGraphicsSceneMouseEvent* event);
|
||||
void mouseDoubleClick(QGraphicsSceneMouseEvent* event);
|
||||
|
||||
void mousePressHandle(int x, int y, QGraphicsSceneMouseEvent* event);
|
||||
void mouseMoveHandle(int x, int y, QGraphicsSceneMouseEvent* event);
|
||||
void mouseReleaseHandle(int x, int y, QGraphicsSceneMouseEvent* event);
|
||||
|
||||
QPoint getHandleMultiplier(QGraphicsItem* handle);
|
||||
|
||||
void updateHandlePositions();
|
||||
QGraphicsRectItem* createHandleItem(QGraphicsScene* scene);
|
||||
|
||||
QGraphicsRectItem* mainRect;
|
||||
QGraphicsRectItem* topLeft;
|
||||
QGraphicsRectItem* topCenter;
|
||||
QGraphicsRectItem* topRight;
|
||||
QGraphicsRectItem* rightCenter;
|
||||
QGraphicsRectItem* bottomRight;
|
||||
QGraphicsRectItem* bottomCenter;
|
||||
QGraphicsRectItem* bottomLeft;
|
||||
QGraphicsRectItem* leftCenter;
|
||||
|
||||
};
|
||||
|
||||
|
||||
|
||||
#endif // SCREENGRABBERCHOOSERRECTITEM_HPP
|
81
src/widget/tool/screengrabberoverlayitem.cpp
Normal file
81
src/widget/tool/screengrabberoverlayitem.cpp
Normal file
|
@ -0,0 +1,81 @@
|
|||
/*
|
||||
Copyright (C) 2014 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 "screengrabberoverlayitem.hpp"
|
||||
|
||||
#include <QGraphicsSceneMouseEvent>
|
||||
#include <QPainter>
|
||||
#include <QPen>
|
||||
|
||||
#include "screenshotgrabber.h"
|
||||
|
||||
ScreenGrabberOverlayItem::ScreenGrabberOverlayItem(ScreenshotGrabber* grabber)
|
||||
: screnshootGrabber(grabber)
|
||||
{
|
||||
|
||||
QBrush overlayBrush(QColor(0x00, 0x00, 0x00, 0x70)); // Translucent black
|
||||
|
||||
setCursor(QCursor(Qt::CrossCursor));
|
||||
setBrush(overlayBrush);
|
||||
setPen(QPen(Qt::NoPen));
|
||||
|
||||
}
|
||||
|
||||
ScreenGrabberOverlayItem::~ScreenGrabberOverlayItem()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void ScreenGrabberOverlayItem::setChosenRect(QRect rect)
|
||||
{
|
||||
this->chosenRect = rect;
|
||||
update();
|
||||
}
|
||||
|
||||
void ScreenGrabberOverlayItem::mousePressEvent(QGraphicsSceneMouseEvent* event)
|
||||
{
|
||||
if (event->button() == Qt::LeftButton)
|
||||
this->screnshootGrabber->beginRectChooser(event);
|
||||
|
||||
}
|
||||
|
||||
void ScreenGrabberOverlayItem::paint(QPainter* painter, const QStyleOptionGraphicsItem* option, QWidget* widget)
|
||||
{
|
||||
if (!this->chosenRect.isValid())
|
||||
{
|
||||
QGraphicsRectItem::paint(painter, option, widget);
|
||||
return;
|
||||
}
|
||||
|
||||
//
|
||||
painter->save();
|
||||
|
||||
painter->setBrush(brush());
|
||||
painter->setPen(pen());
|
||||
|
||||
QRectF self = rect();
|
||||
qreal leftX = chosenRect.x();
|
||||
qreal rightX = chosenRect.x() + chosenRect.width();
|
||||
qreal topY = chosenRect.y();
|
||||
qreal bottomY = chosenRect.y() + chosenRect.height();
|
||||
|
||||
painter->drawRect(0, 0, leftX, self.height()); // Left of chosen
|
||||
painter->drawRect(rightX, 0, self.width() - rightX, self.height()); // Right of chosen
|
||||
painter->drawRect(leftX, 0, chosenRect.width(), topY); // Top of chosen
|
||||
painter->drawRect(leftX, bottomY, chosenRect.width(), self.height() - bottomY); // Bottom of chosen
|
||||
|
||||
painter->restore();
|
||||
}
|
46
src/widget/tool/screengrabberoverlayitem.hpp
Normal file
46
src/widget/tool/screengrabberoverlayitem.hpp
Normal file
|
@ -0,0 +1,46 @@
|
|||
/*
|
||||
Copyright (C) 2014 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.
|
||||
*/
|
||||
|
||||
#ifndef SCREENGRABBEROVERLAYITEM_HPP
|
||||
#define SCREENGRABBEROVERLAYITEM_HPP
|
||||
|
||||
#include <QGraphicsRectItem>
|
||||
|
||||
class ScreenshotGrabber;
|
||||
|
||||
class ScreenGrabberOverlayItem : public QObject, public QGraphicsRectItem
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
ScreenGrabberOverlayItem(ScreenshotGrabber* grabber);
|
||||
~ScreenGrabberOverlayItem();
|
||||
|
||||
void setChosenRect(QRect rect);
|
||||
|
||||
void paint(QPainter* painter, const QStyleOptionGraphicsItem* option, QWidget* widget);
|
||||
|
||||
protected:
|
||||
void mousePressEvent(QGraphicsSceneMouseEvent* event);
|
||||
|
||||
private:
|
||||
ScreenshotGrabber* screnshootGrabber;
|
||||
|
||||
QRect chosenRect;
|
||||
|
||||
|
||||
};
|
||||
|
||||
#endif // SCREENGRABBEROVERLAYITEM_HPP
|
183
src/widget/tool/screenshotgrabber.cpp
Normal file
183
src/widget/tool/screenshotgrabber.cpp
Normal file
|
@ -0,0 +1,183 @@
|
|||
/*
|
||||
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.hpp"
|
||||
#include "screengrabberoverlayitem.hpp"
|
||||
#include "toolboxgraphicsitem.hpp"
|
||||
|
||||
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();
|
||||
}
|
84
src/widget/tool/screenshotgrabber.h
Normal file
84
src/widget/tool/screenshotgrabber.h
Normal file
|
@ -0,0 +1,84 @@
|
|||
/*
|
||||
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.
|
||||
*/
|
||||
|
||||
#ifndef SCREENSHOTGRABBER_H
|
||||
#define SCREENSHOTGRABBER_H
|
||||
|
||||
#include <QWidget>
|
||||
#include <QPixmap>
|
||||
#include <QPoint>
|
||||
|
||||
class ScreenGrabberChooserRectItem;
|
||||
class QGraphicsSceneMouseEvent;
|
||||
class ScreenGrabberOverlayItem;
|
||||
class QGraphicsPixmapItem;
|
||||
class ToolBoxGraphicsItem;
|
||||
class QGraphicsRectItem;
|
||||
class QGraphicsTextItem;
|
||||
class QGraphicsScene;
|
||||
class QGraphicsView;
|
||||
|
||||
class ScreenshotGrabber : public QWidget
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
|
||||
ScreenshotGrabber(QWidget* parent);
|
||||
~ScreenshotGrabber() override;
|
||||
|
||||
bool eventFilter(QObject* object, QEvent* event);
|
||||
|
||||
public slots:
|
||||
|
||||
void showGrabber();
|
||||
void acceptRegion();
|
||||
|
||||
signals:
|
||||
void screenshotTaken(const QPixmap &pixmap);
|
||||
void rejected();
|
||||
|
||||
private:
|
||||
friend class ScreenGrabberOverlayItem;
|
||||
|
||||
void setupWindow();
|
||||
void setupScene(QGraphicsScene* scene);
|
||||
|
||||
void useNothingSelectedTooltip();
|
||||
void useRegionSelectedTooltip();
|
||||
void adjustTooltipPosition();
|
||||
|
||||
bool handleKeyPress(QKeyEvent* event);
|
||||
void reject();
|
||||
|
||||
QRect getSystemScreenRect();
|
||||
void adjustWindowSize();
|
||||
QPixmap grabScreen();
|
||||
|
||||
void beginRectChooser(QGraphicsSceneMouseEvent* event);
|
||||
|
||||
QPixmap screenGrab;
|
||||
QGraphicsView* window;
|
||||
QGraphicsPixmapItem* screenGrabDisplay;
|
||||
ScreenGrabberOverlayItem* overlay;
|
||||
ScreenGrabberChooserRectItem* chooserRect;
|
||||
ToolBoxGraphicsItem* helperToolbox;
|
||||
QGraphicsTextItem* helperTooltip;
|
||||
|
||||
};
|
||||
|
||||
|
||||
#endif // SCREENSHOTGRABBER_H
|
||||
|
64
src/widget/tool/toolboxgraphicsitem.cpp
Normal file
64
src/widget/tool/toolboxgraphicsitem.cpp
Normal file
|
@ -0,0 +1,64 @@
|
|||
/*
|
||||
Copyright (C) 2014 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 "toolboxgraphicsitem.hpp"
|
||||
|
||||
#include <QPainter>
|
||||
|
||||
ToolBoxGraphicsItem::ToolBoxGraphicsItem()
|
||||
{
|
||||
this->opacityAnimation = new QPropertyAnimation(this, QByteArrayLiteral("opacity"), this);
|
||||
|
||||
this->opacityAnimation->setKeyValueAt(0, this->idleOpacity);
|
||||
this->opacityAnimation->setKeyValueAt(1, this->activeOpacity);
|
||||
this->opacityAnimation->setDuration(this->fadeTimeMs);
|
||||
|
||||
setOpacity(this->idleOpacity);
|
||||
}
|
||||
|
||||
ToolBoxGraphicsItem::~ToolBoxGraphicsItem()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void ToolBoxGraphicsItem::hoverEnterEvent(QGraphicsSceneHoverEvent* event)
|
||||
{
|
||||
startAnimation(QAbstractAnimation::Forward);
|
||||
QGraphicsItemGroup::hoverEnterEvent(event);
|
||||
}
|
||||
|
||||
void ToolBoxGraphicsItem::hoverLeaveEvent(QGraphicsSceneHoverEvent* event)
|
||||
{
|
||||
startAnimation(QAbstractAnimation::Backward);
|
||||
QGraphicsItemGroup::hoverLeaveEvent(event);
|
||||
}
|
||||
|
||||
void ToolBoxGraphicsItem::startAnimation(QAbstractAnimation::Direction direction)
|
||||
{
|
||||
this->opacityAnimation->setDirection(direction);
|
||||
this->opacityAnimation->start();
|
||||
}
|
||||
|
||||
void ToolBoxGraphicsItem::paint(QPainter* painter, const QStyleOptionGraphicsItem* option, QWidget* widget)
|
||||
{
|
||||
painter->save();
|
||||
painter->setPen(Qt::NoPen);
|
||||
painter->setBrush(QBrush(QColor(0xFF, 0xE2, 0x82)));
|
||||
painter->drawRect(childrenBoundingRect());
|
||||
painter->restore();
|
||||
|
||||
QGraphicsItemGroup::paint(painter, option, widget);
|
||||
}
|
49
src/widget/tool/toolboxgraphicsitem.hpp
Normal file
49
src/widget/tool/toolboxgraphicsitem.hpp
Normal file
|
@ -0,0 +1,49 @@
|
|||
/*
|
||||
Copyright (C) 2014 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.
|
||||
*/
|
||||
|
||||
#ifndef TOOLBOXGRAPHICSITEM_HPP
|
||||
#define TOOLBOXGRAPHICSITEM_HPP
|
||||
|
||||
#include <QGraphicsItemGroup>
|
||||
#include <QPropertyAnimation>
|
||||
#include <QObject>
|
||||
|
||||
class ToolBoxGraphicsItem : public QObject, public QGraphicsItemGroup
|
||||
{
|
||||
Q_OBJECT
|
||||
Q_PROPERTY(qreal opacity READ opacity WRITE setOpacity)
|
||||
public:
|
||||
ToolBoxGraphicsItem();
|
||||
~ToolBoxGraphicsItem();
|
||||
|
||||
void paint(QPainter* painter, const QStyleOptionGraphicsItem* option, QWidget* widget);
|
||||
|
||||
protected:
|
||||
void hoverEnterEvent(QGraphicsSceneHoverEvent* event);
|
||||
void hoverLeaveEvent(QGraphicsSceneHoverEvent* event);
|
||||
|
||||
private:
|
||||
|
||||
void startAnimation(QAbstractAnimation::Direction direction);
|
||||
|
||||
QPropertyAnimation* opacityAnimation;
|
||||
qreal idleOpacity = 0.7f;
|
||||
qreal activeOpacity = 1.0f;
|
||||
int fadeTimeMs = 300;
|
||||
|
||||
};
|
||||
|
||||
#endif // TOOLBOXGRAPHICSITEM_HPP
|
|
@ -10,7 +10,7 @@ QPushButton
|
|||
height: 24px;
|
||||
}
|
||||
|
||||
QPushButton:hover
|
||||
QAbstractButton:hover
|
||||
{
|
||||
background-color: #79c76f;
|
||||
}
|
||||
|
@ -25,7 +25,6 @@ QPushButton[enabled="false"]
|
|||
background-color: #919191;
|
||||
}
|
||||
|
||||
QPushButton:focus
|
||||
{
|
||||
QPushButton:focus {
|
||||
outline: none;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue
Block a user