From ae46699b95a1c8be79d6a85d25beef4784fef1fc Mon Sep 17 00:00:00 2001 From: ArsenArsen Date: Mon, 1 May 2017 11:28:54 +0200 Subject: [PATCH] Blur! --- KShare.pro | 13 +++- cropeditor/cropeditor.cpp | 2 +- cropeditor/cropscene.cpp | 8 ++- cropeditor/cropscene.hpp | 7 ++- cropeditor/drawing/bluritem.cpp | 36 +++++++++++ cropeditor/drawing/bluritem.hpp | 30 +++++++++ cropeditor/drawing/drawitem.hpp | 6 ++ cropeditor/drawing/lineitem.cpp | 2 +- cropeditor/settings/blurdialog.cpp | 43 +++++++++++++ cropeditor/settings/blurdialog.hpp | 29 +++++++++ cropeditor/settings/blurdialog.ui | 98 ++++++++++++++++++++++++++++++ main.cpp | 13 ++-- 12 files changed, 272 insertions(+), 15 deletions(-) create mode 100644 cropeditor/drawing/bluritem.cpp create mode 100644 cropeditor/drawing/bluritem.hpp create mode 100644 cropeditor/settings/blurdialog.cpp create mode 100644 cropeditor/settings/blurdialog.hpp create mode 100644 cropeditor/settings/blurdialog.ui diff --git a/KShare.pro b/KShare.pro index 2a50737..5689847 100644 --- a/KShare.pro +++ b/KShare.pro @@ -41,7 +41,10 @@ SOURCES += main.cpp\ hotkeying.cpp \ cropeditor/drawing/dotitem.cpp \ cropeditor/drawing/lineitem.cpp \ - cropeditor/settings/brushpenselection.cpp + cropeditor/settings/brushpenselection.cpp \ + effects.cpp \ + cropeditor/drawing/bluritem.cpp \ + cropeditor/settings/blurdialog.cpp HEADERS += mainwindow.hpp \ cropeditor/cropeditor.hpp \ @@ -62,10 +65,14 @@ HEADERS += mainwindow.hpp \ cropeditor/drawing/drawitem.hpp \ cropeditor/drawing/dotitem.hpp \ cropeditor/drawing/lineitem.hpp \ - cropeditor/settings/brushpenselection.hpp + cropeditor/settings/brushpenselection.hpp \ + effects.hpp \ + cropeditor/drawing/bluritem.hpp \ + cropeditor/settings/blurdialog.hpp FORMS += mainwindow.ui \ - cropeditor/settings/brushpenselection.ui + cropeditor/settings/brushpenselection.ui \ + cropeditor/settings/blurdialog.ui DISTFILES += \ README.md \ diff --git a/cropeditor/cropeditor.cpp b/cropeditor/cropeditor.cpp index d318422..b1e6848 100644 --- a/cropeditor/cropeditor.cpp +++ b/cropeditor/cropeditor.cpp @@ -9,7 +9,7 @@ CropEditor::CropEditor(QPixmap *image, QObject *parent) : QObject(parent) { - scene = new CropScene(parent); + scene = new CropScene(parent, image); view = new CropView(scene); pixmapItem = new QGraphicsPixmapItem(*image); diff --git a/cropeditor/cropscene.cpp b/cropeditor/cropscene.cpp index 881d4cd..e3a4cb9 100644 --- a/cropeditor/cropscene.cpp +++ b/cropeditor/cropscene.cpp @@ -6,12 +6,14 @@ #include #include #include +#include #include #include #include -CropScene::CropScene(QObject *parent) : QGraphicsScene(parent), prevButtons(Qt::NoButton) +CropScene::CropScene(QObject *parent, QPixmap *pixmap) : QGraphicsScene(parent), prevButtons(Qt::NoButton) { + _pixmap = pixmap; QTimer::singleShot(0, [&] { QPolygonF poly; poly.append(sceneRect().topLeft()); @@ -38,6 +40,7 @@ QBrush &CropScene::brush() void CropScene::setDrawingSelection(DrawItem *drawAction) { drawingSelection = drawAction; + drawAction->init(this); } void CropScene::mouseMoveEvent(QGraphicsSceneMouseEvent *e) @@ -116,7 +119,7 @@ void CropScene::addDrawingAction(QMenu &menu, DrawItem *item) { QAction *action = new QAction; action->setText(item->name()); - QObject::connect(action, &QAction::triggered, [this, item](bool) { setDrawingSelection(item); }); + connect(action, &QAction::triggered, [this, item](bool) { setDrawingSelection(item); }); menu.addAction(action); } @@ -126,6 +129,7 @@ void CropScene::contextMenuEvent(QGraphicsSceneContextMenuEvent *e) addDrawingAction(menu, new DotItem); addDrawingAction(menu, new LineItem); + addDrawingAction(menu, new BlurItem); menu.addSeparator(); QAction *settings = new QAction; diff --git a/cropeditor/cropscene.hpp b/cropeditor/cropscene.hpp index eb75e45..0284b15 100644 --- a/cropeditor/cropscene.hpp +++ b/cropeditor/cropscene.hpp @@ -15,10 +15,14 @@ class CropScene : public QGraphicsScene { Q_OBJECT public: - CropScene(QObject *parent); + CropScene(QObject *parent, QPixmap *pixmap); QPen &pen(); QBrush &brush(); void setDrawingSelection(DrawItem *drawAction); + QPixmap *pixmap() + { + return _pixmap; + } signals: void closedWithRect(QRect rect); @@ -34,6 +38,7 @@ class CropScene : public QGraphicsScene private: void addDrawingAction(QMenu &menu, DrawItem *item); void done(); + QPixmap *_pixmap; QFlags prevButtons; QGraphicsRectItem *rect = nullptr; QPointF initPos; diff --git a/cropeditor/drawing/bluritem.cpp b/cropeditor/drawing/bluritem.cpp new file mode 100644 index 0000000..d56c9bc --- /dev/null +++ b/cropeditor/drawing/bluritem.cpp @@ -0,0 +1,36 @@ +#include "bluritem.hpp" + +#include +#include +#include + +void BlurItem::init(CropScene *) +{ + effect = new QGraphicsBlurEffect; + BlurDialog(effect).exec(); +} + +void BlurItem::mouseDragEvent(QGraphicsSceneMouseEvent *e, CropScene *scene) +{ + if (pos.isNull()) + { + pos = e->scenePos(); + rect = scene->addRect(QRect(e->scenePos().toPoint(), QSize(1, 1)), QPen(Qt::cyan), Qt::NoBrush); + pixmap = scene->addPixmap(scene->pixmap()->copy(rect->rect().toRect())); + pixmap->setPos(e->scenePos()); + pixmap->setZValue(rect->zValue() - 0.1); + pixmap->setGraphicsEffect(effect); + } + else + { + QPointF p = e->scenePos(); + rect->setRect(QRect(qMin(pos.x(), p.x()), qMin(pos.y(), p.y()), qAbs(pos.x() - p.x()), qAbs(pos.y() - p.y()))); + pixmap->setPixmap(scene->pixmap()->copy(rect->rect().toRect())); + pixmap->setPos(rect->rect().topLeft()); + } +} + +void BlurItem::mouseDragEndEvent(QGraphicsSceneMouseEvent *, CropScene *) +{ + if (rect != nullptr) rect->setPen(Qt::NoPen); +} diff --git a/cropeditor/drawing/bluritem.hpp b/cropeditor/drawing/bluritem.hpp new file mode 100644 index 0000000..7a7bdb1 --- /dev/null +++ b/cropeditor/drawing/bluritem.hpp @@ -0,0 +1,30 @@ +#ifndef BLURITEM_HPP +#define BLURITEM_HPP + +#include "drawitem.hpp" + +#include + +class BlurItem : public DrawItem +{ + public: + QString name() + { + return "Blur"; + } + ~BlurItem() + { + } + + void init(CropScene *) override; + void mouseDragEvent(QGraphicsSceneMouseEvent *e, CropScene *scene) override; + void mouseDragEndEvent(QGraphicsSceneMouseEvent *, CropScene *) override; + + private: + QGraphicsBlurEffect *effect; + QPointF pos; + QGraphicsRectItem *rect; + QGraphicsPixmapItem *pixmap; +}; + +#endif // BLURITEM_HPP diff --git a/cropeditor/drawing/drawitem.hpp b/cropeditor/drawing/drawitem.hpp index 114e59a..e5b1705 100644 --- a/cropeditor/drawing/drawitem.hpp +++ b/cropeditor/drawing/drawitem.hpp @@ -1,6 +1,8 @@ #ifndef DRAWITEM_HPP #define DRAWITEM_HPP +class DrawItem; + #include #include @@ -11,6 +13,10 @@ class DrawItem { } virtual QString name() = 0; + virtual void init(CropScene *scene) + { + Q_UNUSED(scene) + } virtual void mouseDragEvent(QGraphicsSceneMouseEvent *e, CropScene *scene) = 0; virtual void mouseDragEndEvent(QGraphicsSceneMouseEvent *e, CropScene *scene) = 0; }; diff --git a/cropeditor/drawing/lineitem.cpp b/cropeditor/drawing/lineitem.cpp index 66d72f0..5494a6d 100644 --- a/cropeditor/drawing/lineitem.cpp +++ b/cropeditor/drawing/lineitem.cpp @@ -18,7 +18,7 @@ void LineItem::mouseDragEvent(QGraphicsSceneMouseEvent *e, CropScene *scene) } else { - path->lineTo(e->scenePos()); + path->quadTo(path->currentPosition(), e->scenePos()); pathItem->setPath(*path); } } diff --git a/cropeditor/settings/blurdialog.cpp b/cropeditor/settings/blurdialog.cpp new file mode 100644 index 0000000..9b6c131 --- /dev/null +++ b/cropeditor/settings/blurdialog.cpp @@ -0,0 +1,43 @@ +#include "blurdialog.hpp" +#include "ui_blurdialog.h" + +#include +#include +#include +#include + +BlurDialog::BlurDialog(QGraphicsBlurEffect *e, QWidget *parent) : QDialog(parent), ui(new Ui::BlurDialog) +{ + effect = e; + ui->setupUi(this); + ui->animated->setChecked(effect->blurHints().testFlag(QGraphicsBlurEffect::AnimationHint)); + ui->performance->setChecked(effect->blurHints().testFlag(QGraphicsBlurEffect::PerformanceHint)); + ui->quality->setChecked(effect->blurHints().testFlag(QGraphicsBlurEffect::QualityHint)); + ui->radSlider->setValue(effect->blurRadius() * 100); + ui->radSpinner->setValue(effect->blurRadius()); + connect(ui->buttonBox, &QDialogButtonBox::accepted, [&] { + QFlags hints; + hints.setFlag(QGraphicsBlurEffect::AnimationHint, ui->animated->isChecked()); + hints.setFlag(QGraphicsBlurEffect::PerformanceHint, ui->performance->isChecked()); + hints.setFlag(QGraphicsBlurEffect::QualityHint, ui->quality->isChecked()); + effect->setBlurHints(hints); + effect->setBlurRadius(ui->radSpinner->value()); + close(); + }); + connect(ui->buttonBox, &QDialogButtonBox::accepted, [&] { close(); }); +} + +BlurDialog::~BlurDialog() +{ + delete ui; +} + +void BlurDialog::on_radSpinner_valueChanged(double arg1) +{ + ui->radSlider->setValue(arg1 * 100); +} + +void BlurDialog::on_radSlider_sliderMoved(int position) +{ + ui->radSpinner->setValue(position / 100.); +} diff --git a/cropeditor/settings/blurdialog.hpp b/cropeditor/settings/blurdialog.hpp new file mode 100644 index 0000000..639feb8 --- /dev/null +++ b/cropeditor/settings/blurdialog.hpp @@ -0,0 +1,29 @@ +#ifndef BLURDIALOG_HPP +#define BLURDIALOG_HPP + +#include +#include + +namespace Ui +{ +class BlurDialog; +} + +class BlurDialog : public QDialog +{ + Q_OBJECT + + public: + explicit BlurDialog(QGraphicsBlurEffect *effect, QWidget *parent = 0); + ~BlurDialog(); + + private slots: + void on_radSpinner_valueChanged(double arg1); + void on_radSlider_sliderMoved(int position); + + private: + Ui::BlurDialog *ui; + QGraphicsBlurEffect *effect; +}; + +#endif // BLURDIALOG_HPP diff --git a/cropeditor/settings/blurdialog.ui b/cropeditor/settings/blurdialog.ui new file mode 100644 index 0000000..55a3f70 --- /dev/null +++ b/cropeditor/settings/blurdialog.ui @@ -0,0 +1,98 @@ + + + BlurDialog + + + + 0 + 0 + 400 + 222 + + + + Blur Settings + + + + + + 3000 + + + Qt::Horizontal + + + + + + + px + + + 30.000000000000000 + + + + + + + http://doc.qt.io/qt-5/qgraphicsblureffect.html#BlurHint-enum + + + <a href="http://doc.qt.io/qt-5/qgraphicsblureffect.html#BlurHint-enum">Blur Hints + + + true + + + Qt::TextBrowserInteraction + + + + + + + Blur Radius + + + + + + + Performance Hint + + + + + + + Animated Hint + + + + + + + Quality Hint + + + + + + + Qt::Horizontal + + + QDialogButtonBox::Cancel|QDialogButtonBox::Ok + + + true + + + + + + + + diff --git a/main.cpp b/main.cpp index fe3eaa4..99bddb2 100644 --- a/main.cpp +++ b/main.cpp @@ -7,26 +7,25 @@ bool verbose = false; -void handler(QtMsgType type, const QMessageLogContext &context, const QString &msg) +void handler(QtMsgType type, const QMessageLogContext &, const QString &msg) { QByteArray localMsg = msg.toLocal8Bit(); switch (type) { case QtDebugMsg: - if (verbose) - fprintf(stdout, "DEBUG %s:%s(%d): %s\n", context.file, context.function, context.line, localMsg.constData()); + if (verbose) fprintf(stderr, "DEBUG: %s\n", localMsg.constData()); break; case QtInfoMsg: - fprintf(stdout, "INFO %s:%s(%d): %s\n", context.file, context.function, context.line, localMsg.constData()); + fprintf(stderr, "INFO: %s\n", localMsg.constData()); break; case QtWarningMsg: - fprintf(stdout, "WARN %s:%s(%d): %s\n", context.file, context.function, context.line, localMsg.constData()); + fprintf(stderr, "WARN: %s\n", localMsg.constData()); break; case QtCriticalMsg: - fprintf(stdout, "CRIT %s:%s(%d): %s\n", context.file, context.function, context.line, localMsg.constData()); + fprintf(stderr, "CRIT: %s\n", localMsg.constData()); break; case QtFatalMsg: - fprintf(stdout, "FATAL %s:%s(%d): %s\n", context.file, context.function, context.line, localMsg.constData()); + fprintf(stderr, "FATAL: %s\n", localMsg.constData()); break; } }