Commit a0eea794 authored by Dmitry Kazakov's avatar Dmitry Kazakov
Browse files

Major cleanup in KisToolFreehand

1) Extracted all the painting stuff from the KisToolFreehand into
   a separate class
2) Removed airbrushing duplications from KisToolBrush and KisToolDyna
   (now airbrushing is in KisToolFreehandHelper)
3) Removed some old unused code
parent 18ac7e53
......@@ -19,103 +19,29 @@
*/
#include "kis_tool_brush.h"
#include <QEvent>
#include <QLabel>
#include <QLayout>
#include <QWidget>
#include <QTimer>
#include <QPushButton>
#include <QPainter>
#include <QRect>
#include <QCheckBox>
#include <QGridLayout>
#include <QComboBox>
#include <QSizePolicy>
#include <kis_debug.h>
#include <klocale.h>
#include "KoPointerEvent.h"
#include "KoCanvasBase.h"
#include "kis_slider_spin_box.h"
#include "kis_config.h"
#include "kis_paintop_preset.h"
#include "kis_paintop_registry.h"
#include "kis_cursor.h"
#include "kis_painter.h"
#include "kis_slider_spin_box.h"
#include "kis_paint_device.h"
#include "kis_layer.h"
#define MAXIMUM_SMOOTHNESS 1000
#define MAXIMUM_MAGNETISM 1000
const int MAXIMUM_RATE = 1000; // 1 second for rate? Just quick test
KisToolBrush::KisToolBrush(KoCanvasBase * canvas)
: KisToolFreehand(canvas, KisCursor::load("tool_freehand_cursor.png", 5, 5), i18nc("(qtundo-format)", "Brush"))
{
setObjectName("tool_brush");
m_isAirbrushing = false;
m_rate = 100;
m_timer = new QTimer(this);
Q_CHECK_PTR(m_timer);
connect(m_timer, SIGNAL(timeout()), this, SLOT(timeoutPaint()));
}
KisToolBrush::~KisToolBrush()
{
delete m_timer;
m_timer = 0;
}
void KisToolBrush::timeoutPaint()
{
Q_ASSERT(currentPaintOpPreset()->settings()->isAirbrushing());
if (currentImage() && m_painter) {
paintAt(m_previousPaintInformation);
currentNode()->setDirty(m_painter->takeDirtyRegion());
}
}
void KisToolBrush::initPaint(KoPointerEvent *e)
{
KisToolFreehand::initPaint(e);
m_rate = currentPaintOpPreset()->settings()->rate();
m_isAirbrushing = currentPaintOpPreset()->settings()->isAirbrushing();
if (!m_painter) {
warnKrita << "Didn't create a painter! Something is wrong!";
return;
}
if (m_isAirbrushing) {
m_timer->start(m_rate);
}
}
void KisToolBrush::endPaint()
{
m_timer->stop();
KisToolFreehand::endPaint();
}
void KisToolBrush::mouseMoveEvent(KoPointerEvent *e)
{
KisToolFreehand::mouseMoveEvent(e);
if (m_painter && m_painter->paintOp() && m_isAirbrushing) {
m_timer->start(m_rate);
}
}
void KisToolBrush::slotSetSmoothness(int smoothness)
{
m_smoothness = smoothness / (double)MAXIMUM_SMOOTHNESS;
......
......@@ -25,7 +25,6 @@
#include <flake/kis_node_shape.h>
class QTimer;
class QCheckBox;
class QComboBox;
class QGridLayout;
......@@ -43,24 +42,11 @@ public:
QWidget * createOptionWidget();
virtual void mouseMoveEvent(KoPointerEvent *e);
protected:
virtual void initPaint(KoPointerEvent *e);
virtual void endPaint();
private slots:
void timeoutPaint();
void slotSetSmoothness(int smoothness);
void slotSetMagnetism(int magnetism);
private:
bool m_isAirbrushing;
qint32 m_rate;
QTimer *m_timer;
QGridLayout *m_optionLayout;
QCheckBox *m_chkSmooth;
QCheckBox *m_chkAssistant;
......
......@@ -19,36 +19,16 @@
*/
#include "kis_tool_dyna.h"
#include <QEvent>
#include <QLabel>
#include <QLayout>
#include <QWidget>
#include <QTimer>
#include <QPushButton>
#include <QPainter>
#include <QRect>
#include <QCheckBox>
#include <QGridLayout>
#include <QSlider>
#include <QComboBox>
#include <QDoubleSpinBox>
#include <kis_debug.h>
#include <klocale.h>
#include "KoPointerEvent.h"
#include "KoCanvasBase.h"
#include "kis_config.h"
#include "kis_paintop_preset.h"
#include "kis_paintop_registry.h"
#include "kis_paint_information.h"
#include "kis_cursor.h"
#include "kis_painter.h"
#include "kis_paint_device.h"
#include "kis_layer.h"
#include <QDoubleSpinBox>
#define MAXIMUM_SMOOTHNESS 1000
#define MAXIMUM_MAGNETISM 1000
......@@ -58,11 +38,6 @@ KisToolDyna::KisToolDyna(KoCanvasBase * canvas)
{
setObjectName("tool_dyna");
m_rate = 200; // Conveniently hardcoded for now
m_timer = new QTimer(this);
Q_CHECK_PTR(m_timer);
connect(m_timer, SIGNAL(timeout()), this, SLOT(timeoutPaint()));
initDyna();
}
......@@ -77,57 +52,23 @@ void KisToolDyna::initDyna()
m_xangle = 0.60;
m_yangle = 0.20;
m_widthRange = 0.05;
m_previousPressure = 0.5;
}
KisToolDyna::~KisToolDyna()
{
delete m_timer;
m_timer = 0;
}
void KisToolDyna::timeoutPaint()
{
Q_ASSERT(currentPaintOpPreset()->settings()->isAirbrushing());
if (currentImage() && m_painter) {
paintAt(m_previousPaintInformation);
currentNode()->setDirty(m_painter->takeDirtyRegion());
}
}
void KisToolDyna::initPaint(KoPointerEvent *e)
void KisToolDyna::initStroke(KoPointerEvent *event)
{
m_rate = currentPaintOpPreset()->settings()->rate();
QRectF imageSize = QRectF(QPointF(0.0,0.0),currentImage()->size());
QRectF documentSize = currentImage()->pixelToDocument(imageSize);
m_surfaceWidth = documentSize.width();
m_surfaceHeight = documentSize.height();
setMousePosition(e->point);
setMousePosition(event->point);
m_mouse.init(m_mousePos.x(), m_mousePos.y());
KisToolFreehand::initPaint(e);
if (!m_painter) {
warnKrita << "Didn't create a painter! Something is wrong!";
return;
}
if (currentPaintOpPreset()->settings()->isAirbrushing()) {
m_timer->start(m_rate);
}
}
void KisToolDyna::endPaint()
{
m_timer->stop();
KisToolFreehand::endPaint();
KisToolFreehand::initStroke(event);
}
void KisToolDyna::mousePressEvent(KoPointerEvent *e)
......@@ -154,10 +95,6 @@ void KisToolDyna::mouseMoveEvent(KoPointerEvent *e)
KoPointerEvent newEvent = filterEvent(e);
KisToolFreehand::mouseMoveEvent(&newEvent);
}
if (m_painter && m_painter->paintOp() && currentPaintOpPreset()->settings()->isAirbrushing()) {
m_timer->start(m_rate);
}
}
// dyna algorithm
......
......@@ -26,7 +26,6 @@
#include <flake/kis_node_shape.h>
class QTimer;
class QCheckBox;
class QComboBox;
class QGridLayout;
......@@ -89,14 +88,10 @@ public:
virtual void mouseMoveEvent(KoPointerEvent *e);
protected:
virtual void initPaint(KoPointerEvent *e);
virtual void endPaint();
virtual void initStroke(KoPointerEvent *event);
private slots:
void timeoutPaint();
void slotSetDynaWidth(double width);
void slotSetMass(double mass);
void slotSetDrag(double drag);
......@@ -106,8 +101,6 @@ private slots:
void slotSetFixedAngle(bool fixedAngle);
private:
qint32 m_rate;
QTimer * m_timer;
QGridLayout* m_optionLayout;
// dyna gui
......@@ -119,15 +112,12 @@ private:
QDoubleSpinBox * m_yAngleSPBox;
QDoubleSpinBox * m_widthRangeSPBox;
qreal m_previousPressure;
// dyna algorithm
QVector<QPointF> m_prevPosition;
qreal m_odelx, m_odely;
// mouse info
QPointF m_mousePos;
bool first;
qreal m_surfaceWidth;
qreal m_surfaceHeight;
......
......@@ -124,6 +124,8 @@ set(kritaui_LIB_SRCS
tool/kis_shape_tool_helper.cpp
tool/kis_tool.cc
tool/kis_tool_freehand.cc
tool/kis_painting_information_builder.cpp
tool/kis_tool_freehand_helper.cpp
tool/kis_tool_paint.cc
tool/kis_tool_shape.cc
tool/kis_tool_select_base.cpp
......
/*
* Copyright (c) 2011 Dmitry Kazakov <dimula73@gmail.com>
*
* 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_painting_information_builder.h"
#include <KoPointerEvent.h>
#include "kis_config.h"
#include "kis_config_notifier.h"
#include "kis_cubic_curve.h"
/***********************************************************************/
/* KisPaintingInformationBuilder */
/***********************************************************************/
const int KisPaintingInformationBuilder::LEVEL_OF_PRESSURE_RESOLUTION = 1024;
KisPaintingInformationBuilder::KisPaintingInformationBuilder()
{
connect(KisConfigNotifier::instance(), SIGNAL(configChanged()),
SLOT(updateSettings()));
updateSettings();
}
void KisPaintingInformationBuilder::updateSettings()
{
KisConfig cfg;
KisCubicCurve curve;
curve.fromString(cfg.pressureTabletCurve());
m_pressureSamples = curve.floatTransfer(LEVEL_OF_PRESSURE_RESOLUTION + 1);
}
KisPaintInformation
KisPaintingInformationBuilder::startStroke(KoPointerEvent *event,
int timeElapsed)
{
m_startPoint = event->point;
QPointF adjusted = adjustDocumentPoint(event->point);
return createPaintingInformation(event, QPointF(), timeElapsed);
}
KisPaintInformation
KisPaintingInformationBuilder::continueStroke(KoPointerEvent *event,
const QPointF &prevImagePoint,
int timeElapsed)
{
QPointF adjusted = adjustDocumentPoint(event->point);
QPointF imagePoint = documentToImage(adjusted);
QPointF dragVector = imagePoint - prevImagePoint;
return createPaintingInformation(event, dragVector, timeElapsed);
}
QPointF KisPaintingInformationBuilder::startPoint() const
{
return m_startPoint;
}
QPointF KisPaintingInformationBuilder::adjustDocumentPoint(const QPointF &point)
{
return point;
}
QPointF KisPaintingInformationBuilder::documentToImage(const QPointF &point)
{
return point;
}
qreal KisPaintingInformationBuilder::calculatePerspective(const QPointF &documentPoint)
{
Q_UNUSED(documentPoint);
return 1.0;
}
KisPaintInformation KisPaintingInformationBuilder::createPaintingInformation(KoPointerEvent *event,
const QPointF &dragVector,
int timeElapsed)
{
QPointF adjusted = adjustDocumentPoint(event->point);
QPointF imagePoint = documentToImage(adjusted);
qreal perspective = calculatePerspective(adjusted);
return KisPaintInformation(imagePoint,
pressureToCurve(event->pressure()),
event->xTilt(), event->yTilt(),
toKisVector2D(dragVector),
event->rotation(),
event->tangentialPressure(),
perspective,
timeElapsed);
}
qreal KisPaintingInformationBuilder::pressureToCurve(qreal pressure)
{
return m_pressureSamples.at(qRound(pressure * LEVEL_OF_PRESSURE_RESOLUTION));
}
/***********************************************************************/
/* KisToolPaintingInformationBuilder */
/***********************************************************************/
#include "kis_tool_freehand.h"
KisToolPaintingInformationBuilder::KisToolPaintingInformationBuilder(KisToolFreehand *tool)
: m_tool(tool)
{
}
QPointF KisToolPaintingInformationBuilder::adjustDocumentPoint(const QPointF &point)
{
return m_tool->adjustPosition(point, startPoint());
}
QPointF KisToolPaintingInformationBuilder::documentToImage(const QPointF &point)
{
return m_tool->convertToPixelCoord(point);
}
qreal KisToolPaintingInformationBuilder::calculatePerspective(const QPointF &documentPoint)
{
return m_tool->calculatePerspective(documentPoint);
}
/*
* Copyright (c) 2011 Dmitry Kazakov <dimula73@gmail.com>
*
* 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_PAINTING_INFORMATION_BUILDER_H
#define __KIS_PAINTING_INFORMATION_BUILDER_H
#include <QObject>
#include <QVector>
#include "kis_types.h"
#include "krita_export.h"
#include "kis_paint_information.h"
class KoPointerEvent;
class KisToolFreehand;
class KRITAUI_EXPORT KisPaintingInformationBuilder : public QObject
{
Q_OBJECT
public:
KisPaintingInformationBuilder();
KisPaintInformation startStroke(KoPointerEvent *event, int timeElapsed);
KisPaintInformation continueStroke(KoPointerEvent *event,
const QPointF &prevImagePoint,
int timeElapsed);
QPointF startPoint() const;
protected slots:
void updateSettings();
protected:
virtual QPointF adjustDocumentPoint(const QPointF &point);
virtual QPointF documentToImage(const QPointF &point);
virtual qreal calculatePerspective(const QPointF &documentPoint);
private:
KisPaintInformation createPaintingInformation(KoPointerEvent *event,
const QPointF &dragVector,
int timeElapsed);
/**
* Defines how many descret samples are stored in a precomputed array
* of different pressures.
*/
static const int LEVEL_OF_PRESSURE_RESOLUTION;
qreal pressureToCurve(qreal pressure);
private:
QVector<qreal> m_pressureSamples;
QPointF m_startPoint;
};
class KRITAUI_EXPORT KisToolPaintingInformationBuilder : public KisPaintingInformationBuilder
{
Q_OBJECT
public:
KisToolPaintingInformationBuilder(KisToolFreehand *tool);
protected:
virtual QPointF adjustDocumentPoint(const QPointF &point);
virtual QPointF documentToImage(const QPointF &point);
virtual qreal calculatePerspective(const QPointF &documentPoint);
private:
KisToolFreehand *m_tool;
};
#endif /* __KIS_PAINTING_INFORMATION_BUILDER_H */
......@@ -137,6 +137,21 @@ KisNodeSP KisResourcesSnapshot::currentNode() const
return m_d->currentNode;
}
bool KisResourcesSnapshot::needsIndirectPainting() const
{
return !m_d->currentPaintOpPreset->settings()->paintIncremental();
}
bool KisResourcesSnapshot::needsAirbrushing() const
{
return m_d->currentPaintOpPreset->settings()->isAirbrushing();
}
int KisResourcesSnapshot::airbrushingRate() const
{
return m_d->currentPaintOpPreset->settings()->rate();
}
quint8 KisResourcesSnapshot::opacity() const
{
return m_d->opacity;
......
......@@ -42,6 +42,11 @@ public:
KisPostExecutionUndoAdapter* postExecutionUndoAdapter() const;
void setCurrentNode(KisNodeSP node);
KisNodeSP currentNode() const;
bool needsIndirectPainting() const;
bool needsAirbrushing() const;
int airbrushingRate() const;
quint8 opacity() const;
const KoCompositeOp* compositeOp() const;
......
......@@ -57,8 +57,12 @@
#include <kis_painting_assistants_manager.h>
#include <kis_3d_object_model.h>
#include "kis_painting_information_builder.h"
#include "kis_tool_freehand_helper.h"
#include "strokes/freehand_stroke.h"
#define ENABLE_RECORDING
static const int HIDE_OUTLINE_TIMEOUT = 800; // ms
......@@ -98,10 +102,16 @@ KisToolFreehand::KisToolFreehand(KoCanvasBase * canvas, const QCursor & cursor,
m_strokeTimer.setSingleShot(true);
connect(&m_strokeTimer, SIGNAL(timeout()), this, SLOT(finishStroke()));
m_infoBuilder = new KisToolPaintingInformationBuilder(this);
m_helper = new KisToolFreehandHelper(m_infoBuilder);
}
KisToolFreehand::~KisToolFreehand()