diff --git a/src/config/buttonlistview.cpp b/src/config/buttonlistview.cpp index df2354bd..54d5f446 100644 --- a/src/config/buttonlistview.cpp +++ b/src/config/buttonlistview.cpp @@ -23,7 +23,7 @@ void ButtonListView::initButtonList() ToolFactory factory; auto listTypes = CaptureToolButton::getIterableButtonTypes(); - for (const CaptureToolButton::ButtonType t : listTypes) { + for (const CaptureTool::Type t : listTypes) { CaptureTool* tool = factory.CreateTool(t); // add element to the local map @@ -49,11 +49,11 @@ void ButtonListView::initButtonList() void ButtonListView::updateActiveButtons(QListWidgetItem* item) { - CaptureToolButton::ButtonType bType = m_buttonTypeByName[item->text()]; + CaptureTool::Type bType = m_buttonTypeByName[item->text()]; if (item->checkState() == Qt::Checked) { m_listButtons.append(bType); // TODO refactor so we don't need external sorts - using bt = CaptureToolButton::ButtonType; + using bt = CaptureTool::Type; std::sort(m_listButtons.begin(), m_listButtons.end(), [](bt a, bt b) { return CaptureToolButton::getPriorityByButton(a) < CaptureToolButton::getPriorityByButton(b); @@ -89,7 +89,7 @@ void ButtonListView::updateComponents() auto listTypes = CaptureToolButton::getIterableButtonTypes(); for (int i = 0; i < this->count(); ++i) { QListWidgetItem* item = this->item(i); - auto elem = static_cast(listTypes.at(i)); + auto elem = static_cast(listTypes.at(i)); if (m_listButtons.contains(elem)) { item->setCheckState(Qt::Checked); } else { diff --git a/src/config/buttonlistview.h b/src/config/buttonlistview.h index eef646c8..f7b47bb2 100644 --- a/src/config/buttonlistview.h +++ b/src/config/buttonlistview.h @@ -22,8 +22,8 @@ protected: void initButtonList(); private: - QList m_listButtons; - QMap m_buttonTypeByName; + QList m_listButtons; + QMap m_buttonTypeByName; void updateActiveButtons(QListWidgetItem*); }; diff --git a/src/config/shortcutswidget.cpp b/src/config/shortcutswidget.cpp index f47da3d9..b50cbded 100644 --- a/src/config/shortcutswidget.cpp +++ b/src/config/shortcutswidget.cpp @@ -5,6 +5,7 @@ #include "capturetool.h" #include "setshortcutwidget.h" #include "src/core/qguiappcurrentscreen.h" +#include "toolfactory.h" #include #include #include @@ -159,16 +160,19 @@ void ShortcutsWidget::slotShortcutCellClicked(int row, int col) void ShortcutsWidget::initShortcuts() { - auto buttons = CaptureToolButton::getIterableButtonTypes(); + auto buttonTypes = CaptureToolButton::getIterableButtonTypes(); // get shortcuts names from capture buttons - for (const CaptureToolButton::ButtonType& t : buttons) { - CaptureToolButton* b = new CaptureToolButton(t, nullptr); + for (const CaptureTool::Type& t : buttonTypes) { + CaptureTool* tool = ToolFactory().CreateTool(t); QString shortcutName = QVariant::fromValue(t).toString(); - if (shortcutName != "TYPE_IMAGEUPLOADER") { - appendShortcut(shortcutName, b->tool()->description()); + if (t != CaptureTool::TYPE_IMAGEUPLOADER) { + appendShortcut(shortcutName, tool->description()); + if (shortcutName == "TYPE_COPY") + m_shortcuts << (QStringList() << "" << tool->description() + << "Left Double-click"); } - delete b; + delete tool; } // additional tools that don't have their own buttons diff --git a/src/config/uicoloreditor.h b/src/config/uicoloreditor.h index 33b9a5a1..2e7f69d4 100644 --- a/src/config/uicoloreditor.h +++ b/src/config/uicoloreditor.h @@ -35,8 +35,7 @@ private: CaptureToolButton* m_lastButtonPressed; color_widgets::ColorWheel* m_colorWheel; - static const CaptureToolButton::ButtonType m_buttonIconType = - CaptureToolButton::TYPE_CIRCLE; + static const CaptureTool::Type m_buttonIconType = CaptureTool::TYPE_CIRCLE; QHBoxLayout* m_hLayout; QVBoxLayout* m_vLayout; diff --git a/src/tools/abstractactiontool.cpp b/src/tools/abstractactiontool.cpp index 17e7dc62..e172cebe 100644 --- a/src/tools/abstractactiontool.cpp +++ b/src/tools/abstractactiontool.cpp @@ -22,6 +22,11 @@ bool AbstractActionTool::showMousePreview() const return false; } +QRect AbstractActionTool::boundingRect() const +{ + return {}; +} + void AbstractActionTool::process(QPainter& painter, const QPixmap& pixmap) { Q_UNUSED(painter) @@ -50,12 +55,12 @@ void AbstractActionTool::drawStart(const CaptureContext& context) Q_UNUSED(context) } -void AbstractActionTool::colorChanged(const QColor& c) +void AbstractActionTool::onColorChanged(const QColor& c) { Q_UNUSED(c) } -void AbstractActionTool::thicknessChanged(int th) +void AbstractActionTool::onThicknessChanged(int th) { Q_UNUSED(th) } diff --git a/src/tools/abstractactiontool.h b/src/tools/abstractactiontool.h index 1372b5c1..9721f2f7 100644 --- a/src/tools/abstractactiontool.h +++ b/src/tools/abstractactiontool.h @@ -14,6 +14,7 @@ public: bool isValid() const override; bool isSelectable() const override; bool showMousePreview() const override; + QRect boundingRect() const override; void process(QPainter& painter, const QPixmap& pixmap) override; void paintMousePreview(QPainter& painter, @@ -23,6 +24,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(int th) override; + void onColorChanged(const QColor& c) override; + void onThicknessChanged(int th) override; }; diff --git a/src/tools/abstractpathtool.cpp b/src/tools/abstractpathtool.cpp index 15bace1c..3b6079a0 100644 --- a/src/tools/abstractpathtool.cpp +++ b/src/tools/abstractpathtool.cpp @@ -44,6 +44,46 @@ bool AbstractPathTool::showMousePreview() const return true; } +QRect AbstractPathTool::mousePreviewRect(const CaptureContext& context) const +{ + QRect rect(0, 0, context.thickness + 2, context.thickness + 2); + rect.moveCenter(context.mousePos); + return rect; +} + +QRect AbstractPathTool::boundingRect() const +{ + if (m_points.isEmpty()) { + return {}; + } + int min_x = m_points.at(0).x(); + int min_y = m_points.at(0).y(); + int max_x = m_points.at(0).x(); + int max_y = m_points.at(0).y(); + for (auto point : m_points) { + if (point.x() < min_x) { + min_x = point.x(); + } + if (point.y() < min_y) { + min_y = point.y(); + } + if (point.x() > max_x) { + max_x = point.x(); + } + if (point.y() > max_y) { + max_y = point.y(); + } + } + + int offset = + m_thickness <= 1 ? 1 : static_cast(round(m_thickness * 0.7 + 0.5)); + return QRect(min_x - offset, + min_y - offset, + std::abs(min_x - max_x) + offset * 2, + std::abs(min_y - max_y) + offset * 2) + .normalized(); +} + void AbstractPathTool::drawEnd(const QPoint& p) { Q_UNUSED(p) @@ -54,12 +94,12 @@ void AbstractPathTool::drawMove(const QPoint& p) addPoint(p); } -void AbstractPathTool::colorChanged(const QColor& c) +void AbstractPathTool::onColorChanged(const QColor& c) { m_color = c; } -void AbstractPathTool::thicknessChanged(int th) +void AbstractPathTool::onThicknessChanged(int th) { m_thickness = th; } @@ -91,36 +131,6 @@ void AbstractPathTool::move(const QPoint& mousePos) } } -void AbstractPathTool::drawObjectSelection(QPainter& painter) -{ - int min_x = m_points.at(0).x(); - int min_y = m_points.at(0).y(); - int max_x = m_points.at(0).x(); - int max_y = m_points.at(0).y(); - for (auto point : m_points) { - if (point.x() < min_x) { - min_x = point.x(); - } - if (point.y() < min_y) { - min_y = point.y(); - } - if (point.x() > max_x) { - max_x = point.x(); - } - if (point.y() > max_y) { - max_y = point.y(); - } - } - - int offset = - m_thickness <= 1 ? 1 : static_cast(round(m_thickness / 2 + 0.5)); - QRect rect = QRect(min_x - offset, - min_y - offset, - std::abs(min_x - max_x) + offset * 2, - std::abs(min_y - max_y) + offset * 2); - drawObjectSelectionRect(painter, rect); -} - const QPoint* AbstractPathTool::pos() { if (m_points.empty()) { diff --git a/src/tools/abstractpathtool.h b/src/tools/abstractpathtool.h index c134ee2f..dea2f26b 100644 --- a/src/tools/abstractpathtool.h +++ b/src/tools/abstractpathtool.h @@ -15,16 +15,17 @@ public: bool closeOnButtonPressed() const override; bool isSelectable() const override; bool showMousePreview() const override; + QRect mousePreviewRect(const CaptureContext& context) const override; + QRect boundingRect() const override; void move(const QPoint& mousePos) override; const QPoint* pos() override; - void drawObjectSelection(QPainter& painter) override; - int thickness() override { return m_thickness; }; + int thickness() const override { return m_thickness; }; public slots: void drawEnd(const QPoint& p) override; void drawMove(const QPoint& p) override; - void colorChanged(const QColor& c) override; - void thicknessChanged(int th) override; + void onColorChanged(const QColor& c) override; + void onThicknessChanged(int th) override; protected: void copyParams(const AbstractPathTool* from, AbstractPathTool* to); diff --git a/src/tools/abstracttwopointtool.cpp b/src/tools/abstracttwopointtool.cpp index 5beb9879..aae95bf2 100644 --- a/src/tools/abstracttwopointtool.cpp +++ b/src/tools/abstracttwopointtool.cpp @@ -67,6 +67,30 @@ bool AbstractTwoPointTool::showMousePreview() const return true; } +QRect AbstractTwoPointTool::mousePreviewRect( + const CaptureContext& context) const +{ + QRect rect(0, 0, context.thickness + 2, context.thickness + 2); + rect.moveCenter(context.mousePos); + return rect; +} + +QRect AbstractTwoPointTool::boundingRect() const +{ + if (!isValid()) { + return {}; + } + int offset = + m_thickness <= 1 ? 1 : static_cast(round(m_thickness * 0.7 + 0.5)); + QRect rect = + QRect(std::min(m_points.first.x(), m_points.second.x()) - offset, + std::min(m_points.first.y(), m_points.second.y()) - offset, + std::abs(m_points.first.x() - m_points.second.x()) + offset * 2, + std::abs(m_points.first.y() - m_points.second.y()) + offset * 2); + + return rect.normalized(); +} + void AbstractTwoPointTool::drawEnd(const QPoint& p) { Q_UNUSED(p) @@ -82,12 +106,12 @@ void AbstractTwoPointTool::drawMoveWithAdjustment(const QPoint& p) m_points.second = m_points.first + adjustedVector(p - m_points.first); } -void AbstractTwoPointTool::colorChanged(const QColor& c) +void AbstractTwoPointTool::onColorChanged(const QColor& c) { m_color = c; } -void AbstractTwoPointTool::thicknessChanged(int th) +void AbstractTwoPointTool::onThicknessChanged(int th) { m_thickness = th; } @@ -101,10 +125,10 @@ void AbstractTwoPointTool::paintMousePreview(QPainter& painter, void AbstractTwoPointTool::drawStart(const CaptureContext& context) { - colorChanged(context.color); + onColorChanged(context.color); m_points.first = context.mousePos; m_points.second = context.mousePos; - thicknessChanged(context.thickness); + onThicknessChanged(context.thickness); } QPoint AbstractTwoPointTool::adjustedVector(QPoint v) const @@ -160,15 +184,3 @@ const QPoint* AbstractTwoPointTool::pos() { return &m_points.first; } - -void AbstractTwoPointTool::drawObjectSelection(QPainter& painter) -{ - int offset = - m_thickness <= 1 ? 1 : static_cast(round(m_thickness / 2 + 0.5)); - QRect rect = - QRect(std::min(m_points.first.x(), m_points.second.x()) - offset, - std::min(m_points.first.y(), m_points.second.y()) - offset, - std::abs(m_points.first.x() - m_points.second.x()) + offset * 2, - std::abs(m_points.first.y() - m_points.second.y()) + offset * 2); - drawObjectSelectionRect(painter, rect); -} diff --git a/src/tools/abstracttwopointtool.h b/src/tools/abstracttwopointtool.h index d245ec40..ba22f44f 100644 --- a/src/tools/abstracttwopointtool.h +++ b/src/tools/abstracttwopointtool.h @@ -15,12 +15,13 @@ public: bool closeOnButtonPressed() const override; bool isSelectable() const override; bool showMousePreview() const override; + QRect mousePreviewRect(const CaptureContext& context) const override; + QRect boundingRect() const override; void move(const QPoint& pos) override; const QPoint* pos() override; - void drawObjectSelection(QPainter& painter) override; - int thickness() override { return m_thickness; }; + int thickness() const override { return m_thickness; }; const QColor& color() { return m_color; }; - const QPair points() { return m_points; }; + const QPair points() const { return m_points; }; void paintMousePreview(QPainter& painter, const CaptureContext& context) override; @@ -28,8 +29,8 @@ public slots: void drawEnd(const QPoint& p) override; void drawMove(const QPoint& p) override; void drawMoveWithAdjustment(const QPoint& p) override; - void colorChanged(const QColor& c) override; - void thicknessChanged(int th) override; + void onColorChanged(const QColor& c) override; + void onThicknessChanged(int th) override; virtual void drawStart(const CaptureContext& context) override; private: diff --git a/src/tools/arrow/arrowtool.cpp b/src/tools/arrow/arrowtool.cpp index 9d56f89e..fa8a77fe 100644 --- a/src/tools/arrow/arrowtool.cpp +++ b/src/tools/arrow/arrowtool.cpp @@ -72,9 +72,9 @@ QString ArrowTool::name() const return tr("Arrow"); } -ToolType ArrowTool::type() const +CaptureTool::Type ArrowTool::type() const { - return ToolType::ARROW; + return CaptureTool::TYPE_ARROW; } QString ArrowTool::description() const @@ -82,36 +82,12 @@ QString ArrowTool::description() const return tr("Set the Arrow as the paint tool"); } -CaptureTool* ArrowTool::copy(QObject* parent) +QRect ArrowTool::boundingRect() const { - ArrowTool* tool = new ArrowTool(parent); - copyParams(this, tool); - return tool; -} + if (!isValid()) { + return {}; + } -void ArrowTool::copyParams(const ArrowTool* from, ArrowTool* to) -{ - AbstractTwoPointTool::copyParams(from, to); - to->m_arrowPath = this->m_arrowPath; -} - -void ArrowTool::process(QPainter& painter, const QPixmap& pixmap) -{ - Q_UNUSED(pixmap) - painter.setPen(QPen(color(), thickness())); - painter.drawLine( - getShorterLine(points().first, points().second, thickness())); - m_arrowPath = getArrowHead(points().first, points().second, thickness()); - painter.fillPath(m_arrowPath, QBrush(color())); -} - -void ArrowTool::pressed(const CaptureContext& context) -{ - Q_UNUSED(context) -} - -void ArrowTool::drawObjectSelection(QPainter& painter) -{ int offset = thickness() <= 1 ? 1 : static_cast(round(thickness() / 2 + 0.5)); @@ -150,5 +126,34 @@ void ArrowTool::drawObjectSelection(QPainter& painter) line_pos_min_y - offset, line_pos_max_x - line_pos_min_x + offset * 2, line_pos_max_y - line_pos_min_y + offset * 2); - drawObjectSelectionRect(painter, rect); + + return rect.normalized(); +} + +CaptureTool* ArrowTool::copy(QObject* parent) +{ + ArrowTool* tool = new ArrowTool(parent); + copyParams(this, tool); + return tool; +} + +void ArrowTool::copyParams(const ArrowTool* from, ArrowTool* to) +{ + AbstractTwoPointTool::copyParams(from, to); + to->m_arrowPath = this->m_arrowPath; +} + +void ArrowTool::process(QPainter& painter, const QPixmap& pixmap) +{ + Q_UNUSED(pixmap) + painter.setPen(QPen(color(), thickness())); + painter.drawLine( + getShorterLine(points().first, points().second, thickness())); + m_arrowPath = getArrowHead(points().first, points().second, thickness()); + painter.fillPath(m_arrowPath, QBrush(color())); +} + +void ArrowTool::pressed(const CaptureContext& context) +{ + Q_UNUSED(context) } diff --git a/src/tools/arrow/arrowtool.h b/src/tools/arrow/arrowtool.h index 1b789878..6a2fd20f 100644 --- a/src/tools/arrow/arrowtool.h +++ b/src/tools/arrow/arrowtool.h @@ -16,14 +16,14 @@ public: QIcon icon(const QColor& background, bool inEditor) const override; QString name() const override; QString description() const override; + QRect boundingRect() const override; CaptureTool* copy(QObject* parent = nullptr) override; void process(QPainter& painter, const QPixmap& pixmap) override; - void drawObjectSelection(QPainter& painter) override; protected: void copyParams(const ArrowTool* from, ArrowTool* to); - ToolType type() const override; + CaptureTool::Type type() const override; public slots: void pressed(const CaptureContext& context) override; diff --git a/src/tools/capturetool.h b/src/tools/capturetool.h index bc4b0607..19871ac8 100644 --- a/src/tools/capturetool.h +++ b/src/tools/capturetool.h @@ -9,39 +9,47 @@ #include #include -enum class ToolType -{ - ARROW, - CIRCLE, - CIRCLECOUNT, - COPY, - EXIT, - IMGUR, - LAUNCHER, - LINE, - MARKER, - MOVE, - PENCIL, - PIN, - PIXELATE, - RECTANGLE, - REDO, - SAVE, - INVERT, - SELECTION, - SIZEINDICATOR, - TEXT, - UNDO, - UPLOAD, - SIZEINCREASE, - SIZEDECREASE, -}; - class CaptureTool : public QObject { Q_OBJECT public: + // IMPORTANT: + // Add new entries to the BOTTOM so existing user configurations don't get + // messed up. + // ALSO NOTE: + // When adding new types, don't forget to update: + // - CaptureToolButton::iterableButtonTypes + // - CaptureToolButton::buttonTypeOrder + enum Type + { + NONE = -1, + TYPE_PENCIL = 0, + TYPE_DRAWER = 1, + TYPE_ARROW = 2, + TYPE_SELECTION = 3, + TYPE_RECTANGLE = 4, + TYPE_CIRCLE = 5, + TYPE_MARKER = 6, + TYPE_SELECTIONINDICATOR = 7, + TYPE_MOVESELECTION = 8, + TYPE_UNDO = 9, + TYPE_COPY = 10, + TYPE_SAVE = 11, + TYPE_EXIT = 12, + TYPE_IMAGEUPLOADER = 13, + TYPE_OPEN_APP = 14, + TYPE_PIXELATE = 15, + TYPE_REDO = 16, + TYPE_PIN = 17, + TYPE_TEXT = 18, + TYPE_CIRCLECOUNT = 19, + TYPE_SIZEINCREASE = 20, + TYPE_SIZEDECREASE = 21, + TYPE_INVERT = 22, + }; + Q_ENUM(Type); + // Request actions on the main widget enum Request { @@ -49,24 +57,12 @@ public: 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, // Notify to redraw screenshot with tools without object selection. REQ_CLEAR_SELECTION, // Notify is the screenshot has been saved. @@ -87,6 +83,7 @@ public: , m_editMode(false) {} + // TODO unused virtual void setCapture(const QPixmap& pixmap){}; // Returns false when the tool is in an inconsistent state and shouldn't @@ -99,6 +96,11 @@ public: virtual bool isSelectable() const = 0; // Enable mouse preview. virtual bool showMousePreview() const = 0; + virtual QRect mousePreviewRect(const CaptureContext& context) const + { + return {}; + }; + virtual QRect boundingRect() const = 0; // The icon of the tool. // inEditor is true when the icon is requested inside the editor @@ -108,7 +110,7 @@ public: virtual QString name() const = 0; // Codename for the tool, this shouldn't change as it is used as ID // for the tool in the internals of Flameshot - virtual ToolType type() const = 0; + virtual CaptureTool::Type type() const = 0; // Short description of the tool. virtual QString description() const = 0; // Short tool item info @@ -133,7 +135,7 @@ public: // Counter for all object types (currently is used for the CircleCounter // only) virtual void setCount(int count) { m_count = count; }; - virtual int count() { return m_count; }; + virtual int count() const { return m_count; }; // Called every time the tool has to draw virtual void process(QPainter& painter, const QPixmap& pixmap) = 0; @@ -141,7 +143,10 @@ public: { process(painter, pixmap); }; - virtual void drawObjectSelection(QPainter& painter) { Q_UNUSED(painter) }; + virtual void drawObjectSelection(QPainter& painter) + { + drawObjectSelectionRect(painter, boundingRect()); + }; // When the tool is selected, this is called when the mouse moves virtual void paintMousePreview(QPainter& painter, const CaptureContext& context) = 0; @@ -150,9 +155,6 @@ public: virtual void move(const QPoint& pos) { Q_UNUSED(pos) }; virtual const QPoint* pos() { return nullptr; }; - // get selection region - const QRect& selectionRect() { return m_selectionRect; }; - signals: void requestAction(Request r); @@ -176,7 +178,6 @@ protected: painter.setPen(QPen(Qt::white, 1, Qt::DotLine)); painter.drawRect(rect); painter.setPen(orig_pen); - m_selectionRect = rect; } public slots: @@ -192,13 +193,12 @@ public slots: // 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; + virtual void onColorChanged(const QColor& c) = 0; // Called when the thickness of the tool is updated in the editor. - virtual void thicknessChanged(int th) = 0; - virtual int thickness() { return -1; }; + virtual void onThicknessChanged(int th) = 0; + virtual int thickness() const { return -1; }; private: unsigned int m_count; bool m_editMode; - QRect m_selectionRect; }; diff --git a/src/tools/circle/circletool.cpp b/src/tools/circle/circletool.cpp index 8e83fee3..e4ac46bf 100644 --- a/src/tools/circle/circletool.cpp +++ b/src/tools/circle/circletool.cpp @@ -20,9 +20,9 @@ QString CircleTool::name() const return tr("Circle"); } -ToolType CircleTool::type() const +CaptureTool::Type CircleTool::type() const { - return ToolType::CIRCLE; + return CaptureTool::TYPE_CIRCLE; } QString CircleTool::description() const diff --git a/src/tools/circle/circletool.h b/src/tools/circle/circletool.h index 11223a08..da75f500 100644 --- a/src/tools/circle/circletool.h +++ b/src/tools/circle/circletool.h @@ -19,7 +19,7 @@ public: void process(QPainter& painter, const QPixmap& pixmap) override; protected: - ToolType type() const override; + CaptureTool::Type type() const override; public slots: void pressed(const CaptureContext& context) override; diff --git a/src/tools/circlecount/circlecounttool.cpp b/src/tools/circlecount/circlecounttool.cpp index 395689d7..67e58a07 100644 --- a/src/tools/circlecount/circlecounttool.cpp +++ b/src/tools/circlecount/circlecounttool.cpp @@ -14,6 +14,7 @@ namespace { CircleCountTool::CircleCountTool(QObject* parent) : AbstractTwoPointTool(parent) + , m_valid(false) {} QIcon CircleCountTool::icon(const QColor& background, bool inEditor) const @@ -28,14 +29,47 @@ QString CircleCountTool::info() return m_tempString; } +bool CircleCountTool::isValid() const +{ + return m_valid; +} + +QRect CircleCountTool::mousePreviewRect(const CaptureContext& context) const +{ + int width = (context.thickness + THICKNESS_OFFSET) * 2; + QRect rect(0, 0, width, width); + rect.moveCenter(context.mousePos); + return rect; +} + +QRect CircleCountTool::boundingRect() const +{ + if (!isValid()) { + return {}; + } + int bubble_size = thickness() + THICKNESS_OFFSET + PADDING_VALUE; + return QRect(points().first.x() - bubble_size, + points().first.y() - bubble_size, + bubble_size * 2, + bubble_size * 2); +} + QString CircleCountTool::name() const { return tr("Circle Counter"); } -ToolType CircleCountTool::type() const +CaptureTool::Type CircleCountTool::type() const { - return ToolType::CIRCLECOUNT; + return CaptureTool::TYPE_CIRCLECOUNT; +} + +void CircleCountTool::copyParams(const CircleCountTool* from, + CircleCountTool* to) +{ + AbstractTwoPointTool::copyParams(from, to); + to->setCount(from->count()); + to->m_valid = from->m_valid; } QString CircleCountTool::description() const @@ -106,20 +140,10 @@ void CircleCountTool::process(QPainter& painter, const QPixmap& pixmap) painter.setPen(orig_pen); } -void CircleCountTool::drawObjectSelection(QPainter& painter) -{ - int bubble_size = thickness() + THICKNESS_OFFSET + PADDING_VALUE; - drawObjectSelectionRect(painter, - QRect(points().first.x() - bubble_size, - points().first.y() - bubble_size, - bubble_size * 2, - bubble_size * 2)); -} - void CircleCountTool::paintMousePreview(QPainter& painter, const CaptureContext& context) { - thicknessChanged(context.thickness + PADDING_VALUE); + onThicknessChanged(context.thickness + PADDING_VALUE); // Thickness for pen is *2 to range from radius to diameter to match the // ellipse draw function @@ -139,6 +163,7 @@ void CircleCountTool::paintMousePreview(QPainter& painter, void CircleCountTool::drawStart(const CaptureContext& context) { AbstractTwoPointTool::drawStart(context); + m_valid = true; } void CircleCountTool::pressed(const CaptureContext& context) diff --git a/src/tools/circlecount/circlecounttool.h b/src/tools/circlecount/circlecounttool.h index faad79ba..49b2527a 100644 --- a/src/tools/circlecount/circlecounttool.h +++ b/src/tools/circlecount/circlecounttool.h @@ -15,15 +15,19 @@ public: QString name() const override; QString description() const override; QString info() override; + bool isValid() const override; + + QRect mousePreviewRect(const CaptureContext& context) const override; + QRect boundingRect() const override; CaptureTool* copy(QObject* parent = nullptr) override; void process(QPainter& painter, const QPixmap& pixmap) override; - void drawObjectSelection(QPainter& painter) override; void paintMousePreview(QPainter& painter, const CaptureContext& context) override; protected: - ToolType type() const override; + CaptureTool::Type type() const override; + void copyParams(const CircleCountTool* from, CircleCountTool* to); public slots: void drawStart(const CaptureContext& context) override; @@ -31,4 +35,5 @@ public slots: private: QString m_tempString; + bool m_valid; }; diff --git a/src/tools/copy/copytool.cpp b/src/tools/copy/copytool.cpp index f431061e..99c9b073 100644 --- a/src/tools/copy/copytool.cpp +++ b/src/tools/copy/copytool.cpp @@ -24,9 +24,9 @@ QString CopyTool::name() const return tr("Copy"); } -ToolType CopyTool::type() const +CaptureTool::Type CopyTool::type() const { - return ToolType::COPY; + return CaptureTool::TYPE_COPY; } QString CopyTool::description() const diff --git a/src/tools/copy/copytool.h b/src/tools/copy/copytool.h index 60500c7d..6c19c013 100644 --- a/src/tools/copy/copytool.h +++ b/src/tools/copy/copytool.h @@ -20,7 +20,7 @@ public: CaptureTool* copy(QObject* parent = nullptr) override; protected: - ToolType type() const override; + CaptureTool::Type type() const override; public slots: void pressed(const CaptureContext& context) override; diff --git a/src/tools/exit/exittool.cpp b/src/tools/exit/exittool.cpp index 04f7a027..0b71f084 100644 --- a/src/tools/exit/exittool.cpp +++ b/src/tools/exit/exittool.cpp @@ -23,9 +23,9 @@ QString ExitTool::name() const return tr("Exit"); } -ToolType ExitTool::type() const +CaptureTool::Type ExitTool::type() const { - return ToolType::EXIT; + return CaptureTool::TYPE_EXIT; } QString ExitTool::description() const diff --git a/src/tools/exit/exittool.h b/src/tools/exit/exittool.h index 2fdfe01b..976ff77a 100644 --- a/src/tools/exit/exittool.h +++ b/src/tools/exit/exittool.h @@ -16,11 +16,12 @@ public: QIcon icon(const QColor& background, bool inEditor) const override; QString name() const override; QString description() const override; + // TODO create a new abstract class to get rid of such baggage CaptureTool* copy(QObject* parent = nullptr) override; protected: - ToolType type() const override; + CaptureTool::Type type() const override; public slots: void pressed(const CaptureContext& context) override; diff --git a/src/tools/imgur/imguruploadertool.cpp b/src/tools/imgur/imguruploadertool.cpp index 68924df3..b627fde0 100644 --- a/src/tools/imgur/imguruploadertool.cpp +++ b/src/tools/imgur/imguruploadertool.cpp @@ -24,9 +24,9 @@ QString ImgurUploaderTool::name() const return tr("Image Uploader"); } -ToolType ImgurUploaderTool::type() const +CaptureTool::Type ImgurUploaderTool::type() const { - return ToolType::IMGUR; + return CaptureTool::TYPE_IMAGEUPLOADER; } QString ImgurUploaderTool::description() const diff --git a/src/tools/imgur/imguruploadertool.h b/src/tools/imgur/imguruploadertool.h index 84189e26..d4fda8e9 100644 --- a/src/tools/imgur/imguruploadertool.h +++ b/src/tools/imgur/imguruploadertool.h @@ -22,7 +22,7 @@ public: CaptureTool* copy(QObject* parent = nullptr) override; protected: - ToolType type() const override; + CaptureTool::Type type() const override; public slots: void pressed(const CaptureContext& context) override; diff --git a/src/tools/invert/inverttool.cpp b/src/tools/invert/inverttool.cpp index 144a2ac0..3f52ef4f 100644 --- a/src/tools/invert/inverttool.cpp +++ b/src/tools/invert/inverttool.cpp @@ -25,9 +25,9 @@ QString InvertTool::name() const return tr("Invert"); } -ToolType InvertTool::type() const +CaptureTool::Type InvertTool::type() const { - return ToolType::INVERT; + return CaptureTool::TYPE_INVERT; } QString InvertTool::description() const @@ -35,6 +35,15 @@ QString InvertTool::description() const return tr("Set Inverter as the paint tool"); } +QRect InvertTool::boundingRect() const +{ + return QRect(std::min(points().first.x(), points().second.x()), + std::min(points().first.y(), points().second.y()), + std::abs(points().first.x() - points().second.x()), + std::abs(points().first.y() - points().second.y())) + .normalized(); +} + CaptureTool* InvertTool::copy(QObject* parent) { auto* tool = new InvertTool(parent); @@ -77,12 +86,3 @@ void InvertTool::pressed(const CaptureContext& context) { Q_UNUSED(context) } - -void InvertTool::drawObjectSelection(QPainter& painter) -{ - QRect rect = QRect(std::min(points().first.x(), points().second.x()), - std::min(points().first.y(), points().second.y()), - std::abs(points().first.x() - points().second.x()), - std::abs(points().first.y() - points().second.y())); - drawObjectSelectionRect(painter, rect); -} diff --git a/src/tools/invert/inverttool.h b/src/tools/invert/inverttool.h index a39dbd40..4d5dba1a 100644 --- a/src/tools/invert/inverttool.h +++ b/src/tools/invert/inverttool.h @@ -14,16 +14,16 @@ public: QIcon icon(const QColor& background, bool inEditor) const override; QString name() const override; QString description() const override; + QRect boundingRect() const override; CaptureTool* copy(QObject* parent = nullptr) override; void process(QPainter& painter, const QPixmap& pixmap) override; void drawSearchArea(QPainter& painter, const QPixmap& pixmap) override; void paintMousePreview(QPainter& painter, const CaptureContext& context) override; - void drawObjectSelection(QPainter& painter) override; protected: - ToolType type() const override; + CaptureTool::Type type() const override; public slots: void pressed(const CaptureContext& context) override; diff --git a/src/tools/launcher/applaunchertool.cpp b/src/tools/launcher/applaunchertool.cpp index 11545c51..29f3f7b0 100644 --- a/src/tools/launcher/applaunchertool.cpp +++ b/src/tools/launcher/applaunchertool.cpp @@ -23,9 +23,9 @@ QString AppLauncher::name() const return tr("App Launcher"); } -ToolType AppLauncher::type() const +CaptureTool::Type AppLauncher::type() const { - return ToolType::LAUNCHER; + return CaptureTool::TYPE_OPEN_APP; } QString AppLauncher::description() const diff --git a/src/tools/launcher/applaunchertool.h b/src/tools/launcher/applaunchertool.h index f2bdf374..a1c22b9f 100644 --- a/src/tools/launcher/applaunchertool.h +++ b/src/tools/launcher/applaunchertool.h @@ -22,7 +22,7 @@ public: CaptureTool* copy(QObject* parent = nullptr) override; protected: - ToolType type() const override; + CaptureTool::Type type() const override; public slots: void pressed(const CaptureContext& context) override; diff --git a/src/tools/line/linetool.cpp b/src/tools/line/linetool.cpp index 50f4a0dd..548250cd 100644 --- a/src/tools/line/linetool.cpp +++ b/src/tools/line/linetool.cpp @@ -22,9 +22,9 @@ QString LineTool::name() const return tr("Line"); } -ToolType LineTool::type() const +CaptureTool::Type LineTool::type() const { - return ToolType::LINE; + return CaptureTool::TYPE_DRAWER; } QString LineTool::description() const diff --git a/src/tools/line/linetool.h b/src/tools/line/linetool.h index efa90c82..3a353b21 100644 --- a/src/tools/line/linetool.h +++ b/src/tools/line/linetool.h @@ -19,7 +19,7 @@ public: void process(QPainter& painter, const QPixmap& pixmap) override; protected: - ToolType type() const override; + CaptureTool::Type type() const override; public slots: void pressed(const CaptureContext& context) override; diff --git a/src/tools/marker/markertool.cpp b/src/tools/marker/markertool.cpp index 9d73a845..5f79dfaf 100644 --- a/src/tools/marker/markertool.cpp +++ b/src/tools/marker/markertool.cpp @@ -4,12 +4,8 @@ #include "markertool.h" #include -namespace { - #define PADDING_VALUE 14 -} - MarkerTool::MarkerTool(QObject* parent) : AbstractTwoPointTool(parent) { @@ -27,9 +23,9 @@ QString MarkerTool::name() const return tr("Marker"); } -ToolType MarkerTool::type() const +CaptureTool::Type MarkerTool::type() const { - return ToolType::MARKER; + return CaptureTool::TYPE_MARKER; } QString MarkerTool::description() const @@ -37,6 +33,14 @@ QString MarkerTool::description() const return tr("Set the Marker as the paint tool"); } +QRect MarkerTool::mousePreviewRect(const CaptureContext& context) const +{ + int width = PADDING_VALUE + context.thickness; + QRect rect(0, 0, width + 2, width + 2); + rect.moveCenter(context.mousePos); + return rect; +} + CaptureTool* MarkerTool::copy(QObject* parent) { auto* tool = new MarkerTool(parent); @@ -77,7 +81,7 @@ void MarkerTool::paintMousePreview(QPainter& painter, void MarkerTool::drawStart(const CaptureContext& context) { AbstractTwoPointTool::drawStart(context); - thicknessChanged(context.thickness + PADDING_VALUE); + onThicknessChanged(context.thickness + PADDING_VALUE); } void MarkerTool::pressed(const CaptureContext& context) diff --git a/src/tools/marker/markertool.h b/src/tools/marker/markertool.h index e4f51ce4..d4ccb221 100644 --- a/src/tools/marker/markertool.h +++ b/src/tools/marker/markertool.h @@ -14,6 +14,7 @@ public: QIcon icon(const QColor& background, bool inEditor) const override; QString name() const override; QString description() const override; + QRect mousePreviewRect(const CaptureContext& context) const override; CaptureTool* copy(QObject* parent = nullptr) override; void process(QPainter& painter, const QPixmap& pixmap) override; @@ -21,7 +22,7 @@ public: const CaptureContext& context) override; protected: - ToolType type() const override; + CaptureTool::Type type() const override; public slots: void drawStart(const CaptureContext& context) override; diff --git a/src/tools/move/movetool.cpp b/src/tools/move/movetool.cpp index 6f875290..37d39069 100644 --- a/src/tools/move/movetool.cpp +++ b/src/tools/move/movetool.cpp @@ -23,9 +23,9 @@ QString MoveTool::name() const return tr("Move"); } -ToolType MoveTool::type() const +CaptureTool::Type MoveTool::type() const { - return ToolType::MOVE; + return CaptureTool::TYPE_MOVESELECTION; } QString MoveTool::description() const @@ -41,7 +41,6 @@ CaptureTool* MoveTool::copy(QObject* parent) void MoveTool::pressed(const CaptureContext& context) { Q_UNUSED(context) - emit requestAction(REQ_MOVE_MODE); } bool MoveTool::isSelectable() const diff --git a/src/tools/move/movetool.h b/src/tools/move/movetool.h index 749cc9c7..8fde1472 100644 --- a/src/tools/move/movetool.h +++ b/src/tools/move/movetool.h @@ -15,7 +15,7 @@ public: QIcon icon(const QColor& background, bool inEditor) const override; QString name() const override; - ToolType type() const override; + CaptureTool::Type type() const override; QString description() const override; bool isSelectable() const override; diff --git a/src/tools/pencil/penciltool.cpp b/src/tools/pencil/penciltool.cpp index 7fecd600..bdbcfd40 100644 --- a/src/tools/pencil/penciltool.cpp +++ b/src/tools/pencil/penciltool.cpp @@ -18,9 +18,9 @@ QString PencilTool::name() const return tr("Pencil"); } -ToolType PencilTool::type() const +CaptureTool::Type PencilTool::type() const { - return ToolType::PENCIL; + return CaptureTool::TYPE_PENCIL; } QString PencilTool::description() const @@ -52,7 +52,7 @@ void PencilTool::paintMousePreview(QPainter& painter, void PencilTool::drawStart(const CaptureContext& context) { m_color = context.color; - thicknessChanged(context.thickness); + onThicknessChanged(context.thickness); m_points.append(context.mousePos); m_pathArea.setTopLeft(context.mousePos); m_pathArea.setBottomRight(context.mousePos); diff --git a/src/tools/pencil/penciltool.h b/src/tools/pencil/penciltool.h index 7be168ff..4c2f561b 100644 --- a/src/tools/pencil/penciltool.h +++ b/src/tools/pencil/penciltool.h @@ -22,7 +22,7 @@ public: const CaptureContext& context) override; protected: - ToolType type() const override; + CaptureTool::Type type() const override; public slots: void drawStart(const CaptureContext& context) override; diff --git a/src/tools/pin/pintool.cpp b/src/tools/pin/pintool.cpp index f668b764..0b1a79a0 100644 --- a/src/tools/pin/pintool.cpp +++ b/src/tools/pin/pintool.cpp @@ -25,9 +25,9 @@ QString PinTool::name() const return tr("Pin Tool"); } -ToolType PinTool::type() const +CaptureTool::Type PinTool::type() const { - return ToolType::PIN; + return CaptureTool::TYPE_PIN; } QString PinTool::description() const diff --git a/src/tools/pin/pintool.h b/src/tools/pin/pintool.h index 71d9664b..886bb751 100644 --- a/src/tools/pin/pintool.h +++ b/src/tools/pin/pintool.h @@ -22,7 +22,7 @@ public: CaptureTool* copy(QObject* parent = nullptr) override; protected: - ToolType type() const override; + CaptureTool::Type type() const override; public slots: void pressed(const CaptureContext& context) override; diff --git a/src/tools/pixelate/pixelatetool.cpp b/src/tools/pixelate/pixelatetool.cpp index 542080e9..d1ddef79 100644 --- a/src/tools/pixelate/pixelatetool.cpp +++ b/src/tools/pixelate/pixelatetool.cpp @@ -23,9 +23,9 @@ QString PixelateTool::name() const return tr("Pixelate"); } -ToolType PixelateTool::type() const +CaptureTool::Type PixelateTool::type() const { - return ToolType::PIXELATE; + return CaptureTool::TYPE_PIXELATE; } QString PixelateTool::description() const @@ -33,6 +33,15 @@ QString PixelateTool::description() const return tr("Set Pixelate as the paint tool"); } +QRect PixelateTool::boundingRect() const +{ + return QRect(std::min(points().first.x(), points().second.x()), + std::min(points().first.y(), points().second.y()), + std::abs(points().first.x() - points().second.x()), + std::abs(points().first.y() - points().second.y())) + .normalized(); +} + CaptureTool* PixelateTool::copy(QObject* parent) { auto* tool = new PixelateTool(parent); @@ -100,12 +109,3 @@ void PixelateTool::pressed(const CaptureContext& context) { Q_UNUSED(context) } - -void PixelateTool::drawObjectSelection(QPainter& painter) -{ - QRect rect = QRect(std::min(points().first.x(), points().second.x()), - std::min(points().first.y(), points().second.y()), - std::abs(points().first.x() - points().second.x()), - std::abs(points().first.y() - points().second.y())); - drawObjectSelectionRect(painter, rect); -} diff --git a/src/tools/pixelate/pixelatetool.h b/src/tools/pixelate/pixelatetool.h index 9d181619..81a639c2 100644 --- a/src/tools/pixelate/pixelatetool.h +++ b/src/tools/pixelate/pixelatetool.h @@ -14,16 +14,16 @@ public: QIcon icon(const QColor& background, bool inEditor) const override; QString name() const override; QString description() const override; + QRect boundingRect() const override; CaptureTool* copy(QObject* parent = nullptr) override; void process(QPainter& painter, const QPixmap& pixmap) override; void drawSearchArea(QPainter& painter, const QPixmap& pixmap) override; void paintMousePreview(QPainter& painter, const CaptureContext& context) override; - void drawObjectSelection(QPainter& painter) override; protected: - ToolType type() const override; + CaptureTool::Type type() const override; public slots: void pressed(const CaptureContext& context) override; diff --git a/src/tools/rectangle/rectangletool.cpp b/src/tools/rectangle/rectangletool.cpp index 42a4ca99..19e9d680 100644 --- a/src/tools/rectangle/rectangletool.cpp +++ b/src/tools/rectangle/rectangletool.cpp @@ -22,9 +22,9 @@ QString RectangleTool::name() const return tr("Rectangle"); } -ToolType RectangleTool::type() const +CaptureTool::Type RectangleTool::type() const { - return ToolType::RECTANGLE; + return CaptureTool::TYPE_RECTANGLE; } QString RectangleTool::description() const @@ -70,7 +70,7 @@ void RectangleTool::process(QPainter& painter, const QPixmap& pixmap) void RectangleTool::drawStart(const CaptureContext& context) { AbstractTwoPointTool::drawStart(context); - thicknessChanged(context.thickness); + onThicknessChanged(context.thickness); } void RectangleTool::pressed(const CaptureContext& context) diff --git a/src/tools/rectangle/rectangletool.h b/src/tools/rectangle/rectangletool.h index 5eba238a..7bba80ef 100644 --- a/src/tools/rectangle/rectangletool.h +++ b/src/tools/rectangle/rectangletool.h @@ -19,7 +19,7 @@ public: void process(QPainter& painter, const QPixmap& pixmap) override; protected: - ToolType type() const override; + CaptureTool::Type type() const override; public slots: void drawStart(const CaptureContext& context) override; diff --git a/src/tools/redo/redotool.cpp b/src/tools/redo/redotool.cpp index 750202a7..9efa1708 100644 --- a/src/tools/redo/redotool.cpp +++ b/src/tools/redo/redotool.cpp @@ -23,9 +23,9 @@ QString RedoTool::name() const return tr("Redo"); } -ToolType RedoTool::type() const +CaptureTool::Type RedoTool::type() const { - return ToolType::REDO; + return CaptureTool::TYPE_REDO; } QString RedoTool::description() const diff --git a/src/tools/redo/redotool.h b/src/tools/redo/redotool.h index 90187d8d..8642838b 100644 --- a/src/tools/redo/redotool.h +++ b/src/tools/redo/redotool.h @@ -20,7 +20,7 @@ public: CaptureTool* copy(QObject* parent = nullptr) override; protected: - ToolType type() const override; + CaptureTool::Type type() const override; public slots: void pressed(const CaptureContext& context) override; diff --git a/src/tools/save/savetool.cpp b/src/tools/save/savetool.cpp index 3d5c2574..13d29440 100644 --- a/src/tools/save/savetool.cpp +++ b/src/tools/save/savetool.cpp @@ -29,9 +29,9 @@ QString SaveTool::name() const return tr("Save"); } -ToolType SaveTool::type() const +CaptureTool::Type SaveTool::type() const { - return ToolType::SAVE; + return CaptureTool::TYPE_SAVE; } QString SaveTool::description() const diff --git a/src/tools/save/savetool.h b/src/tools/save/savetool.h index d2b4b3f1..ce7f89b9 100644 --- a/src/tools/save/savetool.h +++ b/src/tools/save/savetool.h @@ -20,7 +20,7 @@ public: CaptureTool* copy(QObject* parent = nullptr) override; protected: - ToolType type() const override; + CaptureTool::Type type() const override; public slots: void pressed(const CaptureContext& context) override; diff --git a/src/tools/selection/selectiontool.cpp b/src/tools/selection/selectiontool.cpp index b4cac4e9..2827d381 100644 --- a/src/tools/selection/selectiontool.cpp +++ b/src/tools/selection/selectiontool.cpp @@ -25,9 +25,9 @@ QString SelectionTool::name() const return tr("Rectangular Selection"); } -ToolType SelectionTool::type() const +CaptureTool::Type SelectionTool::type() const { - return ToolType::SELECTION; + return CaptureTool::TYPE_SELECTION; } QString SelectionTool::description() const diff --git a/src/tools/selection/selectiontool.h b/src/tools/selection/selectiontool.h index 949306cc..846a259d 100644 --- a/src/tools/selection/selectiontool.h +++ b/src/tools/selection/selectiontool.h @@ -21,7 +21,7 @@ public: void process(QPainter& painter, const QPixmap& pixmap) override; protected: - ToolType type() const override; + CaptureTool::Type type() const override; public slots: void pressed(const CaptureContext& context) override; diff --git a/src/tools/sizedecrease/sizedecreasetool.cpp b/src/tools/sizedecrease/sizedecreasetool.cpp index 82eac65f..8e28de92 100644 --- a/src/tools/sizedecrease/sizedecreasetool.cpp +++ b/src/tools/sizedecrease/sizedecreasetool.cpp @@ -37,9 +37,9 @@ QString SizeDecreaseTool::name() const return tr("Decrease Tool Size"); } -ToolType SizeDecreaseTool::type() const +CaptureTool::Type SizeDecreaseTool::type() const { - return ToolType::SIZEDECREASE; + return CaptureTool::TYPE_SIZEDECREASE; } QString SizeDecreaseTool::description() const diff --git a/src/tools/sizedecrease/sizedecreasetool.h b/src/tools/sizedecrease/sizedecreasetool.h index b7ba764e..ce558489 100644 --- a/src/tools/sizedecrease/sizedecreasetool.h +++ b/src/tools/sizedecrease/sizedecreasetool.h @@ -34,7 +34,7 @@ public: CaptureTool* copy(QObject* parent = nullptr) override; protected: - ToolType type() const override; + CaptureTool::Type type() const override; public slots: void pressed(const CaptureContext& context) override; diff --git a/src/tools/sizeincrease/sizeincreasetool.cpp b/src/tools/sizeincrease/sizeincreasetool.cpp index 0c2aca71..3c660396 100644 --- a/src/tools/sizeincrease/sizeincreasetool.cpp +++ b/src/tools/sizeincrease/sizeincreasetool.cpp @@ -37,9 +37,9 @@ QString SizeIncreaseTool::name() const return tr("Increase Tool Size"); } -ToolType SizeIncreaseTool::type() const +CaptureTool::Type SizeIncreaseTool::type() const { - return ToolType::SIZEINCREASE; + return CaptureTool::TYPE_SIZEINCREASE; } QString SizeIncreaseTool::description() const diff --git a/src/tools/sizeincrease/sizeincreasetool.h b/src/tools/sizeincrease/sizeincreasetool.h index 950f4db6..8c64bc04 100644 --- a/src/tools/sizeincrease/sizeincreasetool.h +++ b/src/tools/sizeincrease/sizeincreasetool.h @@ -34,7 +34,7 @@ public: CaptureTool* copy(QObject* parent = nullptr) override; protected: - ToolType type() const override; + CaptureTool::Type type() const override; public slots: void pressed(const CaptureContext& context) override; diff --git a/src/tools/sizeindicator/sizeindicatortool.cpp b/src/tools/sizeindicator/sizeindicatortool.cpp index 1fde4b3d..d6635c69 100644 --- a/src/tools/sizeindicator/sizeindicatortool.cpp +++ b/src/tools/sizeindicator/sizeindicatortool.cpp @@ -23,9 +23,9 @@ QString SizeIndicatorTool::name() const return tr("Selection Size Indicator"); } -ToolType SizeIndicatorTool::type() const +CaptureTool::Type SizeIndicatorTool::type() const { - return ToolType::SIZEINDICATOR; + return CaptureTool::TYPE_SELECTIONINDICATOR; } QString SizeIndicatorTool::description() const diff --git a/src/tools/sizeindicator/sizeindicatortool.h b/src/tools/sizeindicator/sizeindicatortool.h index 63ee0f68..3811a031 100644 --- a/src/tools/sizeindicator/sizeindicatortool.h +++ b/src/tools/sizeindicator/sizeindicatortool.h @@ -20,7 +20,7 @@ public: CaptureTool* copy(QObject* parent = nullptr) override; protected: - ToolType type() const override; + CaptureTool::Type type() const override; public slots: void pressed(const CaptureContext& context) override; diff --git a/src/tools/text/texttool.cpp b/src/tools/text/texttool.cpp index ca45bacb..3e6fa7bb 100644 --- a/src/tools/text/texttool.cpp +++ b/src/tools/text/texttool.cpp @@ -57,6 +57,11 @@ bool TextTool::showMousePreview() const return false; } +QRect TextTool::boundingRect() const +{ + return m_textArea; +} + QIcon TextTool::icon(const QColor& background, bool inEditor) const { Q_UNUSED(inEditor) @@ -82,9 +87,9 @@ QString TextTool::info() return name(); } -ToolType TextTool::type() const +CaptureTool::Type TextTool::type() const { - return ToolType::TEXT; + return CaptureTool::TYPE_TEXT; } QString TextTool::description() const @@ -220,7 +225,7 @@ void TextTool::drawObjectSelection(QPainter& painter) if (m_text.isEmpty()) { return; } - drawObjectSelectionRect(painter, m_textArea); + drawObjectSelectionRect(painter, boundingRect()); } void TextTool::paintMousePreview(QPainter& painter, @@ -252,7 +257,7 @@ void TextTool::pressed(const CaptureContext& context) Q_UNUSED(context) } -void TextTool::colorChanged(const QColor& c) +void TextTool::onColorChanged(const QColor& c) { m_color = c; if (m_widget) { @@ -260,7 +265,7 @@ void TextTool::colorChanged(const QColor& c) } } -void TextTool::thicknessChanged(int th) +void TextTool::onThicknessChanged(int th) { m_size = th; m_font.setPointSize(m_size + BASE_POINT_SIZE); diff --git a/src/tools/text/texttool.h b/src/tools/text/texttool.h index 272191ec..40f3e63a 100644 --- a/src/tools/text/texttool.h +++ b/src/tools/text/texttool.h @@ -21,6 +21,7 @@ public: bool closeOnButtonPressed() const override; bool isSelectable() const override; bool showMousePreview() const override; + QRect boundingRect() const override; QIcon icon(const QColor& background, bool inEditor) const override; QString name() const override; @@ -43,16 +44,16 @@ public: protected: void copyParams(const TextTool* from, TextTool* to); - ToolType type() const override; + CaptureTool::Type type() const 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(int th) override; - virtual int thickness() override { return m_size; }; + void onColorChanged(const QColor& c) override; + void onThicknessChanged(int th) override; + virtual int thickness() const override { return m_size; }; private slots: void updateText(const QString& s); diff --git a/src/tools/toolfactory.cpp b/src/tools/toolfactory.cpp index f57310bd..3f837d84 100644 --- a/src/tools/toolfactory.cpp +++ b/src/tools/toolfactory.cpp @@ -31,85 +31,39 @@ ToolFactory::ToolFactory(QObject* parent) : QObject(parent) {} -CaptureTool* ToolFactory::CreateTool(CaptureToolButton::ButtonType t, - QObject* parent) +CaptureTool* ToolFactory::CreateTool(CaptureTool::Type t, QObject* parent) { - CaptureTool* tool; +#define if_TYPE_return_TOOL(TYPE, TOOL) \ + case CaptureTool::TYPE: \ + return new TOOL(parent) + switch (t) { - case CaptureToolButton::TYPE_ARROW: - tool = new ArrowTool(parent); - break; - case CaptureToolButton::TYPE_CIRCLE: - tool = new CircleTool(parent); - break; - case CaptureToolButton::TYPE_COPY: - tool = new CopyTool(parent); - break; - case CaptureToolButton::TYPE_EXIT: - tool = new ExitTool(parent); - break; - case CaptureToolButton::TYPE_IMAGEUPLOADER: - tool = new ImgurUploaderTool(parent); - break; - case CaptureToolButton::TYPE_DRAWER: - tool = new LineTool(parent); - break; - case CaptureToolButton::TYPE_MARKER: - tool = new MarkerTool(parent); - break; - case CaptureToolButton::TYPE_MOVESELECTION: - tool = new MoveTool(parent); - break; - case CaptureToolButton::TYPE_PENCIL: - tool = new PencilTool(parent); - break; - case CaptureToolButton::TYPE_RECTANGLE: - tool = new RectangleTool(parent); - break; - case CaptureToolButton::TYPE_SAVE: - tool = new SaveTool(parent); - break; - case CaptureToolButton::TYPE_INVERT: - tool = new InvertTool(parent); - break; - case CaptureToolButton::TYPE_SELECTION: - tool = new SelectionTool(parent); - break; - case CaptureToolButton::TYPE_SELECTIONINDICATOR: - tool = new SizeIndicatorTool(parent); - break; - case CaptureToolButton::TYPE_UNDO: - tool = new UndoTool(parent); - break; - case CaptureToolButton::TYPE_REDO: - tool = new RedoTool(parent); - break; + if_TYPE_return_TOOL(TYPE_PENCIL, PencilTool); + if_TYPE_return_TOOL(TYPE_DRAWER, LineTool); + if_TYPE_return_TOOL(TYPE_ARROW, ArrowTool); + if_TYPE_return_TOOL(TYPE_SELECTION, SelectionTool); + if_TYPE_return_TOOL(TYPE_RECTANGLE, RectangleTool); + if_TYPE_return_TOOL(TYPE_CIRCLE, CircleTool); + if_TYPE_return_TOOL(TYPE_MARKER, MarkerTool); + if_TYPE_return_TOOL(TYPE_SELECTIONINDICATOR, SizeIndicatorTool); + if_TYPE_return_TOOL(TYPE_MOVESELECTION, MoveTool); + if_TYPE_return_TOOL(TYPE_UNDO, UndoTool); + if_TYPE_return_TOOL(TYPE_COPY, CopyTool); + if_TYPE_return_TOOL(TYPE_SAVE, SaveTool); + if_TYPE_return_TOOL(TYPE_EXIT, ExitTool); + if_TYPE_return_TOOL(TYPE_IMAGEUPLOADER, ImgurUploaderTool); #if !defined(Q_OS_MACOS) - case CaptureToolButton::TYPE_OPEN_APP: - tool = new AppLauncher(parent); - break; + if_TYPE_return_TOOL(TYPE_OPEN_APP, AppLauncher); #endif - case CaptureToolButton::TYPE_PIXELATE: - tool = new PixelateTool(parent); - break; - case CaptureToolButton::TYPE_PIN: - tool = new PinTool(parent); - break; - case CaptureToolButton::TYPE_TEXT: - tool = new TextTool(parent); - break; - case CaptureToolButton::TYPE_CIRCLECOUNT: - tool = new CircleCountTool(parent); - break; - case CaptureToolButton::TYPE_SIZEINCREASE: - tool = new SizeIncreaseTool(parent); - break; - case CaptureToolButton::TYPE_SIZEDECREASE: - tool = new SizeDecreaseTool(parent); - break; + if_TYPE_return_TOOL(TYPE_PIXELATE, PixelateTool); + if_TYPE_return_TOOL(TYPE_REDO, RedoTool); + if_TYPE_return_TOOL(TYPE_PIN, PinTool); + if_TYPE_return_TOOL(TYPE_TEXT, TextTool); + if_TYPE_return_TOOL(TYPE_CIRCLECOUNT, CircleCountTool); + if_TYPE_return_TOOL(TYPE_SIZEINCREASE, SizeIncreaseTool); + if_TYPE_return_TOOL(TYPE_SIZEDECREASE, SizeDecreaseTool); + if_TYPE_return_TOOL(TYPE_INVERT, InvertTool); default: - tool = nullptr; - break; + return nullptr; } - return tool; } diff --git a/src/tools/toolfactory.h b/src/tools/toolfactory.h index a058688f..5ce35720 100644 --- a/src/tools/toolfactory.h +++ b/src/tools/toolfactory.h @@ -19,6 +19,5 @@ public: ToolFactory(const ToolFactory&) = delete; ToolFactory& operator=(const ToolFactory&) = delete; - CaptureTool* CreateTool(CaptureToolButton::ButtonType t, - QObject* parent = nullptr); + CaptureTool* CreateTool(CaptureTool::Type t, QObject* parent = nullptr); }; diff --git a/src/tools/undo/undotool.cpp b/src/tools/undo/undotool.cpp index 1a755188..910956e5 100644 --- a/src/tools/undo/undotool.cpp +++ b/src/tools/undo/undotool.cpp @@ -23,9 +23,9 @@ QString UndoTool::name() const return tr("Undo"); } -ToolType UndoTool::type() const +CaptureTool::Type UndoTool::type() const { - return ToolType::UNDO; + return CaptureTool::TYPE_UNDO; } QString UndoTool::description() const diff --git a/src/tools/undo/undotool.h b/src/tools/undo/undotool.h index 1c434ec8..1771615f 100644 --- a/src/tools/undo/undotool.h +++ b/src/tools/undo/undotool.h @@ -20,7 +20,7 @@ public: CaptureTool* copy(QObject* parent = nullptr) override; protected: - ToolType type() const override; + CaptureTool::Type type() const override; public slots: void pressed(const CaptureContext& context) override; diff --git a/src/utils/confighandler.cpp b/src/utils/confighandler.cpp index 17a9cf2e..e45d2486 100644 --- a/src/utils/confighandler.cpp +++ b/src/utils/confighandler.cpp @@ -307,7 +307,7 @@ QString ConfigHandler::saveAsFileExtension() void ConfigHandler::setAllTheButtons() { - QList buttons = + QList buttons = CaptureToolButton::getIterableButtonTypes(); setValue(QStringLiteral("buttons"), QVariant::fromValue(buttons)); } diff --git a/src/utils/confighandler.h b/src/utils/confighandler.h index ec79cb93..94ab33b7 100644 --- a/src/utils/confighandler.h +++ b/src/utils/confighandler.h @@ -93,9 +93,7 @@ public: setIgnoreUpdateToVersion, QString) CONFIG_GETTER_SETTER(undoLimit, setUndoLimit, int) - CONFIG_GETTER_SETTER(buttons, - setButtons, - QList) + CONFIG_GETTER_SETTER(buttons, setButtons, QList) // SPECIAL CASES bool startupLaunch(); diff --git a/src/utils/configshortcuts.cpp b/src/utils/configshortcuts.cpp deleted file mode 100644 index 75fb6e0e..00000000 --- a/src/utils/configshortcuts.cpp +++ /dev/null @@ -1,152 +0,0 @@ -#include "configshortcuts.h" -#include "src/tools/capturetool.h" -#include -#include - -ConfigShortcuts::ConfigShortcuts() {} - -const QVector& ConfigShortcuts::captureShortcutsDefault( - const QVector& buttons) -{ - // get shortcuts names from capture buttons - for (const CaptureToolButton::ButtonType& t : buttons) { - CaptureToolButton* b = new CaptureToolButton(t, nullptr); - QString shortcutName = QVariant::fromValue(t).toString(); - if (shortcutName != "TYPE_IMAGEUPLOADER") { - addShortcut(shortcutName, b->tool()->description()); - if (shortcutName == "TYPE_COPY") - m_shortcuts << (QStringList() << "" << b->tool()->description() - << "Left Double-click"); - } - delete b; - } - - // additional tools that don't have their own buttons - addShortcut("TYPE_TOGGLE_PANEL", "Toggle side panel"); - addShortcut("TYPE_RESIZE_LEFT", "Resize selection left 1px"); - addShortcut("TYPE_RESIZE_RIGHT", "Resize selection right 1px"); - addShortcut("TYPE_RESIZE_UP", "Resize selection up 1px"); - addShortcut("TYPE_RESIZE_DOWN", "Resize selection down 1px"); - addShortcut("TYPE_SELECT_ALL", "Select entire screen"); - addShortcut("TYPE_MOVE_LEFT", "Move selection left 1px"); - addShortcut("TYPE_MOVE_RIGHT", "Move selection right 1px"); - addShortcut("TYPE_MOVE_UP", "Move selection up 1px"); - addShortcut("TYPE_MOVE_DOWN", "Move selection down 1px"); - addShortcut("TYPE_COMMIT_CURRENT_TOOL", "Commit text in text area"); - addShortcut("TYPE_DELETE_CURRENT_TOOL", "Delete current tool"); - - // non-editable shortcuts have an empty shortcut name - - m_shortcuts << (QStringList() << "" << QObject::tr("Quit capture") - << QKeySequence(Qt::Key_Escape).toString()); - - // Global hotkeys -#if defined(Q_OS_MACOS) - m_shortcuts << (QStringList() - << "" << QObject::tr("Screenshot history") << "⇧⌘⌥H"); - m_shortcuts << (QStringList() - << "" << QObject::tr("Capture screen") << "⇧⌘⌥4"); -#elif defined(Q_OS_WIN) - m_shortcuts << (QStringList() << "" << QObject::tr("Screenshot history") - << "Shift+Print Screen"); - m_shortcuts << (QStringList() - << "" << QObject::tr("Capture screen") << "Print Screen"); -#else - // TODO - Linux doesn't support global shortcuts for (XServer and Wayland), - // possibly it will be solved in the QHotKey library later. So it is - // disabled for now. -#endif - m_shortcuts << (QStringList() - << "" << QObject::tr("Show color picker") << "Right Click"); - m_shortcuts << (QStringList() - << "" << QObject::tr("Change the tool's thickness") - << "Mouse Wheel"); - - return m_shortcuts; -} - -const QKeySequence& ConfigShortcuts::captureShortcutDefault( - const QString& buttonType) -{ - m_ks = QKeySequence(); - if (buttonType == "TYPE_PENCIL") { - m_ks = QKeySequence(Qt::Key_P); - } else if (buttonType == "TYPE_DRAWER") { - m_ks = QKeySequence(Qt::Key_D); - } else if (buttonType == "TYPE_ARROW") { - m_ks = QKeySequence(Qt::Key_A); - } else if (buttonType == "TYPE_SELECTION") { - m_ks = QKeySequence(Qt::Key_S); - } else if (buttonType == "TYPE_RECTANGLE") { - m_ks = QKeySequence(Qt::Key_R); - } else if (buttonType == "TYPE_CIRCLE") { - m_ks = QKeySequence(Qt::Key_C); - } else if (buttonType == "TYPE_MARKER") { - m_ks = QKeySequence(Qt::Key_M); - } else if (buttonType == "TYPE_MOVESELECTION") { - m_ks = QKeySequence(Qt::CTRL + Qt::Key_M); - } else if (buttonType == "TYPE_UNDO") { - m_ks = QKeySequence(Qt::CTRL + Qt::Key_Z); - } else if (buttonType == "TYPE_COPY") { - m_ks = QKeySequence(Qt::CTRL + Qt::Key_C); - } else if (buttonType == "TYPE_SAVE") { - m_ks = QKeySequence(Qt::CTRL + Qt::Key_S); - } else if (buttonType == "TYPE_EXIT") { - m_ks = QKeySequence(Qt::CTRL + Qt::Key_Q); - } else if (buttonType == "TYPE_IMAGEUPLOADER") { - m_ks = QKeySequence(Qt::CTRL + Qt::Key_U); - } -#if !defined(Q_OS_MACOS) - else if (buttonType == "TYPE_OPEN_APP") { - m_ks = QKeySequence(Qt::CTRL + Qt::Key_O); - } -#endif - else if (buttonType == "TYPE_PIXELATE") { - m_ks = QKeySequence(Qt::Key_B); - } else if (buttonType == "TYPE_REDO") { - m_ks = QKeySequence(Qt::CTRL + Qt::SHIFT + Qt::Key_Z); - } else if (buttonType == "TYPE_TEXT") { - m_ks = QKeySequence(Qt::Key_T); - } else if (buttonType == "TYPE_INVERT") { - m_ks = QKeySequence(Qt::Key_I); - } else if (buttonType == "TYPE_TOGGLE_PANEL") { - m_ks = QKeySequence(Qt::Key_Space); - } else if (buttonType == "TYPE_RESIZE_LEFT") { - m_ks = QKeySequence(Qt::SHIFT + Qt::Key_Left); - } else if (buttonType == "TYPE_RESIZE_RIGHT") { - m_ks = QKeySequence(Qt::SHIFT + Qt::Key_Right); - } else if (buttonType == "TYPE_RESIZE_UP") { - m_ks = QKeySequence(Qt::SHIFT + Qt::Key_Up); - } else if (buttonType == "TYPE_RESIZE_DOWN") { - m_ks = QKeySequence(Qt::SHIFT + Qt::Key_Down); - } else if (buttonType == "TYPE_SELECT_ALL") { - m_ks = QKeySequence(Qt::CTRL + Qt::Key_A); - } else if (buttonType == "TYPE_MOVE_LEFT") { - m_ks = QKeySequence(Qt::Key_Left); - } else if (buttonType == "TYPE_MOVE_RIGHT") { - m_ks = QKeySequence(Qt::Key_Right); - } else if (buttonType == "TYPE_MOVE_UP") { - m_ks = QKeySequence(Qt::Key_Up); - } else if (buttonType == "TYPE_MOVE_DOWN") { - m_ks = QKeySequence(Qt::Key_Down); - } else if (buttonType == "TYPE_COMMIT_CURRENT_TOOL") { - m_ks = QKeySequence(Qt::CTRL + Qt::Key_Return); - } else if (buttonType == "TYPE_DELETE_CURRENT_TOOL") { -#if defined(Q_OS_MACOS) - m_ks = QKeySequence(Qt::Key_Backspace); -#else - m_ks = QKeySequence(Qt::Key_Delete); -#endif - } - return m_ks; -} - -// Helper function -void ConfigShortcuts::addShortcut(const QString& shortcutName, - const QString& description) -{ - m_shortcuts << (QStringList() - << shortcutName - << QObject::tr(description.toStdString().c_str()) - << captureShortcutDefault(shortcutName).toString()); -} diff --git a/src/utils/valuehandler.cpp b/src/utils/valuehandler.cpp index 951dce38..fe8826ff 100644 --- a/src/utils/valuehandler.cpp +++ b/src/utils/valuehandler.cpp @@ -1,4 +1,5 @@ #include "valuehandler.h" +#include "capturetool.h" #include "confighandler.h" #include #include @@ -267,15 +268,16 @@ QString FilenamePattern::expected() // BUTTON LIST -using BType = CaptureToolButton::ButtonType; -using BList = QList; +using BType = CaptureTool::Type; +using BList = QList; bool ButtonList::check(const QVariant& val) { + // TODO stop using CTB using CTB = CaptureToolButton; auto allButtons = CTB::getIterableButtonTypes(); for (int btn : val.value>()) { - if (!allButtons.contains(static_cast(btn))) { + if (!allButtons.contains(static_cast(btn))) { return false; } } @@ -302,8 +304,8 @@ QVariant ButtonList::process(const QVariant& val) QVariant ButtonList::fallback() { auto buttons = CaptureToolButton::getIterableButtonTypes(); - buttons.removeOne(CaptureToolButton::TYPE_SIZEDECREASE); - buttons.removeOne(CaptureToolButton::TYPE_SIZEINCREASE); + buttons.removeOne(CaptureTool::TYPE_SIZEDECREASE); + buttons.removeOne(CaptureTool::TYPE_SIZEINCREASE); sortButtons(buttons); return QVariant::fromValue(buttons); } @@ -320,17 +322,16 @@ QString ButtonList::expected() return QStringLiteral("please don't edit by hand"); } -QList ButtonList::fromIntList( - const QList& l) +QList ButtonList::fromIntList(const QList& l) { - QList buttons; + QList buttons; buttons.reserve(l.size()); for (auto const i : l) - buttons << static_cast(i); + buttons << static_cast(i); return buttons; } -QList ButtonList::toIntList(const QList& l) +QList ButtonList::toIntList(const QList& l) { QList buttons; buttons.reserve(l.size()); diff --git a/src/utils/valuehandler.h b/src/utils/valuehandler.h index 60f1d490..d6d767b6 100644 --- a/src/utils/valuehandler.h +++ b/src/utils/valuehandler.h @@ -183,8 +183,8 @@ public: QString expected() override; // UTILITY FUNCTIONS - static QList fromIntList(const QList&); - static QList toIntList(const QList& l); + static QList fromIntList(const QList&); + static QList toIntList(const QList& l); static bool normalizeButtons(QList& buttons); }; diff --git a/src/widgets/capture/capturetoolbutton.cpp b/src/widgets/capture/capturetoolbutton.cpp index 44b52da7..a54d8595 100644 --- a/src/widgets/capture/capturetoolbutton.cpp +++ b/src/widgets/capture/capturetoolbutton.cpp @@ -16,14 +16,14 @@ // Button represents a single button of the capture widget, it can enable // multiple functionality. -CaptureToolButton::CaptureToolButton(const ButtonType t, QWidget* parent) +CaptureToolButton::CaptureToolButton(const CaptureTool::Type t, QWidget* parent) : CaptureButton(parent) , m_buttonType(t) , m_tool(nullptr) , m_emergeAnimation(nullptr) { initButton(); - if (t == TYPE_SELECTIONINDICATOR) { + if (t == CaptureTool::TYPE_SELECTIONINDICATOR) { QFont f = this->font(); setFont(QFont(f.family(), 7, QFont::Bold)); } else { @@ -62,8 +62,11 @@ void CaptureToolButton::initButton() QString tooltip = m_tool->description(); QString shortcut = ConfigHandler().shortcut(QVariant::fromValue(m_buttonType).toString()); - if (!shortcut.isEmpty()) { - tooltip += QString(" (%1)").arg(shortcut); + if (m_buttonType == CaptureTool::TYPE_COPY) { + tooltip += QStringLiteral(" (%1Left Double-Click)") + .arg(shortcut.isEmpty() ? QString() : shortcut + " or "); + } else if (!shortcut.isEmpty()) { + tooltip += QStringLiteral(" (%1)").arg(shortcut); } setToolTip(tooltip); @@ -81,7 +84,7 @@ void CaptureToolButton::updateIcon() setIconSize(size() * 0.6); } -QList CaptureToolButton::getIterableButtonTypes() +const QList& CaptureToolButton::getIterableButtonTypes() { return iterableButtonTypes; } @@ -105,8 +108,10 @@ void CaptureToolButton::animatedShow() if (!isVisible()) { show(); m_emergeAnimation->start(); - connect( - m_emergeAnimation, &QPropertyAnimation::finished, this, []() {}); + connect(m_emergeAnimation, + &QPropertyAnimation::finished, + this, + [this]() { updateIcon(); }); } } @@ -124,68 +129,60 @@ void CaptureToolButton::setColor(const QColor& c) QColor CaptureToolButton::m_mainColor; -static std::map buttonTypeOrder +static std::map buttonTypeOrder { - { CaptureToolButton::TYPE_PENCIL, 0 }, - { CaptureToolButton::TYPE_DRAWER, 1 }, - { CaptureToolButton::TYPE_ARROW, 2 }, - { CaptureToolButton::TYPE_SELECTION, 3 }, - { CaptureToolButton::TYPE_RECTANGLE, 4 }, - { CaptureToolButton::TYPE_CIRCLE, 5 }, - { CaptureToolButton::TYPE_MARKER, 6 }, - { CaptureToolButton::TYPE_TEXT, 7 }, - { CaptureToolButton::TYPE_PIXELATE, 8 }, - { CaptureToolButton::TYPE_INVERT, 9 }, - { CaptureToolButton::TYPE_CIRCLECOUNT, 10 }, - { CaptureToolButton::TYPE_SELECTIONINDICATOR, 11 }, - { CaptureToolButton::TYPE_MOVESELECTION, 12 }, - { CaptureToolButton::TYPE_UNDO, 13 }, - { CaptureToolButton::TYPE_REDO, 14 }, - { CaptureToolButton::TYPE_COPY, 15 }, - { CaptureToolButton::TYPE_SAVE, 16 }, - { CaptureToolButton::TYPE_IMAGEUPLOADER, 17 }, + { CaptureTool::TYPE_PENCIL, 0 }, { CaptureTool::TYPE_DRAWER, 1 }, + { CaptureTool::TYPE_ARROW, 2 }, { CaptureTool::TYPE_SELECTION, 3 }, + { CaptureTool::TYPE_RECTANGLE, 4 }, { CaptureTool::TYPE_CIRCLE, 5 }, + { CaptureTool::TYPE_MARKER, 6 }, { CaptureTool::TYPE_TEXT, 7 }, + { CaptureTool::TYPE_PIXELATE, 8 }, { CaptureTool::TYPE_INVERT, 9 }, + { CaptureTool::TYPE_CIRCLECOUNT, 10 }, + { CaptureTool::TYPE_SELECTIONINDICATOR, 11 }, + { CaptureTool::TYPE_MOVESELECTION, 12 }, { CaptureTool::TYPE_UNDO, 13 }, + { CaptureTool::TYPE_REDO, 14 }, { CaptureTool::TYPE_COPY, 15 }, + { CaptureTool::TYPE_SAVE, 16 }, { CaptureTool::TYPE_IMAGEUPLOADER, 17 }, #if !defined(Q_OS_MACOS) - { CaptureToolButton::TYPE_OPEN_APP, 18 }, - { CaptureToolButton::TYPE_EXIT, 19 }, { CaptureToolButton::TYPE_PIN, 20 }, + { CaptureTool::TYPE_OPEN_APP, 18 }, { CaptureTool::TYPE_EXIT, 19 }, + { CaptureTool::TYPE_PIN, 20 }, #else - { CaptureToolButton::TYPE_EXIT, 18 }, { CaptureToolButton::TYPE_PIN, 19 }, + { CaptureTool::TYPE_EXIT, 18 }, { CaptureTool::TYPE_PIN, 19 }, #endif - { CaptureToolButton::TYPE_SIZEINCREASE, 21 }, - { CaptureToolButton::TYPE_SIZEDECREASE, 22 }, + { CaptureTool::TYPE_SIZEINCREASE, 21 }, + { CaptureTool::TYPE_SIZEDECREASE, 22 }, }; -int CaptureToolButton::getPriorityByButton(CaptureToolButton::ButtonType b) +int CaptureToolButton::getPriorityByButton(CaptureTool::Type b) { auto it = buttonTypeOrder.find(b); return it == buttonTypeOrder.cend() ? (int)buttonTypeOrder.size() : it->second; } -QList CaptureToolButton::iterableButtonTypes = { - CaptureToolButton::TYPE_PENCIL, - CaptureToolButton::TYPE_DRAWER, - CaptureToolButton::TYPE_ARROW, - CaptureToolButton::TYPE_SELECTION, - CaptureToolButton::TYPE_RECTANGLE, - CaptureToolButton::TYPE_CIRCLE, - CaptureToolButton::TYPE_MARKER, - CaptureToolButton::TYPE_TEXT, - CaptureToolButton::TYPE_PIXELATE, - CaptureToolButton::TYPE_INVERT, - CaptureToolButton::TYPE_SELECTIONINDICATOR, - CaptureToolButton::TYPE_MOVESELECTION, - CaptureToolButton::TYPE_UNDO, - CaptureToolButton::TYPE_REDO, - CaptureToolButton::TYPE_COPY, - CaptureToolButton::TYPE_SAVE, - CaptureToolButton::TYPE_EXIT, - CaptureToolButton::TYPE_IMAGEUPLOADER, +QList CaptureToolButton::iterableButtonTypes = { + CaptureTool::TYPE_PENCIL, + CaptureTool::TYPE_DRAWER, + CaptureTool::TYPE_ARROW, + CaptureTool::TYPE_SELECTION, + CaptureTool::TYPE_RECTANGLE, + CaptureTool::TYPE_CIRCLE, + CaptureTool::TYPE_MARKER, + CaptureTool::TYPE_TEXT, + CaptureTool::TYPE_PIXELATE, + CaptureTool::TYPE_INVERT, + CaptureTool::TYPE_SELECTIONINDICATOR, + CaptureTool::TYPE_MOVESELECTION, + CaptureTool::TYPE_UNDO, + CaptureTool::TYPE_REDO, + CaptureTool::TYPE_COPY, + CaptureTool::TYPE_SAVE, + CaptureTool::TYPE_EXIT, + CaptureTool::TYPE_IMAGEUPLOADER, #if !defined(Q_OS_MACOS) - CaptureToolButton::TYPE_OPEN_APP, + CaptureTool::TYPE_OPEN_APP, #endif - CaptureToolButton::TYPE_PIN, - CaptureToolButton::TYPE_CIRCLECOUNT, - CaptureToolButton::TYPE_SIZEINCREASE, - CaptureToolButton::TYPE_SIZEDECREASE, + CaptureTool::TYPE_PIN, + CaptureTool::TYPE_CIRCLECOUNT, + CaptureTool::TYPE_SIZEINCREASE, + CaptureTool::TYPE_SIZEDECREASE, }; diff --git a/src/widgets/capture/capturetoolbutton.h b/src/widgets/capture/capturetoolbutton.h index bf456dbd..2799ac41 100644 --- a/src/widgets/capture/capturetoolbutton.h +++ b/src/widgets/capture/capturetoolbutton.h @@ -4,55 +4,24 @@ #pragma once #include "capturebutton.h" +#include "src/tools/capturetool.h" #include #include class QWidget; class QPropertyAnimation; -class CaptureTool; class CaptureToolButton : public CaptureButton { Q_OBJECT public: - // Don't forget to add the new types to CaptureButton::iterableButtonTypes - // in the .cpp and the order value in the private array buttonTypeOrder - // NOTE: Add new entries to the BOTTOM so existing user configurations don't - // get messed up. - enum ButtonType - { - TYPE_PENCIL = 0, - TYPE_DRAWER = 1, - TYPE_ARROW = 2, - TYPE_SELECTION = 3, - TYPE_RECTANGLE = 4, - TYPE_CIRCLE = 5, - TYPE_MARKER = 6, - TYPE_SELECTIONINDICATOR = 7, - TYPE_MOVESELECTION = 8, - TYPE_UNDO = 9, - TYPE_COPY = 10, - TYPE_SAVE = 11, - TYPE_EXIT = 12, - TYPE_IMAGEUPLOADER = 13, - TYPE_OPEN_APP = 14, - TYPE_PIXELATE = 15, - TYPE_REDO = 16, - TYPE_PIN = 17, - TYPE_TEXT = 18, - TYPE_CIRCLECOUNT = 19, - TYPE_SIZEINCREASE = 20, - TYPE_SIZEDECREASE = 21, - TYPE_INVERT = 22, - }; - Q_ENUM(ButtonType) - - explicit CaptureToolButton(const ButtonType, QWidget* parent = nullptr); + explicit CaptureToolButton(const CaptureTool::Type, + QWidget* parent = nullptr); ~CaptureToolButton(); - static QList getIterableButtonTypes(); - static int getPriorityByButton(CaptureToolButton::ButtonType); + static const QList& getIterableButtonTypes(); + static int getPriorityByButton(CaptureTool::Type); QString name() const; QString description() const; @@ -64,7 +33,7 @@ public: protected: void mousePressEvent(QMouseEvent* e) override; - static QList iterableButtonTypes; + static QList iterableButtonTypes; CaptureTool* m_tool; @@ -73,7 +42,7 @@ signals: private: CaptureToolButton(QWidget* parent = nullptr); - ButtonType m_buttonType; + CaptureTool::Type m_buttonType; QPropertyAnimation* m_emergeAnimation; diff --git a/src/widgets/capture/capturetoolobjects.cpp b/src/widgets/capture/capturetoolobjects.cpp index bf7f6226..6365710b 100644 --- a/src/widgets/capture/capturetoolobjects.cpp +++ b/src/widgets/capture/capturetoolobjects.cpp @@ -99,7 +99,7 @@ int CaptureToolObjects::findWithRadius(QPainter& painter, m_imageCache.insert(0, image); } - if (toolItem->type() == ToolType::TEXT) { + if (toolItem->type() == CaptureTool::TYPE_TEXT) { if (currentRadius > SEARCH_RADIUS_NEAR) { // Text already has a big currentRadius and no need to search // with a bit bigger currentRadius than diff --git a/src/widgets/capture/capturewidget.cpp b/src/widgets/capture/capturewidget.cpp index a07f7a95..1c5bfa4c 100644 --- a/src/widgets/capture/capturewidget.cpp +++ b/src/widgets/capture/capturewidget.cpp @@ -28,6 +28,7 @@ #include "src/widgets/updatenotificationwidget.h" #include #include +#include #include #include #include @@ -52,9 +53,6 @@ CaptureWidget::CaptureWidget(uint id, QWidget* parent) : QWidget(parent) , m_mouseIsClicked(false) - , m_newSelection(true) - , m_grabbing(false) - , m_movingSelection(false) , m_captureDone(false) , m_previewEnabled(true) , m_adjustmentButtonPressed(false) @@ -64,7 +62,6 @@ CaptureWidget::CaptureWidget(uint id, , m_activeTool(nullptr) , m_toolWidget(nullptr) , m_colorPicker(nullptr) - , m_mouseOverHandle(SelectionWidget::NO_SIDE) , m_id(id) , m_lastMouseWheel(0) , m_updateNotificationWidget(nullptr) @@ -94,7 +91,8 @@ CaptureWidget::CaptureWidget(uint id, m_contrastUiColor = m_config.contrastUiColor(); setMouseTracking(true); initContext(savePath, fullScreen); - initShortcuts(); + initSelection(); + initShortcuts(); // must be called after initSelection #if (defined(Q_OS_WIN) || defined(Q_OS_MACOS)) // Top left of the whole set of screens QPoint topLeft(0, 0); @@ -181,9 +179,6 @@ CaptureWidget::CaptureWidget(uint id, m_buttonHandler->updateScreenRegions(areas); m_buttonHandler->hide(); - initSelection(); - updateCursor(); - // Init color picker m_colorPicker = new ColorPicker(this); connect(m_colorPicker, @@ -211,14 +206,15 @@ CaptureWidget::CaptureWidget(uint id, connect(ConfigHandler::getInstance(), &ConfigHandler::error, this, [=]() { m_configError = true; m_configErrorResolved = false; - update(); + OverlayMessage::instance()->update(); }); connect( ConfigHandler::getInstance(), &ConfigHandler::errorResolved, this, [=]() { m_configError = false; m_configErrorResolved = true; - update(); + OverlayMessage::instance()->update(); }); + OverlayMessage::init(this, QGuiAppCurrentScreen().currentScreen()->geometry()); @@ -230,6 +226,8 @@ CaptureWidget::CaptureWidget(uint id, "\nUse the Mouse Wheel to change the thickness of your tool." "\nPress Space to open the side panel.")); } + + updateCursor(); } CaptureWidget::~CaptureWidget() @@ -249,22 +247,24 @@ void CaptureWidget::initButtons() // Add all buttons but hide those that were disabled in the Interface config // This will allow keyboard shortcuts for those buttons to work - for (const CaptureToolButton::ButtonType& t : allButtonTypes) { + for (const CaptureTool::Type& t : allButtonTypes) { CaptureToolButton* b = new CaptureToolButton(t, this); - if (t == CaptureToolButton::TYPE_SELECTIONINDICATOR) { + if (t == CaptureTool::TYPE_SELECTIONINDICATOR) { m_sizeIndButton = b; } b->setColor(m_uiColor); b->hide(); + // must be enabled for SelectionWidget's eventFilter to work correctly + b->setAttribute(Qt::WA_NoMousePropagation); makeChild(b); switch (t) { - case CaptureToolButton::ButtonType::TYPE_EXIT: - case CaptureToolButton::ButtonType::TYPE_SAVE: - case CaptureToolButton::ButtonType::TYPE_COPY: - case CaptureToolButton::ButtonType::TYPE_UNDO: - case CaptureToolButton::ButtonType::TYPE_IMAGEUPLOADER: - case CaptureToolButton::ButtonType::TYPE_REDO: + case CaptureTool::TYPE_EXIT: + case CaptureTool::TYPE_SAVE: + case CaptureTool::TYPE_COPY: + case CaptureTool::TYPE_UNDO: + case CaptureTool::TYPE_IMAGEUPLOADER: + case CaptureTool::TYPE_REDO: // nothing to do, just skip non-dynamic buttons with existing // hard coded slots break; @@ -313,6 +313,9 @@ bool CaptureWidget::commitCurrentTool() m_toolWidget) { pushToolToStack(); } + if (m_toolWidget) { + m_toolWidget->update(); + } releaseActiveTool(); return true; } @@ -321,12 +324,11 @@ bool CaptureWidget::commitCurrentTool() void CaptureWidget::deleteToolWidgetOrClose() { - if (!m_activeButton.isNull()) { + if (m_activeButton != nullptr) { uncheckActiveTool(); } else if (m_panel->activeLayerIndex() >= 0) { // remove active tool selection m_panel->setActiveLayer(-1); - drawToolsData(false, true); } else if (m_panel->isVisible()) { // hide panel if visible m_panel->hide(); @@ -370,10 +372,11 @@ void CaptureWidget::uncheckActiveTool() // uncheck active tool m_panel->setToolWidget(nullptr); m_activeButton->setColor(m_uiColor); + updateToolMousePreview(activeButtonTool()); m_activeButton = nullptr; releaseActiveTool(); + updateSelectionState(); updateCursor(); - update(); // clear mouse preview } void CaptureWidget::paintEvent(QPaintEvent* paintEvent) @@ -386,7 +389,7 @@ void CaptureWidget::paintEvent(QPaintEvent* paintEvent) painter.save(); m_activeTool->process(painter, m_context.screenshot); painter.restore(); - } else if (m_previewEnabled && m_activeButton && m_activeButton->tool() && + } else if (m_previewEnabled && activeButtonTool() && m_activeButton->tool()->showMousePreview()) { painter.save(); m_activeButton->tool()->paintMousePreview(painter, m_context); @@ -405,7 +408,7 @@ void CaptureWidget::showColorPicker(const QPoint& pos) { // Try to select new object if current pos out of active object auto toolItem = activeToolObject(); - if (!toolItem || toolItem && !toolItem->selectionRect().contains(pos)) { + if (!toolItem || toolItem && !toolItem->boundingRect().contains(pos)) { selectToolItemAtPos(pos); } @@ -423,8 +426,8 @@ void CaptureWidget::showColorPicker(const QPoint& pos) bool CaptureWidget::startDrawObjectTool(const QPoint& pos) { - if (m_activeButton && m_activeButton->tool() && - m_activeButton->tool()->type() != ToolType::MOVE) { + if (activeButtonToolType() != CaptureTool::NONE && + activeButtonToolType() != CaptureTool::TYPE_MOVESELECTION) { if (commitCurrentTool()) { return false; } @@ -433,18 +436,19 @@ bool CaptureWidget::startDrawObjectTool(const QPoint& pos) connect(this, &CaptureWidget::colorChanged, m_activeTool, - &CaptureTool::colorChanged); + &CaptureTool::onColorChanged); connect(this, &CaptureWidget::thicknessChanged, m_activeTool, - &CaptureTool::thicknessChanged); + &CaptureTool::onThicknessChanged); connect(m_activeTool, &CaptureTool::requestAction, this, &CaptureWidget::handleToolSignal); m_context.mousePos = pos; m_activeTool->drawStart(m_context); - if (m_activeTool->type() == ToolType::CIRCLECOUNT) { + // TODO this is the wrong place to do this + if (m_activeTool->type() == CaptureTool::TYPE_CIRCLECOUNT) { // While it is based on AbstractTwoPointTool it has the only one // point and shouldn't wait for second point and move event m_activeTool->drawEnd(m_context.mousePos); @@ -453,8 +457,6 @@ bool CaptureWidget::startDrawObjectTool(const QPoint& pos) m_captureToolObjects.append(m_activeTool); pushObjectsStateToUndoStack(); releaseActiveTool(); - drawToolsData(); - m_mouseIsClicked = false; } return true; @@ -473,12 +475,14 @@ int CaptureWidget::selectToolItemAtPos(const QPoint& pos) { // Try to select existing tool, "-1" - no active tool int activeLayerIndex = -1; + auto selectionMouseSide = m_selection->getMouseSide(pos); if (m_activeButton.isNull() && m_captureToolObjects.captureToolObjects().size() > 0 && - m_selection->getMouseSide(pos) == SelectionWidget::NO_SIDE) { + (selectionMouseSide == SelectionWidget::NO_SIDE || + selectionMouseSide == SelectionWidget::CENTER)) { auto toolItem = activeToolObject(); if (!toolItem || - (toolItem && !toolItem->selectionRect().contains(pos))) { + (toolItem && !toolItem->boundingRect().contains(pos))) { activeLayerIndex = m_captureToolObjects.find(pos, size()); int thickness_old = m_context.thickness; m_panel->setActiveLayer(activeLayerIndex); @@ -495,7 +499,7 @@ void CaptureWidget::mousePressEvent(QMouseEvent* e) { m_startMove = false; m_startMovePos = QPoint(); - m_dragStartPoint = m_mousePressedPos = e->pos(); + m_mousePressedPos = e->pos(); m_activeToolOffsetToMouseOnStart = QPoint(); if (m_colorPicker->isVisible()) { updateCursor(); @@ -503,7 +507,7 @@ void CaptureWidget::mousePressEvent(QMouseEvent* e) } // reset object selection if capture area selection is active - if (m_selection->getMouseSide(e->pos()) != SelectionWidget::NO_SIDE) { + if (m_selection->getMouseSide(e->pos()) != SelectionWidget::CENTER) { m_panel->setActiveLayer(-1); } @@ -522,21 +526,6 @@ void CaptureWidget::mousePressEvent(QMouseEvent* e) // return if success return; } - - m_selection->saveGeometry(); - // New selection - if (m_captureToolObjects.captureToolObjects().size() == 0) { - if (!m_selection->geometry().contains(e->pos()) && - m_mouseOverHandle == SelectionWidget::NO_SIDE) { - m_selection->setGeometry( - QRect(m_mousePressedPos, m_mousePressedPos)); - m_selection->setVisible(false); - m_buttonHandler->hide(); - update(); - } else { - m_grabbing = true; - } - } } // Commit current tool if it has edit widget and mouse click is outside @@ -545,11 +534,12 @@ void CaptureWidget::mousePressEvent(QMouseEvent* e) commitCurrentTool(); m_panel->setToolWidget(nullptr); drawToolsData(); - update(); + updateLayersPanel(); } selectToolItemAtPos(m_mousePressedPos); + updateSelectionState(); updateCursor(); } @@ -559,34 +549,33 @@ void CaptureWidget::mouseDoubleClickEvent(QMouseEvent* event) if (activeLayerIndex != -1) { // Start object editing auto activeTool = m_captureToolObjects.at(activeLayerIndex); - if (activeTool && activeTool->type() == ToolType::TEXT) { + if (activeTool && activeTool->type() == CaptureTool::TYPE_TEXT) { m_activeTool = activeTool; m_mouseIsClicked = false; m_context.mousePos = *m_activeTool->pos(); m_captureToolObjectsBackup = m_captureToolObjects; m_activeTool->setEditMode(true); - drawToolsData(true, false); - m_mouseIsClicked = false; + drawToolsData(); + updateLayersPanel(); handleToolSignal(CaptureTool::REQ_ADD_CHILD_WIDGET); m_panel->setToolWidget(m_activeTool->configurationWidget()); } - } else { - if (m_selection->geometry().contains(event->pos())) { - copyScreenshot(); - } + } else if (m_selection->geometry().contains(event->pos())) { + copyScreenshot(); } } void CaptureWidget::mouseMoveEvent(QMouseEvent* e) { m_context.mousePos = e->pos(); - bool symmetryMod = qApp->keyboardModifiers() & Qt::ShiftModifier; - - int activeLayerIndex = -1; - if (m_mouseIsClicked) { - activeLayerIndex = m_panel->activeLayerIndex(); + if (e->buttons() != Qt::LeftButton) { + updateToolMousePreview(activeButtonTool()); + updateCursor(); + return; } - if (m_mouseIsClicked && !m_activeButton && activeLayerIndex >= 0) { + + // The rest assumes that left mouse button is clicked + if (!m_activeButton && m_panel->activeLayerIndex() >= 0) { // Move existing object if (!m_startMove) { // Check for the minimal offset to start moving an object @@ -600,9 +589,9 @@ void CaptureWidget::mouseMoveEvent(QMouseEvent* e) } if (m_startMove) { QPointer activeTool = - m_captureToolObjects.at(activeLayerIndex); + m_captureToolObjects.at(m_panel->activeLayerIndex()); if (m_activeToolOffsetToMouseOnStart.isNull()) { - setCursor(Qt::OpenHandCursor); + setCursor(Qt::ClosedHandCursor); m_activeToolOffsetToMouseOnStart = e->pos() - *activeTool->pos(); } @@ -611,94 +600,21 @@ void CaptureWidget::mouseMoveEvent(QMouseEvent* e) m_captureToolObjectsBackup = m_captureToolObjects; } m_activeToolIsMoved = true; + // update the old region of the selection, margins are added to + // ensure selection outline is updated too + update(paddedUpdateRect(activeTool->boundingRect())); activeTool->move(e->pos() - m_activeToolOffsetToMouseOnStart); - drawToolsData(false); + drawToolsData(); } - } else if (m_mouseIsClicked && - (!m_activeButton || - (m_activeButton && m_activeButton->tool() && - m_activeButton->tool()->type() == ToolType::MOVE))) { - // Drawing, moving, or stretching a selection - m_selection->setVisible(true); - if (m_buttonHandler->isVisible()) { - m_buttonHandler->hide(); - } - QRect inputRect; - if (m_mouseOverHandle != SelectionWidget::NO_SIDE) { - // Dragging a handle - inputRect = m_selection->savedGeometry(); - QPoint offset = e->pos() - m_dragStartPoint; - - using sw = SelectionWidget; - QRect& r = inputRect; - if (m_mouseOverHandle == sw::TOPLEFT_SIDE || - m_mouseOverHandle == sw::TOP_SIDE || - m_mouseOverHandle == sw::TOPRIGHT_SIDE) { - // dragging one of the top handles - r.setTop(r.top() + offset.y()); - if (symmetryMod) { - r.setBottom(r.bottom() - offset.y()); - } - } - if (m_mouseOverHandle == sw::TOPLEFT_SIDE || - m_mouseOverHandle == sw::LEFT_SIDE || - m_mouseOverHandle == sw::BOTTOMLEFT_SIDE) { - // dragging one of the left handles - r.setLeft(r.left() + offset.x()); - if (symmetryMod) { - r.setRight(r.right() - offset.x()); - } - } - if (m_mouseOverHandle == sw::BOTTOMLEFT_SIDE || - m_mouseOverHandle == sw::BOTTOM_SIDE || - m_mouseOverHandle == sw::BOTTOMRIGHT_SIDE) { - // dragging one of the bottom handles - r.setBottom(r.bottom() + offset.y()); - if (symmetryMod) { - r.setTop(r.top() - offset.y()); - } - } - if (m_mouseOverHandle == sw::TOPRIGHT_SIDE || - m_mouseOverHandle == sw::RIGHT_SIDE || - m_mouseOverHandle == sw::BOTTOMRIGHT_SIDE) { - // dragging one of the right handles - r.setRight(r.right() + offset.x()); - if (symmetryMod) { - r.setLeft(r.left() - offset.x()); - } - } - } else if (!m_movingSelection && - (!m_selection->geometry().contains(e->pos()) || - m_newSelection)) { - m_newSelection = true; - // Drawing a new selection - inputRect = symmetryMod - ? QRect(m_dragStartPoint * 2 - m_context.mousePos, - m_context.mousePos) - : QRect(m_dragStartPoint, m_context.mousePos); - } else if (m_mouseOverHandle == SelectionWidget::NO_SIDE) { - // Moving the whole selection - m_movingSelection = true; - if (m_adjustmentButtonPressed || activeToolObject().isNull()) { - setCursor(Qt::OpenHandCursor); - QRect initialRect = m_selection->savedGeometry().normalized(); - QPoint newTopLeft = - initialRect.topLeft() + (e->pos() - m_dragStartPoint); - inputRect = QRect(newTopLeft, initialRect.size()); - } else { - return; - } - } - m_selection->setGeometry(inputRect.intersected(rect()).normalized()); - update(); - } else if (m_mouseIsClicked && m_activeTool) { + } else if (m_activeTool) { // drawing with a tool if (m_adjustmentButtonPressed) { m_activeTool->drawMoveWithAdjustment(e->pos()); } else { m_activeTool->drawMove(e->pos()); } - update(); + // update drawing object + updateToolMousePreview(m_activeTool); // Hides the buttons under the mouse. If the mouse leaves, it shows // them. if (m_buttonHandler->buttonsAreInside()) { @@ -710,15 +626,8 @@ void CaptureWidget::mouseMoveEvent(QMouseEvent* e) m_buttonHandler->show(); } } - } else if (m_activeButton && m_activeButton->tool()) { - update(); - } else { - if (!m_selection->isVisible()) { - return; - } - m_mouseOverHandle = m_selection->getMouseSide(m_context.mousePos); - updateCursor(); } + updateCursor(); } void CaptureWidget::mouseReleaseEvent(QMouseEvent* e) @@ -747,57 +656,20 @@ void CaptureWidget::mouseReleaseEvent(QMouseEvent* e) if (m_activeToolIsMoved) { m_activeToolIsMoved = false; pushObjectsStateToUndoStack(); - } else if (e->pos() == m_mousePressedPos && - m_activeButton.isNull()) { - // Try to select existing tool if it was in the selection area - // but need to select another one - m_panel->setActiveLayer( - m_captureToolObjects.find(e->pos(), size())); } - drawToolsData(true, true); } } - - if (!m_buttonHandler->isVisible() && m_selection->isVisible()) { - // Show the buttons after the resize of the selection or the creation - // of a new one. - - // Don't go outside - QRect newGeometry = m_selection->geometry().intersected(rect()); - // normalize - if (newGeometry.width() <= 0) { - int left = newGeometry.left(); - newGeometry.setLeft(newGeometry.right()); - newGeometry.setRight(left); - } - if (newGeometry.height() <= 0) { - int top = newGeometry.top(); - newGeometry.setTop(newGeometry.bottom()); - newGeometry.setBottom(top); - } - m_selection->setGeometry(newGeometry); - updateSizeIndicator(); - m_buttonHandler->updatePosition(newGeometry); - m_buttonHandler->show(); - } m_mouseIsClicked = false; m_activeToolIsMoved = false; - m_grabbing = false; - m_movingSelection = false; - if (m_selection->isVisible()) { - m_newSelection = false; - } + updateSelectionState(); updateCursor(); } -void CaptureWidget::moveSelection(QPoint p) -{ - adjustSelection(QMargins(-p.x(), -p.y(), p.x(), p.y())); -} - void CaptureWidget::updateThickness(int thickness) { + auto tool = activeButtonTool(); + updateToolMousePreview(tool); m_context.thickness = qBound(1, thickness, maxDrawThickness); QPoint topLeft = @@ -806,16 +678,15 @@ void CaptureWidget::updateThickness(int thickness) m_notifierBox->move(mapFromGlobal(topLeft) + QPoint(offset, offset)); m_notifierBox->showMessage(QString::number(m_context.thickness)); - if (m_activeButton && m_activeButton->tool() && - m_activeButton->tool()->showMousePreview()) { + if (tool && tool->showMousePreview()) { setCursor(Qt::BlankCursor); - update(); + updateToolMousePreview(tool); } // update selected object thickness auto toolItem = activeToolObject(); if (toolItem) { - toolItem->thicknessChanged(m_context.thickness); + toolItem->onThicknessChanged(m_context.thickness); if (!m_existingObjectIsChanged) { m_captureToolObjectsBackup = m_captureToolObjects; m_existingObjectIsChanged = true; @@ -824,26 +695,6 @@ void CaptureWidget::updateThickness(int thickness) emit thicknessChanged(m_context.thickness); } -void CaptureWidget::moveLeft() -{ - moveSelection(QPoint(-1, 0)); -} - -void CaptureWidget::moveRight() -{ - moveSelection(QPoint(1, 0)); -} - -void CaptureWidget::moveUp() -{ - moveSelection(QPoint(0, -1)); -} - -void CaptureWidget::moveDown() -{ - moveSelection(QPoint(0, 1)); -} - void CaptureWidget::keyPressEvent(QKeyEvent* e) { // If the key is a digit, change the thickness @@ -1068,16 +919,24 @@ void CaptureWidget::showAppUpdateNotification(const QString& appLatestVersion, void CaptureWidget::initSelection() { m_selection = new SelectionWidget(m_uiColor, this); - connect(m_selection, &SelectionWidget::animationEnded, this, [this]() { - this->m_buttonHandler->updatePosition(this->m_selection->geometry()); - }); - connect(m_selection, &SelectionWidget::resized, this, [this]() { + m_selection->setVisible(false); + m_selection->setGeometry(QRect()); + connect(m_selection, &SelectionWidget::geometryChanged, this, [this]() { + m_buttonHandler->updatePosition(m_selection->geometry()); QRect constrainedToCaptureArea = m_selection->geometry().intersected(rect()); m_context.selection = extendedRect(constrainedToCaptureArea); + updateSizeIndicator(); + m_buttonHandler->hide(); + updateCursor(); + }); + connect(m_selection, &SelectionWidget::geometrySettled, this, [this]() { + if (m_selection->isVisible()) { + m_buttonHandler->show(); + } else { + m_buttonHandler->hide(); + } }); - m_selection->setVisible(false); - m_selection->setGeometry(QRect()); } void CaptureWidget::setState(CaptureToolButton* b) @@ -1124,15 +983,15 @@ void CaptureWidget::setState(CaptureToolButton* b) } loadDrawThickness(); updateCursor(); - update(); // clear mouse preview + updateSelectionState(); + updateToolMousePreview(b->tool()); } } void CaptureWidget::loadDrawThickness() { - if ((m_activeButton && m_activeButton->tool() && - m_activeButton->tool()->type() == ToolType::TEXT) || - (m_activeTool && m_activeTool->type() == ToolType::TEXT)) { + if ((activeButtonToolType() == CaptureTool::TYPE_TEXT) || + (m_activeTool && m_activeTool->type() == CaptureTool::TYPE_TEXT)) { m_context.thickness = m_config.drawFontSize(); } else { m_context.thickness = m_config.drawThickness(); @@ -1143,47 +1002,25 @@ void CaptureWidget::loadDrawThickness() void CaptureWidget::handleToolSignal(CaptureTool::Request r) { switch (r) { - case CaptureTool::REQ_CLEAR_MODIFICATIONS: - m_captureToolObjects.clear(); - m_undoStack.setIndex(0); - update(); - break; case CaptureTool::REQ_CLOSE_GUI: close(); break; case CaptureTool::REQ_HIDE_GUI: hide(); break; - case CaptureTool::REQ_HIDE_SELECTION: - m_newSelection = true; - m_selection->setVisible(false); - updateCursor(); - break; - case CaptureTool::REQ_SELECT_ALL: - m_selection->setGeometryAnimated(rect()); - break; case CaptureTool::REQ_UNDO_MODIFICATION: undo(); break; case CaptureTool::REQ_REDO_MODIFICATION: redo(); break; - case CaptureTool::REQ_REDRAW: - update(); - break; - case CaptureTool::REQ_TOGGLE_SIDEBAR: - m_panel->toggle(); - break; case CaptureTool::REQ_SHOW_COLOR_PICKER: // TODO break; - case CaptureTool::REQ_MOVE_MODE: - setState(m_activeButton); // Disable the actual button - break; case CaptureTool::REQ_CLEAR_SELECTION: if (m_panel->activeLayerIndex() >= 0) { m_panel->setActiveLayer(-1); - drawToolsData(false, false); + drawToolsData(); } break; case CaptureTool::REQ_CAPTURE_DONE_OK: @@ -1238,17 +1075,17 @@ void CaptureWidget::setDrawColor(const QColor& c) auto toolItem = activeToolObject(); if (toolItem) { // Change color - toolItem->colorChanged(c); - drawToolsData(false, true); + toolItem->onColorChanged(c); + drawToolsData(); } } } -void CaptureWidget::updateActiveLayer(const int& layer) +void CaptureWidget::updateActiveLayer(int layer) { // TODO - refactor this part, make all objects to work with // m_activeTool->isChanged() and remove m_existingObjectIsChanged - if (m_activeTool && m_activeTool->type() == ToolType::TEXT && + if (m_activeTool && m_activeTool->type() == CaptureTool::TYPE_TEXT && m_activeTool->isChanged()) { commitCurrentTool(); } @@ -1263,22 +1100,35 @@ void CaptureWidget::updateActiveLayer(const int& layer) m_existingObjectIsChanged = false; pushObjectsStateToUndoStack(); } - drawToolsData(false, true); + drawToolsData(); + drawObjectSelection(); + updateSelectionState(); +} + +void CaptureWidget::selectAll() +{ + m_selection->show(); + m_selection->setGeometry(rect()); + m_buttonHandler->show(); + updateSelectionState(); } void CaptureWidget::removeToolObject(int index) { --index; if (index >= 0 && index < m_captureToolObjects.size()) { - const ToolType currentToolType = m_captureToolObjects.at(index)->type(); + const CaptureTool::Type currentToolType = + m_captureToolObjects.at(index)->type(); m_captureToolObjectsBackup = m_captureToolObjects; + update( + paddedUpdateRect(m_captureToolObjects.at(index)->boundingRect())); m_captureToolObjects.removeAt(index); - if (currentToolType == ToolType::CIRCLECOUNT) { + if (currentToolType == CaptureTool::TYPE_CIRCLECOUNT) { // Do circle count reindex int circleCount = 1; for (int cnt = 0; cnt < m_captureToolObjects.size(); cnt++) { auto toolItem = m_captureToolObjects.at(cnt); - if (toolItem->type() != ToolType::CIRCLECOUNT) { + if (toolItem->type() != CaptureTool::TYPE_CIRCLECOUNT) { continue; } if (cnt >= index) { @@ -1289,16 +1139,16 @@ void CaptureWidget::removeToolObject(int index) } pushObjectsStateToUndoStack(); drawToolsData(); + updateLayersPanel(); } } -void CaptureWidget::setDrawThickness(const int& t) +void CaptureWidget::setDrawThickness(int t) { m_context.thickness = qBound(1, t, maxDrawThickness); // save draw thickness for text and other tool separately if (m_activeButton) { - if (m_activeButton->tool() && - m_activeButton->tool()->type() == ToolType::TEXT) { + if (activeButtonToolType() == CaptureTool::TYPE_TEXT) { m_config.setDrawFontSize(m_context.thickness); } else { m_config.setDrawThickness(m_context.thickness); @@ -1308,62 +1158,14 @@ void CaptureWidget::setDrawThickness(const int& t) auto toolItem = activeToolObject(); if (toolItem) { // Change thickness - toolItem->thicknessChanged(t); - drawToolsData(false, true); + toolItem->onThicknessChanged(t); + drawToolsData(); + drawObjectSelection(); } else { emit thicknessChanged(m_context.thickness); } } -void CaptureWidget::repositionSelection(QRect r) -{ - if (m_selection->isVisible()) { - m_selection->setGeometry(r); - m_buttonHandler->updatePosition(m_selection->geometry()); - updateSizeIndicator(); - update(); - } -} - -void CaptureWidget::adjustSelection(QMargins m) -{ - QRect newGeometry = m_selection->geometry() + m; - if (rect().contains(newGeometry)) { - repositionSelection(newGeometry); - } -} - -void CaptureWidget::resizeLeft() -{ - adjustSelection(QMargins(0, 0, -1, 0)); -} - -void CaptureWidget::resizeRight() -{ - adjustSelection(QMargins(0, 0, 1, 0)); -} - -void CaptureWidget::resizeUp() -{ - adjustSelection(QMargins(0, 0, 0, -1)); -} - -void CaptureWidget::resizeDown() -{ - adjustSelection(QMargins(0, 0, 0, 1)); -} - -void CaptureWidget::selectAll() -{ - QRect newGeometry = rect(); - m_selection->setGeometry(newGeometry); - m_selection->setVisible(true); - m_buttonHandler->updatePosition(m_selection->geometry()); - updateSizeIndicator(); - m_buttonHandler->show(); - update(); -} - void CaptureWidget::initShortcuts() { new QShortcut( @@ -1388,29 +1190,29 @@ void CaptureWidget::initShortcuts() SLOT(togglePanel())); new QShortcut(QKeySequence(ConfigHandler().shortcut("TYPE_RESIZE_LEFT")), - this, + m_selection, SLOT(resizeLeft())); new QShortcut(QKeySequence(ConfigHandler().shortcut("TYPE_RESIZE_RIGHT")), - this, + m_selection, SLOT(resizeRight())); new QShortcut(QKeySequence(ConfigHandler().shortcut("TYPE_RESIZE_UP")), - this, + m_selection, SLOT(resizeUp())); new QShortcut(QKeySequence(ConfigHandler().shortcut("TYPE_RESIZE_DOWN")), - this, + m_selection, SLOT(resizeDown())); new QShortcut(QKeySequence(ConfigHandler().shortcut("TYPE_MOVE_LEFT")), - this, + m_selection, SLOT(moveLeft())); new QShortcut(QKeySequence(ConfigHandler().shortcut("TYPE_MOVE_RIGHT")), - this, + m_selection, SLOT(moveRight())); new QShortcut(QKeySequence(ConfigHandler().shortcut("TYPE_MOVE_UP")), - this, + m_selection, SLOT(moveUp())); new QShortcut(QKeySequence(ConfigHandler().shortcut("TYPE_MOVE_DOWN")), - this, + m_selection, SLOT(moveDown())); new QShortcut( @@ -1454,58 +1256,58 @@ void CaptureWidget::updateCursor() { if (m_colorPicker && m_colorPicker->isVisible()) { setCursor(Qt::ArrowCursor); - } else if (m_grabbing) { - if (m_adjustmentButtonPressed) { - setCursor(Qt::OpenHandCursor); - } else { - setCursor(Qt::ArrowCursor); - } - } else if (m_activeButton && m_activeButton->tool() && - m_activeButton->tool()->type() == ToolType::MOVE) { + } else if (m_activeButton != nullptr && + activeButtonToolType() != CaptureTool::TYPE_MOVESELECTION) { + setCursor(Qt::CrossCursor); + } else if (m_selection->getMouseSide(mapFromGlobal(QCursor::pos())) != + SelectionWidget::NO_SIDE) { + setCursor(m_selection->cursor()); + } else if (activeButtonToolType() == CaptureTool::TYPE_MOVESELECTION) { setCursor(Qt::OpenHandCursor); - } else if (!m_activeButton) { - using sw = SelectionWidget; - if (m_mouseOverHandle != sw::NO_SIDE) { - // cursor on the handlers - switch (m_mouseOverHandle) { - case sw::TOPLEFT_SIDE: - case sw::BOTTOMRIGHT_SIDE: - setCursor(Qt::SizeFDiagCursor); - break; - case sw::TOPRIGHT_SIDE: - case sw::BOTTOMLEFT_SIDE: - setCursor(Qt::SizeBDiagCursor); - break; - case sw::LEFT_SIDE: - case sw::RIGHT_SIDE: - setCursor(Qt::SizeHorCursor); - break; - case sw::TOP_SIDE: - case sw::BOTTOM_SIDE: - setCursor(Qt::SizeVerCursor); - break; - default: - break; - } - } else if (m_selection->isVisible() && - m_selection->geometry().contains(m_context.mousePos)) { - if (m_adjustmentButtonPressed) { - setCursor(Qt::OpenHandCursor); - } else { - setCursor(Qt::ArrowCursor); - } - } else if (m_selection->isVisible() && - m_captureToolObjects.captureToolObjects().size() > 0 && - m_activeTool.isNull()) { - setCursor(Qt::ArrowCursor); - } else { - setCursor(Qt::CrossCursor); - } } else { setCursor(Qt::CrossCursor); } } +void CaptureWidget::updateSelectionState() +{ + auto toolType = activeButtonToolType(); + if (toolType == CaptureTool::TYPE_MOVESELECTION) { + m_selection->setIdleCentralCursor(Qt::OpenHandCursor); + m_selection->setIgnoreMouse(false); + } else { + m_selection->setIdleCentralCursor(Qt::ArrowCursor); + if (toolType == CaptureTool::NONE) { + m_selection->setIgnoreMouse(m_panel->activeLayerIndex() != -1); + } else { + m_selection->setIgnoreMouse(true); + } + } +} + +void CaptureWidget::updateToolMousePreview(CaptureTool* tool) +{ + if (!tool || !tool->showMousePreview()) { + return; + } + + static QRect oldRect; + + QRect r(tool->mousePreviewRect(m_context)); + r += QMargins(r.width(), r.height(), r.width(), r.height()); + + QRect toolObjectRect = paddedUpdateRect(tool->boundingRect()); + + // oldRect is united with the current rect to handle sudden mouse movement + update(r.united(oldRect).united(toolObjectRect)); + oldRect = r; +} + +void CaptureWidget::updateLayersPanel() +{ + m_panel->fillCaptureTools(m_captureToolObjects.captureToolObjects()); +} + void CaptureWidget::pushToolToStack() { // append current tool to the new state @@ -1513,60 +1315,47 @@ void CaptureWidget::pushToolToStack() disconnect(this, &CaptureWidget::colorChanged, m_activeTool, - &CaptureTool::colorChanged); + &CaptureTool::onColorChanged); disconnect(this, &CaptureWidget::thicknessChanged, m_activeTool, - &CaptureTool::thicknessChanged); + &CaptureTool::onThicknessChanged); if (m_panel->toolWidget()) { disconnect(m_panel->toolWidget(), nullptr, m_activeTool, nullptr); } // disable signal connect for updating layer because it may call this // function again on text objects - disconnect(m_panel, - &UtilityPanel::layerChanged, - this, - &CaptureWidget::updateActiveLayer); + m_panel->blockSignals(true); m_captureToolObjectsBackup = m_captureToolObjects; m_captureToolObjects.append(m_activeTool); pushObjectsStateToUndoStack(); releaseActiveTool(); drawToolsData(); + updateLayersPanel(); // restore signal connection for updating layer - connect(m_panel, - &UtilityPanel::layerChanged, - this, - &CaptureWidget::updateActiveLayer); + m_panel->blockSignals(false); } } -void CaptureWidget::drawToolsData(bool updateLayersPanel, bool drawSelection) +void CaptureWidget::drawToolsData() { - QPixmap pixmapItem = m_context.origScreenshot.copy(); + // TODO refactor this for performance. The objects should not all be updated + // at once every time + QPixmap pixmapItem = m_context.origScreenshot; int circleCount = 1; for (auto toolItem : m_captureToolObjects.captureToolObjects()) { - if (toolItem->type() == ToolType::CIRCLECOUNT) { + if (toolItem->type() == CaptureTool::TYPE_CIRCLECOUNT) { toolItem->setCount(circleCount++); } processPixmapWithTool(&pixmapItem, toolItem); + update(paddedUpdateRect(toolItem->boundingRect())); } - m_context.screenshot = pixmapItem.copy(); - update(); - if (updateLayersPanel) { - m_panel->fillCaptureTools(m_captureToolObjects.captureToolObjects()); - } - - if (drawSelection) { - int thickness_old = m_context.thickness; - drawObjectSelection(); - if (thickness_old != m_context.thickness) { - emit thicknessChanged(m_context.thickness); - } - } + m_context.screenshot = pixmapItem; + drawObjectSelection(); } void CaptureWidget::drawObjectSelection() @@ -1592,6 +1381,23 @@ void CaptureWidget::processPixmapWithTool(QPixmap* pixmap, CaptureTool* tool) tool->process(painter, *pixmap); } +CaptureTool* CaptureWidget::activeButtonTool() const +{ + if (m_activeButton == nullptr) { + return nullptr; + } + return m_activeButton->tool(); +} + +CaptureTool::Type CaptureWidget::activeButtonToolType() const +{ + auto* activeTool = activeButtonTool(); + if (activeTool == nullptr) { + return CaptureTool::NONE; + } + return activeTool->type(); +} + QPointer CaptureWidget::activeToolObject() { return m_captureToolObjects.at(m_panel->activeLayerIndex()); @@ -1611,13 +1417,13 @@ void CaptureWidget::togglePanel() void CaptureWidget::childEnter() { m_previewEnabled = false; - update(); + updateToolMousePreview(activeButtonTool()); } void CaptureWidget::childLeave() { m_previewEnabled = true; - update(); + updateToolMousePreview(activeButtonTool()); } void CaptureWidget::copyScreenshot() @@ -1656,7 +1462,9 @@ void CaptureWidget::setCaptureToolObjects( { // Used for undo/redo m_captureToolObjects = captureToolObjects; - drawToolsData(true, true); + drawToolsData(); + updateLayersPanel(); + drawObjectSelection(); } void CaptureWidget::undo() @@ -1668,14 +1476,23 @@ void CaptureWidget::undo() m_panel->setActiveLayer(-1); } + // drawToolsData is called twice to update both previous and new regions + // FIXME this is a temporary workaround + drawToolsData(); m_undoStack.undo(); drawToolsData(); + updateLayersPanel(); } void CaptureWidget::redo() { + // drawToolsData is called twice to update both previous and new regions + // FIXME this is a temporary workaround + drawToolsData(); m_undoStack.redo(); drawToolsData(); + update(); + updateLayersPanel(); } QRect CaptureWidget::extendedSelection() const @@ -1696,6 +1513,15 @@ QRect CaptureWidget::extendedRect(const QRect& r) const r.height() * devicePixelRatio); } +QRect CaptureWidget::paddedUpdateRect(const QRect& r) const +{ + if (r.isNull()) { + return r; + } else { + return r + QMargins(20, 20, 20, 20); + } +} + void CaptureWidget::drawConfigErrorMessage(QPainter* painter) { QString msg; @@ -1724,22 +1550,11 @@ void CaptureWidget::drawInactiveRegion(QPainter* painter) painter->setBrush(overlayColor); QRect r; if (m_selection->isVisible()) { - r = m_selection->geometry().normalized().adjusted(0, 0, -1, -1); + r = m_selection->geometry().normalized(); } QRegion grey(rect()); grey = grey.subtracted(r); painter->setClipRegion(grey); painter->drawRect(-1, -1, rect().width() + 1, rect().height() + 1); - painter->setClipRect(rect()); - - if (m_selection->isVisible()) { - // paint handlers - painter->setPen(m_uiColor); - painter->setRenderHint(QPainter::Antialiasing); - painter->setBrush(m_uiColor); - for (auto rect : m_selection->handlerAreas()) { - painter->drawRoundedRect(rect, 100, 100); - } - } } diff --git a/src/widgets/capture/capturewidget.h b/src/widgets/capture/capturewidget.h index 3c2cf7ed..4b9691e4 100644 --- a/src/widgets/capture/capturewidget.h +++ b/src/widgets/capture/capturewidget.h @@ -71,25 +71,14 @@ private slots: void childEnter(); void childLeave(); - void selectAll(); - - void resizeLeft(); - void resizeRight(); - void resizeUp(); - void resizeDown(); - - void moveLeft(); - void moveRight(); - void moveUp(); - void moveDown(); - void deleteCurrentTool(); void setState(CaptureToolButton* b); void handleToolSignal(CaptureTool::Request r); void setDrawColor(const QColor& c); - void setDrawThickness(const int& t); - void updateActiveLayer(const int& layer); + void setDrawThickness(int t); + void updateActiveLayer(int layer); + void selectAll(); public: void removeToolObject(int index = -1); @@ -122,24 +111,27 @@ private: void initButtons(); void updateSizeIndicator(); void updateCursor(); + void updateSelectionState(); + void updateToolMousePreview(CaptureTool* tool); + void updateLayersPanel(); void pushToolToStack(); void makeChild(QWidget* w); - void repositionSelection(QRect r); - void adjustSelection(QMargins m); - void moveSelection(QPoint p); void updateThickness(int thicknessOffset); QRect extendedSelection() const; QRect extendedRect(const QRect& r) const; + QRect paddedUpdateRect(const QRect& r) const; void drawConfigErrorMessage(QPainter* painter); void drawInactiveRegion(QPainter* painter); - void drawToolsData(bool updateLayersPanel = true, - bool drawSelection = false); + void drawToolsData(); void drawObjectSelection(); void processPixmapWithTool(QPixmap* pixmap, CaptureTool* tool); + CaptureTool* activeButtonTool() const; + CaptureTool::Type activeButtonToolType() const; + //////////////////////////////////////// // Class members @@ -158,7 +150,6 @@ private: // utility flags bool m_mouseIsClicked; bool m_newSelection; - bool m_grabbing; bool m_movingSelection; bool m_captureDone; bool m_previewEnabled; @@ -184,7 +175,6 @@ private: HoverEventFilter* m_eventFilter; SelectionWidget* m_selection; - QPoint m_dragStartPoint; SelectionWidget::SideType m_mouseOverHandle; uint m_id; diff --git a/src/widgets/capture/colorpicker.cpp b/src/widgets/capture/colorpicker.cpp index da1a9ec9..43de9bf8 100644 --- a/src/widgets/capture/colorpicker.cpp +++ b/src/widgets/capture/colorpicker.cpp @@ -9,6 +9,8 @@ ColorPicker::ColorPicker(QWidget* parent) : QWidget(parent) + , m_selectedIndex(0) + , m_lastIndex(0) { ConfigHandler config; m_colorList = config.userColors(); @@ -16,7 +18,14 @@ ColorPicker::ColorPicker(QWidget* parent) setMouseTracking(true); // save the color values in member variables for faster access m_uiColor = config.uiColor(); - m_drawColor = config.drawColor(); + QColor drawColor = config.drawColor(); + for (int i = 0; i < m_colorList.size(); ++i) { + if (m_colorList.at(i) == drawColor) { + m_selectedIndex = i; + m_lastIndex = i; + break; + } + } // extraSize represents the extra space needed for the highlight of the // selected color. const int extraSize = 6; @@ -39,71 +48,66 @@ ColorPicker::ColorPicker(QWidget* parent) } } -void ColorPicker::show() -{ - grabMouse(); - QWidget::show(); -} - -void ColorPicker::hide() -{ - releaseMouse(); - QWidget::hide(); -} - -void ColorPicker::paintEvent(QPaintEvent*) +void ColorPicker::paintEvent(QPaintEvent* e) { QPainter painter(this); painter.setRenderHint(QPainter::Antialiasing); - - QVector rects = handleMask(); painter.setPen(QColor(Qt::black)); - for (int i = 0; i < rects.size(); ++i) { - // draw the highlight when we have to draw the selected color - if (m_drawColor == QColor(m_colorList.at(i))) { - QColor c = QColor(m_uiColor); - c.setAlpha(155); - painter.setBrush(c); - c.setAlpha(100); - painter.setPen(c); - QRect highlight = rects.at(i); - highlight.moveTo(highlight.x() - 3, highlight.y() - 3); - highlight.setHeight(highlight.height() + 6); - highlight.setWidth(highlight.width() + 6); - painter.drawRoundedRect(highlight, 100, 100); - painter.setPen(QColor(Qt::black)); + + for (int i = 0; i < m_colorAreaList.size(); ++i) { + if (e->region().contains(m_colorAreaList.at(i))) { + painter.setClipRegion(e->region()); + repaint(i, painter); } + } +} - // draw available colors - if (m_colorList.at(i).isValid()) { - // draw preset color - painter.setBrush(QColor(m_colorList.at(i))); - painter.drawRoundedRect(rects.at(i), 100, 100); - } else { - // draw rainbow (part) for custom color - QRect lastRect = rects.at(i); - int nStep = 1; - int nSteps = lastRect.height() / nStep; - // 0.02 - start rainbow color, 0.33 - end rainbow color from range: - // 0.0 - 1.0 - float h = 0.02; - for (int radius = nSteps; radius > 0; radius -= nStep * 2) { - // calculate color - float fHStep = (0.33 - h) / (nSteps / nStep / 2); - QColor color = QColor::fromHslF(h, 0.95, 0.5); +void ColorPicker::repaint(int i, QPainter& painter) +{ + // draw the highlight when we have to draw the selected color + if (i == m_selectedIndex) { + QColor c = QColor(m_uiColor); + c.setAlpha(155); + painter.setBrush(c); + c.setAlpha(100); + painter.setPen(c); + QRect highlight = m_colorAreaList.at(i); + highlight.moveTo(highlight.x() - 3, highlight.y() - 3); + highlight.setHeight(highlight.height() + 6); + highlight.setWidth(highlight.width() + 6); + painter.drawRoundedRect(highlight, 100, 100); + painter.setPen(QColor(Qt::black)); + } - // set color and draw circle - painter.setPen(color); - painter.setBrush(color); - painter.drawRoundedRect(lastRect, 100, 100); + // draw available colors + if (m_colorList.at(i).isValid()) { + // draw preset color + painter.setBrush(QColor(m_colorList.at(i))); + painter.drawRoundedRect(m_colorAreaList.at(i), 100, 100); + } else { + // draw rainbow (part) for custom color + QRect lastRect = m_colorAreaList.at(i); + int nStep = 1; + int nSteps = lastRect.height() / nStep; + // 0.02 - start rainbow color, 0.33 - end rainbow color from range: + // 0.0 - 1.0 + float h = 0.02; + for (int radius = nSteps; radius > 0; radius -= nStep * 2) { + // calculate color + float fHStep = (0.33 - h) / (nSteps / nStep / 2); + QColor color = QColor::fromHslF(h, 0.95, 0.5); - // set next color, circle geometry - h += fHStep; - lastRect.setX(lastRect.x() + nStep); - lastRect.setY(lastRect.y() + nStep); - lastRect.setHeight(lastRect.height() - nStep); - lastRect.setWidth(lastRect.width() - nStep); - } + // set color and draw circle + painter.setPen(color); + painter.setBrush(color); + painter.drawRoundedRect(lastRect, 100, 100); + + // set next color, circle geometry + h += fHStep; + lastRect.setX(lastRect.x() + nStep); + lastRect.setY(lastRect.y() + nStep); + lastRect.setHeight(lastRect.height() - nStep); + lastRect.setWidth(lastRect.width() - nStep); } } } @@ -112,19 +116,22 @@ void ColorPicker::mouseMoveEvent(QMouseEvent* e) { for (int i = 0; i < m_colorList.size(); ++i) { if (m_colorAreaList.at(i).contains(e->pos())) { - m_drawColor = m_colorList.at(i); - emit colorSelected(m_drawColor); - update(); + m_selectedIndex = i; + update(m_colorAreaList.at(i) + QMargins(10, 10, 10, 10)); + update(m_colorAreaList.at(m_lastIndex) + QMargins(10, 10, 10, 10)); + m_lastIndex = i; break; } } } -QVector ColorPicker::handleMask() const +void ColorPicker::showEvent(QShowEvent* event) { - QVector areas; - for (const QRect& rect : m_colorAreaList) { - areas.append(rect); - } - return areas; + grabMouse(); +} + +void ColorPicker::hideEvent(QHideEvent* event) +{ + releaseMouse(); + emit colorSelected(m_colorList.at(m_selectedIndex)); } diff --git a/src/widgets/capture/colorpicker.h b/src/widgets/capture/colorpicker.h index edf39c9d..6476ebd1 100644 --- a/src/widgets/capture/colorpicker.h +++ b/src/widgets/capture/colorpicker.h @@ -11,22 +11,21 @@ class ColorPicker : public QWidget public: explicit ColorPicker(QWidget* parent = nullptr); - void show(); - void hide(); - signals: void colorSelected(QColor c); protected: - void paintEvent(QPaintEvent*); + void paintEvent(QPaintEvent* event) override; + void repaint(int i, QPainter& painter); void mouseMoveEvent(QMouseEvent*); - - QVector handleMask() const; + void showEvent(QShowEvent* event) override; + void hideEvent(QHideEvent* event) override; private: int m_colorAreaSize; + int m_selectedIndex, m_lastIndex; QVector m_colorAreaList; QVector m_colorList; - QColor m_uiColor, m_drawColor; + QColor m_uiColor; }; diff --git a/src/widgets/capture/selectionwidget.cpp b/src/widgets/capture/selectionwidget.cpp index 514728a8..6e06045a 100644 --- a/src/widgets/capture/selectionwidget.cpp +++ b/src/widgets/capture/selectionwidget.cpp @@ -2,26 +2,39 @@ // SPDX-FileCopyrightText: 2017-2019 Alejandro Sirgo Rica & Contributors #include "selectionwidget.h" +#include "capturetool.h" +#include "capturetoolbutton.h" #include "src/utils/globalvalues.h" +#include +#include +#include #include #include +#include + +#define MARGIN (m_THandle.width()) SelectionWidget::SelectionWidget(const QColor& c, QWidget* parent) : QWidget(parent) , m_color(c) + , m_activeSide(NO_SIDE) + , m_ignoreMouse(false) { + // prevents this widget from consuming CaptureToolButton mouse events + setAttribute(Qt::WA_TransparentForMouseEvents); + parent->installEventFilter(this); + m_animation = new QPropertyAnimation(this, "geometry", this); m_animation->setEasingCurve(QEasingCurve::InOutQuad); m_animation->setDuration(200); - connect(m_animation, - &QPropertyAnimation::finished, - this, - &SelectionWidget::animationEnded); + connect(m_animation, &QPropertyAnimation::finished, this, [this]() { + emit geometrySettled(); + }); - setAttribute(Qt::WA_TransparentForMouseEvents); int sideVal = GlobalValues::buttonBaseSize() * 0.6; int handleSide = sideVal / 2; const QRect areaRect(0, 0, sideVal, sideVal); + const QRect handleRect(0, 0, handleSide, handleSide); m_TLHandle = m_TRHandle = m_BLHandle = m_BRHandle = m_LHandle = m_THandle = m_RHandle = m_BHandle = handleRect; @@ -31,25 +44,35 @@ SelectionWidget::SelectionWidget(const QColor& c, QWidget* parent) m_handleOffset = QPoint(-handleSide / 2, -handleSide / 2); } +/** + * @brief Get the side where the mouse cursor is. + * @param mousePos Mouse cursor position relative to the parent widget. + */ SelectionWidget::SideType SelectionWidget::getMouseSide( - const QPoint& point) const + const QPoint& mousePos) const { - if (m_TLArea.contains(point)) { + if (!isVisible()) { + return NO_SIDE; + } + QPoint localPos = mapFromParent(mousePos); + if (m_TLArea.contains(localPos)) { return TOPLEFT_SIDE; - } else if (m_TRArea.contains(point)) { + } else if (m_TRArea.contains(localPos)) { return TOPRIGHT_SIDE; - } else if (m_BLArea.contains(point)) { + } else if (m_BLArea.contains(localPos)) { return BOTTOMLEFT_SIDE; - } else if (m_BRArea.contains(point)) { + } else if (m_BRArea.contains(localPos)) { return BOTTOMRIGHT_SIDE; - } else if (m_LArea.contains(point)) { + } else if (m_LArea.contains(localPos)) { return LEFT_SIDE; - } else if (m_TArea.contains(point)) { + } else if (m_TArea.contains(localPos)) { return TOP_SIDE; - } else if (m_RArea.contains(point)) { + } else if (m_RArea.contains(localPos)) { return RIGHT_SIDE; - } else if (m_BArea.contains(point)) { + } else if (m_BArea.contains(localPos)) { return BOTTOM_SIDE; + } else if (rect().contains(localPos)) { + return CENTER; } else { return NO_SIDE; } @@ -63,6 +86,39 @@ QVector SelectionWidget::handlerAreas() return areas; } +// helper function +SelectionWidget::SideType getProperSide(SelectionWidget::SideType side, + const QRect& r) +{ + using SideType = SelectionWidget::SideType; + int intSide = side; + if (r.right() < r.left()) { + intSide ^= SideType::LEFT_SIDE; + intSide ^= SideType::RIGHT_SIDE; + } + if (r.bottom() < r.top()) { + intSide ^= SideType::TOP_SIDE; + intSide ^= SideType::BOTTOM_SIDE; + } + + return (SideType)intSide; +} + +void SelectionWidget::setIgnoreMouse(bool ignore) +{ + m_ignoreMouse = ignore; + updateCursor(); +} + +/** + * Set the cursor that will be active when the mouse is inside the selection and + * the mouse is not clicked. + */ +void SelectionWidget::setIdleCentralCursor(const QCursor& cursor) +{ + m_idleCentralCursor = cursor; +} + void SelectionWidget::setGeometryAnimated(const QRect& r) { if (isVisible()) { @@ -72,14 +128,150 @@ void SelectionWidget::setGeometryAnimated(const QRect& r) } } -void SelectionWidget::saveGeometry() +void SelectionWidget::setGeometry(const QRect& r) { - m_geometryBackup = geometry(); + QWidget::setGeometry(r + QMargins(MARGIN, MARGIN, MARGIN, MARGIN)); + updateCursor(); + emit geometryChanged(); } -QRect SelectionWidget::savedGeometry() +QRect SelectionWidget::geometry() const { - return m_geometryBackup; + return QWidget::geometry() - QMargins(MARGIN, MARGIN, MARGIN, MARGIN); +} + +QRect SelectionWidget::fullGeometry() const +{ + return QWidget::geometry(); +} + +QRect SelectionWidget::rect() const +{ + return QWidget::rect() - QMargins(MARGIN, MARGIN, MARGIN, MARGIN); +} + +bool SelectionWidget::eventFilter(QObject* obj, QEvent* event) +{ + if (m_ignoreMouse && dynamic_cast(event)) { + m_activeSide = NO_SIDE; + unsetCursor(); + } else if (event->type() == QEvent::MouseButtonRelease) { + parentMouseReleaseEvent(static_cast(event)); + } else if (event->type() == QEvent::MouseButtonPress) { + parentMousePressEvent(static_cast(event)); + } else if (event->type() == QEvent::MouseMove) { + parentMouseMoveEvent(static_cast(event)); + } + return false; +} + +void SelectionWidget::parentMousePressEvent(QMouseEvent* e) +{ + if (e->button() != Qt::LeftButton) { + return; + } + + m_dragStartPos = e->pos(); + m_activeSide = getMouseSide(e->pos()); +} + +void SelectionWidget::parentMouseReleaseEvent(QMouseEvent* e) +{ + // released outside of the selection area + if (!getMouseSide(e->pos())) { + hide(); + } + + m_activeSide = NO_SIDE; + updateCursor(); + emit geometrySettled(); +} + +void SelectionWidget::parentMouseMoveEvent(QMouseEvent* e) +{ + updateCursor(); + + if (e->buttons() != Qt::LeftButton) { + return; + } + + SideType mouseSide = m_activeSide; + if (!m_activeSide) { + mouseSide = getMouseSide(e->pos()); + } + + if (!isVisible() || !mouseSide) { + show(); + m_dragStartPos = e->pos(); + m_activeSide = TOPLEFT_SIDE; + setGeometry({ e->pos(), e->pos() }); + } + + QPoint pos = e->pos(); + auto geom = geometry(); + bool symmetryMod = qApp->keyboardModifiers() & Qt::ShiftModifier; + + QPoint newTopLeft = geom.topLeft(), newBottomRight = geom.bottomRight(); + int &newLeft = newTopLeft.rx(), &newRight = newBottomRight.rx(), + &newTop = newTopLeft.ry(), &newBottom = newBottomRight.ry(); + switch (mouseSide) { + case TOPLEFT_SIDE: + if (m_activeSide) + newTopLeft = pos; + break; + case BOTTOMRIGHT_SIDE: + if (m_activeSide) + newBottomRight = pos; + break; + case TOPRIGHT_SIDE: + if (m_activeSide) { + newTop = pos.y(); + newRight = pos.x(); + } + break; + case BOTTOMLEFT_SIDE: + if (m_activeSide) { + newBottom = pos.y(); + newLeft = pos.x(); + } + break; + case LEFT_SIDE: + if (m_activeSide) + newLeft = pos.x(); + break; + case RIGHT_SIDE: + if (m_activeSide) + newRight = pos.x(); + break; + case TOP_SIDE: + if (m_activeSide) + newTop = pos.y(); + break; + case BOTTOM_SIDE: + if (m_activeSide) + newBottom = pos.y(); + break; + default: + if (m_activeSide) { + move(this->pos() + pos - m_dragStartPos); + m_dragStartPos = pos; + } + return; + } + // finalize geometry change + if (m_activeSide) { + if (symmetryMod) { + QPoint deltaTopLeft = newTopLeft - geom.topLeft(); + QPoint deltaBottomRight = newBottomRight - geom.bottomRight(); + newTopLeft = geom.topLeft() + deltaTopLeft - deltaBottomRight; + newBottomRight = + geom.bottomRight() + deltaBottomRight - deltaTopLeft; + } + geom = { newTopLeft, newBottomRight }; + setGeometry(geom.normalized()); + m_activeSide = getProperSide(m_activeSide, geom); + } + m_dragStartPos = pos; } void SelectionWidget::paintEvent(QPaintEvent*) @@ -87,17 +279,23 @@ void SelectionWidget::paintEvent(QPaintEvent*) QPainter p(this); p.setPen(m_color); p.drawRect(rect() + QMargins(0, 0, -1, -1)); + p.setRenderHint(QPainter::Antialiasing); + p.setBrush(m_color); + for (auto rect : handlerAreas()) { + p.drawEllipse(rect); + } } void SelectionWidget::resizeEvent(QResizeEvent*) { updateAreas(); + emit geometryChanged(); } void SelectionWidget::moveEvent(QMoveEvent*) { updateAreas(); - emit resized(); + emit geometryChanged(); } void SelectionWidget::updateColor(const QColor& c) @@ -105,13 +303,53 @@ void SelectionWidget::updateColor(const QColor& c) m_color = c; } +void SelectionWidget::moveLeft() +{ + setGeometryByKeyboard(geometry().adjusted(-1, 0, -1, 0)); +} + +void SelectionWidget::moveRight() +{ + setGeometryByKeyboard(geometry().adjusted(1, 0, 1, 0)); +} + +void SelectionWidget::moveUp() +{ + setGeometryByKeyboard(geometry().adjusted(0, -1, 0, -1)); +} + +void SelectionWidget::moveDown() +{ + setGeometryByKeyboard(geometry().adjusted(0, 1, 0, 1)); +} + +void SelectionWidget::resizeLeft() +{ + setGeometryByKeyboard(geometry().adjusted(0, 0, -1, 0)); +} + +void SelectionWidget::resizeRight() +{ + setGeometryByKeyboard(geometry().adjusted(0, 0, 1, 0)); +} + +void SelectionWidget::resizeUp() +{ + setGeometryByKeyboard(geometry().adjusted(0, 0, 0, -1)); +} + +void SelectionWidget::resizeDown() +{ + setGeometryByKeyboard(geometry().adjusted(0, 0, 0, 1)); +} + void SelectionWidget::updateAreas() { QRect r = rect(); - m_TLArea.moveTo(m_areaOffset + pos()); - m_TRArea.moveTo(r.topRight() + m_areaOffset + pos()); - m_BLArea.moveTo(r.bottomLeft() + m_areaOffset + pos()); - m_BRArea.moveTo(r.bottomRight() + m_areaOffset + pos()); + m_TLArea.moveTo(r.topLeft() + m_areaOffset); + m_TRArea.moveTo(r.topRight() + m_areaOffset); + m_BLArea.moveTo(r.bottomLeft() + m_areaOffset); + m_BRArea.moveTo(r.bottomRight() + m_areaOffset); m_LArea = QRect(m_TLArea.bottomLeft(), m_BLArea.topRight()); m_TArea = QRect(m_TLArea.topRight(), m_TRArea.bottomLeft()); @@ -127,3 +365,64 @@ void SelectionWidget::updateAreas() m_RHandle.moveTo(m_RArea.center() + m_handleOffset); m_BHandle.moveTo(m_BArea.center() + m_handleOffset); } + +void SelectionWidget::updateCursor() +{ + SideType mouseSide = m_activeSide; + if (!m_activeSide) { + mouseSide = getMouseSide(parentWidget()->mapFromGlobal(QCursor::pos())); + } + + switch (mouseSide) { + case TOPLEFT_SIDE: + setCursor(Qt::SizeFDiagCursor); + break; + case BOTTOMRIGHT_SIDE: + setCursor(Qt::SizeFDiagCursor); + break; + case TOPRIGHT_SIDE: + setCursor(Qt::SizeBDiagCursor); + break; + case BOTTOMLEFT_SIDE: + setCursor(Qt::SizeBDiagCursor); + break; + case LEFT_SIDE: + setCursor(Qt::SizeHorCursor); + break; + case RIGHT_SIDE: + setCursor(Qt::SizeHorCursor); + break; + case TOP_SIDE: + setCursor(Qt::SizeVerCursor); + break; + case BOTTOM_SIDE: + setCursor(Qt::SizeVerCursor); + break; + default: + if (m_activeSide) { + setCursor(Qt::ClosedHandCursor); + } else { + setCursor(m_idleCentralCursor); + return; + } + break; + } +} + +void SelectionWidget::setGeometryByKeyboard(const QRect& r) +{ + static QTimer timer; + QRect rect = r.intersected(parentWidget()->rect()); + if (rect.width() <= 0) + rect.setWidth(1); + if (rect.height() <= 0) + rect.setHeight(1); + setGeometry(rect); + connect( + &timer, + &QTimer::timeout, + this, + [this]() { emit geometrySettled(); }, + Qt::UniqueConnection); + timer.start(400); +} diff --git a/src/widgets/capture/selectionwidget.h b/src/widgets/capture/selectionwidget.h index f1179d28..3100bc58 100644 --- a/src/widgets/capture/selectionwidget.h +++ b/src/widgets/capture/selectionwidget.h @@ -13,47 +13,77 @@ class SelectionWidget : public QWidget public: enum SideType { - TOPLEFT_SIDE, - BOTTOMLEFT_SIDE, - TOPRIGHT_SIDE, - BOTTOMRIGHT_SIDE, - TOP_SIDE, - BOTTOM_SIDE, - RIGHT_SIDE, - LEFT_SIDE, - NO_SIDE, + NO_SIDE = 0, + TOP_SIDE = 0b0001, + BOTTOM_SIDE = 0b0010, + RIGHT_SIDE = 0b0100, + LEFT_SIDE = 0b1000, + TOPLEFT_SIDE = TOP_SIDE | LEFT_SIDE, + BOTTOMLEFT_SIDE = BOTTOM_SIDE | LEFT_SIDE, + TOPRIGHT_SIDE = TOP_SIDE | RIGHT_SIDE, + BOTTOMRIGHT_SIDE = BOTTOM_SIDE | RIGHT_SIDE, + CENTER = 0b10000, }; explicit SelectionWidget(const QColor& c, QWidget* parent = nullptr); - SideType getMouseSide(const QPoint& point) const; + SideType getMouseSide(const QPoint& mousePos) const; QVector handlerAreas(); + void setIgnoreMouse(bool ignore); + void setIdleCentralCursor(const QCursor& cursor); + void setGeometryAnimated(const QRect& r); - void saveGeometry(); - QRect savedGeometry(); + void setGeometry(const QRect& r); + QRect geometry() const; + QRect fullGeometry() const; + + QRect rect() const; protected: + bool eventFilter(QObject*, QEvent*) override; + void parentMousePressEvent(QMouseEvent* e); + void parentMouseReleaseEvent(QMouseEvent* e); + void parentMouseMoveEvent(QMouseEvent* e); + void paintEvent(QPaintEvent*); void resizeEvent(QResizeEvent*); void moveEvent(QMoveEvent*); signals: void animationEnded(); - void resized(); + void geometryChanged(); + void geometrySettled(); public slots: void updateColor(const QColor& c); + void moveLeft(); + void moveRight(); + void moveUp(); + void moveDown(); + + void resizeLeft(); + void resizeRight(); + void resizeUp(); + void resizeDown(); + private: void updateAreas(); + void updateCursor(); + void setGeometryByKeyboard(const QRect& r); QPropertyAnimation* m_animation; QColor m_color; QPoint m_areaOffset; QPoint m_handleOffset; - QRect m_geometryBackup; + + QPoint m_dragStartPos; + SideType m_activeSide; + QCursor m_idleCentralCursor; + bool m_ignoreMouse; + bool m_mouseStartMove; // naming convention for handles // T top, B bottom, R Right, L left diff --git a/src/widgets/panel/sidepanelwidget.cpp b/src/widgets/panel/sidepanelwidget.cpp index cbd7d7d3..f36bba5b 100644 --- a/src/widgets/panel/sidepanelwidget.cpp +++ b/src/widgets/panel/sidepanelwidget.cpp @@ -84,7 +84,7 @@ SidePanelWidget::SidePanelWidget(QPixmap* p, QWidget* parent) this, &SidePanelWidget::colorChanged); connect(m_colorWheel, - &color_widgets::ColorWheel::colorChanged, + &color_widgets::ColorWheel::colorSelected, this, &SidePanelWidget::updateColorNoWheel); } diff --git a/src/widgets/panel/utilitypanel.cpp b/src/widgets/panel/utilitypanel.cpp index b0bbd23d..a0fddce3 100644 --- a/src/widgets/panel/utilitypanel.cpp +++ b/src/widgets/panel/utilitypanel.cpp @@ -137,7 +137,7 @@ void UtilityPanel::initInternalPanel() connect(m_captureTools, SIGNAL(currentRowChanged(int)), this, - SLOT(slotCaptureToolsCurrentRowChanged(int))); + SLOT(onCurrentRowChanged(int))); QHBoxLayout* layersButtons = new QHBoxLayout(); m_layersLayout->addLayout(layersButtons); @@ -180,10 +180,8 @@ void UtilityPanel::fillCaptureTools( void UtilityPanel::setActiveLayer(int index) { - index++; - if (index >= 0 && index < m_captureTools->count()) { - m_captureTools->setCurrentRow(index); - } + Q_ASSERT(index >= -1); + m_captureTools->setCurrentRow(index + 1); } int UtilityPanel::activeLayerIndex() @@ -192,14 +190,14 @@ int UtilityPanel::activeLayerIndex() : -1; } -void UtilityPanel::slotCaptureToolsCurrentRowChanged(int currentRow) +void UtilityPanel::onCurrentRowChanged(int currentRow) { if (currentRow > 0) { m_buttonDelete->setDisabled(false); } else { m_buttonDelete->setDisabled(true); } - emit layerChanged(currentRow); + emit layerChanged(activeLayerIndex()); } void UtilityPanel::slotButtonDelete(bool clicked) diff --git a/src/widgets/panel/utilitypanel.h b/src/widgets/panel/utilitypanel.h index afa1a239..f48b3b05 100644 --- a/src/widgets/panel/utilitypanel.h +++ b/src/widgets/panel/utilitypanel.h @@ -39,7 +39,7 @@ signals: public slots: void toggle(); void slotButtonDelete(bool clicked); - void slotCaptureToolsCurrentRowChanged(int currentRow); + void onCurrentRowChanged(int currentRow); private: void initInternalPanel();