diff --git a/libs/ui/forms/wdgrectangleconstraints.ui b/libs/ui/forms/wdgrectangleconstraints.ui
index c232202b2f..ccb9d1b86d 100644
--- a/libs/ui/forms/wdgrectangleconstraints.ui
+++ b/libs/ui/forms/wdgrectangleconstraints.ui
@@ -1,198 +1,266 @@
WdgRectangleConstraints
0
0
- 230
- 149
+ 243
+ 328
0
0
Size
-
-
- 0
-
-
- 0
-
-
- 0
-
-
- 0
-
-
- 0
-
- -
+
+
-
7
7
7
7
7
-
true
-
true
-
true
-
+
+
+ 0
+ 0
+
+
Height
px
99999
-
Width:
Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter
-
+
+
+ 0
+ 0
+
+
Aspect ratio
10000.000000000000000
0.100000000000000
-
+
+
+ 0
+ 0
+
+
Width
px
99999
-
Ratio:
Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter
-
Height:
Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter
- -
-
-
- Qt::Horizontal
-
-
-
- 40
- 20
-
-
-
+
-
+
+
-
+
+
+ Round X:
+
+
+
+ -
+
+
+
+ 0
+ 0
+
+
+
+ Height
+
+
+ px
+
+
+ 99999
+
+
+
+ -
+
+
+
+ 0
+ 0
+
+
+
+
+ 24
+ 24
+
+
+
+
+ -
+
+
+ Round Y:
+
+
+
+ -
+
+
+
+ 0
+ 0
+
+
+
+ Height
+
+
+ px
+
+
+ 99999
+
+
+
+
- -
+
-
Qt::Vertical
20
- 40
+ 187
KisIntParseSpinBox
QSpinBox
KisDoubleParseSpinBox
QDoubleSpinBox
kis_double_parse_spin_box.h
+
+ KoAspectButton
+ QWidget
+
+ 1
+
diff --git a/libs/ui/tool/kis_rectangle_constraint_widget.cpp b/libs/ui/tool/kis_rectangle_constraint_widget.cpp
index 0b0f124792..83b03c4794 100644
--- a/libs/ui/tool/kis_rectangle_constraint_widget.cpp
+++ b/libs/ui/tool/kis_rectangle_constraint_widget.cpp
@@ -1,71 +1,123 @@
/*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
#include "kis_rectangle_constraint_widget.h"
#include "kis_tool_rectangle_base.h"
#include
+#include "kis_aspect_ratio_locker.h"
+#include "kis_signals_blocker.h"
+#include
+#include
-KisRectangleConstraintWidget::KisRectangleConstraintWidget(QWidget *parent, KisToolRectangleBase *tool) : QWidget(parent)
+KisRectangleConstraintWidget::KisRectangleConstraintWidget(QWidget *parent, KisToolRectangleBase *tool, bool showRoundCornersGUI)
+ : QWidget(parent)
{
m_tool = tool;
setupUi(this);
lockWidthButton->setIcon(KisIconUtils::loadIcon("layer-locked"));
lockHeightButton->setIcon(KisIconUtils::loadIcon("layer-locked"));
lockRatioButton->setIcon(KisIconUtils::loadIcon("layer-locked"));
connect(lockWidthButton, SIGNAL(toggled(bool)), this, SLOT(inputsChanged(void)));
connect(lockHeightButton, SIGNAL(toggled(bool)), this, SLOT(inputsChanged(void)));
connect(lockRatioButton, SIGNAL(toggled(bool)), this, SLOT(inputsChanged(void)));
connect(intWidth, SIGNAL(valueChanged(int)), this, SLOT(inputsChanged(void)));
connect(intHeight, SIGNAL(valueChanged(int)), this, SLOT(inputsChanged(void)));
connect(doubleRatio, SIGNAL(valueChanged(double)), this, SLOT(inputsChanged(void)));
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()
{
emit constraintsChanged(
lockRatioButton->isChecked(),
lockWidthButton->isChecked(),
lockHeightButton->isChecked(),
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)
{
intWidth->blockSignals(true);
intHeight->blockSignals(true);
doubleRatio->blockSignals(true);
if (!lockWidthButton->isChecked()) intWidth->setValue(rect.width());
if (!lockHeightButton->isChecked()) intHeight->setValue(rect.height());
if (!lockRatioButton->isChecked() && !(rect.width() == 0 && rect.height() == 0)) {
doubleRatio->setValue(fabs(rect.width()) / fabs(rect.height()));
}
intWidth->blockSignals(false);
intHeight->blockSignals(false);
doubleRatio->blockSignals(false);
}
diff --git a/libs/ui/tool/kis_rectangle_constraint_widget.h b/libs/ui/tool/kis_rectangle_constraint_widget.h
index fc803db6e4..f4cfdefb4d 100644
--- a/libs/ui/tool/kis_rectangle_constraint_widget.h
+++ b/libs/ui/tool/kis_rectangle_constraint_widget.h
@@ -1,44 +1,51 @@
/*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
#ifndef KISRECTANGLECONSTRAINTWIDGET_H
#define KISRECTANGLECONSTRAINTWIDGET_H
#include "ui_wdgrectangleconstraints.h"
#include
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);
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 54552765d0..4edab2a3d7 100644
--- a/libs/ui/tool/kis_shape_tool_helper.cpp
+++ b/libs/ui/tool/kis_shape_tool_helper.cpp
@@ -1,70 +1,79 @@
/*
* Copyright (c) 2009 Sven Langkamp
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
#include "kis_shape_tool_helper.h"
#include
#include
#include
+#include
-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;
}
KoShape* KisShapeToolHelper::createEllipseShape(const QRectF& rect)
{
KoShape* shape;
KoShapeFactoryBase *rectFactory = KoShapeRegistry::instance()->value("EllipseShape");
if (rectFactory) {
shape = rectFactory->createDefaultShape();
shape->setSize(rect.size());
shape->setPosition(rect.topLeft());
} else {
//Fallback if the plugin wasn't found
KoPathShape* path = new KoPathShape();
path->setShapeId(KoPathShapeId);
QPointF rightMiddle = QPointF(rect.left() + rect.width(), rect.top() + rect.height() / 2);
path->moveTo(rightMiddle);
path->arcTo(rect.width() / 2, rect.height() / 2, 0, 360.0);
path->close();
path->normalize();
shape = path;
}
return shape;
}
diff --git a/libs/ui/tool/kis_shape_tool_helper.h b/libs/ui/tool/kis_shape_tool_helper.h
index 60e3074907..36d18b10c8 100644
--- a/libs/ui/tool/kis_shape_tool_helper.h
+++ b/libs/ui/tool/kis_shape_tool_helper.h
@@ -1,41 +1,41 @@
/*
* Copyright (c) 2009 Sven Langkamp
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
#ifndef KIS_SHAPE_TOOL_HELPER_H
#define KIS_SHAPE_TOOL_HELPER_H
#include
#include
class KoShape;
/**
* KisShapeToolHelper provides shapes and fallback shapes for shape based tools
*/
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);
};
#endif
diff --git a/libs/ui/tool/kis_tool.cc b/libs/ui/tool/kis_tool.cc
index f9ee6ee555..c6091e2e37 100644
--- a/libs/ui/tool/kis_tool.cc
+++ b/libs/ui/tool/kis_tool.cc
@@ -1,703 +1,709 @@
/*
* Copyright (c) 2006, 2010 Boudewijn Rempt
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
#include "kis_tool.h"
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include "kis_node_manager.h"
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include "opengl/kis_opengl_canvas2.h"
#include "kis_canvas_resource_provider.h"
#include "canvas/kis_canvas2.h"
#include "kis_coordinates_converter.h"
#include "filter/kis_filter_configuration.h"
#include "kis_config.h"
#include "kis_config_notifier.h"
#include "kis_cursor.h"
#include
#include "kis_resources_snapshot.h"
#include
#include "kis_action_registry.h"
#include "kis_tool_utils.h"
struct Q_DECL_HIDDEN KisTool::Private {
QCursor cursor; // the cursor that should be shown on tool activation.
// From the canvas resources
KoPattern* currentPattern{0};
KoAbstractGradient* currentGradient{0};
KoColor currentFgColor;
KoColor currentBgColor;
float currentExposure{1.0};
KisFilterConfigurationSP currentGenerator;
QWidget* optionWidget{0};
ToolMode m_mode{HOVER_MODE};
bool m_isActive{false};
};
KisTool::KisTool(KoCanvasBase * canvas, const QCursor & cursor)
: KoToolBase(canvas)
, d(new Private)
{
d->cursor = cursor;
connect(KisConfigNotifier::instance(), SIGNAL(configChanged()), SLOT(resetCursorStyle()));
connect(this, SIGNAL(isActiveChanged()), SLOT(resetCursorStyle()));
KActionCollection *collection = this->canvas()->canvasController()->actionCollection();
if (!collection->action("toggle_fg_bg")) {
QAction *toggleFgBg = KisActionRegistry::instance()->makeQAction("toggle_fg_bg", collection);
collection->addAction("toggle_fg_bg", toggleFgBg);
}
if (!collection->action("reset_fg_bg")) {
QAction *toggleFgBg = KisActionRegistry::instance()->makeQAction("reset_fg_bg", collection);
collection->addAction("reset_fg_bg", toggleFgBg);
}
addAction("toggle_fg_bg", dynamic_cast(collection->action("toggle_fg_bg")));
addAction("reset_fg_bg", dynamic_cast(collection->action("reset_fg_bg")));
}
KisTool::~KisTool()
{
delete d;
}
void KisTool::activate(ToolActivation activation, const QSet &shapes)
{
KoToolBase::activate(activation, shapes);
resetCursorStyle();
if (!canvas()) return;
if (!canvas()->resourceManager()) return;
d->currentFgColor = canvas()->resourceManager()->resource(KoCanvasResourceManager::ForegroundColor).value();
d->currentBgColor = canvas()->resourceManager()->resource(KoCanvasResourceManager::BackgroundColor).value();
if (canvas()->resourceManager()->hasResource(KisCanvasResourceProvider::CurrentPattern)) {
d->currentPattern = canvas()->resourceManager()->resource(KisCanvasResourceProvider::CurrentPattern).value();
}
if (canvas()->resourceManager()->hasResource(KisCanvasResourceProvider::CurrentGradient)) {
d->currentGradient = canvas()->resourceManager()->resource(KisCanvasResourceProvider::CurrentGradient).value();
}
KisPaintOpPresetSP preset = canvas()->resourceManager()->resource(KisCanvasResourceProvider::CurrentPaintOpPreset).value();
if (preset && preset->settings()) {
preset->settings()->activate();
}
if (canvas()->resourceManager()->hasResource(KisCanvasResourceProvider::HdrExposure)) {
d->currentExposure = static_cast(canvas()->resourceManager()->resource(KisCanvasResourceProvider::HdrExposure).toDouble());
}
if (canvas()->resourceManager()->hasResource(KisCanvasResourceProvider::CurrentGeneratorConfiguration)) {
d->currentGenerator = canvas()->resourceManager()->resource(KisCanvasResourceProvider::CurrentGeneratorConfiguration).value();
}
connect(action("toggle_fg_bg"), SIGNAL(triggered()), SLOT(slotToggleFgBg()), Qt::UniqueConnection);
connect(action("reset_fg_bg"), SIGNAL(triggered()), SLOT(slotResetFgBg()), Qt::UniqueConnection);
d->m_isActive = true;
emit isActiveChanged();
}
void KisTool::deactivate()
{
bool result = true;
result &= disconnect(action("toggle_fg_bg"), 0, this, 0);
result &= disconnect(action("reset_fg_bg"), 0, this, 0);
if (!result) {
warnKrita << "WARNING: KisTool::deactivate() failed to disconnect"
<< "some signal connections. Your actions might be executed twice!";
}
d->m_isActive = false;
emit isActiveChanged();
KoToolBase::deactivate();
}
void KisTool::canvasResourceChanged(int key, const QVariant & v)
{
QString formattedBrushName;
if (key == KisCanvasResourceProvider::CurrentPaintOpPreset) {
formattedBrushName = v.value()->name().replace("_", " ");
}
switch (key) {
case(KoCanvasResourceManager::ForegroundColor):
d->currentFgColor = v.value();
break;
case(KoCanvasResourceManager::BackgroundColor):
d->currentBgColor = v.value();
break;
case(KisCanvasResourceProvider::CurrentPattern):
d->currentPattern = static_cast(v.value());
break;
case(KisCanvasResourceProvider::CurrentGradient):
d->currentGradient = static_cast(v.value());
break;
case(KisCanvasResourceProvider::HdrExposure):
d->currentExposure = static_cast(v.toDouble());
break;
case(KisCanvasResourceProvider::CurrentGeneratorConfiguration):
d->currentGenerator = static_cast(v.value());
break;
case(KisCanvasResourceProvider::CurrentPaintOpPreset):
emit statusTextChanged(formattedBrushName);
break;
case(KisCanvasResourceProvider::CurrentKritaNode):
resetCursorStyle();
break;
default:
break; // Do nothing
};
}
void KisTool::updateSettingsViews()
{
}
QPointF KisTool::widgetCenterInWidgetPixels()
{
KisCanvas2 *kritaCanvas = dynamic_cast(canvas());
Q_ASSERT(kritaCanvas);
const KisCoordinatesConverter *converter = kritaCanvas->coordinatesConverter();
return converter->flakeToWidget(converter->flakeCenterPoint());
}
QPointF KisTool::convertDocumentToWidget(const QPointF& pt)
{
KisCanvas2 *kritaCanvas = dynamic_cast(canvas());
Q_ASSERT(kritaCanvas);
return kritaCanvas->coordinatesConverter()->documentToWidget(pt);
}
QPointF KisTool::convertToPixelCoord(KoPointerEvent *e)
{
if (!image())
return e->point;
return image()->documentToPixel(e->point);
}
QPointF KisTool::convertToPixelCoord(const QPointF& pt)
{
if (!image())
return pt;
return image()->documentToPixel(pt);
}
QPointF KisTool::convertToPixelCoordAndSnap(KoPointerEvent *e, const QPointF &offset, bool useModifiers)
{
if (!image())
return e->point;
KoSnapGuide *snapGuide = canvas()->snapGuide();
QPointF pos = snapGuide->snap(e->point, offset, useModifiers ? e->modifiers() : Qt::NoModifier);
return image()->documentToPixel(pos);
}
QPointF KisTool::convertToPixelCoordAndSnap(const QPointF& pt, const QPointF &offset)
{
if (!image())
return pt;
KoSnapGuide *snapGuide = canvas()->snapGuide();
QPointF pos = snapGuide->snap(pt, offset, Qt::NoModifier);
return image()->documentToPixel(pos);
}
QPoint KisTool::convertToImagePixelCoordFloored(KoPointerEvent *e)
{
if (!image())
return e->point.toPoint();
return image()->documentToImagePixelFloored(e->point);
}
QPointF KisTool::viewToPixel(const QPointF &viewCoord) const
{
if (!image())
return viewCoord;
return image()->documentToPixel(canvas()->viewConverter()->viewToDocument(viewCoord));
}
QRectF KisTool::convertToPt(const QRectF &rect)
{
if (!image())
return rect;
QRectF r;
//We add 1 in the following to the extreme coords because a pixel always has size
r.setCoords(int(rect.left()) / image()->xRes(), int(rect.top()) / image()->yRes(),
int(rect.right()) / image()->xRes(), int( rect.bottom()) / image()->yRes());
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())
return pixelCoord;
QPointF documentCoord = image()->pixelToDocument(pixelCoord);
return canvas()->viewConverter()->documentToView(documentCoord);
}
QPointF KisTool::pixelToView(const QPointF &pixelCoord) const
{
if (!image())
return pixelCoord;
QPointF documentCoord = image()->pixelToDocument(pixelCoord);
return canvas()->viewConverter()->documentToView(documentCoord);
}
QRectF KisTool::pixelToView(const QRectF &pixelRect) const
{
if (!image())
return pixelRect;
QPointF topLeft = pixelToView(pixelRect.topLeft());
QPointF bottomRight = pixelToView(pixelRect.bottomRight());
return QRectF(topLeft, bottomRight);
}
QPainterPath KisTool::pixelToView(const QPainterPath &pixelPolygon) const
{
QTransform matrix;
qreal zoomX, zoomY;
canvas()->viewConverter()->zoom(&zoomX, &zoomY);
matrix.scale(zoomX/image()->xRes(), zoomY/ image()->yRes());
return matrix.map(pixelPolygon);
}
QPolygonF KisTool::pixelToView(const QPolygonF &pixelPath) const
{
QTransform matrix;
qreal zoomX, zoomY;
canvas()->viewConverter()->zoom(&zoomX, &zoomY);
matrix.scale(zoomX/image()->xRes(), zoomY/ image()->yRes());
return matrix.map(pixelPath);
}
void KisTool::updateCanvasPixelRect(const QRectF &pixelRect)
{
canvas()->updateCanvas(convertToPt(pixelRect));
}
void KisTool::updateCanvasViewRect(const QRectF &viewRect)
{
canvas()->updateCanvas(canvas()->viewConverter()->viewToDocument(viewRect));
}
KisImageWSP KisTool::image() const
{
// For now, krita tools only work in krita, not for a krita shape. Krita shapes are for 2.1
KisCanvas2 * kisCanvas = dynamic_cast(canvas());
if (kisCanvas) {
return kisCanvas->currentImage();
}
return 0;
}
QCursor KisTool::cursor() const
{
return d->cursor;
}
void KisTool::notifyModified() const
{
if (image()) {
image()->setModified();
}
}
KoPattern * KisTool::currentPattern()
{
return d->currentPattern;
}
KoAbstractGradient * KisTool::currentGradient()
{
return d->currentGradient;
}
KisPaintOpPresetSP KisTool::currentPaintOpPreset()
{
return canvas()->resourceManager()->resource(KisCanvasResourceProvider::CurrentPaintOpPreset).value();
}
KisNodeSP KisTool::currentNode() const
{
KisNodeSP node = canvas()->resourceManager()->resource(KisCanvasResourceProvider::CurrentKritaNode).value();
return node;
}
KisNodeList KisTool::selectedNodes() const
{
KisCanvas2 * kiscanvas = static_cast(canvas());
KisViewManager* viewManager = kiscanvas->viewManager();
return viewManager->nodeManager()->selectedNodes();
}
KoColor KisTool::currentFgColor()
{
return d->currentFgColor;
}
KoColor KisTool::currentBgColor()
{
return d->currentBgColor;
}
KisImageWSP KisTool::currentImage()
{
return image();
}
KisFilterConfigurationSP KisTool::currentGenerator()
{
return d->currentGenerator;
}
void KisTool::setMode(ToolMode mode) {
d->m_mode = mode;
}
KisTool::ToolMode KisTool::mode() const {
return d->m_mode;
}
void KisTool::setCursor(const QCursor &cursor)
{
d->cursor = cursor;
}
KisTool::AlternateAction KisTool::actionToAlternateAction(ToolAction action) {
KIS_ASSERT_RECOVER_RETURN_VALUE(action != Primary, Secondary);
return (AlternateAction)action;
}
void KisTool::activatePrimaryAction()
{
resetCursorStyle();
}
void KisTool::deactivatePrimaryAction()
{
resetCursorStyle();
}
void KisTool::beginPrimaryAction(KoPointerEvent *event)
{
Q_UNUSED(event);
}
void KisTool::beginPrimaryDoubleClickAction(KoPointerEvent *event)
{
beginPrimaryAction(event);
}
void KisTool::continuePrimaryAction(KoPointerEvent *event)
{
Q_UNUSED(event);
}
void KisTool::endPrimaryAction(KoPointerEvent *event)
{
Q_UNUSED(event);
}
bool KisTool::primaryActionSupportsHiResEvents() const
{
return false;
}
void KisTool::activateAlternateAction(AlternateAction action)
{
Q_UNUSED(action);
}
void KisTool::deactivateAlternateAction(AlternateAction action)
{
Q_UNUSED(action);
}
void KisTool::beginAlternateAction(KoPointerEvent *event, AlternateAction action)
{
Q_UNUSED(event);
Q_UNUSED(action);
}
void KisTool::beginAlternateDoubleClickAction(KoPointerEvent *event, AlternateAction action)
{
beginAlternateAction(event, action);
}
void KisTool::continueAlternateAction(KoPointerEvent *event, AlternateAction action)
{
Q_UNUSED(event);
Q_UNUSED(action);
}
void KisTool::endAlternateAction(KoPointerEvent *event, AlternateAction action)
{
Q_UNUSED(event);
Q_UNUSED(action);
}
void KisTool::mouseDoubleClickEvent(KoPointerEvent *event)
{
Q_UNUSED(event);
}
void KisTool::mouseTripleClickEvent(KoPointerEvent *event)
{
mouseDoubleClickEvent(event);
}
void KisTool::mousePressEvent(KoPointerEvent *event)
{
Q_UNUSED(event);
}
void KisTool::mouseReleaseEvent(KoPointerEvent *event)
{
Q_UNUSED(event);
}
void KisTool::mouseMoveEvent(KoPointerEvent *event)
{
Q_UNUSED(event);
}
void KisTool::deleteSelection()
{
KisResourcesSnapshotSP resources =
new KisResourcesSnapshot(image(), currentNode(), this->canvas()->resourceManager());
if (!blockUntilOperationsFinished()) {
return;
}
if (!KisToolUtils::clearImage(image(), resources->currentNode(), resources->activeSelection())) {
KoToolBase::deleteSelection();
}
}
QWidget* KisTool::createOptionWidget()
{
d->optionWidget = new QLabel(i18n("No options"));
d->optionWidget->setObjectName("SpecialSpacer");
return d->optionWidget;
}
#define NEAR_VAL -1000.0
#define FAR_VAL 1000.0
#define PROGRAM_VERTEX_ATTRIBUTE 0
void KisTool::paintToolOutline(QPainter* painter, const QPainterPath &path)
{
KisOpenGLCanvas2 *canvasWidget = dynamic_cast(canvas()->canvasWidget());
if (canvasWidget) {
painter->beginNativePainting();
canvasWidget->paintToolOutline(path);
painter->endNativePainting();
}
else {
painter->save();
painter->setCompositionMode(QPainter::RasterOp_SourceXorDestination);
painter->setPen(QColor(128, 255, 128));
painter->drawPath(path);
painter->restore();
}
}
void KisTool::resetCursorStyle()
{
useCursor(d->cursor);
}
bool KisTool::overrideCursorIfNotEditable()
{
// override cursor for canvas iff this tool is active
// and we can't paint on the active layer
if (isActive()) {
KisNodeSP node = currentNode();
if (node && !node->isEditable()) {
canvas()->setCursor(Qt::ForbiddenCursor);
return true;
}
}
return false;
}
bool KisTool::blockUntilOperationsFinished()
{
KisCanvas2 * kiscanvas = static_cast(canvas());
KisViewManager* viewManager = kiscanvas->viewManager();
return viewManager->blockUntilOperationsFinished(image());
}
void KisTool::blockUntilOperationsFinishedForced()
{
KisCanvas2 * kiscanvas = static_cast(canvas());
KisViewManager* viewManager = kiscanvas->viewManager();
viewManager->blockUntilOperationsFinishedForced(image());
}
bool KisTool::isActive() const
{
return d->m_isActive;
}
void KisTool::slotToggleFgBg()
{
KoCanvasResourceManager* resourceManager = canvas()->resourceManager();
KoColor newFg = resourceManager->backgroundColor();
KoColor newBg = resourceManager->foregroundColor();
/**
* NOTE: Some of color selectors do not differentiate foreground
* and background colors, so if one wants them to end up
* being set up to foreground color, it should be set the
* last.
*/
resourceManager->setBackgroundColor(newBg);
resourceManager->setForegroundColor(newFg);
}
void KisTool::slotResetFgBg()
{
KoCanvasResourceManager* resourceManager = canvas()->resourceManager();
// see a comment in slotToggleFgBg()
resourceManager->setBackgroundColor(KoColor(Qt::white, KoColorSpaceRegistry::instance()->rgb8()));
resourceManager->setForegroundColor(KoColor(Qt::black, KoColorSpaceRegistry::instance()->rgb8()));
}
bool KisTool::nodeEditable()
{
KisNodeSP node = currentNode();
if (!node) {
return false;
}
bool blockedNoIndirectPainting = false;
const bool presetUsesIndirectPainting =
!currentPaintOpPreset()->settings()->paintIncremental();
if (!presetUsesIndirectPainting) {
const KisIndirectPaintingSupport *indirectPaintingLayer =
dynamic_cast(node.data());
if (indirectPaintingLayer) {
blockedNoIndirectPainting = !indirectPaintingLayer->supportsNonIndirectPainting();
}
}
bool nodeEditable = node->isEditable() && !blockedNoIndirectPainting;
if (!nodeEditable) {
KisCanvas2 * kiscanvas = static_cast(canvas());
QString message;
if (!node->visible() && node->userLocked()) {
message = i18n("Layer is locked and invisible.");
} else if (node->userLocked()) {
message = i18n("Layer is locked.");
} else if(!node->visible()) {
message = i18n("Layer is invisible.");
} else if (blockedNoIndirectPainting) {
message = i18n("Layer can be painted in Wash Mode only.");
} else {
message = i18n("Group not editable.");
}
kiscanvas->viewManager()->showFloatingMessage(message, KisIconUtils::loadIcon("object-locked"));
}
return nodeEditable;
}
bool KisTool::selectionEditable()
{
KisCanvas2 * kisCanvas = static_cast(canvas());
KisViewManager * view = kisCanvas->viewManager();
bool editable = view->selectionEditable();
if (!editable) {
KisCanvas2 * kiscanvas = static_cast(canvas());
kiscanvas->viewManager()->showFloatingMessage(i18n("Local selection is locked."), KisIconUtils::loadIcon("object-locked"));
}
return editable;
}
void KisTool::listenToModifiers(bool listen)
{
Q_UNUSED(listen);
}
bool KisTool::listeningToModifiers()
{
return false;
}
diff --git a/libs/ui/tool/kis_tool.h b/libs/ui/tool/kis_tool.h
index dcf5368519..efede6c1fd 100644
--- a/libs/ui/tool/kis_tool.h
+++ b/libs/ui/tool/kis_tool.h
@@ -1,321 +1,322 @@
/*
* Copyright (c) 2006 Boudewijn Rempt
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
#ifndef KIS_TOOL_H_
#define KIS_TOOL_H_
#include
#include
#include
#include
#include
#include
#include
#ifdef __GNUC__
#define WARN_WRONG_MODE(_mode) warnKrita << "Unexpected tool event has come to" << __func__ << "while being mode" << _mode << "!"
#else
#define WARN_WRONG_MODE(_mode) warnKrita << "Unexpected tool event has come while being mode" << _mode << "!"
#endif
#define CHECK_MODE_SANITY_OR_RETURN(_mode) if (mode() != _mode) { WARN_WRONG_MODE(mode()); return; }
class KoCanvasBase;
class KoPattern;
class KoAbstractGradient;
class KisFilterConfiguration;
class QPainter;
class QPainterPath;
class QPolygonF;
/// Definitions of the toolgroups of Krita
static const QString TOOL_TYPE_SHAPE = "0 Krita/Shape"; // Geometric shapes like ellipses and lines
static const QString TOOL_TYPE_TRANSFORM = "2 Krita/Transform"; // Tools that transform the layer;
static const QString TOOL_TYPE_FILL = "3 Krita/Fill"; // Tools that fill parts of the canvas
static const QString TOOL_TYPE_VIEW = "4 Krita/View"; // Tools that affect the canvas: pan, zoom, etc.
static const QString TOOL_TYPE_SELECTION = "5 Krita/Select"; // Tools that select pixels
//activation id for Krita tools, Krita tools are always active and handle locked and invisible layers by themself
static const QString KRITA_TOOL_ACTIVATION_ID = "flake/always";
class KRITAUI_EXPORT KisTool
: public KoToolBase
{
Q_OBJECT
Q_PROPERTY(bool isActive READ isActive NOTIFY isActiveChanged)
public:
enum { FLAG_USES_CUSTOM_PRESET=0x01, FLAG_USES_CUSTOM_COMPOSITEOP=0x02, FLAG_USES_CUSTOM_SIZE=0x04 };
KisTool(KoCanvasBase * canvas, const QCursor & cursor);
~KisTool() override;
virtual int flags() const { return 0; }
void deleteSelection() override;
// KoToolBase Implementation.
public:
/**
* Called by KisToolProxy when the primary action of the tool is
* going to be started now, that is when all the modifiers are
* pressed and the only thing left is just to press the mouse
* button. On coming of this callback the tool is supposed to
* prepare the cursor and/or the outline to show the user shat is
* going to happen next
*/
virtual void activatePrimaryAction();
/**
* Called by KisToolProxy when the primary is no longer possible
* to be started now, e.g. when its modifiers and released. The
* tool is supposed revert all the preparetions it has doen in
* activatePrimaryAction().
*/
virtual void deactivatePrimaryAction();
/**
* Called by KisToolProxy when a primary action for the tool is
* started. The \p event stores the original event that
* started the stroke. The \p event is _accepted_ by default. If
* the tool decides to ignore this particular action (e.g. when
* the node is not editable), it should call event->ignore(). Then
* no further continuePrimaryAction() or endPrimaryAction() will
* be called until the next user action.
*/
virtual void beginPrimaryAction(KoPointerEvent *event);
/**
* Called by KisToolProxy when the primary action is in progress
* of pointer movement. If the tool has ignored the event in
* beginPrimaryAction(), this method will not be called.
*/
virtual void continuePrimaryAction(KoPointerEvent *event);
/**
* Called by KisToolProxy when the primary action is being
* finished, that is while mouseRelease or tabletRelease event.
* If the tool has ignored the event in beginPrimaryAction(), this
* method will not be called.
*/
virtual void endPrimaryAction(KoPointerEvent *event);
/**
* The same as beginPrimaryAction(), but called when the stroke is
* started by a double-click
*
* \see beginPrimaryAction()
*/
virtual void beginPrimaryDoubleClickAction(KoPointerEvent *event);
/**
* Returns true if the tool can handle (and wants to handle) a
* very tight flow of input events from the tablet
*/
virtual bool primaryActionSupportsHiResEvents() const;
enum ToolAction {
Primary,
AlternateChangeSize,
AlternatePickFgNode,
AlternatePickBgNode,
AlternatePickFgImage,
AlternatePickBgImage,
AlternateSecondary,
AlternateThird,
AlternateFourth,
AlternateFifth,
Alternate_NONE = 10000
};
// Technically users are allowed to configure this, but nobody ever would do that.
// So these can basically be thought of as aliases to ctrl+click, etc.
enum AlternateAction {
ChangeSize = AlternateChangeSize, // Default: Shift+Left click
PickFgNode = AlternatePickFgNode, // Default: Ctrl+Alt+Left click
PickBgNode = AlternatePickBgNode, // Default: Ctrl+Alt+Right click
PickFgImage = AlternatePickFgImage, // Default: Ctrl+Left click
PickBgImage = AlternatePickBgImage, // Default: Ctrl+Right click
Secondary = AlternateSecondary,
Third = AlternateThird,
Fourth = AlternateFourth,
Fifth = AlternateFifth,
NONE = 10000
};
static AlternateAction actionToAlternateAction(ToolAction action);
virtual void activateAlternateAction(AlternateAction action);
virtual void deactivateAlternateAction(AlternateAction action);
virtual void beginAlternateAction(KoPointerEvent *event, AlternateAction action);
virtual void continueAlternateAction(KoPointerEvent *event, AlternateAction action);
virtual void endAlternateAction(KoPointerEvent *event, AlternateAction action);
virtual void beginAlternateDoubleClickAction(KoPointerEvent *event, AlternateAction action);
void mousePressEvent(KoPointerEvent *event) override;
void mouseDoubleClickEvent(KoPointerEvent *event) override;
void mouseTripleClickEvent(KoPointerEvent *event) override;
void mouseReleaseEvent(KoPointerEvent *event) override;
void mouseMoveEvent(KoPointerEvent *event) override;
bool isActive() const;
public Q_SLOTS:
void activate(ToolActivation activation, const QSet &shapes) override;
void deactivate() override;
void canvasResourceChanged(int key, const QVariant & res) override;
// Implement this slot in case there are any widgets or properties which need
// to be updated after certain operations, to reflect the inner state correctly.
// At the moment this is used for smoothing options in the freehand brush, but
// this will likely be expanded.
virtual void updateSettingsViews();
Q_SIGNALS:
void isActiveChanged();
protected:
// conversion methods are also needed by the paint information builder
friend class KisToolPaintingInformationBuilder;
/// Convert from native (postscript points) to image pixel
/// coordinates.
QPointF convertToPixelCoord(KoPointerEvent *e);
QPointF convertToPixelCoord(const QPointF& pt);
QPointF convertToPixelCoordAndSnap(KoPointerEvent *e, const QPointF &offset = QPointF(), bool useModifiers = true);
QPointF convertToPixelCoordAndSnap(const QPointF& pt, const QPointF &offset = QPointF());
protected:
QPointF widgetCenterInWidgetPixels();
QPointF convertDocumentToWidget(const QPointF& pt);
/// Convert from native (postscript points) to integer image pixel
/// coordinates. This rounds down (not truncate) the pixel coordinates and
/// should be used in preference to QPointF::toPoint(), which rounds,
/// to ensure the cursor acts on the pixel it is visually over.
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.
/// The view coordinate is at the centre of the pixel.
QPointF pixelToView(const QPoint &pixelCoord) const;
/// Convert a floating point pixel coordinate into a view coordinate.
QPointF pixelToView(const QPointF &pixelCoord) const;
/// Convert a pixel rectangle into a view rectangle.
QRectF pixelToView(const QRectF &pixelRect) const;
/// Convert a pixel path into a view path
QPainterPath pixelToView(const QPainterPath &pixelPath) const;
/// Convert a pixel polygon into a view path
QPolygonF pixelToView(const QPolygonF &pixelPolygon) const;
/// Update the canvas for the given rectangle in image pixel coordinates.
void updateCanvasPixelRect(const QRectF &pixelRect);
/// Update the canvas for the given rectangle in view coordinates.
void updateCanvasViewRect(const QRectF &viewRect);
QWidget* createOptionWidget() override;
/**
* To determine whether this tool will change its behavior when
* modifier keys are pressed
*/
virtual bool listeningToModifiers();
/**
* Request that this tool no longer listen to modifier keys
* (Responding to the request is optional)
*/
virtual void listenToModifiers(bool listen);
protected:
KisImageWSP image() const;
QCursor cursor() const;
/// Call this to set the document modified
void notifyModified() const;
KisImageWSP currentImage();
KoPattern* currentPattern();
KoAbstractGradient *currentGradient();
KisNodeSP currentNode() const;
KisNodeList selectedNodes() const;
KoColor currentFgColor();
KoColor currentBgColor();
KisPaintOpPresetSP currentPaintOpPreset();
KisFilterConfigurationSP currentGenerator();
/// paint the path which is in view coordinates, default paint mode is XOR_MODE, BW_MODE is also possible
/// never apply transformations to the painter, they would be useless, if drawing in OpenGL mode. The coordinates in the path should be in view coordinates.
void paintToolOutline(QPainter * painter, const QPainterPath &path);
/// Checks checks if the current node is editable
bool nodeEditable();
/// Checks checks if the selection is editable, only applies to local selection as global selection is always editable
bool selectionEditable();
/// Override the cursor appropriately if current node is not editable
bool overrideCursorIfNotEditable();
bool blockUntilOperationsFinished();
void blockUntilOperationsFinishedForced();
protected:
enum ToolMode {
HOVER_MODE,
PAINT_MODE,
SECONDARY_PAINT_MODE,
MIRROR_AXIS_SETUP_MODE,
GESTURE_MODE,
PAN_MODE,
OTHER // not used now
};
virtual void setMode(ToolMode mode);
virtual ToolMode mode() const;
void setCursor(const QCursor &cursor);
protected Q_SLOTS:
/**
* Called whenever the configuration settings change.
*/
virtual void resetCursorStyle();
private Q_SLOTS:
void slotToggleFgBg();
void slotResetFgBg();
private:
struct Private;
Private* const d;
};
#endif // KIS_TOOL_H_
diff --git a/libs/ui/tool/kis_tool_ellipse_base.cpp b/libs/ui/tool/kis_tool_ellipse_base.cpp
index fa291d2d93..5ea46fb467 100644
--- a/libs/ui/tool/kis_tool_ellipse_base.cpp
+++ b/libs/ui/tool/kis_tool_ellipse_base.cpp
@@ -1,43 +1,48 @@
/* This file is part of the KDE project
* Copyright (C) 2009 Boudewijn Rempt
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Library General Public License for more details.
*
* You should have received a copy of the GNU Library General Public License
* along with this library; see the file COPYING.LIB. If not, write to
* the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
* Boston, MA 02110-1301, USA.
*/
#include "kis_tool_ellipse_base.h"
#include
#include
#include
#include
#include "kis_canvas2.h"
KisToolEllipseBase::KisToolEllipseBase(KoCanvasBase * canvas, KisToolEllipseBase::ToolType type, const QCursor & cursor)
: KisToolRectangleBase(canvas, type, cursor)
{
}
void KisToolEllipseBase::paintRectangle(QPainter &gc, const QRectF &imageRect)
{
KIS_ASSERT_RECOVER_RETURN(canvas());
QRect viewRect = pixelToView(imageRect).toRect();
QPainterPath path;
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 8d5231f9e5..487c80a3f5 100644
--- a/libs/ui/tool/kis_tool_ellipse_base.h
+++ b/libs/ui/tool/kis_tool_ellipse_base.h
@@ -1,34 +1,37 @@
/* This file is part of the KDE project
* Copyright (C) 2009 Boudewijn Rempt
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Library General Public License for more details.
*
* You should have received a copy of the GNU Library General Public License
* along with this library; see the file COPYING.LIB. If not, write to
* the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
* Boston, MA 02110-1301, USA.
*/
#ifndef KIS_TOOL_ELLIPSE_BASE_H
#define KIS_TOOL_ELLIPSE_BASE_H
#include
#include
class KRITAUI_EXPORT KisToolEllipseBase : public KisToolRectangleBase
{
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 1ae46e4b0e..2c6e9270c2 100644
--- a/libs/ui/tool/kis_tool_rectangle_base.cpp
+++ b/libs/ui/tool/kis_tool_rectangle_base.cpp
@@ -1,247 +1,281 @@
/* This file is part of the KDE project
* Copyright (C) 2009 Boudewijn Rempt
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Library General Public License for more details.
*
* You should have received a copy of the GNU Library General Public License
* along with this library; see the file COPYING.LIB. If not, write to
* the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
* Boston, MA 02110-1301, USA.
*/
#include "kis_tool_rectangle_base.h"
#include
#include
#include
#include
#include
+#include "kis_canvas2.h"
#include "kis_rectangle_constraint_widget.h"
KisToolRectangleBase::KisToolRectangleBase(KoCanvasBase * canvas, KisToolRectangleBase::ToolType type, const QCursor & cursor)
: KisToolShape(canvas, cursor)
, m_dragStart(0, 0)
, m_dragEnd(0, 0)
, m_type(type)
, m_isRatioForced(false)
, m_isWidthForced(false)
, m_isHeightForced(false)
, m_listenToModifiers(true)
, m_forcedRatio(1.0)
, m_forcedWidth(0)
, m_forcedHeight(0)
+ , m_roundCornersX(0)
+ , m_roundCornersY(0)
{
}
QList > KisToolRectangleBase::createOptionWidgets()
{
QList > widgetsList = KisToolShape::createOptionWidgets();
- widgetsList.append(new KisRectangleConstraintWidget(0, this));
+ widgetsList.append(new KisRectangleConstraintWidget(0, this, showRoundCornersGUI()));
return widgetsList;
}
void KisToolRectangleBase::constraintsChanged(bool forceRatio, bool forceWidth, bool forceHeight, float ratio, float width, float height)
{
m_isWidthForced = forceWidth;
m_isHeightForced = forceHeight;
m_isRatioForced = forceRatio;
m_forcedHeight = height;
m_forcedWidth = width;
m_forcedRatio = ratio;
// Avoid division by zero in size calculations
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) {
paintRectangle(gc, createRect(m_dragStart, m_dragEnd));
}
KisToolPaint::paint(gc, converter);
}
+void KisToolRectangleBase::activate(KoToolBase::ToolActivation toolActivation, const QSet &shapes)
+{
+ KisToolShape::activate(toolActivation, shapes);
+
+ emit sigRequestReloadConfig();
+}
+
void KisToolRectangleBase::deactivate()
{
updateArea();
KisToolShape::deactivate();
}
void KisToolRectangleBase::listenToModifiers(bool listen)
{
m_listenToModifiers = listen;
}
bool KisToolRectangleBase::listeningToModifiers()
{
return m_listenToModifiers;
}
void KisToolRectangleBase::beginPrimaryAction(KoPointerEvent *event)
{
if ((m_type == PAINT && (!nodeEditable() || nodePaintAbility() == NONE)) ||
(m_type == SELECT && !selectionEditable())) {
event->ignore();
return;
}
setMode(KisTool::PAINT_MODE);
QPointF pos = convertToPixelCoordAndSnap(event, QPointF(), false);
m_dragStart = m_dragCenter = pos;
QSizeF area = QSizeF(0,0);
applyConstraints(area, false);
m_dragEnd.setX(m_dragStart.x() + area.width());
m_dragEnd.setY(m_dragStart.y() + area.height());
event->accept();
}
bool KisToolRectangleBase::isFixedSize() {
if (m_isWidthForced && m_isHeightForced) return true;
if (m_isRatioForced && (m_isWidthForced || m_isHeightForced)) return true;
return false;
}
void KisToolRectangleBase::applyConstraints(QSizeF &area, bool overrideRatio) {
if (m_isWidthForced) {
area.setWidth(m_forcedWidth);
}
if (m_isHeightForced) {
area.setHeight(m_forcedHeight);
}
if (m_isHeightForced && m_isWidthForced) return;
if (m_isRatioForced || overrideRatio) {
float ratio = m_isRatioForced ? m_forcedRatio : 1.0f;
if (m_isWidthForced) {
area.setHeight(area.width() / ratio);
} else {
area.setWidth(area.height() * ratio);
}
}
}
void KisToolRectangleBase::continuePrimaryAction(KoPointerEvent *event)
{
CHECK_MODE_SANITY_OR_RETURN(KisTool::PAINT_MODE);
bool constraintToggle = (event->modifiers() & Qt::ShiftModifier) && m_listenToModifiers;
bool translateMode = (event->modifiers() & Qt::AltModifier) && m_listenToModifiers;
bool expandFromCenter = (event->modifiers() & Qt::ControlModifier) && m_listenToModifiers;
bool fixedSize = isFixedSize() && !constraintToggle;
QPointF pos = convertToPixelCoordAndSnap(event, QPointF(), false);
if (fixedSize) {
m_dragStart = pos;
} else if (translateMode) {
QPointF trans = pos - m_dragEnd;
m_dragStart += trans;
m_dragEnd += trans;
}
QPointF diag = pos - m_dragStart;
QSizeF area = QSizeF(fabs(diag.x()), fabs(diag.y()));
bool overrideRatio = constraintToggle && !(m_isHeightForced || m_isWidthForced || m_isRatioForced);
if (!constraintToggle || overrideRatio) {
applyConstraints(area, overrideRatio);
}
diag = QPointF(
(diag.x() < 0) ? -area.width() : area.width(),
(diag.y() < 0) ? -area.height() : area.height()
);
// resize around center point?
if (expandFromCenter && !fixedSize) {
m_dragStart = m_dragCenter - diag / 2;
m_dragEnd = m_dragCenter + diag / 2;
} else {
m_dragEnd = m_dragStart + diag;
}
updateArea();
m_dragCenter = QPointF((m_dragStart.x() + m_dragEnd.x()) / 2,
(m_dragStart.y() + m_dragEnd.y()) / 2);
KisToolPaint::requestUpdateOutline(event->point, event);
}
void KisToolRectangleBase::endPrimaryAction(KoPointerEvent *event)
{
CHECK_MODE_SANITY_OR_RETURN(KisTool::PAINT_MODE);
setMode(KisTool::HOVER_MODE);
updateArea();
- finishRect(createRect(m_dragStart, m_dragEnd));
+ finishRect(createRect(m_dragStart, m_dragEnd), m_roundCornersX, m_roundCornersY);
event->accept();
}
QRectF KisToolRectangleBase::createRect(const QPointF &start, const QPointF &end)
{
/**
* To make the dragging user-friendly it should work in a bit
* non-obvious way: the start-drag point must be handled with
* "ceil"/"floor" (depending on the direction of the drag) and the
* end-drag point should follow usual "round" semantics.
*/
qreal x0 = start.x();
qreal y0 = start.y();
qreal x1 = end.x();
qreal y1 = end.y();
int newX0 = qRound(x0);
int newY0 = qRound(y0);
int newX1 = qRound(x1);
int newY1 = qRound(y1);
QRectF result;
result.setCoords(newX0, newY0, newX1, newY1);
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(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);
}
void KisToolRectangleBase::updateArea() {
const QRectF bound = createRect(m_dragStart, m_dragEnd);
canvas()->updateCanvas(convertToPt(bound).adjusted(-100, -100, +200, +200));
emit rectangleChanged(bound);
}
diff --git a/libs/ui/tool/kis_tool_rectangle_base.h b/libs/ui/tool/kis_tool_rectangle_base.h
index 3ab9b2116d..f5684f092d 100644
--- a/libs/ui/tool/kis_tool_rectangle_base.h
+++ b/libs/ui/tool/kis_tool_rectangle_base.h
@@ -1,79 +1,84 @@
/* This file is part of the KDE project
* Copyright (C) 2009 Boudewijn Rempt
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Library General Public License for more details.
*
* You should have received a copy of the GNU Library General Public License
* along with this library; see the file COPYING.LIB. If not, write to
* the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
* Boston, MA 02110-1301, USA.
*/
#ifndef KIS_TOOL_RECTANGLE_BASE_H
#define KIS_TOOL_RECTANGLE_BASE_H
#include
#include
class KRITAUI_EXPORT KisToolRectangleBase : public KisToolShape
{
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,
SELECT
};
explicit KisToolRectangleBase(KoCanvasBase * canvas, KisToolRectangleBase::ToolType type, const QCursor & cursor=KisCursor::load("tool_rectangle_cursor.png", 6, 6));
void beginPrimaryAction(KoPointerEvent *event) override;
void continuePrimaryAction(KoPointerEvent *event) override;
void endPrimaryAction(KoPointerEvent *event) override;
void paint(QPainter& gc, const KoViewConverter &converter) override;
+ void activate(ToolActivation toolActivation, const QSet &shapes) override;
void deactivate() override;
void listenToModifiers(bool listen) override;
bool listeningToModifiers() override;
QList > 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;
QPointF m_dragEnd;
ToolType m_type;
bool m_isRatioForced;
bool m_isWidthForced;
bool m_isHeightForced;
bool m_listenToModifiers;
float m_forcedRatio;
float m_forcedWidth;
float m_forcedHeight;
+ int m_roundCornersX;
+ int m_roundCornersY;
bool isFixedSize();
void applyConstraints(QSizeF& area, bool overrideRatio);
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 3209bb7de7..6e0de7e4d3 100644
--- a/plugins/flake/pathshapes/rectangle/RectangleShape.cpp
+++ b/plugins/flake/pathshapes/rectangle/RectangleShape.cpp
@@ -1,389 +1,387 @@
/* This file is part of the KDE project
Copyright (C) 2006-2008 Thorsten Zachmann
Copyright (C) 2006-2008 Jan Hambrecht
Copyright (C) 2009 Thomas Zander
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Library General Public
License as published by the Free Software Foundation; either
version 2 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Library General Public License for more details.
You should have received a copy of the GNU Library General Public License
along with this library; see the file COPYING.LIB. If not, write to
the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
* Boston, MA 02110-1301, USA.
*/
#include "RectangleShape.h"
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
RectangleShape::RectangleShape()
: m_cornerRadiusX(0)
, m_cornerRadiusY(0)
{
QList handles;
handles.push_back(QPointF(100, 0));
handles.push_back(QPointF(100, 0));
setHandles(handles);
QSizeF size(100, 100);
updatePath(size);
}
RectangleShape::RectangleShape(const RectangleShape &rhs)
: KoParameterShape(new KoParameterShapePrivate(*rhs.d_func(), this)),
m_cornerRadiusX(rhs.m_cornerRadiusX),
m_cornerRadiusY(rhs.m_cornerRadiusY)
{
}
RectangleShape::~RectangleShape()
{
}
KoShape *RectangleShape::cloneShape() const
{
return new RectangleShape(*this);
}
bool RectangleShape::loadOdf(const KoXmlElement &element, KoShapeLoadingContext &context)
{
loadOdfAttributes(element, context, OdfMandatories | OdfGeometry | OdfAdditionalAttributes | OdfCommonChildElements);
if (element.hasAttributeNS(KoXmlNS::svg, "rx") && element.hasAttributeNS(KoXmlNS::svg, "ry")) {
qreal rx = KoUnit::parseValue(element.attributeNS(KoXmlNS::svg, "rx", "0"));
qreal ry = KoUnit::parseValue(element.attributeNS(KoXmlNS::svg, "ry", "0"));
m_cornerRadiusX = rx / (0.5 * size().width()) * 100;
m_cornerRadiusY = ry / (0.5 * size().height()) * 100;
} else {
QString cornerRadius = element.attributeNS(KoXmlNS::draw, "corner-radius", "");
if (!cornerRadius.isEmpty()) {
qreal radius = KoUnit::parseValue(cornerRadius);
m_cornerRadiusX = qMin(radius / (0.5 * size().width()) * 100, qreal(100));
m_cornerRadiusY = qMin(radius / (0.5 * size().height()) * 100, qreal(100));
}
}
updatePath(size());
updateHandles();
loadOdfAttributes(element, context, OdfTransformation);
loadText(element, context);
return true;
}
void RectangleShape::saveOdf(KoShapeSavingContext &context) const
{
if (isParametricShape()) {
context.xmlWriter().startElement("draw:rect");
saveOdfAttributes(context, OdfAllAttributes);
if (m_cornerRadiusX > 0 && m_cornerRadiusY > 0) {
context.xmlWriter().addAttribute("svg:rx", m_cornerRadiusX * (0.5 * size().width()) / 100.0);
context.xmlWriter().addAttribute("svg:ry", m_cornerRadiusY * (0.5 * size().height()) / 100.0);
}
saveOdfCommonChildElements(context);
saveText(context);
context.xmlWriter().endElement();
} else {
KoPathShape::saveOdf(context);
}
}
void RectangleShape::moveHandleAction(int handleId, const QPointF &point, Qt::KeyboardModifiers modifiers)
{
Q_UNUSED(modifiers);
QPointF p(point);
qreal width2 = size().width() / 2.0;
qreal height2 = size().height() / 2.0;
switch (handleId) {
case 0:
if (p.x() < width2) {
p.setX(width2);
} else if (p.x() > size().width()) {
p.setX(size().width());
}
p.setY(0);
m_cornerRadiusX = (size().width() - p.x()) / width2 * 100.0;
if (!(modifiers & Qt::ControlModifier)) {
m_cornerRadiusY = (size().width() - p.x()) / height2 * 100.0;
}
break;
case 1:
if (p.y() < 0) {
p.setY(0);
} else if (p.y() > height2) {
p.setY(height2);
}
p.setX(size().width());
m_cornerRadiusY = p.y() / height2 * 100.0;
if (!(modifiers & Qt::ControlModifier)) {
m_cornerRadiusX = p.y() / width2 * 100.0;
}
break;
}
// this is needed otherwise undo/redo might not end in the same result
if (100 - m_cornerRadiusX < 1e-10) {
m_cornerRadiusX = 100;
}
if (100 - m_cornerRadiusY < 1e-10) {
m_cornerRadiusY = 100;
}
updateHandles();
}
void RectangleShape::updateHandles()
{
QList handles;
handles.append(QPointF(size().width() - m_cornerRadiusX / 100.0 * 0.5 * size().width(), 0.0));
handles.append(QPointF(size().width(), m_cornerRadiusY / 100.0 * 0.5 * size().height()));
setHandles(handles);
}
void RectangleShape::updatePath(const QSizeF &size)
{
Q_D(KoParameterShape);
qreal rx = 0;
qreal ry = 0;
if (m_cornerRadiusX > 0 && m_cornerRadiusY > 0) {
rx = size.width() / 200.0 * m_cornerRadiusX;
ry = size.height() / 200.0 * m_cornerRadiusY;
}
qreal x2 = size.width() - rx;
qreal y2 = size.height() - ry;
QPointF curvePoints[12];
int requiredCurvePointCount = 4;
if (rx && m_cornerRadiusX < 100) {
requiredCurvePointCount += 2;
}
if (ry && m_cornerRadiusY < 100) {
requiredCurvePointCount += 2;
}
createPoints(requiredCurvePointCount);
KoSubpath &points = *d->subpaths[0];
int cp = 0;
// first path starts and closes path
points[cp]->setProperty(KoPathPoint::StartSubpath);
points[cp]->setProperty(KoPathPoint::CloseSubpath);
points[cp]->setPoint(QPointF(rx, 0));
points[cp]->removeControlPoint1();
points[cp]->removeControlPoint2();
if (m_cornerRadiusX < 100 || m_cornerRadiusY == 0) {
// end point of the top edge
points[++cp]->setPoint(QPointF(x2, 0));
points[cp]->removeControlPoint1();
points[cp]->removeControlPoint2();
}
if (rx) {
// the top right radius
arcToCurve(rx, ry, 90, -90, points[cp]->point(), curvePoints);
points[cp]->setControlPoint2(curvePoints[0]);
points[++cp]->setControlPoint1(curvePoints[1]);
points[cp]->setPoint(curvePoints[2]);
points[cp]->removeControlPoint2();
}
if (m_cornerRadiusY < 100 || m_cornerRadiusX == 0) {
// the right edge
points[++cp]->setPoint(QPointF(size.width(), y2));
points[cp]->removeControlPoint1();
points[cp]->removeControlPoint2();
}
if (rx) {
// the bottom right radius
arcToCurve(rx, ry, 0, -90, points[cp]->point(), curvePoints);
points[cp]->setControlPoint2(curvePoints[0]);
points[++cp]->setControlPoint1(curvePoints[1]);
points[cp]->setPoint(curvePoints[2]);
points[cp]->removeControlPoint2();
}
if (m_cornerRadiusX < 100 || m_cornerRadiusY == 0) {
// the bottom edge
points[++cp]->setPoint(QPointF(rx, size.height()));
points[cp]->removeControlPoint1();
points[cp]->removeControlPoint2();
}
if (rx) {
// the bottom left radius
arcToCurve(rx, ry, 270, -90, points[cp]->point(), curvePoints);
points[cp]->setControlPoint2(curvePoints[0]);
points[++cp]->setControlPoint1(curvePoints[1]);
points[cp]->setPoint(curvePoints[2]);
points[cp]->removeControlPoint2();
}
if ((m_cornerRadiusY < 100 || m_cornerRadiusX == 0) && ry) {
// the right edge
points[++cp]->setPoint(QPointF(0, ry));
points[cp]->removeControlPoint1();
points[cp]->removeControlPoint2();
}
if (rx) {
// the top left radius
arcToCurve(rx, ry, 180, -90, points[cp]->point(), curvePoints);
points[cp]->setControlPoint2(curvePoints[0]);
points[0]->setControlPoint1(curvePoints[1]);
points[0]->setPoint(curvePoints[2]);
}
// unset all stop/close path properties
for (int i = 1; i < cp; ++i) {
points[i]->unsetProperty(KoPathPoint::StopSubpath);
points[i]->unsetProperty(KoPathPoint::CloseSubpath);
}
// last point stops and closes path
points.last()->setProperty(KoPathPoint::StopSubpath);
points.last()->setProperty(KoPathPoint::CloseSubpath);
notifyPointsChanged();
}
void RectangleShape::createPoints(int requiredPointCount)
{
Q_D(KoParameterShape);
if (d->subpaths.count() != 1) {
clear();
d->subpaths.append(new KoSubpath());
}
int currentPointCount = d->subpaths[0]->count();
if (currentPointCount > requiredPointCount) {
for (int i = 0; i < currentPointCount - requiredPointCount; ++i) {
delete d->subpaths[0]->front();
d->subpaths[0]->pop_front();
}
} else if (requiredPointCount > currentPointCount) {
for (int i = 0; i < requiredPointCount - currentPointCount; ++i) {
d->subpaths[0]->append(new KoPathPoint(this, QPointF()));
}
}
notifyPointsChanged();
}
qreal RectangleShape::cornerRadiusX() const
{
return m_cornerRadiusX;
}
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
{
return m_cornerRadiusY;
}
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
{
return RectangleShapeId;
}
bool RectangleShape::saveSvg(SvgSavingContext &context)
{
// let basic path saiving code handle our saving
if (!isParametricShape()) return false;
context.shapeWriter().startElement("rect");
context.shapeWriter().addAttribute("id", context.getID(this));
SvgUtil::writeTransformAttributeLazy("transform", transformation(), context.shapeWriter());
SvgStyleWriter::saveSvgStyle(this, context);
const QSizeF size = this->size();
context.shapeWriter().addAttribute("width", size.width());
context.shapeWriter().addAttribute("height", size.height());
double rx = cornerRadiusX();
if (rx > 0.0) {
context.shapeWriter().addAttribute("rx", 0.01 * rx * 0.5 * size.width());
}
double ry = cornerRadiusY();
if (ry > 0.0) {
context.shapeWriter().addAttribute("ry", 0.01 * ry * 0.5 * size.height());
}
context.shapeWriter().endElement();
return true;
}
bool RectangleShape::loadSvg(const KoXmlElement &element, SvgLoadingContext &context)
{
const qreal x = SvgUtil::parseUnitX(context.currentGC(), element.attribute("x"));
const qreal y = SvgUtil::parseUnitY(context.currentGC(), element.attribute("y"));
const qreal w = SvgUtil::parseUnitX(context.currentGC(), element.attribute("width"));
const qreal h = SvgUtil::parseUnitY(context.currentGC(), element.attribute("height"));
const QString rxStr = element.attribute("rx");
const QString ryStr = element.attribute("ry");
qreal rx = rxStr.isEmpty() ? 0.0 : SvgUtil::parseUnitX(context.currentGC(), rxStr);
qreal ry = ryStr.isEmpty() ? 0.0 : SvgUtil::parseUnitY(context.currentGC(), ryStr);
// if one radius is given but not the other, use the same value for both
if (!rxStr.isEmpty() && ryStr.isEmpty()) {
ry = rx;
}
if (rxStr.isEmpty() && !ryStr.isEmpty()) {
rx = ry;
}
setSize(QSizeF(w, h));
setPosition(QPointF(x, y));
if (rx >= 0.0) {
setCornerRadiusX(qMin(qreal(100.0), qreal(rx / (0.5 * w) * 100.0)));
}
if (ry >= 0.0) {
setCornerRadiusY(qMin(qreal(100.0), qreal(ry / (0.5 * h) * 100.0)));
}
if (w == 0.0 || h == 0.0) {
setVisible(false);
}
return true;
}
diff --git a/plugins/flake/pathshapes/rectangle/RectangleShapeFactory.cpp b/plugins/flake/pathshapes/rectangle/RectangleShapeFactory.cpp
index 7a5538670a..a518a0625a 100644
--- a/plugins/flake/pathshapes/rectangle/RectangleShapeFactory.cpp
+++ b/plugins/flake/pathshapes/rectangle/RectangleShapeFactory.cpp
@@ -1,77 +1,101 @@
/* This file is part of the KDE project
* Copyright (C) 2006 Thomas Zander
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Library General Public License for more details.
*
* You should have received a copy of the GNU Library General Public License
* along with this library; see the file COPYING.LIB. If not, write to
* the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
* Boston, MA 02110-1301, USA.
*/
#include "RectangleShapeFactory.h"
#include "RectangleShape.h"
#include "RectangleShapeConfigWidget.h"
#include "KoShapeStroke.h"
#include
#include
#include
#include
+#include
+#include "kis_assert.h"
#include
#include
#include "kis_pointer_utils.h"
RectangleShapeFactory::RectangleShapeFactory()
: KoShapeFactoryBase(RectangleShapeId, i18n("Rectangle"))
{
setToolTip(i18n("A rectangle"));
setIconName(koIconNameCStr("rectangle-shape"));
setFamily("geometric");
setLoadingPriority(1);
QList > elementNamesList;
elementNamesList.append(qMakePair(QString(KoXmlNS::draw), QStringList("rect")));
elementNamesList.append(qMakePair(QString(KoXmlNS::svg), QStringList("rect")));
setXmlElements(elementNamesList);
}
KoShape *RectangleShapeFactory::createDefaultShape(KoDocumentResourceManager *) const
{
RectangleShape *rect = new RectangleShape();
rect->setStroke(toQShared(new KoShapeStroke(1.0)));
rect->setShapeId(KoPathShapeId);
QLinearGradient *gradient = new QLinearGradient(QPointF(0, 0), QPointF(1, 1));
gradient->setCoordinateMode(QGradient::ObjectBoundingMode);
gradient->setColorAt(0.0, Qt::white);
gradient->setColorAt(1.0, Qt::green);
rect->setBackground(QSharedPointer(new KoGradientBackground(gradient)));
return rect;
}
+KoShape *RectangleShapeFactory::createShape(const KoProperties *params, KoDocumentResourceManager *documentResources) const
+{
+ KoShape *shape = createDefaultShape(documentResources);
+ RectangleShape *rectShape = dynamic_cast(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);
return (e.localName() == "rect" && e.namespaceURI() == KoXmlNS::draw);
}
QList RectangleShapeFactory::createShapeOptionPanels()
{
QList panels;
panels.append(new RectangleShapeConfigWidget());
return panels;
}
diff --git a/plugins/flake/pathshapes/rectangle/RectangleShapeFactory.h b/plugins/flake/pathshapes/rectangle/RectangleShapeFactory.h
index 2e9aebcfa4..360813514c 100644
--- a/plugins/flake/pathshapes/rectangle/RectangleShapeFactory.h
+++ b/plugins/flake/pathshapes/rectangle/RectangleShapeFactory.h
@@ -1,39 +1,41 @@
/* This file is part of the KDE project
Copyright (C) 2006 Thorsten Zachmann
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Library General Public
License as published by the Free Software Foundation; either
version 2 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Library General Public License for more details.
You should have received a copy of the GNU Library General Public License
along with this library; see the file COPYING.LIB. If not, write to
the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
* Boston, MA 02110-1301, USA.
*/
#ifndef KORECTANGLESHAPEFACTORY_H
#define KORECTANGLESHAPEFACTORY_H
#include "KoShapeFactoryBase.h"
class KoShape;
/// Factory for path shapes
class RectangleShapeFactory : public KoShapeFactoryBase
{
public:
/// constructor
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 createShapeOptionPanels() override;
};
#endif
diff --git a/plugins/tools/basictools/kis_tool_ellipse.cc b/plugins/tools/basictools/kis_tool_ellipse.cc
index 92ef3c6b0f..812f3ed8a0 100644
--- a/plugins/tools/basictools/kis_tool_ellipse.cc
+++ b/plugins/tools/basictools/kis_tool_ellipse.cc
@@ -1,80 +1,83 @@
/*
* kis_tool_ellipse.cc - part of Krayon
*
* Copyright (c) 2000 John Califf
* Copyright (c) 2002 Patrick Julien
* Copyright (c) 2004 Boudewijn Rempt
* Copyright (c) 2004 Clarence Dang
* Copyright (c) 2009 Lukáš Tvrdý
* Copyright (c) 2010 Cyrille Berger
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
#include "kis_tool_ellipse.h"
#include
#include
#include
#include "kis_figure_painting_tool_helper.h"
#include
KisToolEllipse::KisToolEllipse(KoCanvasBase * canvas)
: KisToolEllipseBase(canvas, KisToolEllipseBase::PAINT, KisCursor::load("tool_ellipse_cursor.png", 6, 6))
{
setObjectName("tool_ellipse");
setSupportOutline(true);
}
KisToolEllipse::~KisToolEllipse()
{
}
void KisToolEllipse::resetCursorStyle()
{
KisToolEllipseBase::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;
const KisToolShape::ShapeAddInfo info =
shouldAddShape(currentNode());
if (!info.shouldAddShape) {
KisFigurePaintingToolHelper helper(kundo2_i18n("Draw Ellipse"),
image(),
currentNode(),
canvas()->resourceManager(),
strokeStyle(),
fillStyle());
helper.paintEllipse(rect);
} else {
QRectF r = convertToPt(rect);
KoShape* shape = KisShapeToolHelper::createEllipseShape(r);
KoShapeStrokeSP border(new KoShapeStroke(currentStrokeWidth(), currentFgColor().toQColor()));
shape->setStroke(border);
info.markAsSelectionShapeIfNeeded(shape);
addShape(shape);
}
notifyModified();
}
diff --git a/plugins/tools/basictools/kis_tool_ellipse.h b/plugins/tools/basictools/kis_tool_ellipse.h
index 70c83f34cb..f655aa662c 100644
--- a/plugins/tools/basictools/kis_tool_ellipse.h
+++ b/plugins/tools/basictools/kis_tool_ellipse.h
@@ -1,75 +1,75 @@
/*
* kis_tool_ellipse.h - part of Krayon
*
* Copyright (c) 2000 John Califf
* Copyright (c) 2002 Patrick Julien
* Copyright (c) 2004 Clarence Dang
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
#ifndef __KIS_TOOL_ELLIPSE_H__
#define __KIS_TOOL_ELLIPSE_H__
#include "kis_tool_shape.h"
#include "kis_types.h"
#include "KoToolFactoryBase.h"
#include "flake/kis_node_shape.h"
#include
#include
class KoCanvasBase;
class KisToolEllipse : public KisToolEllipseBase
{
Q_OBJECT
public:
KisToolEllipse(KoCanvasBase * canvas);
~KisToolEllipse() override;
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
{
public:
KisToolEllipseFactory()
: KoToolFactoryBase("KritaShape/KisToolEllipse") {
setToolTip(i18n("Ellipse Tool"));
setSection(TOOL_TYPE_SHAPE);
setActivationShapeId(KRITA_TOOL_ACTIVATION_ID);
setIconName(koIconNameCStr("krita_tool_ellipse"));
setPriority(3);
}
~KisToolEllipseFactory() override {}
KoToolBase * createTool(KoCanvasBase *canvas) override {
return new KisToolEllipse(canvas);
}
};
#endif //__KIS_TOOL_ELLIPSE_H__
diff --git a/plugins/tools/basictools/kis_tool_rectangle.cc b/plugins/tools/basictools/kis_tool_rectangle.cc
index d11c5a678a..fadc347dcb 100644
--- a/plugins/tools/basictools/kis_tool_rectangle.cc
+++ b/plugins/tools/basictools/kis_tool_rectangle.cc
@@ -1,89 +1,100 @@
/*
* kis_tool_rectangle.cc - part of Krita
*
* Copyright (c) 2000 John Califf
* Copyright (c) 2002 Patrick Julien
* Copyright (c) 2004 Boudewijn Rempt
* Copyright (c) 2004 Clarence Dang
* Copyright (c) 2009 Lukáš Tvrdý
* Copyright (c) 2010 Cyrille Berger
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
#include "kis_tool_rectangle.h"
#include
#include
#include "KoCanvasBase.h"
#include "kis_shape_tool_helper.h"
#include "kis_figure_painting_tool_helper.h"
#include
#include
KisToolRectangle::KisToolRectangle(KoCanvasBase * canvas)
: KisToolRectangleBase(canvas, KisToolRectangleBase::PAINT, KisCursor::load("tool_rectangle_cursor.png", 6, 6))
{
setSupportOutline(true);
setObjectName("tool_rectangle");
}
KisToolRectangle::~KisToolRectangle()
{
}
void KisToolRectangle::resetCursorStyle()
{
KisToolRectangleBase::resetCursorStyle();
overrideCursorIfNotEditable();
}
-void KisToolRectangle::finishRect(const QRectF &rect)
+void KisToolRectangle::finishRect(const QRectF &rect, qreal roundCornersX, qreal roundCornersY)
{
if (rect.isNull() || !blockUntilOperationsFinished())
return;
const KisToolShape::ShapeAddInfo info =
shouldAddShape(currentNode());
if (!info.shouldAddShape) {
KisFigurePaintingToolHelper helper(kundo2_i18n("Draw Rectangle"),
image(),
currentNode(),
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) {
border = toQShared(new KoShapeStroke(currentStrokeWidth(), currentFgColor().toQColor()));
}
shape->setStroke(border);
info.markAsSelectionShapeIfNeeded(shape);
addShape(shape);
}
notifyModified();
}
diff --git a/plugins/tools/basictools/kis_tool_rectangle.h b/plugins/tools/basictools/kis_tool_rectangle.h
index 754483cd63..5798e8841c 100644
--- a/plugins/tools/basictools/kis_tool_rectangle.h
+++ b/plugins/tools/basictools/kis_tool_rectangle.h
@@ -1,79 +1,79 @@
/*
* kis_tool_rectangle.h - part of KImageShop^WKrayon^WKrita
*
* Copyright (c) 1999 Michael Koch
* Copyright (c) 2002 Patrick Julien
* Copyright (c) 2004 Boudewijn Rempt
* Copyright (c) 2004 Clarence Dang
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
#ifndef __KIS_TOOL_RECTANGLE_H__
#define __KIS_TOOL_RECTANGLE_H__
#include "kis_tool_shape.h"
#include "kis_types.h"
#include "KoToolFactoryBase.h"
#include "flake/kis_node_shape.h"
#include
#include
class QRect;
class KoCanvasBase;
class KisToolRectangle : public KisToolRectangleBase
{
Q_OBJECT
public:
KisToolRectangle(KoCanvasBase * canvas);
~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;
};
class KisToolRectangleFactory : public KoToolFactoryBase
{
public:
KisToolRectangleFactory()
: KoToolFactoryBase("KritaShape/KisToolRectangle") {
setToolTip(i18n("Rectangle Tool"));
setSection(TOOL_TYPE_SHAPE);
setActivationShapeId(KRITA_TOOL_ACTIVATION_ID);
setIconName(koIconNameCStr("krita_tool_rectangle"));
//setShortcut( Qt::Key_F6 );
setPriority(2);
}
~KisToolRectangleFactory() override {}
KoToolBase * createTool(KoCanvasBase *canvas) override {
return new KisToolRectangle(canvas);
}
};
#endif // __KIS_TOOL_RECTANGLE_H__
diff --git a/plugins/tools/selectiontools/kis_tool_select_elliptical.cc b/plugins/tools/selectiontools/kis_tool_select_elliptical.cc
index df26677de9..d925bfe624 100644
--- a/plugins/tools/selectiontools/kis_tool_select_elliptical.cc
+++ b/plugins/tools/selectiontools/kis_tool_select_elliptical.cc
@@ -1,100 +1,103 @@
/*
* kis_tool_select_elliptical.cc -- part of Krita
*
* Copyright (c) 2004 Boudewijn Rempt (boud@valdyas.org)
* Copyright (c) 2007 Sven Langkamp
* Copyright (c) 2015 Michael Abrahams
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
#include "kis_tool_select_elliptical.h"
#include
#include "kis_painter.h"
#include
#include "kis_selection_options.h"
#include "kis_canvas2.h"
#include "kis_pixel_selection.h"
#include "kis_selection_tool_helper.h"
#include "kis_shape_tool_helper.h"
#include "KisViewManager.h"
#include "kis_selection_manager.h"
__KisToolSelectEllipticalLocal::__KisToolSelectEllipticalLocal(KoCanvasBase *canvas)
: KisToolEllipseBase(canvas, KisToolEllipseBase::SELECT,
KisCursor::load("tool_elliptical_selection_cursor.png", 6, 6))
{
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(canvas());
Q_ASSERT(kisCanvas);
KisSelectionToolHelper helper(kisCanvas, kundo2_i18n("Select Ellipse"));
if (helper.tryDeselectCurrentSelection(pixelToView(rect), selectionAction())) {
return;
}
if (selectionMode() == PIXEL_SELECTION) {
KisPixelSelectionSP tmpSel = new KisPixelSelection();
KisPainter painter(tmpSel);
painter.setPaintColor(KoColor(Qt::black, tmpSel->colorSpace()));
painter.setAntiAliasPolygonFill(antiAliasSelection());
painter.setFillStyle(KisPainter::FillStyleForegroundColor);
painter.setStrokeStyle(KisPainter::StrokeStyleNone);
painter.paintEllipse(rect);
QPainterPath cache;
cache.addEllipse(rect);
tmpSel->setOutlineCache(cache);
helper.selectPixelSelection(tmpSel, selectionAction());
} else {
QRectF ptRect = convertToPt(rect);
KoShape* shape = KisShapeToolHelper::createEllipseShape(ptRect);
helper.addSelectionShape(shape);
}
}
KisToolSelectElliptical::KisToolSelectElliptical(KoCanvasBase *canvas):
KisToolSelectEllipticalTemplate(canvas, i18n("Elliptical Selection"))
{
connect(&m_widgetHelper, &KisSelectionToolConfigWidgetHelper::selectionActionChanged,
this, &KisToolSelectElliptical::setSelectionAction);
}
void KisToolSelectElliptical::setSelectionAction(int action)
{
changeSelectionAction(action);
}
QMenu* KisToolSelectElliptical::popupActionsMenu()
{
KisCanvas2 * kisCanvas = dynamic_cast(canvas());
Q_ASSERT(kisCanvas);
return KisSelectionToolHelper::getSelectionContextMenu(kisCanvas);
}
diff --git a/plugins/tools/selectiontools/kis_tool_select_elliptical.h b/plugins/tools/selectiontools/kis_tool_select_elliptical.h
index c2ba6ece97..e06b938d84 100644
--- a/plugins/tools/selectiontools/kis_tool_select_elliptical.h
+++ b/plugins/tools/selectiontools/kis_tool_select_elliptical.h
@@ -1,93 +1,93 @@
/*
* kis_tool_select_elliptical.h - part of Krayon^WKrita
*
* Copyright (c) 2000 John Califf
* Copyright (c) 2002 Patrick Julien
* Copyright (c) 2004 Boudewijn Rempt *
* Copyright (c) 2015 Michael Abrahams
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
#ifndef __KIS_TOOL_SELECT_ELLIPTICAL_H__
#define __KIS_TOOL_SELECT_ELLIPTICAL_H__
#include "KoToolFactoryBase.h"
#include "kis_tool_ellipse_base.h"
#include
#include "kis_selection_tool_config_widget_helper.h"
#include
#include
#include
#include
class __KisToolSelectEllipticalLocal : public KisToolEllipseBase
{
Q_OBJECT
public:
__KisToolSelectEllipticalLocal(KoCanvasBase *canvas);
protected:
virtual SelectionMode selectionMode() const = 0;
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;
};
typedef KisToolSelectBase<__KisToolSelectEllipticalLocal> KisToolSelectEllipticalTemplate;
class KisToolSelectElliptical : public KisToolSelectEllipticalTemplate
{
Q_OBJECT
public:
KisToolSelectElliptical(KoCanvasBase* canvas);
QMenu* popupActionsMenu() override;
public Q_SLOTS:
void setSelectionAction(int);
};
class KisToolSelectEllipticalFactory : public KoToolFactoryBase
{
public:
KisToolSelectEllipticalFactory()
: KoToolFactoryBase("KisToolSelectElliptical")
{
setToolTip(i18n("Elliptical Selection Tool"));
setSection(TOOL_TYPE_SELECTION);
setActivationShapeId(KRITA_TOOL_ACTIVATION_ID);
setIconName(koIconNameCStr("tool_elliptical_selection"));
setShortcut(QKeySequence(Qt::Key_J));
setPriority(1);
}
~KisToolSelectEllipticalFactory() override {}
KoToolBase * createTool(KoCanvasBase *canvas) override {
return new KisToolSelectElliptical(canvas);
}
};
#endif //__KIS_TOOL_SELECT_ELLIPTICAL_H__
diff --git a/plugins/tools/selectiontools/kis_tool_select_rectangular.cc b/plugins/tools/selectiontools/kis_tool_select_rectangular.cc
index e38b9346e0..b6257f83b6 100644
--- a/plugins/tools/selectiontools/kis_tool_select_rectangular.cc
+++ b/plugins/tools/selectiontools/kis_tool_select_rectangular.cc
@@ -1,100 +1,109 @@
/*
* kis_tool_select_rectangular.cc -- part of Krita
*
* Copyright (c) 1999 Michael Koch
* Copyright (c) 2001 John Califf
* Copyright (c) 2002 Patrick Julien
* Copyright (c) 2007 Sven Langkamp
* Copyright (c) 2015 Michael Abrahams
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
#include "kis_tool_select_rectangular.h"
#include "kis_painter.h"
#include
#include "kis_selection_options.h"
#include "kis_canvas2.h"
#include "kis_pixel_selection.h"
#include "kis_selection_tool_helper.h"
#include "kis_shape_tool_helper.h"
#include "KisViewManager.h"
#include "kis_selection_manager.h"
__KisToolSelectRectangularLocal::__KisToolSelectRectangularLocal(KoCanvasBase * canvas)
: KisToolRectangleBase(canvas, KisToolRectangleBase::SELECT,
KisCursor::load("tool_rectangular_selection_cursor.png", 6, 6))
{
setObjectName("tool_select_rectangular");
}
-void __KisToolSelectRectangularLocal::finishRect(const QRectF& rect)
+void __KisToolSelectRectangularLocal::finishRect(const QRectF& rect, qreal roundCornersX, qreal roundCornersY)
{
KisCanvas2 * kisCanvas = dynamic_cast(canvas());
if (!kisCanvas)
return;
KisSelectionToolHelper helper(kisCanvas, kundo2_i18n("Select Rectangle"));
QRect rc(rect.normalized().toRect());
if (helper.tryDeselectCurrentSelection(pixelToView(rc), selectionAction())) {
return;
}
if (helper.canShortcutToNoop(rc, selectionAction())) {
return;
}
if (selectionMode() == PIXEL_SELECTION) {
if (rc.isValid()) {
KisPixelSelectionSP tmpSel = KisPixelSelectionSP(new KisPixelSelection());
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));
}
}
KisToolSelectRectangular::KisToolSelectRectangular(KoCanvasBase *canvas):
KisToolSelectBase<__KisToolSelectRectangularLocal>(canvas, i18n("Rectangular Selection"))
{
connect(&m_widgetHelper, &KisSelectionToolConfigWidgetHelper::selectionActionChanged,
this, &KisToolSelectRectangular::setSelectionAction);
}
void KisToolSelectRectangular::setSelectionAction(int action)
{
changeSelectionAction(action);
}
QMenu* KisToolSelectRectangular::popupActionsMenu()
{
KisCanvas2 * kisCanvas = dynamic_cast(canvas());
Q_ASSERT(kisCanvas);
return KisSelectionToolHelper::getSelectionContextMenu(kisCanvas);
}
diff --git a/plugins/tools/selectiontools/kis_tool_select_rectangular.h b/plugins/tools/selectiontools/kis_tool_select_rectangular.h
index ecb33d5e3b..4f3eda0cb2 100644
--- a/plugins/tools/selectiontools/kis_tool_select_rectangular.h
+++ b/plugins/tools/selectiontools/kis_tool_select_rectangular.h
@@ -1,86 +1,86 @@
/*
* kis_tool_select_rectangular.h - part of Krita
*
* Copyright (c) 1999 Michael Koch
* 2002 Patrick Julien
*
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
#ifndef KIS_TOOL_SELECT_RECTANGULAR_H_
#define KIS_TOOL_SELECT_RECTANGULAR_H_
#include "KoToolFactoryBase.h"
#include "kis_tool_rectangle_base.h"
#include
#include "kis_selection_tool_config_widget_helper.h"
#include
#include
class __KisToolSelectRectangularLocal : public KisToolRectangleBase
{
Q_OBJECT
public:
__KisToolSelectRectangularLocal(KoCanvasBase * canvas);
protected:
virtual SelectionMode selectionMode() const = 0;
virtual SelectionAction selectionAction() const = 0;
private:
- void finishRect(const QRectF& rect) override;
+ void finishRect(const QRectF& rect, qreal roundCornersX, qreal roundCornersY) override;
};
class KisToolSelectRectangular : public KisToolSelectBase<__KisToolSelectRectangularLocal>
{
Q_OBJECT
public:
KisToolSelectRectangular(KoCanvasBase* canvas);
QMenu* popupActionsMenu() override;
public Q_SLOTS:
void setSelectionAction(int);
};
class KisToolSelectRectangularFactory : public KoToolFactoryBase
{
public:
KisToolSelectRectangularFactory()
: KoToolFactoryBase("KisToolSelectRectangular")
{
setToolTip(i18n("Rectangular Selection Tool"));
setSection(TOOL_TYPE_SELECTION);
setActivationShapeId(KRITA_TOOL_ACTIVATION_ID);
setIconName(koIconNameCStr("tool_rect_selection"));
setShortcut(QKeySequence(Qt::CTRL + Qt::Key_R));
setPriority(0);
}
~KisToolSelectRectangularFactory() override {}
KoToolBase * createTool(KoCanvasBase *canvas) override {
return new KisToolSelectRectangular(canvas);
}
};
#endif // KIS_TOOL_SELECT_RECTANGULAR_H_