From 5432614651f7fad4f764cdd31d3a9d81970aa732 Mon Sep 17 00:00:00 2001 From: lupoDharkael Date: Sun, 6 May 2018 13:56:45 +0200 Subject: [PATCH] Add Text tool closes #11 Add an initial version of the text tool. This commit adds: - Basic text tool. - On demand thickness and color update. - Generalized logic for future widget based tools. --- flameshot.pro | 10 +- graphics.qrc | 2 + img/buttonIconsBlack/text.png | Bin 0 -> 120 bytes img/buttonIconsBlack/text.svg | 4 + img/buttonIconsWhite/text.png | Bin 0 -> 121 bytes img/buttonIconsWhite/text.svg | 60 ++++++++++ src/core/controller.cpp | 1 + src/tools/abstractactiontool.cpp | 8 ++ src/tools/abstractactiontool.h | 4 +- src/tools/abstractpathtool.cpp | 8 ++ src/tools/abstractpathtool.h | 3 + src/tools/abstracttwopointtool.cpp | 8 ++ src/tools/abstracttwopointtool.h | 3 + src/tools/arrow/arrowtool.h | 3 - src/tools/capturetool.h | 40 ++++++- src/tools/circle/circletool.h | 3 - src/tools/line/linetool.h | 3 - src/tools/marker/markertool.cpp | 4 + src/tools/marker/markertool.h | 4 +- src/tools/pencil/penciltool.h | 3 - src/tools/pin/pintool.cpp | 6 +- src/tools/rectangle/rectangletool.h | 3 - src/tools/selection/selectiontool.h | 3 - src/tools/text/textconfig.cpp | 24 ++++ src/tools/text/textconfig.h | 31 ++++++ src/tools/text/texttool.cpp | 151 ++++++++++++++++++++++++++ src/tools/text/texttool.h | 69 ++++++++++++ src/tools/text/textwidget.cpp | 87 +++++++++++++++ src/tools/text/textwidget.h | 49 +++++++++ src/tools/toolfactory.cpp | 4 + src/widgets/capture/capturebutton.cpp | 24 ++-- src/widgets/capture/capturebutton.h | 1 + src/widgets/capture/capturewidget.cpp | 93 +++++++++++++--- src/widgets/capture/capturewidget.h | 7 ++ 34 files changed, 666 insertions(+), 57 deletions(-) create mode 100755 img/buttonIconsBlack/text.png create mode 100755 img/buttonIconsBlack/text.svg create mode 100755 img/buttonIconsWhite/text.png create mode 100644 img/buttonIconsWhite/text.svg create mode 100644 src/tools/text/textconfig.cpp create mode 100644 src/tools/text/textconfig.h create mode 100644 src/tools/text/texttool.cpp create mode 100644 src/tools/text/texttool.h create mode 100644 src/tools/text/textwidget.cpp create mode 100644 src/tools/text/textwidget.h diff --git a/flameshot.pro b/flameshot.pro index a9c755f8..87cb3944 100644 --- a/flameshot.pro +++ b/flameshot.pro @@ -134,7 +134,10 @@ SOURCES += src/main.cpp \ src/widgets/capture/hovereventfilter.cpp \ src/widgets/capture/selectionwidget.cpp \ src/tools/pin/pinwidget.cpp \ - src/core/capturerequest.cpp + src/tools/text/texttool.cpp \ + src/tools/text/textwidget.cpp \ + src/core/capturerequest.cpp \ + src/tools/text/textconfig.cpp HEADERS += src/widgets/capture/buttonhandler.h \ src/widgets/infowindow.h \ @@ -202,7 +205,10 @@ HEADERS += src/widgets/capture/buttonhandler.h \ src/widgets/capture/hovereventfilter.h \ src/widgets/capture/selectionwidget.h \ src/tools/pin/pinwidget.h \ - src/core/capturerequest.h + src/tools/text/texttool.h \ + src/tools/text/textwidget.h \ + src/core/capturerequest.h \ + src/tools/text/textconfig.h unix:!macx { SOURCES += src/core/flameshotdbusadapter.cpp \ diff --git a/graphics.qrc b/graphics.qrc index 963c8b1f..590d6183 100644 --- a/graphics.qrc +++ b/graphics.qrc @@ -47,5 +47,7 @@ img/buttonIconsWhite/redo-variant.png img/buttonIconsBlack/pin.png img/buttonIconsWhite/pin.png + img/buttonIconsBlack/text.png + img/buttonIconsWhite/text.png diff --git a/img/buttonIconsBlack/text.png b/img/buttonIconsBlack/text.png new file mode 100755 index 0000000000000000000000000000000000000000..5e137e0fef20f32a27c957d6cb321916c8e0ab81 GIT binary patch literal 120 zcmeAS@N?(olHy`uVBq!ia0vp^Dj>|k0wldT1B8K;y{C&~NCjiE1Y3fLiNPOrA+w%{ zW*G^ofCo%FjpgQu&X%Q~loCIA@rA1wd? literal 0 HcmV?d00001 diff --git a/img/buttonIconsBlack/text.svg b/img/buttonIconsBlack/text.svg new file mode 100755 index 00000000..342d4033 --- /dev/null +++ b/img/buttonIconsBlack/text.svg @@ -0,0 +1,4 @@ + + + + diff --git a/img/buttonIconsWhite/text.png b/img/buttonIconsWhite/text.png new file mode 100755 index 0000000000000000000000000000000000000000..9288e78c899c1ecda4c504bfc5fddc6465e5dbf2 GIT binary patch literal 121 zcmeAS@N?(olHy`uVBq!ia0vp^Dj>|k0wldT1B8K;gQtsQNCjiE#IFRAKlwlWbuuJ2 zvRVGgcWC5(ASJ%wq{RfWAAAPI2Bv(z&2GF>rWscj1U8F2P+i32=ejsSgn@yhy+dw| S*a;b+Sqz@8elF{r5}E+nO(6UL literal 0 HcmV?d00001 diff --git a/img/buttonIconsWhite/text.svg b/img/buttonIconsWhite/text.svg new file mode 100644 index 00000000..32074fd5 --- /dev/null +++ b/img/buttonIconsWhite/text.svg @@ -0,0 +1,60 @@ + + + + + + image/svg+xml + + + + + + + + + + diff --git a/src/core/controller.cpp b/src/core/controller.cpp index 671686b6..651db8b1 100644 --- a/src/core/controller.cpp +++ b/src/core/controller.cpp @@ -104,6 +104,7 @@ void Controller::startVisualCapture(const uint id, const QString &forcedSavePath } while (modalWidget); m_captureWindow = new CaptureWidget(id, forcedSavePath); + //m_captureWindow = new CaptureWidget(id, forcedSavePath, false); // debug connect(m_captureWindow, &CaptureWidget::captureFailed, this, &Controller::captureFailed); connect(m_captureWindow, &CaptureWidget::captureTaken, diff --git a/src/tools/abstractactiontool.cpp b/src/tools/abstractactiontool.cpp index 0ff58f85..7b9d28b7 100644 --- a/src/tools/abstractactiontool.cpp +++ b/src/tools/abstractactiontool.cpp @@ -69,3 +69,11 @@ void AbstractActionTool::drawMove(const QPoint &p) { void AbstractActionTool::drawStart(const CaptureContext &context) { Q_UNUSED(context); } + +void AbstractActionTool::colorChanged(const QColor &c) { + Q_UNUSED(c); +} + +void AbstractActionTool::thicknessChanged(const int th) { + Q_UNUSED(th); +} diff --git a/src/tools/abstractactiontool.h b/src/tools/abstractactiontool.h index f424a791..788d4c4b 100644 --- a/src/tools/abstractactiontool.h +++ b/src/tools/abstractactiontool.h @@ -19,7 +19,7 @@ #include "capturetool.h" -class AbstractActionTool : public CaptureTool{ +class AbstractActionTool : public CaptureTool { Q_OBJECT public: explicit AbstractActionTool(QObject *parent = nullptr); @@ -39,4 +39,6 @@ public slots: void drawEnd(const QPoint &p) override; void drawMove(const QPoint &p) override; void drawStart(const CaptureContext &context) override; + void colorChanged(const QColor &c) override; + void thicknessChanged(const int th) override; }; diff --git a/src/tools/abstractpathtool.cpp b/src/tools/abstractpathtool.cpp index 52b9dcf6..8df38ef9 100644 --- a/src/tools/abstractpathtool.cpp +++ b/src/tools/abstractpathtool.cpp @@ -63,6 +63,14 @@ void AbstractPathTool::drawMove(const QPoint &p) { addPoint(p); } +void AbstractPathTool::colorChanged(const QColor &c) { + m_color = c; +} + +void AbstractPathTool::thicknessChanged(const int th) { + m_thickness = th; +} + void AbstractPathTool::updateBackup(const QPixmap &pixmap) { const int val = m_thickness + m_padding; QRect area = m_backupArea.normalized() + QMargins(val, val, val, val); diff --git a/src/tools/abstractpathtool.h b/src/tools/abstractpathtool.h index a97b5c88..aef05ce4 100644 --- a/src/tools/abstractpathtool.h +++ b/src/tools/abstractpathtool.h @@ -37,6 +37,8 @@ public: public slots: void drawEnd(const QPoint &p) override; void drawMove(const QPoint &p) override; + void colorChanged(const QColor &c) override; + void thicknessChanged(const int th) override; protected: void updateBackup(const QPixmap &pixmap); @@ -44,6 +46,7 @@ protected: QPixmap m_pixmapBackup; QRect m_backupArea; + QColor m_color; QVector m_points; int m_thickness; // use m_padding to extend the area of the backup diff --git a/src/tools/abstracttwopointtool.cpp b/src/tools/abstracttwopointtool.cpp index 3de0d460..1a3cc5fb 100644 --- a/src/tools/abstracttwopointtool.cpp +++ b/src/tools/abstracttwopointtool.cpp @@ -60,6 +60,14 @@ void AbstractTwoPointTool::drawMove(const QPoint &p) { m_points.second = p; } +void AbstractTwoPointTool::colorChanged(const QColor &c) { + m_color = c; +} + +void AbstractTwoPointTool::thicknessChanged(const int th) { + m_thickness = th; +} + void AbstractTwoPointTool::updateBackup(const QPixmap &pixmap) { m_pixmapBackup = pixmap.copy(backupRect(pixmap.rect())); } diff --git a/src/tools/abstracttwopointtool.h b/src/tools/abstracttwopointtool.h index 4b3bdedc..25416e2a 100644 --- a/src/tools/abstracttwopointtool.h +++ b/src/tools/abstracttwopointtool.h @@ -37,6 +37,8 @@ public: public slots: void drawEnd(const QPoint &p) override; void drawMove(const QPoint &p) override; + void colorChanged(const QColor &c) override; + void thicknessChanged(const int th) override; protected: void updateBackup(const QPixmap &pixmap); @@ -44,6 +46,7 @@ protected: QPixmap m_pixmapBackup; QPair m_points; + QColor m_color; int m_thickness; // use m_padding to extend the area of the backup int m_padding; diff --git a/src/tools/arrow/arrowtool.h b/src/tools/arrow/arrowtool.h index 812e768e..abdbe336 100644 --- a/src/tools/arrow/arrowtool.h +++ b/src/tools/arrow/arrowtool.h @@ -38,7 +38,4 @@ public: public slots: void drawStart(const CaptureContext &context) override; void pressed(const CaptureContext &context) override; - -private: - QColor m_color; }; diff --git a/src/tools/capturetool.h b/src/tools/capturetool.h index dd493ece..1c352515 100644 --- a/src/tools/capturetool.h +++ b/src/tools/capturetool.h @@ -29,20 +29,38 @@ class CaptureTool : public QObject { public: // Request actions on the main widget enum Request { + // Call close() in the editor. REQ_CLOSE_GUI, + // Call hide() in the editor. REQ_HIDE_GUI, + // Select the whole screen. REQ_SELECT_ALL, + // Disable the selection. REQ_HIDE_SELECTION, + // Undo the last active modification in the stack. REQ_UNDO_MODIFICATION, + // Redo the next modification in the stack. REQ_REDO_MODIFICATION, + // Remove all the modifications. REQ_CLEAR_MODIFICATIONS, + // Disable the active tool. REQ_MOVE_MODE, + // Open the color picker under the mouse. REQ_SHOW_COLOR_PICKER, + // Open/Close the side-panel. REQ_TOGGLE_SIDEBAR, + // Call update() in the editor. REQ_REDRAW, + // Append this tool to the undo/redo stack + REQ_APPEND_TO_STACK, + // Notify is the screenshot has been saved. REQ_CAPTURE_DONE_OK, - REQ_ADD_CHILD_WIDGETS, + // Instance this->widget()'s widget inside the editor under the mouse. + REQ_ADD_CHILD_WIDGET, + // Instance this->widget()'s widget as a window which closes after + // closing the editor. REQ_ADD_CHILD_WINDOW, + // Instance this->widget()'s widget which handles its own lifetime. REQ_ADD_EXTERNAL_WIDGETS, }; @@ -69,6 +87,7 @@ public: // Codename for the tool, this hsouldn't change as it is used as ID // for the tool in the internals of Flameshot static QString nameID(); + // Short description of the tool. virtual QString description() const = 0; // if the type is TYPE_WIDGET the widget is loaded in the main widget. @@ -84,8 +103,12 @@ public: // revert changes virtual void undo(QPixmap &pixmap) = 0; // Called everytime the tool has to draw - virtual void process( - QPainter &painter, const QPixmap &pixmap, bool recordUndo = false) = 0; + // recordUndo indicates when the tool should save the information + // for the undo(), if the value is false calling undo() after + // that process should not modify revert the changes. + virtual void process(QPainter &painter, + const QPixmap &pixmap, + bool recordUndo = false) = 0; // When the tool is selected, this is called when the mouse moves virtual void paintMousePreview(QPainter &painter, const CaptureContext &context) = 0; @@ -99,11 +122,16 @@ protected: } public slots: - // On mouse release + // On mouse release. virtual void drawEnd(const QPoint &p) = 0; - // Mouse pressed and moving, called once a pixel + // Mouse pressed and moving, called once a pixel. virtual void drawMove(const QPoint &p) = 0; - // Called when the tool is activated + // Called when the tool is activated. virtual void drawStart(const CaptureContext &context) = 0; + // Called right after pressign the button which activates the tool. virtual void pressed(const CaptureContext &context) = 0; + // Called when the color is changed in the editor. + virtual void colorChanged(const QColor &c) = 0; + // Called when the thickness of the tool is updated in the editor. + virtual void thicknessChanged(const int th) = 0; }; diff --git a/src/tools/circle/circletool.h b/src/tools/circle/circletool.h index da03ecbe..7d06fbc2 100644 --- a/src/tools/circle/circletool.h +++ b/src/tools/circle/circletool.h @@ -37,7 +37,4 @@ public: public slots: void drawStart(const CaptureContext &context) override; void pressed(const CaptureContext &context) override; - -private: - QColor m_color; }; diff --git a/src/tools/line/linetool.h b/src/tools/line/linetool.h index 1a3629fc..0705138a 100644 --- a/src/tools/line/linetool.h +++ b/src/tools/line/linetool.h @@ -38,7 +38,4 @@ public slots: void drawMove(const QPoint &p) override; void drawStart(const CaptureContext &context) override; void pressed(const CaptureContext &context) override; - -private: - QColor m_color; }; diff --git a/src/tools/marker/markertool.cpp b/src/tools/marker/markertool.cpp index 6fdaf737..d2eccfc2 100644 --- a/src/tools/marker/markertool.cpp +++ b/src/tools/marker/markertool.cpp @@ -86,3 +86,7 @@ void MarkerTool::drawStart(const CaptureContext &context) { void MarkerTool::pressed(const CaptureContext &context) { Q_UNUSED(context); } + +void MarkerTool::thicknessChanged(const int th) { + m_thickness = th + PADDING_VALUE; +} diff --git a/src/tools/marker/markertool.h b/src/tools/marker/markertool.h index bac7577a..f39f6d5e 100644 --- a/src/tools/marker/markertool.h +++ b/src/tools/marker/markertool.h @@ -38,7 +38,5 @@ public slots: void drawMove(const QPoint &p) override; void drawStart(const CaptureContext &context) override; void pressed(const CaptureContext &context) override; - -private: - QColor m_color; + void thicknessChanged(const int th) override; }; diff --git a/src/tools/pencil/penciltool.h b/src/tools/pencil/penciltool.h index 9cf5314a..621c1a00 100644 --- a/src/tools/pencil/penciltool.h +++ b/src/tools/pencil/penciltool.h @@ -38,7 +38,4 @@ public: public slots: void drawStart(const CaptureContext &context) override; void pressed(const CaptureContext &context) override; - -private: - QColor m_color; }; diff --git a/src/tools/pin/pintool.cpp b/src/tools/pin/pintool.cpp index c206b311..474660be 100755 --- a/src/tools/pin/pintool.cpp +++ b/src/tools/pin/pintool.cpp @@ -45,7 +45,11 @@ QString PinTool::description() const { QWidget* PinTool::widget() { PinWidget *w = new PinWidget(m_pixmap); const int &&m = w->margin(); - QRect adjusted_pos = m_geometry + QMargins(m,m,m,m); +#ifdef Q_OS_LINUX + QRect adjusted_pos = m_geometry + QMargins(m,-m,-m,-m); +#else + QRect adjusted_pos = m_geometry + QMargins(m, m, m, m); +#endif w->setGeometry(adjusted_pos); return w; } diff --git a/src/tools/rectangle/rectangletool.h b/src/tools/rectangle/rectangletool.h index be4c0043..dd04cfac 100644 --- a/src/tools/rectangle/rectangletool.h +++ b/src/tools/rectangle/rectangletool.h @@ -37,7 +37,4 @@ public: public slots: void drawStart(const CaptureContext &context) override; void pressed(const CaptureContext &context) override; - -private: - QColor m_color; }; diff --git a/src/tools/selection/selectiontool.h b/src/tools/selection/selectiontool.h index f9195fba..23610866 100644 --- a/src/tools/selection/selectiontool.h +++ b/src/tools/selection/selectiontool.h @@ -39,7 +39,4 @@ public: public slots: void drawStart(const CaptureContext &context) override; void pressed(const CaptureContext &context) override; - -private: - QColor m_color; }; diff --git a/src/tools/text/textconfig.cpp b/src/tools/text/textconfig.cpp new file mode 100644 index 00000000..6f586aae --- /dev/null +++ b/src/tools/text/textconfig.cpp @@ -0,0 +1,24 @@ +// Copyright(c) 2017-2018 Alejandro Sirgo Rica & Contributors +// +// This file is part of Flameshot. +// +// Flameshot is free 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. +// +// Flameshot 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 +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with Flameshot. If not, see . + +#include "textconfig.h" + +TextConfig::TextConfig(QWidget *parent) : QWidget(parent) { + +} + +// https://doc.qt.io/qt-5/qfontdatabase.html#details diff --git a/src/tools/text/textconfig.h b/src/tools/text/textconfig.h new file mode 100644 index 00000000..c5854eda --- /dev/null +++ b/src/tools/text/textconfig.h @@ -0,0 +1,31 @@ +// Copyright(c) 2017-2018 Alejandro Sirgo Rica & Contributors +// +// This file is part of Flameshot. +// +// Flameshot is free 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. +// +// Flameshot 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 +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with Flameshot. If not, see . + +#pragma once + +#include + +class TextConfig : public QWidget { + Q_OBJECT +public: + explicit TextConfig(QWidget *parent = nullptr); + +signals: + void fontFamilyChanged(const QString &f); + +public slots: +}; diff --git a/src/tools/text/texttool.cpp b/src/tools/text/texttool.cpp new file mode 100644 index 00000000..e933a667 --- /dev/null +++ b/src/tools/text/texttool.cpp @@ -0,0 +1,151 @@ +// Copyright(c) 2017-2018 Alejandro Sirgo Rica & Contributors +// +// This file is part of Flameshot. +// +// Flameshot is free 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. +// +// Flameshot 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 +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with Flameshot. If not, see . + +#include "texttool.h" +#include "textwidget.h" +#include "textconfig.h" + +#define BASE_POINT_SIZE 8 + +TextTool::TextTool(QObject *parent) : CaptureTool(parent) { + +} + +bool TextTool::isValid() const { + return !m_text.isEmpty(); +} + +bool TextTool::closeOnButtonPressed() const { + return false; +} + +bool TextTool::isSelectable() const { + return true; +} + +bool TextTool::showMousePreview() const { + return false; +} + +QIcon TextTool::icon(const QColor &background, bool inEditor) const { + Q_UNUSED(inEditor); + return QIcon(iconPath(background) + "text.png"); +} + +QString TextTool::name() const { + return tr("Text"); +} + +QString TextTool::nameID() { + return ""; +} + +QString TextTool::description() const { + return tr("Add text to your capture"); +} + +QWidget *TextTool::widget() { + TextWidget *w = new TextWidget(); + w->setTextColor(m_color); + m_font.setPointSize(m_size + BASE_POINT_SIZE); + w->setFont(m_font); + connect(w, &TextWidget::textUpdated, + this, &TextTool::updateText); + m_widget = w; + return w; +} + +QWidget *TextTool::configurationWidget() { + TextConfig *w = nullptr;//new TextConfig(); + // TODO CONNECT + return w; +} + +CaptureTool *TextTool::copy(QObject *parent) { + return new TextTool(parent); +} + +void TextTool::undo(QPixmap &pixmap) { + QPainter p(&pixmap); + p.drawPixmap(m_backupArea.topLeft(), m_pixmapBackup); +} + +void TextTool::process(QPainter &painter, const QPixmap &pixmap, bool recordUndo) { + // TODO updateBackup() of others + if (m_text.isEmpty()) { + return; + } + QFontMetrics fm(m_font); + QSize size(fm.boundingRect(QRect(), 0, m_text).size()); + m_backupArea.setSize(size); + if (recordUndo) { + m_pixmapBackup = pixmap.copy(m_backupArea + QMargins(0, 0, 5, 5)); + } + // draw text + painter.setFont(m_font); + painter.setPen(m_color); + painter.drawText(m_backupArea + QMargins(-5, -5, 5, 5), m_text); +} + +void TextTool::paintMousePreview(QPainter &painter, const CaptureContext &context) { + Q_UNUSED(painter); + Q_UNUSED(context); +} + +void TextTool::drawEnd(const QPoint &p) { + m_backupArea.moveTo(p); +} + +void TextTool::drawMove(const QPoint &p) { + m_widget->move(p); +} + +void TextTool::drawStart(const CaptureContext &context) { + m_color = context.color; + m_size = context.thickness; + emit requestAction(REQ_ADD_CHILD_WIDGET); +} + +void TextTool::pressed(const CaptureContext &context) { + Q_UNUSED(context); +} + +void TextTool::colorChanged(const QColor &c) { + m_color = c; + if (m_widget) { + m_widget->setTextColor(c); + } +} + +void TextTool::thicknessChanged(const int th) { + m_size = th; + m_font.setPointSize(m_size + BASE_POINT_SIZE); + if (m_widget) { + m_widget->setFont(m_font); + } +} + +void TextTool::updateText(const QString &s) { + m_text = s; +} + +void TextTool::setFont(const QFont &f) { + m_font = f; + if (m_widget) { + m_widget->setFont(f); + } +} diff --git a/src/tools/text/texttool.h b/src/tools/text/texttool.h new file mode 100644 index 00000000..2f78dc0d --- /dev/null +++ b/src/tools/text/texttool.h @@ -0,0 +1,69 @@ +// Copyright(c) 2017-2018 Alejandro Sirgo Rica & Contributors +// +// This file is part of Flameshot. +// +// Flameshot is free 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. +// +// Flameshot 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 +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with Flameshot. If not, see . + +#pragma once + +#include "src/tools/capturetool.h" +#include + +class TextWidget; + +class TextTool : public CaptureTool { +public: + explicit TextTool(QObject *parent = nullptr); + + bool isValid() const override; + bool closeOnButtonPressed() const override; + bool isSelectable() const override; + bool showMousePreview() const override; + + QIcon icon(const QColor &background, + bool inEditor) const override; + QString name() const override; + static QString nameID(); + QString description() const override; + + QWidget* widget() override; + QWidget* configurationWidget() override; + CaptureTool* copy(QObject *parent = nullptr) override; + + void undo(QPixmap &pixmap) override; + void process( + QPainter &painter, const QPixmap &pixmap, bool recordUndo = false) override; + void paintMousePreview(QPainter &painter, const CaptureContext &context) override; + +public slots: + void drawEnd(const QPoint &p) override; + void drawMove(const QPoint &p) override; + void drawStart(const CaptureContext &context) override; + void pressed(const CaptureContext &context) override; + void colorChanged(const QColor &c) override; + void thicknessChanged(const int th) override; + +private slots: + void updateText(const QString &s); + void setFont(const QFont &f); + +private: + QString m_text; + QFont m_font; + int m_size; + QColor m_color; + QPixmap m_pixmapBackup; + QRect m_backupArea; + QPointer m_widget; +}; diff --git a/src/tools/text/textwidget.cpp b/src/tools/text/textwidget.cpp new file mode 100644 index 00000000..100b4c71 --- /dev/null +++ b/src/tools/text/textwidget.cpp @@ -0,0 +1,87 @@ +// Copyright(c) 2017-2018 Alejandro Sirgo Rica & Contributors +// +// This file is part of Flameshot. +// +// Flameshot is free 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. +// +// Flameshot 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 +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with Flameshot. If not, see . + +#include "textwidget.h" + +TextWidget::TextWidget(QWidget *parent) : QTextEdit(parent) { + setStyleSheet("TextWidget { background: transparent; }"); + connect(this, &TextWidget::textChanged, + this, &TextWidget::adjustSize); + connect(this, &TextWidget::textChanged, + this, &TextWidget::emitTextUpdated); + setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff); + setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff); + setContextMenuPolicy(Qt::NoContextMenu); +} + +void TextWidget::showEvent(QShowEvent *e) { + QFont font; + QFontMetrics fm(font); + setFixedWidth(fm.lineSpacing() *6); + setFixedHeight(fm.lineSpacing() * 2.5); + m_baseSize = size(); + m_minSize = m_baseSize; + QTextEdit::showEvent(e); + adjustSize(); +} + +void TextWidget::resizeEvent(QResizeEvent *e) { + m_minSize.setHeight(qMin(m_baseSize.height(), height())); + m_minSize.setWidth(qMin(m_baseSize.width(), width())); + QTextEdit::resizeEvent(e); +} + +void TextWidget::setFont(const QFont &f) { + QTextEdit::setFont(f); + adjustSize(); +} + +void TextWidget::updateFont(const QFont &f) { + setFont(f); +} + +void TextWidget::setFontPointSize(qreal s) { + QFont f = font(); + f.setPointSize(s); + setFont(f); +} + +void TextWidget::setTextColor(const QColor &c) { + QString s("TextWidget { background: transparent; color: %1; }"); + setStyleSheet(s.arg(c.name())); +} + +void TextWidget::adjustSize() { + QString &&text = this->toPlainText(); + + QFontMetrics fm(font()); + QRect bounds = fm.boundingRect(QRect(), 0, text); + int pixelsWide = bounds.width() + fm.lineSpacing(); + int pixelsHigh = bounds.height() * 1.15 + fm.lineSpacing(); + if (pixelsWide < m_minSize.width()) { + pixelsWide = m_minSize.width(); + } + if (pixelsHigh < m_minSize.height()) { + pixelsHigh = m_minSize.height(); + } + + this->setFixedSize(pixelsWide, pixelsHigh); +} + +void TextWidget::emitTextUpdated() { + emit textUpdated(this->toPlainText()); +} diff --git a/src/tools/text/textwidget.h b/src/tools/text/textwidget.h new file mode 100644 index 00000000..7d12b2f5 --- /dev/null +++ b/src/tools/text/textwidget.h @@ -0,0 +1,49 @@ +// Copyright(c) 2017-2018 Alejandro Sirgo Rica & Contributors +// +// This file is part of Flameshot. +// +// Flameshot is free 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. +// +// Flameshot 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 +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with Flameshot. If not, see . + +#pragma once + +#include + +class TextWidget : public QTextEdit +{ + Q_OBJECT +public: + explicit TextWidget(QWidget *parent = nullptr); + + void adjustSize(); + void setFont(const QFont &f); + +protected: + void showEvent(QShowEvent *e); + void resizeEvent(QResizeEvent *e); + +signals: + void textUpdated(const QString &s); + +public slots: + void updateFont(const QFont &f); + void setTextColor(const QColor &c); + void setFontPointSize(qreal s); + +private slots: + void emitTextUpdated(); + +private: + QSize m_baseSize; + QSize m_minSize; +}; diff --git a/src/tools/toolfactory.cpp b/src/tools/toolfactory.cpp index c7ed19ec..9638b598 100644 --- a/src/tools/toolfactory.cpp +++ b/src/tools/toolfactory.cpp @@ -34,6 +34,7 @@ #include "blur/blurtool.h" #include "redo/redotool.h" #include "pin/pintool.h" +#include "text/texttool.h" ToolFactory::ToolFactory(QObject *parent) : QObject(parent) { @@ -99,6 +100,9 @@ CaptureTool* ToolFactory::CreateTool( case CaptureButton::TYPE_PIN: tool = new PinTool(parent); break; + case CaptureButton::TYPE_TEXT: + tool = new TextTool(parent); + break; default: tool = nullptr; break; diff --git a/src/widgets/capture/capturebutton.cpp b/src/widgets/capture/capturebutton.cpp index d4240497..fed3d50f 100644 --- a/src/widgets/capture/capturebutton.cpp +++ b/src/widgets/capture/capturebutton.cpp @@ -158,17 +158,18 @@ static std::map buttonTypeOrder { { CaptureButton::TYPE_RECTANGLE, 4 }, { CaptureButton::TYPE_CIRCLE, 5 }, { CaptureButton::TYPE_MARKER, 6 }, - { CaptureButton::TYPE_SELECTIONINDICATOR, 8 }, - { CaptureButton::TYPE_MOVESELECTION, 9 }, - { CaptureButton::TYPE_UNDO, 10 }, - { CaptureButton::TYPE_COPY, 12 }, - { CaptureButton::TYPE_SAVE, 13 }, - { CaptureButton::TYPE_EXIT, 14 }, - { CaptureButton::TYPE_IMAGEUPLOADER, 15 }, - { CaptureButton::TYPE_OPEN_APP, 16 }, - { CaptureButton::TYPE_PIN, 17 }, - { CaptureButton::TYPE_BLUR, 7 }, - { CaptureButton::TYPE_REDO, 11 }, + { CaptureButton::TYPE_TEXT, 7 }, + { CaptureButton::TYPE_BLUR, 8 }, + { CaptureButton::TYPE_SELECTIONINDICATOR, 9 }, + { CaptureButton::TYPE_MOVESELECTION, 10 }, + { CaptureButton::TYPE_UNDO, 11 }, + { CaptureButton::TYPE_REDO, 12 }, + { CaptureButton::TYPE_COPY, 13 }, + { CaptureButton::TYPE_SAVE, 14 }, + { CaptureButton::TYPE_EXIT, 15 }, + { CaptureButton::TYPE_IMAGEUPLOADER, 16 }, + { CaptureButton::TYPE_OPEN_APP, 17 }, + { CaptureButton::TYPE_PIN, 18 }, }; int CaptureButton::getPriorityByButton(CaptureButton::ButtonType b) { @@ -184,6 +185,7 @@ QVector CaptureButton::iterableButtonTypes = { CaptureButton::TYPE_RECTANGLE, CaptureButton::TYPE_CIRCLE, CaptureButton::TYPE_MARKER, + CaptureButton::TYPE_TEXT, CaptureButton::TYPE_BLUR, CaptureButton::TYPE_SELECTIONINDICATOR, CaptureButton::TYPE_MOVESELECTION, diff --git a/src/widgets/capture/capturebutton.h b/src/widgets/capture/capturebutton.h index 7ed11ddd..fdeaa08d 100644 --- a/src/widgets/capture/capturebutton.h +++ b/src/widgets/capture/capturebutton.h @@ -51,6 +51,7 @@ public: TYPE_BLUR = 15, TYPE_REDO = 16, TYPE_PIN = 17, + TYPE_TEXT = 18, }; CaptureButton() = delete; diff --git a/src/widgets/capture/capturewidget.cpp b/src/widgets/capture/capturewidget.cpp index ae243019..eb762869 100644 --- a/src/widgets/capture/capturewidget.cpp +++ b/src/widgets/capture/capturewidget.cpp @@ -51,7 +51,8 @@ CaptureWidget::CaptureWidget(const uint id, const QString &savePath, bool fullscreen, QWidget *parent) : QWidget(parent), m_mouseIsClicked(false), m_rightClick(false), m_newSelection(false), m_grabbing(false), m_captureDone(false), - m_previewEnabled(true), m_activeButton(nullptr), m_activeTool(nullptr), + m_previewEnabled(true), m_activeButton(nullptr), + m_activeTool(nullptr), m_toolWidget(nullptr), m_mouseOverHandle(SelectionWidget::NO_SIDE), m_id(id) { // Base config of the widget @@ -173,9 +174,26 @@ void CaptureWidget::updateButtons() { } QPixmap CaptureWidget::pixmap() { + QPixmap p; + if (m_toolWidget && m_activeTool) { + p = m_context.selectedScreenshotArea().copy(); + QPainter painter(&p); + m_activeTool->process(painter, p); + } else { + p = m_context.selectedScreenshotArea(); + } return m_context.selectedScreenshotArea(); } +void CaptureWidget::close() { + if (m_toolWidget) { + m_toolWidget->deleteLater(); + m_toolWidget = nullptr; + } else { + QWidget::close(); + } +} + void CaptureWidget::paintEvent(QPaintEvent *) { QPainter painter(this); painter.drawPixmap(0, 0, m_context.screenshot); @@ -260,9 +278,21 @@ void CaptureWidget::mousePressEvent(QMouseEvent *e) { // Click using a tool if (m_activeButton) { if (m_activeTool) { - m_activeTool->deleteLater(); + if (m_activeTool->isValid() && m_toolWidget) { + pushToolToStack(); + } else { + m_activeTool->deleteLater(); + } + if (m_toolWidget) { + m_toolWidget->deleteLater(); + return; + } } m_activeTool = m_activeButton->tool()->copy(this); + connect(this, &CaptureWidget::colorChanged, + m_activeTool, &CaptureTool::colorChanged); + connect(this, &CaptureWidget::thicknessChanged, + m_activeTool, &CaptureTool::thicknessChanged); connect(m_activeTool, &CaptureTool::requestAction, this, &CaptureWidget::handleButtonSignal); m_activeTool->drawStart(m_context); @@ -396,11 +426,11 @@ void CaptureWidget::mouseReleaseEvent(QMouseEvent *e) { } else if (m_mouseIsClicked && m_activeTool) { m_activeTool->drawEnd(m_context.mousePos); if (m_activeTool->isValid()) { - auto mod = new ModificationCommand( - &m_context.screenshot, m_activeTool); - m_undoStack.push(mod); + pushToolToStack(); + } else if (!m_toolWidget){ + m_activeTool->deleteLater(); + m_activeTool = nullptr; } - m_activeTool = nullptr; } // Show the buttons after the resize of the selection or the creation @@ -457,6 +487,7 @@ void CaptureWidget::wheelEvent(QWheelEvent *e) { if (m_activeButton && m_activeButton->tool()->showMousePreview()) { update(); } + emit thicknessChanged(m_context.thickness); } void CaptureWidget::resizeEvent(QResizeEvent *e) { @@ -515,6 +546,15 @@ void CaptureWidget::setState(CaptureButton *b) { if (!b) { return; } + if (m_toolWidget) { + m_toolWidget->deleteLater(); + if (m_activeTool->isValid()) { + auto mod = new ModificationCommand( + &m_context.screenshot, m_activeTool); + m_undoStack.push(mod); + m_activeTool = nullptr; + } + } processTool(b->tool()); // Only close activated from button if (b->tool()->closeOnButtonPressed()) { @@ -589,23 +629,34 @@ void CaptureWidget::handleButtonSignal(CaptureTool::Request r) { case CaptureTool::REQ_CAPTURE_DONE_OK: m_captureDone = true; break; - case CaptureTool::REQ_ADD_CHILD_WIDGETS: - if (m_activeTool) { - QWidget *w = m_activeTool->widget(); - makeChild(w); - w->move(m_context.mousePos); - w->show(); + case CaptureTool::REQ_ADD_CHILD_WIDGET: + if (!m_activeTool) { + break; + } + if (m_toolWidget) { + m_toolWidget->deleteLater(); + } + m_toolWidget = m_activeTool->widget(); + if (m_toolWidget) { + makeChild(m_toolWidget); + m_toolWidget->move(m_context.mousePos); + m_toolWidget->show(); + m_toolWidget->setFocus(); } break; case CaptureTool::REQ_ADD_CHILD_WINDOW: - if (m_activeTool) { + if (!m_activeTool) { + break; + } else { QWidget *w = m_activeTool->widget(); connect(this, &CaptureWidget::destroyed, w, &QWidget::deleteLater); w->show(); } break; case CaptureTool::REQ_ADD_EXTERNAL_WIDGETS: - if (m_activeTool) { + if (!m_activeTool) { + break; + } else { QWidget *w = m_activeTool->widget(); w->setAttribute(Qt::WA_DeleteOnClose); w->show(); @@ -619,6 +670,7 @@ void CaptureWidget::handleButtonSignal(CaptureTool::Request r) { void CaptureWidget::setDrawColor(const QColor &c) { m_context.color = c; ConfigHandler().setDrawColor(m_context.color); + emit colorChanged(c); } void CaptureWidget::leftResize() { @@ -718,6 +770,17 @@ void CaptureWidget::updateCursor() { } } +void CaptureWidget::pushToolToStack() { + auto mod = new ModificationCommand( + &m_context.screenshot, m_activeTool); + m_undoStack.push(mod); + disconnect(this, &CaptureWidget::colorChanged, + m_activeTool, &CaptureTool::colorChanged); + disconnect(this, &CaptureWidget::thicknessChanged, + m_activeTool, &CaptureTool::thicknessChanged); + m_activeTool = nullptr; +} + void CaptureWidget::makeChild(QWidget *w) { w->setParent(this); w->installEventFilter(m_eventFilter); @@ -743,7 +806,7 @@ int CaptureWidget::handleSize() { void CaptureWidget::copyScreenshot() { m_captureDone = true; - ScreenshotSaver().saveToClipboard(m_context.selectedScreenshotArea()); + ScreenshotSaver().saveToClipboard(pixmap()); close(); } diff --git a/src/widgets/capture/capturewidget.h b/src/widgets/capture/capturewidget.h index f30e6d2f..fdea1b69 100644 --- a/src/widgets/capture/capturewidget.h +++ b/src/widgets/capture/capturewidget.h @@ -60,9 +60,14 @@ public: void updateButtons(); QPixmap pixmap(); +public slots: + void close(); + signals: void captureTaken(uint id, QPixmap p); void captureFailed(uint id); + void colorChanged(const QColor &c); + void thicknessChanged(const int thickness); private slots: @@ -122,6 +127,7 @@ private: void initShortcuts(); void updateSizeIndicator(); void updateCursor(); + void pushToolToStack(); void makeChild(QWidget *w); // size of the handlers at the corners of the selection @@ -134,6 +140,7 @@ private: // Last pressed button QPointer m_activeButton; QPointer m_activeTool; + QPointer m_toolWidget; ButtonHandler *m_buttonHandler; UtilityPanel *m_panel;