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
kis_int_parse_spin_box.h
KisDoubleParseSpinBox QDoubleSpinBox
kis_double_parse_spin_box.h
+ + KoAspectButton + QWidget +
KoAspectButton.h
+ 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_