[krita] /: FEATURE: round corners for rectangular tools
Dmitry Kazakov
null at kde.org
Thu Aug 23 16:52:47 BST 2018
Git commit 04931e4fc85ef967a2d3834993890a430a65a864 by Dmitry Kazakov.
Committed on 23/08/2018 at 15:52.
Pushed by dkazakov into branch 'master'.
FEATURE: round corners for rectangular tools
Now both rectangular tools have an ability to set round
corners for the resulting shape. It works both: for vector
and raster shapes
BUG:335568
CC:kimageshop at kde.org
M +101 -33 libs/ui/forms/wdgrectangleconstraints.ui
M +54 -2 libs/ui/tool/kis_rectangle_constraint_widget.cpp
M +8 -1 libs/ui/tool/kis_rectangle_constraint_widget.h
M +22 -13 libs/ui/tool/kis_shape_tool_helper.cpp
M +1 -1 libs/ui/tool/kis_shape_tool_helper.h
M +6 -0 libs/ui/tool/kis_tool.cc
M +1 -0 libs/ui/tool/kis_tool.h
M +5 -0 libs/ui/tool/kis_tool_ellipse_base.cpp
M +3 -0 libs/ui/tool/kis_tool_ellipse_base.h
M +38 -4 libs/ui/tool/kis_tool_rectangle_base.cpp
M +7 -2 libs/ui/tool/kis_tool_rectangle_base.h
M +8 -10 plugins/flake/pathshapes/rectangle/RectangleShape.cpp
M +24 -0 plugins/flake/pathshapes/rectangle/RectangleShapeFactory.cpp
M +2 -0 plugins/flake/pathshapes/rectangle/RectangleShapeFactory.h
M +4 -1 plugins/tools/basictools/kis_tool_ellipse.cc
M +1 -1 plugins/tools/basictools/kis_tool_ellipse.h
M +15 -4 plugins/tools/basictools/kis_tool_rectangle.cc
M +1 -1 plugins/tools/basictools/kis_tool_rectangle.h
M +4 -1 plugins/tools/selectiontools/kis_tool_select_elliptical.cc
M +1 -1 plugins/tools/selectiontools/kis_tool_select_elliptical.h
M +12 -3 plugins/tools/selectiontools/kis_tool_select_rectangular.cc
M +1 -1 plugins/tools/selectiontools/kis_tool_select_rectangular.h
https://commits.kde.org/krita/04931e4fc85ef967a2d3834993890a430a65a864
diff --git a/libs/ui/forms/wdgrectangleconstraints.ui b/libs/ui/forms/wdgrectangleconstraints.ui
index c232202b2f8..ccb9d1b86db 100644
--- a/libs/ui/forms/wdgrectangleconstraints.ui
+++ b/libs/ui/forms/wdgrectangleconstraints.ui
@@ -6,8 +6,8 @@
<rect>
<x>0</x>
<y>0</y>
- <width>230</width>
- <height>149</height>
+ <width>243</width>
+ <height>328</height>
</rect>
</property>
<property name="sizePolicy">
@@ -19,23 +19,8 @@
<property name="windowTitle">
<string>Size</string>
</property>
- <layout class="QGridLayout" name="gridLayout_2">
- <property name="leftMargin">
- <number>0</number>
- </property>
- <property name="topMargin">
- <number>0</number>
- </property>
- <property name="rightMargin">
- <number>0</number>
- </property>
- <property name="bottomMargin">
- <number>0</number>
- </property>
- <property name="spacing">
- <number>0</number>
- </property>
- <item row="0" column="0">
+ <layout class="QVBoxLayout" name="verticalLayout">
+ <item>
<layout class="QGridLayout" name="gridLayout">
<property name="leftMargin">
<number>7</number>
@@ -84,6 +69,12 @@
</item>
<item row="1" column="2">
<widget class="KisIntParseSpinBox" name="intHeight">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="MinimumExpanding" vsizetype="Fixed">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
<property name="toolTip">
<string>Height</string>
</property>
@@ -107,6 +98,12 @@
</item>
<item row="2" column="2">
<widget class="KisDoubleParseSpinBox" name="doubleRatio">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="MinimumExpanding" vsizetype="Fixed">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
<property name="toolTip">
<string>Aspect ratio</string>
</property>
@@ -120,6 +117,12 @@
</item>
<item row="0" column="2">
<widget class="KisIntParseSpinBox" name="intWidth">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="MinimumExpanding" vsizetype="Fixed">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
<property name="toolTip">
<string>Width</string>
</property>
@@ -153,20 +156,79 @@
</item>
</layout>
</item>
- <item row="0" column="1">
- <spacer name="horizontalSpacer">
- <property name="orientation">
- <enum>Qt::Horizontal</enum>
- </property>
- <property name="sizeHint" stdset="0">
- <size>
- <width>40</width>
- <height>20</height>
- </size>
- </property>
- </spacer>
+ <item>
+ <layout class="QGridLayout" name="gridLayout_2">
+ <item row="0" column="0">
+ <widget class="QLabel" name="lblRoundCornersX">
+ <property name="text">
+ <string>Round X:</string>
+ </property>
+ </widget>
+ </item>
+ <item row="0" column="1">
+ <widget class="KisIntParseSpinBox" name="intRoundCornersX">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="MinimumExpanding" vsizetype="Fixed">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="toolTip">
+ <string>Height</string>
+ </property>
+ <property name="suffix">
+ <string> px</string>
+ </property>
+ <property name="maximum">
+ <number>99999</number>
+ </property>
+ </widget>
+ </item>
+ <item row="0" column="2" rowspan="2">
+ <widget class="KoAspectButton" name="cornersAspectButton" native="true">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Fixed" vsizetype="Fixed">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="minimumSize">
+ <size>
+ <width>24</width>
+ <height>24</height>
+ </size>
+ </property>
+ </widget>
+ </item>
+ <item row="1" column="0">
+ <widget class="QLabel" name="lblRoundCornersY">
+ <property name="text">
+ <string>Round Y:</string>
+ </property>
+ </widget>
+ </item>
+ <item row="1" column="1">
+ <widget class="KisIntParseSpinBox" name="intRoundCornersY">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="MinimumExpanding" vsizetype="Fixed">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="toolTip">
+ <string>Height</string>
+ </property>
+ <property name="suffix">
+ <string> px</string>
+ </property>
+ <property name="maximum">
+ <number>99999</number>
+ </property>
+ </widget>
+ </item>
+ </layout>
</item>
- <item row="1" column="0">
+ <item>
<spacer name="verticalSpacer">
<property name="orientation">
<enum>Qt::Vertical</enum>
@@ -174,7 +236,7 @@
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
- <height>40</height>
+ <height>187</height>
</size>
</property>
</spacer>
@@ -192,6 +254,12 @@
<extends>QDoubleSpinBox</extends>
<header>kis_double_parse_spin_box.h</header>
</customwidget>
+ <customwidget>
+ <class>KoAspectButton</class>
+ <extends>QWidget</extends>
+ <header>KoAspectButton.h</header>
+ <container>1</container>
+ </customwidget>
</customwidgets>
<resources/>
<connections/>
diff --git a/libs/ui/tool/kis_rectangle_constraint_widget.cpp b/libs/ui/tool/kis_rectangle_constraint_widget.cpp
index 0b0f1247922..83b03c47942 100644
--- a/libs/ui/tool/kis_rectangle_constraint_widget.cpp
+++ b/libs/ui/tool/kis_rectangle_constraint_widget.cpp
@@ -18,8 +18,13 @@
#include "kis_tool_rectangle_base.h"
#include <kis_icon.h>
+#include "kis_aspect_ratio_locker.h"
+#include "kis_signals_blocker.h"
+#include <KConfigGroup>
+#include <KSharedConfig>
-KisRectangleConstraintWidget::KisRectangleConstraintWidget(QWidget *parent, KisToolRectangleBase *tool) : QWidget(parent)
+KisRectangleConstraintWidget::KisRectangleConstraintWidget(QWidget *parent, KisToolRectangleBase *tool, bool showRoundCornersGUI)
+ : QWidget(parent)
{
m_tool = tool;
@@ -38,6 +43,23 @@ KisRectangleConstraintWidget::KisRectangleConstraintWidget(QWidget *parent, KisT
connect(this, SIGNAL(constraintsChanged(bool,bool,bool,float,float,float)), m_tool, SLOT(constraintsChanged(bool,bool,bool,float,float,float)));
connect(m_tool, SIGNAL(rectangleChanged(QRectF)), this, SLOT(rectangleChanged(QRectF)));
+
+ m_cornersAspectLocker = new KisAspectRatioLocker(this);
+ m_cornersAspectLocker->connectSpinBoxes(intRoundCornersX, intRoundCornersY, cornersAspectButton);
+
+ connect(m_cornersAspectLocker, SIGNAL(sliderValueChanged()), SLOT(slotRoundCornersChanged()));
+ connect(m_cornersAspectLocker, SIGNAL(aspectButtonChanged()), SLOT(slotRoundCornersAspectLockChanged()));
+
+ connect(m_tool, SIGNAL(sigRequestReloadConfig()), SLOT(slotReloadConfig()));
+ slotReloadConfig();
+
+ if (!showRoundCornersGUI) {
+ intRoundCornersX->setVisible(false);
+ intRoundCornersY->setVisible(false);
+ lblRoundCornersX->setVisible(false);
+ lblRoundCornersY->setVisible(false);
+ cornersAspectButton->setVisible(false);
+ }
}
void KisRectangleConstraintWidget::inputsChanged()
@@ -49,7 +71,37 @@ void KisRectangleConstraintWidget::inputsChanged()
doubleRatio->value(),
intWidth->value(),
intHeight->value()
- );
+ );
+}
+
+void KisRectangleConstraintWidget::slotRoundCornersChanged()
+{
+ m_tool->roundCornersChanged(intRoundCornersX->value(), intRoundCornersY->value());
+
+ KConfigGroup cfg = KSharedConfig::openConfig()->group(m_tool->toolId());
+ cfg.writeEntry("roundCornersX", intRoundCornersX->value());
+ cfg.writeEntry("roundCornersY", intRoundCornersY->value());
+}
+
+void KisRectangleConstraintWidget::slotRoundCornersAspectLockChanged()
+{
+ KConfigGroup cfg = KSharedConfig::openConfig()->group(m_tool->toolId());
+ cfg.writeEntry("roundCornersAspectLocked", cornersAspectButton->keepAspectRatio());
+}
+
+void KisRectangleConstraintWidget::slotReloadConfig()
+{
+ KConfigGroup cfg = KSharedConfig::openConfig()->group(m_tool->toolId());
+
+ {
+ KisSignalsBlocker b(intRoundCornersX, intRoundCornersY, cornersAspectButton);
+ intRoundCornersX->setValue(cfg.readEntry("roundCornersX", 0));
+ intRoundCornersY->setValue(cfg.readEntry("roundCornersY", 0));
+ cornersAspectButton->setKeepAspectRatio(cfg.readEntry("roundCornersAspectLocked", true));
+ m_cornersAspectLocker->updateAspect();
+ }
+
+ slotRoundCornersChanged();
}
void KisRectangleConstraintWidget::rectangleChanged(const QRectF &rect)
diff --git a/libs/ui/tool/kis_rectangle_constraint_widget.h b/libs/ui/tool/kis_rectangle_constraint_widget.h
index fc803db6e4c..f4cfdefb4df 100644
--- a/libs/ui/tool/kis_rectangle_constraint_widget.h
+++ b/libs/ui/tool/kis_rectangle_constraint_widget.h
@@ -21,13 +21,14 @@
#include <kritaui_export.h>
class KisToolRectangleBase;
+class KisAspectRatioLocker;
class KRITAUI_EXPORT KisRectangleConstraintWidget : public QWidget, public Ui::WdgRectangleConstraints
{
Q_OBJECT
public:
- KisRectangleConstraintWidget(QWidget *parentWidget, KisToolRectangleBase *tool);
+ KisRectangleConstraintWidget(QWidget *parentWidget, KisToolRectangleBase *tool, bool showRoundCornersGUI);
Q_SIGNALS:
void constraintsChanged(bool forceRatio, bool forceWidth, bool forceHeight, float ratio, float width, float height);
@@ -35,10 +36,16 @@ Q_SIGNALS:
protected Q_SLOTS:
void rectangleChanged(const QRectF &rect);
void inputsChanged();
+
+ void slotRoundCornersChanged();
+ void slotRoundCornersAspectLockChanged();
+
+ void slotReloadConfig();
protected:
KisToolRectangleBase* m_tool;
Ui_WdgRectangleConstraints *m_widget;
+ KisAspectRatioLocker *m_cornersAspectLocker;
};
#endif
diff --git a/libs/ui/tool/kis_shape_tool_helper.cpp b/libs/ui/tool/kis_shape_tool_helper.cpp
index 54552765d0b..4edab2a3d73 100644
--- a/libs/ui/tool/kis_shape_tool_helper.cpp
+++ b/libs/ui/tool/kis_shape_tool_helper.cpp
@@ -21,26 +21,35 @@
#include <KoPathShape.h>
#include <KoShapeRegistry.h>
#include <KoShapeFactoryBase.h>
+#include <KoProperties.h>
-KoShape* KisShapeToolHelper::createRectangleShape(const QRectF& rect)
+
+KoShape* KisShapeToolHelper::createRectangleShape(const QRectF& rect, qreal roundCornersX, qreal roundCornersY)
{
KoShape* shape;
+
KoShapeFactoryBase *rectFactory = KoShapeRegistry::instance()->value("RectangleShape");
if (rectFactory) {
- shape = rectFactory->createDefaultShape();
- shape->setSize(rect.size());
- shape->setPosition(rect.topLeft());
+ KoProperties props;
+ props.setProperty("x", rect.x());
+ props.setProperty("y", rect.y());
+ props.setProperty("width", rect.width());
+ props.setProperty("height", rect.height());
+ props.setProperty("rx", 2 * 100.0 * roundCornersX / rect.width());
+ props.setProperty("ry", 2 * 100.0 * roundCornersY / rect.height());
+
+ shape = rectFactory->createShape(&props);
} else {
//Fallback if the plugin wasn't found
- KoPathShape* path = new KoPathShape();
- path->setShapeId(KoPathShapeId);
- path->moveTo(rect.topLeft());
- path->lineTo(rect.topLeft() + QPointF(rect.width(), 0));
- path->lineTo(rect.bottomRight());
- path->lineTo(rect.topLeft() + QPointF(0, rect.height()));
- path->close();
- path->normalize();
- shape = path;
+ QPainterPath path;
+ if (roundCornersX > 0 || roundCornersY > 0) {
+ path.addRoundedRect(rect, roundCornersX, roundCornersY);
+ } else {
+ path.addRect(rect);
+ }
+ KoPathShape *pathShape = KoPathShape::createShapeFromPainterPath(path);
+ pathShape->normalize();
+ shape = pathShape;
}
return shape;
}
diff --git a/libs/ui/tool/kis_shape_tool_helper.h b/libs/ui/tool/kis_shape_tool_helper.h
index 60e3074907c..36d18b10c8b 100644
--- a/libs/ui/tool/kis_shape_tool_helper.h
+++ b/libs/ui/tool/kis_shape_tool_helper.h
@@ -30,7 +30,7 @@ class KoShape;
class KRITAUI_EXPORT KisShapeToolHelper
{
public:
- static KoShape* createRectangleShape(const QRectF& rect);
+ static KoShape* createRectangleShape(const QRectF& rect, qreal roundCornersX, qreal roundCornersY);
static KoShape* createEllipseShape(const QRectF& rect);
diff --git a/libs/ui/tool/kis_tool.cc b/libs/ui/tool/kis_tool.cc
index f9ee6ee555e..c6091e2e374 100644
--- a/libs/ui/tool/kis_tool.cc
+++ b/libs/ui/tool/kis_tool.cc
@@ -297,6 +297,12 @@ QRectF KisTool::convertToPt(const QRectF &rect)
return r;
}
+qreal KisTool::convertToPt(qreal value)
+{
+ const qreal avgResolution = 0.5 * (image()->xRes() + image()->yRes());
+ return value / avgResolution;
+}
+
QPointF KisTool::pixelToView(const QPoint &pixelCoord) const
{
if (!image())
diff --git a/libs/ui/tool/kis_tool.h b/libs/ui/tool/kis_tool.h
index dcf5368519d..efede6c1fd7 100644
--- a/libs/ui/tool/kis_tool.h
+++ b/libs/ui/tool/kis_tool.h
@@ -216,6 +216,7 @@ protected:
QPoint convertToImagePixelCoordFloored(KoPointerEvent *e);
QRectF convertToPt(const QRectF &rect);
+ qreal convertToPt(qreal value);
QPointF viewToPixel(const QPointF &viewCoord) const;
/// Convert an integer pixel coordinate into a view coordinate.
diff --git a/libs/ui/tool/kis_tool_ellipse_base.cpp b/libs/ui/tool/kis_tool_ellipse_base.cpp
index fa291d2d936..5ea46fb4674 100644
--- a/libs/ui/tool/kis_tool_ellipse_base.cpp
+++ b/libs/ui/tool/kis_tool_ellipse_base.cpp
@@ -41,3 +41,8 @@ void KisToolEllipseBase::paintRectangle(QPainter &gc, const QRectF &imageRect)
path.addEllipse(viewRect);
paintToolOutline(&gc, path);
}
+
+bool KisToolEllipseBase::showRoundCornersGUI() const
+{
+ return false;
+}
diff --git a/libs/ui/tool/kis_tool_ellipse_base.h b/libs/ui/tool/kis_tool_ellipse_base.h
index 8d5231f9e55..487c80a3f56 100644
--- a/libs/ui/tool/kis_tool_ellipse_base.h
+++ b/libs/ui/tool/kis_tool_ellipse_base.h
@@ -29,6 +29,9 @@ public:
KisToolEllipseBase(KoCanvasBase * canvas, KisToolEllipseBase::ToolType type, const QCursor & cursor=KisCursor::load("tool_ellipse_cursor.png", 6, 6));
void paintRectangle(QPainter &gc, const QRectF &imageRect) override;
+
+protected:
+ bool showRoundCornersGUI() const override;
};
#endif // KIS_TOOL_ELLIPSE_BASE_H
diff --git a/libs/ui/tool/kis_tool_rectangle_base.cpp b/libs/ui/tool/kis_tool_rectangle_base.cpp
index 1ae46e4b0e3..2c6e9270c23 100644
--- a/libs/ui/tool/kis_tool_rectangle_base.cpp
+++ b/libs/ui/tool/kis_tool_rectangle_base.cpp
@@ -25,6 +25,7 @@
#include <KoCanvasBase.h>
#include <KoCanvasController.h>
#include <KoViewConverter.h>
+#include "kis_canvas2.h"
#include "kis_rectangle_constraint_widget.h"
@@ -40,6 +41,8 @@ KisToolRectangleBase::KisToolRectangleBase(KoCanvasBase * canvas, KisToolRectang
, m_forcedRatio(1.0)
, m_forcedWidth(0)
, m_forcedHeight(0)
+ , m_roundCornersX(0)
+ , m_roundCornersY(0)
{
}
@@ -48,7 +51,7 @@ QList<QPointer<QWidget> > KisToolRectangleBase::createOptionWidgets()
{
QList<QPointer<QWidget> > widgetsList = KisToolShape::createOptionWidgets();
- widgetsList.append(new KisRectangleConstraintWidget(0, this));
+ widgetsList.append(new KisRectangleConstraintWidget(0, this, showRoundCornersGUI()));
return widgetsList;
}
@@ -67,6 +70,12 @@ void KisToolRectangleBase::constraintsChanged(bool forceRatio, bool forceWidth,
if (ratio < 0.0001f) m_isRatioForced = false;
}
+void KisToolRectangleBase::roundCornersChanged(int rx, int ry)
+{
+ m_roundCornersX = rx;
+ m_roundCornersY = ry;
+}
+
void KisToolRectangleBase::paint(QPainter& gc, const KoViewConverter &converter)
{
if(mode() == KisTool::PAINT_MODE) {
@@ -76,6 +85,13 @@ void KisToolRectangleBase::paint(QPainter& gc, const KoViewConverter &converter)
KisToolPaint::paint(gc, converter);
}
+void KisToolRectangleBase::activate(KoToolBase::ToolActivation toolActivation, const QSet<KoShape *> &shapes)
+{
+ KisToolShape::activate(toolActivation, shapes);
+
+ emit sigRequestReloadConfig();
+}
+
void KisToolRectangleBase::deactivate()
{
updateArea();
@@ -197,7 +213,7 @@ void KisToolRectangleBase::endPrimaryAction(KoPointerEvent *event)
updateArea();
- finishRect(createRect(m_dragStart, m_dragEnd));
+ finishRect(createRect(m_dragStart, m_dragEnd), m_roundCornersX, m_roundCornersY);
event->accept();
}
@@ -226,14 +242,32 @@ QRectF KisToolRectangleBase::createRect(const QPointF &start, const QPointF &end
return result.normalized();
}
+bool KisToolRectangleBase::showRoundCornersGUI() const
+{
+ return true;
+}
+
void KisToolRectangleBase::paintRectangle(QPainter &gc, const QRectF &imageRect)
{
KIS_ASSERT_RECOVER_RETURN(canvas());
- QRect viewRect = pixelToView(imageRect).toAlignedRect();
+ const QRect viewRect = pixelToView(imageRect).toAlignedRect();
+
+ KisCanvas2 *kritaCanvas = dynamic_cast<KisCanvas2*>(canvas());
+ KIS_SAFE_ASSERT_RECOVER_RETURN(kritaCanvas);
+
+ const KisCoordinatesConverter *converter = kritaCanvas->coordinatesConverter();
+ const qreal roundCornersX = converter->effectiveZoom() * m_roundCornersX;
+ const qreal roundCornersY = converter->effectiveZoom() * m_roundCornersY;
QPainterPath path;
- path.addRect(viewRect);
+
+ if (m_roundCornersX > 0 || m_roundCornersY > 0) {
+ path.addRoundedRect(viewRect,
+ roundCornersX, roundCornersY);
+ } else {
+ path.addRect(viewRect);
+ }
paintToolOutline(&gc, path);
}
diff --git a/libs/ui/tool/kis_tool_rectangle_base.h b/libs/ui/tool/kis_tool_rectangle_base.h
index 3ab9b2116d4..f5684f092dc 100644
--- a/libs/ui/tool/kis_tool_rectangle_base.h
+++ b/libs/ui/tool/kis_tool_rectangle_base.h
@@ -29,10 +29,11 @@ Q_OBJECT
Q_SIGNALS:
void rectangleChanged(const QRectF &newRect);
+ void sigRequestReloadConfig();
public Q_SLOTS:
void constraintsChanged(bool forceRatio, bool forceWidth, bool forceHeight, float ratio, float width, float height);
-
+ void roundCornersChanged(int rx, int ry);
public:
enum ToolType {
PAINT,
@@ -46,6 +47,7 @@ public:
void endPrimaryAction(KoPointerEvent *event) override;
void paint(QPainter& gc, const KoViewConverter &converter) override;
+ void activate(ToolActivation toolActivation, const QSet<KoShape*> &shapes) override;
void deactivate() override;
void listenToModifiers(bool listen) override;
bool listeningToModifiers() override;
@@ -53,7 +55,7 @@ public:
QList<QPointer<QWidget> > createOptionWidgets() override;
protected:
- virtual void finishRect(const QRectF&)=0;
+ virtual void finishRect(const QRectF &rect, qreal roundCornersX, qreal roundCornersY) = 0;
QPointF m_dragCenter;
QPointF m_dragStart;
@@ -67,6 +69,8 @@ protected:
float m_forcedRatio;
float m_forcedWidth;
float m_forcedHeight;
+ int m_roundCornersX;
+ int m_roundCornersY;
bool isFixedSize();
void applyConstraints(QSizeF& area, bool overrideRatio);
@@ -74,6 +78,7 @@ protected:
void updateArea();
virtual void paintRectangle(QPainter &gc, const QRectF &imageRect);
virtual QRectF createRect(const QPointF &start, const QPointF &end);
+ virtual bool showRoundCornersGUI() const;
};
#endif // KIS_TOOL_RECTANGLE_BASE_H
diff --git a/plugins/flake/pathshapes/rectangle/RectangleShape.cpp b/plugins/flake/pathshapes/rectangle/RectangleShape.cpp
index 3209bb7de79..6e0de7e4d37 100644
--- a/plugins/flake/pathshapes/rectangle/RectangleShape.cpp
+++ b/plugins/flake/pathshapes/rectangle/RectangleShape.cpp
@@ -300,11 +300,10 @@ qreal RectangleShape::cornerRadiusX() const
void RectangleShape::setCornerRadiusX(qreal radius)
{
- if (radius >= 0.0 && radius <= 100.0) {
- m_cornerRadiusX = radius;
- updatePath(size());
- updateHandles();
- }
+ radius = qBound(0.0, radius, 100.0);
+ m_cornerRadiusX = radius;
+ updatePath(size());
+ updateHandles();
}
qreal RectangleShape::cornerRadiusY() const
@@ -314,11 +313,10 @@ qreal RectangleShape::cornerRadiusY() const
void RectangleShape::setCornerRadiusY(qreal radius)
{
- if (radius >= 0.0 && radius <= 100.0) {
- m_cornerRadiusY = radius;
- updatePath(size());
- updateHandles();
- }
+ radius = qBound(0.0, radius, 100.0);
+ m_cornerRadiusY = radius;
+ updatePath(size());
+ updateHandles();
}
QString RectangleShape::pathShapeId() const
diff --git a/plugins/flake/pathshapes/rectangle/RectangleShapeFactory.cpp b/plugins/flake/pathshapes/rectangle/RectangleShapeFactory.cpp
index 7a5538670ae..a518a0625a0 100644
--- a/plugins/flake/pathshapes/rectangle/RectangleShapeFactory.cpp
+++ b/plugins/flake/pathshapes/rectangle/RectangleShapeFactory.cpp
@@ -25,6 +25,8 @@
#include <KoXmlReader.h>
#include <KoGradientBackground.h>
#include <KoShapeLoadingContext.h>
+#include <KoProperties.h>
+#include "kis_assert.h"
#include <KoIcon.h>
#include <klocalizedstring.h>
@@ -62,6 +64,28 @@ KoShape *RectangleShapeFactory::createDefaultShape(KoDocumentResourceManager *)
return rect;
}
+KoShape *RectangleShapeFactory::createShape(const KoProperties *params, KoDocumentResourceManager *documentResources) const
+{
+ KoShape *shape = createDefaultShape(documentResources);
+ RectangleShape *rectShape = dynamic_cast<RectangleShape*>(shape);
+ KIS_SAFE_ASSERT_RECOVER_RETURN_VALUE(rectShape, shape);
+
+ rectShape->setSize(
+ QSizeF(params->doubleProperty("width", rectShape->size().width()),
+ params->doubleProperty("height", rectShape->size().height())));
+
+ rectShape->setAbsolutePosition(
+ QPointF(params->doubleProperty("x", rectShape->absolutePosition(KoFlake::TopLeft).x()),
+ params->doubleProperty("y", rectShape->absolutePosition(KoFlake::TopLeft).y())),
+ KoFlake::TopLeft);
+
+
+ rectShape->setCornerRadiusX(params->doubleProperty("rx", 0.0));
+ rectShape->setCornerRadiusY(params->doubleProperty("ry", 0.0));
+
+ return shape;
+}
+
bool RectangleShapeFactory::supports(const KoXmlElement &e, KoShapeLoadingContext &/*context*/) const
{
Q_UNUSED(e);
diff --git a/plugins/flake/pathshapes/rectangle/RectangleShapeFactory.h b/plugins/flake/pathshapes/rectangle/RectangleShapeFactory.h
index 2e9aebcfa43..360813514c1 100644
--- a/plugins/flake/pathshapes/rectangle/RectangleShapeFactory.h
+++ b/plugins/flake/pathshapes/rectangle/RectangleShapeFactory.h
@@ -32,6 +32,8 @@ public:
RectangleShapeFactory();
~RectangleShapeFactory() override {}
KoShape *createDefaultShape(KoDocumentResourceManager *documentResources = 0) const override;
+ KoShape *createShape(const KoProperties *params, KoDocumentResourceManager *documentResources = 0) const override;
+
bool supports(const KoXmlElement &e, KoShapeLoadingContext &context) const override;
QList<KoShapeConfigWidgetBase *> createShapeOptionPanels() override;
};
diff --git a/plugins/tools/basictools/kis_tool_ellipse.cc b/plugins/tools/basictools/kis_tool_ellipse.cc
index 92ef3c6b0f3..812f3ed8a01 100644
--- a/plugins/tools/basictools/kis_tool_ellipse.cc
+++ b/plugins/tools/basictools/kis_tool_ellipse.cc
@@ -49,8 +49,11 @@ void KisToolEllipse::resetCursorStyle()
overrideCursorIfNotEditable();
}
-void KisToolEllipse::finishRect(const QRectF& rect)
+void KisToolEllipse::finishRect(const QRectF& rect, qreal roundCornersX, qreal roundCornersY)
{
+ Q_UNUSED(roundCornersX);
+ Q_UNUSED(roundCornersY);
+
if (rect.isEmpty() || !blockUntilOperationsFinished())
return;
diff --git a/plugins/tools/basictools/kis_tool_ellipse.h b/plugins/tools/basictools/kis_tool_ellipse.h
index 70c83f34cb1..f655aa662cb 100644
--- a/plugins/tools/basictools/kis_tool_ellipse.h
+++ b/plugins/tools/basictools/kis_tool_ellipse.h
@@ -46,7 +46,7 @@ protected Q_SLOTS:
void resetCursorStyle() override;
protected:
- void finishRect(const QRectF& rect) override;
+ void finishRect(const QRectF& rect, qreal roundCornersX, qreal roundCornersY) override;
};
class KisToolEllipseFactory : public KoToolFactoryBase
diff --git a/plugins/tools/basictools/kis_tool_rectangle.cc b/plugins/tools/basictools/kis_tool_rectangle.cc
index d11c5a678a4..fadc347dcb5 100644
--- a/plugins/tools/basictools/kis_tool_rectangle.cc
+++ b/plugins/tools/basictools/kis_tool_rectangle.cc
@@ -53,7 +53,7 @@ void KisToolRectangle::resetCursorStyle()
overrideCursorIfNotEditable();
}
-void KisToolRectangle::finishRect(const QRectF &rect)
+void KisToolRectangle::finishRect(const QRectF &rect, qreal roundCornersX, qreal roundCornersY)
{
if (rect.isNull() || !blockUntilOperationsFinished())
return;
@@ -68,10 +68,21 @@ void KisToolRectangle::finishRect(const QRectF &rect)
canvas()->resourceManager(),
strokeStyle(),
fillStyle());
- helper.paintRect(rect);
+
+ QPainterPath path;
+
+ if (roundCornersX > 0 || roundCornersY > 0) {
+ path.addRoundedRect(rect, roundCornersX, roundCornersY);
+ } else {
+ path.addRect(rect);
+ }
+
+ helper.paintPainterPath(path);
} else {
- QRectF r = convertToPt(rect);
- KoShape* shape = KisShapeToolHelper::createRectangleShape(r);
+ const QRectF r = convertToPt(rect);
+ const qreal docRoundCornersX = convertToPt(roundCornersX);
+ const qreal docRoundCornersY = convertToPt(roundCornersY);
+ KoShape* shape = KisShapeToolHelper::createRectangleShape(r, docRoundCornersX, docRoundCornersY);
KoShapeStrokeSP border;
if (strokeStyle() == KisPainter::StrokeStyleBrush) {
diff --git a/plugins/tools/basictools/kis_tool_rectangle.h b/plugins/tools/basictools/kis_tool_rectangle.h
index 754483cd636..5798e8841c4 100644
--- a/plugins/tools/basictools/kis_tool_rectangle.h
+++ b/plugins/tools/basictools/kis_tool_rectangle.h
@@ -45,7 +45,7 @@ public:
~KisToolRectangle() override;
protected:
- void finishRect(const QRectF& rect) override;
+ void finishRect(const QRectF& rect, qreal roundCornersX, qreal roundCornersY) override;
protected Q_SLOTS:
void resetCursorStyle() override;
diff --git a/plugins/tools/selectiontools/kis_tool_select_elliptical.cc b/plugins/tools/selectiontools/kis_tool_select_elliptical.cc
index df26677de96..d925bfe624f 100644
--- a/plugins/tools/selectiontools/kis_tool_select_elliptical.cc
+++ b/plugins/tools/selectiontools/kis_tool_select_elliptical.cc
@@ -41,8 +41,11 @@ __KisToolSelectEllipticalLocal::__KisToolSelectEllipticalLocal(KoCanvasBase *can
setObjectName("tool_select_elliptical");
}
-void __KisToolSelectEllipticalLocal::finishRect(const QRectF &rect)
+void __KisToolSelectEllipticalLocal::finishRect(const QRectF &rect, qreal roundCornersX, qreal roundCornersY)
{
+ Q_UNUSED(roundCornersX);
+ Q_UNUSED(roundCornersY);
+
KisCanvas2 * kisCanvas = dynamic_cast<KisCanvas2*>(canvas());
Q_ASSERT(kisCanvas);
diff --git a/plugins/tools/selectiontools/kis_tool_select_elliptical.h b/plugins/tools/selectiontools/kis_tool_select_elliptical.h
index c2ba6ece972..e06b938d845 100644
--- a/plugins/tools/selectiontools/kis_tool_select_elliptical.h
+++ b/plugins/tools/selectiontools/kis_tool_select_elliptical.h
@@ -46,7 +46,7 @@ protected:
virtual SelectionAction selectionAction() const = 0;
virtual bool antiAliasSelection() const = 0;
private:
- void finishRect(const QRectF &rect) override;
+ void finishRect(const QRectF &rect, qreal roundCornersX, qreal roundCornersY) override;
diff --git a/plugins/tools/selectiontools/kis_tool_select_rectangular.cc b/plugins/tools/selectiontools/kis_tool_select_rectangular.cc
index e38b9346e0b..b6257f83b69 100644
--- a/plugins/tools/selectiontools/kis_tool_select_rectangular.cc
+++ b/plugins/tools/selectiontools/kis_tool_select_rectangular.cc
@@ -42,7 +42,7 @@ __KisToolSelectRectangularLocal::__KisToolSelectRectangularLocal(KoCanvasBase *
setObjectName("tool_select_rectangular");
}
-void __KisToolSelectRectangularLocal::finishRect(const QRectF& rect)
+void __KisToolSelectRectangularLocal::finishRect(const QRectF& rect, qreal roundCornersX, qreal roundCornersY)
{
KisCanvas2 * kisCanvas = dynamic_cast<KisCanvas2*>(canvas());
if (!kisCanvas)
@@ -66,14 +66,23 @@ void __KisToolSelectRectangularLocal::finishRect(const QRectF& rect)
tmpSel->select(rc);
QPainterPath cache;
- cache.addRect(rc);
+
+ if (roundCornersX > 0 || roundCornersY > 0) {
+ cache.addRoundedRect(rc, roundCornersX, roundCornersY);
+ } else {
+ cache.addRect(rc);
+ }
+
tmpSel->setOutlineCache(cache);
helper.selectPixelSelection(tmpSel, selectionAction());
}
} else {
QRectF documentRect = convertToPt(rc);
- helper.addSelectionShape(KisShapeToolHelper::createRectangleShape(documentRect));
+ const qreal docRoundCornersX = convertToPt(roundCornersX);
+ const qreal docRoundCornersY = convertToPt(roundCornersY);
+
+ helper.addSelectionShape(KisShapeToolHelper::createRectangleShape(documentRect, docRoundCornersX, docRoundCornersY));
}
}
diff --git a/plugins/tools/selectiontools/kis_tool_select_rectangular.h b/plugins/tools/selectiontools/kis_tool_select_rectangular.h
index ecb33d5e3b5..4f3eda0cb25 100644
--- a/plugins/tools/selectiontools/kis_tool_select_rectangular.h
+++ b/plugins/tools/selectiontools/kis_tool_select_rectangular.h
@@ -43,7 +43,7 @@ protected:
virtual SelectionAction selectionAction() const = 0;
private:
- void finishRect(const QRectF& rect) override;
+ void finishRect(const QRectF& rect, qreal roundCornersX, qreal roundCornersY) override;
};
More information about the kimageshop
mailing list