Add a huge performance improvement when using the pencil
This commit is contained in:
@@ -81,7 +81,7 @@ CaptureWidget::CaptureWidget(QWidget *parent) :
|
||||
m_buttonHandler->hide();
|
||||
// init screenshot
|
||||
createCapture();
|
||||
resize(m_screenshot.size());
|
||||
resize(m_screenshot->getScreenshot().size());
|
||||
// init interface color
|
||||
m_uiColor = QSettings().value("uiColor").value<QColor>();
|
||||
show();
|
||||
@@ -91,6 +91,7 @@ CaptureWidget::CaptureWidget(QWidget *parent) :
|
||||
|
||||
CaptureWidget::~CaptureWidget() {
|
||||
delete(m_buttonHandler);
|
||||
delete(m_screenshot);
|
||||
}
|
||||
|
||||
// redefineButtons retrieves the buttons configured to be shown with the
|
||||
@@ -122,10 +123,15 @@ void CaptureWidget::paintEvent(QPaintEvent *) {
|
||||
if (m_grabbing) { // grabWindow() should just get the background
|
||||
return;
|
||||
}
|
||||
|
||||
Screenshot s(m_screenshot);
|
||||
s.paintModifications(m_modifications);
|
||||
painter.drawPixmap(0, 0, s.getScreenshot());
|
||||
// if we are creating a new modification to the screenshot we just draw
|
||||
// a temporal modification without antialiasing in the pencil tool for
|
||||
// performance. When we are not drawing we just shot the modified screenshot
|
||||
if (m_mouseIsClicked && m_state != Button::Type::move) {
|
||||
painter.drawPixmap(0, 0, m_screenshot->paintTemporalModification(
|
||||
m_modifications.last()));
|
||||
} else {
|
||||
painter.drawPixmap(0, 0, m_screenshot->getScreenshot());
|
||||
}
|
||||
|
||||
QColor overlayColor(0, 0, 0, 160);
|
||||
painter.setBrush(overlayColor);
|
||||
@@ -166,6 +172,7 @@ void CaptureWidget::mousePressEvent(QMouseEvent *e) {
|
||||
if (m_state != Button::Type::move) {
|
||||
m_modifications.append(CaptureModification(m_state, e->pos(),
|
||||
m_colorPicker->getDrawColor()));
|
||||
m_screenshot->paintModification(m_modifications.last());
|
||||
return;
|
||||
}
|
||||
m_dragStartPoint = e->pos();
|
||||
@@ -293,6 +300,10 @@ void CaptureWidget::mouseReleaseEvent(QMouseEvent *e) {
|
||||
m_colorPicker->hide();
|
||||
m_rightClick = false;
|
||||
return;
|
||||
// when we end the drawing of a modification in the capture we have to
|
||||
// register the last point and add the whole modification to the screenshot
|
||||
} else if (m_mouseIsClicked && m_state != Button::Type::move) {
|
||||
m_screenshot->paintModification(m_modifications.last());
|
||||
}
|
||||
|
||||
if (!m_selection.isNull() && !m_buttonHandler->isVisible()) {
|
||||
@@ -335,22 +346,18 @@ void CaptureWidget::keyPressEvent(QKeyEvent *e) {
|
||||
}
|
||||
|
||||
void CaptureWidget::saveScreenshot() {
|
||||
Screenshot s(m_screenshot);
|
||||
s.paintModifications(m_modifications);
|
||||
if (m_selection.isNull()) {
|
||||
s.graphicalSave();
|
||||
m_screenshot->graphicalSave();
|
||||
} else { // save full screen when no selection
|
||||
s.graphicalSave(getExtendedSelection());
|
||||
m_screenshot->graphicalSave(getExtendedSelection());
|
||||
}
|
||||
}
|
||||
|
||||
void CaptureWidget::copyScreenshot() {
|
||||
Screenshot s(m_screenshot);
|
||||
s.paintModifications(m_modifications);
|
||||
if (m_selection.isNull()) {
|
||||
QApplication::clipboard()->setPixmap(s.getScreenshot());
|
||||
QApplication::clipboard()->setPixmap(m_screenshot->getScreenshot());
|
||||
} else { // copy full screen when no selection
|
||||
QApplication::clipboard()->setPixmap(s.getScreenshot()
|
||||
QApplication::clipboard()->setPixmap(m_screenshot->getScreenshot()
|
||||
.copy(getExtendedSelection()));
|
||||
}
|
||||
close();
|
||||
@@ -367,15 +374,13 @@ void CaptureWidget::openURL(QNetworkReply *reply) {
|
||||
}
|
||||
|
||||
void CaptureWidget::uploadScreenshot() {
|
||||
Screenshot s(m_screenshot);
|
||||
s.paintModifications(m_modifications);
|
||||
QNetworkAccessManager *am = new QNetworkAccessManager(this);
|
||||
connect(am, &QNetworkAccessManager::finished, this,
|
||||
&CaptureWidget::openURL);
|
||||
if (m_selection.isNull()) {
|
||||
s.uploadToImgur(am);
|
||||
m_screenshot->uploadToImgur(am);
|
||||
} else {
|
||||
s.uploadToImgur(am, getExtendedSelection());
|
||||
m_screenshot->uploadToImgur(am, getExtendedSelection());
|
||||
}
|
||||
hide();
|
||||
Q_EMIT newMessage("Uploading image...");
|
||||
@@ -384,6 +389,7 @@ void CaptureWidget::uploadScreenshot() {
|
||||
void CaptureWidget::undo() {
|
||||
if (!m_modifications.isEmpty()) {
|
||||
m_modifications.pop_back();
|
||||
m_screenshot->paintBaseModifications(m_modifications);
|
||||
update();
|
||||
}
|
||||
}
|
||||
@@ -464,7 +470,7 @@ void CaptureWidget::createCapture() {
|
||||
close();
|
||||
return;
|
||||
}
|
||||
m_screenshot = screen->grabWindow(0);
|
||||
m_screenshot = new Screenshot(screen->grabWindow(0));
|
||||
}
|
||||
|
||||
void CaptureWidget::initShortcuts() {
|
||||
@@ -524,7 +530,7 @@ QPoint CaptureWidget::limitPointToRect(const QPoint &p, const QRect &r) const {
|
||||
}
|
||||
|
||||
QRect CaptureWidget::getExtendedSelection() const {
|
||||
auto devicePixelRatio = m_screenshot.devicePixelRatio();
|
||||
auto devicePixelRatio = m_screenshot->getScreenshot().devicePixelRatio();
|
||||
|
||||
return QRect(m_selection.left() * devicePixelRatio,
|
||||
m_selection.top() * devicePixelRatio,
|
||||
|
||||
@@ -36,6 +36,7 @@ class CaptureModification;
|
||||
class QNetworkAccessManager;
|
||||
class QNetworkReply;
|
||||
class ColorPicker;
|
||||
class Screenshot;
|
||||
|
||||
class CaptureWidget : public QWidget {
|
||||
Q_OBJECT
|
||||
@@ -74,7 +75,7 @@ protected:
|
||||
QRegion handleMask() const;
|
||||
|
||||
// pixel map of the screen
|
||||
QPixmap m_screenshot;
|
||||
Screenshot* m_screenshot;
|
||||
|
||||
QPoint m_dragStartPoint;
|
||||
QPoint m_mousePos;
|
||||
|
||||
@@ -21,6 +21,7 @@
|
||||
#include <QStandardPaths>
|
||||
#include <QIcon>
|
||||
#include <QSettings>
|
||||
#include <QDateTime>
|
||||
#include <QObject>
|
||||
#include <QString>
|
||||
#include <QMessageBox>
|
||||
@@ -34,22 +35,30 @@
|
||||
|
||||
// Screenshot is an extension of QPixmap which lets you manage specific tasks
|
||||
|
||||
Screenshot::Screenshot(const QPixmap &p) : m_screenshot(p) {
|
||||
|
||||
}
|
||||
Screenshot::Screenshot(const QPixmap &p) : m_baseScreenshot(p),
|
||||
m_modifiedScreenshot(p) {}
|
||||
|
||||
Screenshot::~Screenshot() {
|
||||
if (m_accessManager) delete(m_accessManager);
|
||||
}
|
||||
|
||||
void Screenshot::setScreenshot(const QPixmap &p) {
|
||||
m_screenshot = p;
|
||||
m_baseScreenshot = p;
|
||||
m_modifiedScreenshot = p;
|
||||
}
|
||||
|
||||
// getScreenshot returns the screenshot with no modifications
|
||||
QPixmap Screenshot::getBaseScreenshot() const {
|
||||
return m_baseScreenshot;
|
||||
}
|
||||
|
||||
// getScreenshot returns the screenshot with all the modifications
|
||||
QPixmap Screenshot::getScreenshot() const {
|
||||
return m_screenshot;
|
||||
return m_modifiedScreenshot;
|
||||
}
|
||||
|
||||
// graphicalSave generates a graphical window to ask about the save path and
|
||||
// saves the screenshot with all the modifications in such directory
|
||||
QString Screenshot::graphicalSave(const QRect &selection) const {
|
||||
const QString format = "png";
|
||||
|
||||
@@ -98,9 +107,9 @@ QString Screenshot::graphicalSave(const QRect &selection) const {
|
||||
|
||||
QPixmap pixToSave;
|
||||
if (selection.isEmpty()) {
|
||||
pixToSave = m_screenshot;
|
||||
pixToSave = m_modifiedScreenshot;
|
||||
} else { // save full screen when no selection
|
||||
pixToSave = m_screenshot.copy(selection);
|
||||
pixToSave = m_modifiedScreenshot.copy(selection);
|
||||
}
|
||||
|
||||
// if (settings.value("mouseVisible").toBool()) {
|
||||
@@ -115,52 +124,101 @@ QString Screenshot::graphicalSave(const QRect &selection) const {
|
||||
return fileName;
|
||||
}
|
||||
|
||||
QPixmap Screenshot::paintModifications(const QVector<CaptureModification> v) {
|
||||
QPainter painter(&m_screenshot);
|
||||
// paintModification adds a new modification to the screenshot
|
||||
QPixmap Screenshot::paintModification(const CaptureModification &modification) {
|
||||
QPainter painter(&m_modifiedScreenshot);
|
||||
painter.setRenderHint(QPainter::Antialiasing);
|
||||
for (CaptureModification modification: v) {
|
||||
painter.setPen(QPen(modification.getColor(), 2));
|
||||
QVector<QPoint> points = modification.getPoints();
|
||||
switch (modification.getType()) {
|
||||
case Button::Type::arrow:
|
||||
painter.drawLine(points[0], points[1]);
|
||||
// TODO
|
||||
|
||||
break;
|
||||
case Button::Type::circle:
|
||||
painter.drawEllipse(QRect(points[0], points[1]));
|
||||
break;
|
||||
case Button::Type::line:
|
||||
painter.drawLine(points[0], points[1]);
|
||||
break;
|
||||
case Button::Type::marker:
|
||||
painter.setOpacity(0.35);
|
||||
painter.setPen(QPen(modification.getColor(), 14));
|
||||
painter.drawLine(points[0], points[1]);
|
||||
painter.setOpacity(1);
|
||||
break;
|
||||
case Button::Type::pencil:
|
||||
painter.drawPolyline(points.data(), points.size());
|
||||
break;
|
||||
case Button::Type::rectangle:
|
||||
painter.drawRect(QRect(points[0], points[1]));
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
painter.setPen(QPen(modification.getColor(), 2));
|
||||
QVector<QPoint> points = modification.getPoints();
|
||||
switch (modification.getType()) {
|
||||
case Button::Type::arrow:
|
||||
painter.drawLine(points[0], points[1]);
|
||||
// TODO
|
||||
|
||||
break;
|
||||
case Button::Type::circle:
|
||||
painter.drawEllipse(QRect(points[0], points[1]));
|
||||
break;
|
||||
case Button::Type::line:
|
||||
painter.drawLine(points[0], points[1]);
|
||||
break;
|
||||
case Button::Type::marker:
|
||||
painter.setOpacity(0.35);
|
||||
painter.setPen(QPen(modification.getColor(), 14));
|
||||
painter.drawLine(points[0], points[1]);
|
||||
painter.setOpacity(1);
|
||||
break;
|
||||
case Button::Type::pencil:
|
||||
painter.drawPolyline(points.data(), points.size());
|
||||
break;
|
||||
case Button::Type::rectangle:
|
||||
painter.drawRect(QRect(points[0], points[1]));
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return m_screenshot;
|
||||
return m_modifiedScreenshot;
|
||||
}
|
||||
|
||||
QPixmap Screenshot::paintTemporalModification(const CaptureModification &modification) {
|
||||
QPixmap tempPix = m_modifiedScreenshot;
|
||||
QPainter painter(&tempPix);
|
||||
if (modification.getType() != Button::Type::pencil) {
|
||||
painter.setRenderHint(QPainter::Antialiasing);
|
||||
}
|
||||
|
||||
painter.setPen(QPen(modification.getColor(), 2));
|
||||
QVector<QPoint> points = modification.getPoints();
|
||||
switch (modification.getType()) {
|
||||
case Button::Type::arrow:
|
||||
painter.drawLine(points[0], points[1]);
|
||||
// TODO
|
||||
|
||||
break;
|
||||
case Button::Type::circle:
|
||||
painter.drawEllipse(QRect(points[0], points[1]));
|
||||
break;
|
||||
case Button::Type::line:
|
||||
painter.drawLine(points[0], points[1]);
|
||||
break;
|
||||
case Button::Type::marker:
|
||||
painter.setOpacity(0.35);
|
||||
painter.setPen(QPen(modification.getColor(), 14));
|
||||
painter.drawLine(points[0], points[1]);
|
||||
painter.setOpacity(1);
|
||||
break;
|
||||
case Button::Type::pencil:
|
||||
painter.drawPolyline(points.data(), points.size());
|
||||
break;
|
||||
case Button::Type::rectangle:
|
||||
painter.drawRect(QRect(points[0], points[1]));
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return tempPix;
|
||||
}
|
||||
|
||||
// paintBaseModifications overrides the modifications of the screenshot with new ones
|
||||
QPixmap Screenshot::paintBaseModifications(const QVector<CaptureModification> &m) {
|
||||
m_modifiedScreenshot = m_baseScreenshot;
|
||||
for (const CaptureModification modification: m) {
|
||||
paintModification(modification);
|
||||
}
|
||||
return m_modifiedScreenshot;
|
||||
}
|
||||
|
||||
void Screenshot::uploadToImgur(QNetworkAccessManager *accessManager,
|
||||
const QRect &selection) {
|
||||
QString title ="asdasdf";
|
||||
QString description = "test";
|
||||
QString title ="flameshot_screenshot";
|
||||
QString datetime = QDateTime().toString();
|
||||
QString description = "flameshot " + datetime;
|
||||
QPixmap pixToSave;
|
||||
if (selection.isEmpty()) {
|
||||
pixToSave = m_screenshot;
|
||||
pixToSave = m_modifiedScreenshot;
|
||||
} else { // save full screen when no selection
|
||||
pixToSave = m_screenshot.copy(selection);
|
||||
pixToSave = m_modifiedScreenshot.copy(selection);
|
||||
}
|
||||
QByteArray byteArray;
|
||||
QBuffer buffer(&byteArray);
|
||||
|
||||
@@ -32,14 +32,19 @@ public:
|
||||
~Screenshot();
|
||||
|
||||
void setScreenshot(const QPixmap &);
|
||||
QPixmap getBaseScreenshot() const;
|
||||
QPixmap getScreenshot() const;
|
||||
|
||||
QString graphicalSave(const QRect &selection = QRect()) const;
|
||||
void uploadToImgur(QNetworkAccessManager *,
|
||||
const QRect &selection = QRect());
|
||||
QPixmap paintModifications(const QVector<CaptureModification>);
|
||||
QPixmap paintModification(const CaptureModification &);
|
||||
QPixmap paintTemporalModification(const CaptureModification &);
|
||||
QPixmap paintBaseModifications(const QVector<CaptureModification> &);
|
||||
|
||||
private:
|
||||
QPixmap m_screenshot;
|
||||
QPixmap m_baseScreenshot;
|
||||
QPixmap m_modifiedScreenshot;
|
||||
QPointer<QNetworkAccessManager> m_accessManager;
|
||||
};
|
||||
|
||||
|
||||
@@ -47,11 +47,11 @@ void UIcolorEditor::initColorWheel() {
|
||||
}
|
||||
|
||||
void UIcolorEditor::initButton() {
|
||||
bool iconsAreWhite = false;
|
||||
QString bgColor = this->palette().color(QWidget::backgroundRole()).name();
|
||||
if (bgColor < QColor(Qt::gray).name()) {
|
||||
iconsAreWhite = true;
|
||||
}
|
||||
bool iconsAreWhite = QSettings().value("whiteIconColor").toBool();
|
||||
// QString bgColor = this->palette().color(QWidget::backgroundRole()).name();
|
||||
// if (bgColor < QColor(Qt::gray).name()) {
|
||||
// iconsAreWhite = true;
|
||||
// }
|
||||
m_button = new Button(Button::Type::circle, iconsAreWhite, this);
|
||||
m_button->setStyleSheet(Button::getStyle());
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user