kis_tool_transform.h 8.95 KB
Newer Older
1 2 3 4
/*
 *  kis_tool_transform.h - part of Krita
 *
 *  Copyright (c) 2004 Boudewijn Rempt <boud@valdyas.org>
C. Boemann's avatar
C. Boemann committed
5
 *  Copyright (c) 2005 C. Boemann <cbo@boemann.dk>
6
 *  Copyright (c) 2010 Marc Pegon <pe.marc@free.fr>
7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25
 *
 *  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_TRANSFORM_H_
#define KIS_TOOL_TRANSFORM_H_

Friedrich W. H. Kossebau's avatar
Friedrich W. H. Kossebau committed
26 27
#include <KoIcon.h>

28 29
#include <QPoint>
#include <QPointF>
30
#include <QVector2D>
31
#include <QVector3D>
32
#include <QButtonGroup>
33

34
#include <kstandarddirs.h>
35

36 37
#include <KoInteractionTool.h>
#include <KoToolFactoryBase.h>
38
#include <KoUpdater.h>
39

40
#include <kis_shape_selection.h>
41 42 43 44 45
#include <kis_undo_adapter.h>
#include <kis_types.h>
#include <flake/kis_node_shape.h>
#include <kis_tool.h>

46
#include "tool_transform_args.h"
47
#include "tool_transform_changes_tracker.h"
48 49
#include "kis_tool_transform_config_widget.h"
#include "transform_transaction_properties.h"
50

51

52
class KoID;
53

54
class KisFilterStrategy;
55
class KisCanvas2;
56

57
class QTouchEvent;
58 59
class KisWarpTransformStrategy;
class KisFreeTransformStrategy;
60

61 62
/**
 * Transform tool
63 64 65 66 67 68 69
 * The tool offers two different modes : Free Transform and Warp
 * - Free Transform mode allows the user to translate, scale, shear, rotate
 * and apply a perspective transformation to a selection or the whole
 * canvas.
 * - Warp mode allows the user to warp the selection of the canvas
 * by grabbing and moving control points placed on the image.
 *   The user can either work with default control points, like a grid
70
 *   whose density can be modified, or place the control points manually.
71 72 73
 * The modifications made on the selected pixels are applied only when
 * the user clicks the Apply button : the semi-transparent image displayed
 * until the user click that button is only a preview.
74
 */
75
class KisToolTransform : public KisTool
76 77 78 79
{

    Q_OBJECT

80 81
    Q_PROPERTY(bool isActive READ isActive NOTIFY isActiveChanged)

82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102
    Q_PROPERTY(TransformToolMode transformMode READ transformMode WRITE setTransformMode NOTIFY transformModeChanged)

    Q_PROPERTY(double translateX READ translateX WRITE setTranslateX NOTIFY freeTransformChanged)
    Q_PROPERTY(double translateY READ translateY WRITE setTranslateY NOTIFY freeTransformChanged)

    Q_PROPERTY(double rotateX READ rotateX WRITE setRotateX NOTIFY freeTransformChanged)
    Q_PROPERTY(double rotateY READ rotateY WRITE setRotateY NOTIFY freeTransformChanged)
    Q_PROPERTY(double rotateZ READ rotateZ WRITE setRotateZ NOTIFY freeTransformChanged)

    Q_PROPERTY(double scaleX READ scaleX WRITE setScaleX NOTIFY freeTransformChanged)
    Q_PROPERTY(double scaleY READ scaleY WRITE setScaleY NOTIFY freeTransformChanged)

    Q_PROPERTY(double shearX READ shearX WRITE setShearX NOTIFY freeTransformChanged)
    Q_PROPERTY(double shearY READ shearY WRITE setShearY NOTIFY freeTransformChanged)

    Q_PROPERTY(WarpType warpType READ warpType WRITE setWarpType NOTIFY warpTransformChanged)
    Q_PROPERTY(double warpFlexibility READ warpFlexibility WRITE setWarpFlexibility NOTIFY warpTransformChanged)
    Q_PROPERTY(int warpPointDensity READ warpPointDensity WRITE setWarpPointDensity NOTIFY warpTransformChanged)



103
public:
104 105 106 107 108 109 110 111 112 113 114 115 116
    enum TransformToolMode {
        FreeTransformMode,
        WarpTransformMode
    };
    Q_ENUMS(TransformToolMode)

    enum WarpType {
        RigidWarpType,
        AffineWarpType,
        SimilitudeWarpType
    };
    Q_ENUMS(WarpType)

117 118 119 120 121 122 123 124
    KisToolTransform(KoCanvasBase * canvas);
    virtual ~KisToolTransform();

    virtual QWidget* createOptionWidget();

    virtual void mousePressEvent(KoPointerEvent *e);
    virtual void mouseMoveEvent(KoPointerEvent *e);
    virtual void mouseReleaseEvent(KoPointerEvent *e);
125
    virtual void touchEvent(QTouchEvent *event);
126

127
    void paint(QPainter& gc, const KoViewConverter &converter);
128

129
    bool isActive() const;
130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150
    TransformToolMode transformMode() const;

    double translateX() const;
    double translateY() const;

    double rotateX() const;
    double rotateY() const;
    double rotateZ() const;

    double scaleX() const;
    double scaleY() const;

    double shearX() const;
    double shearY() const;

    WarpType warpType() const;
    double warpFlexibility() const;
    int warpPointDensity() const;

    bool wantsTouch() const { return true; }

151 152 153
public slots:
    virtual void activate(ToolActivation toolActivation, const QSet<KoShape*> &shapes);
    virtual void deactivate();
154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177
    // Applies the current transformation to the original paint device and commits it to the undo stack
    void applyTransform();

    void setTransformMode( KisToolTransform::TransformToolMode newMode );

    void setTranslateX(double translateX);
    void setTranslateY(double translateY);

    void setRotateX(double rotation);
    void setRotateY(double rotation);
    void setRotateZ(double rotation);

    void setScaleX(double scaleX);
    void setScaleY(double scaleY);

    void setShearX(double shearX);
    void setShearY(double shearY);

    void setWarpType(WarpType type);
    void setWarpFlexibility(double flexibility);
    void setWarpPointDensity(int density);

Q_SIGNALS:
    void transformModeChanged();
178
    void isActiveChanged();
179 180
    void freeTransformChanged();
    void warpTransformChanged();
181

182
public Q_SLOTS:
183
    void requestUndoDuringStroke();
184 185
    void requestStrokeEnd();
    void requestStrokeCancellation();
186 187 188
    void canvasUpdateRequested();
    void resetRotationCenterButtonsRequested();
    void imageTooBigRequested(bool value);
189 190

private:
191 192 193
    void clearDevices(KisNodeSP node, bool recursive);
    void transformDevices(KisNodeSP node, bool recursive);

194 195 196 197
    void startStroke(ToolTransformArgs::TransformMode mode);
    void endStroke();
    void cancelStroke();

198
private:
199 200
    void outlineChanged();
    // Sets the cursor according to mouse position (doesn't take shearing into account well yet)
201
    void setFunctionalCursor();
202
    // Sets m_function according to mouse position and modifier
203
    void setTransformFunction(QPointF mousePos, Qt::KeyboardModifiers modifiers);
204

205 206
    void commitChanges();

207 208
    // Updated the widget according to m_currentArgs
    void updateOptionWidget();
209

210 211
    void initTransformMode(ToolTransformArgs::TransformMode mode);

212
    void initThumbnailImage(KisPaintDeviceSP previewDevice);
213
    void updateSelectionPath();
214
    void updateApplyResetAvailability();
215 216

private:
217
    ToolTransformArgs m_currentArgs;
218

219
    bool m_actuallyMoveWhileSelected; // true <=> selection has been moved while clicked
220 221

    QTransform m_transform; // transformation to apply on origImg
222
    KisPaintDeviceSP m_selectedPortionCache;
223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242

    struct StrokeData {
        StrokeData() {}
        StrokeData(KisStrokeId strokeId) : m_strokeId(strokeId) {}

        void clear() {
            m_strokeId.clear();
            m_clearedNodes.clear();
        }

        const KisStrokeId strokeId() const { return m_strokeId; }
        void addClearedNode(KisNodeSP node) { m_clearedNodes.append(node); }
        const QVector<KisNodeWSP>& clearedNodes() const { return m_clearedNodes; }

    private:
        KisStrokeId m_strokeId;
        QVector<KisNodeWSP> m_clearedNodes;
    };
    StrokeData m_strokeData;

243
    bool m_workRecursively;
244 245 246

    QPainterPath m_selectionPath; // original (unscaled) selection outline, used for painting decorations

247
    KisToolTransformConfigWidget *m_optionsWidget;
248
    KisCanvas2 *m_canvas;
249

250 251
    bool m_isActive;

252
    TransformTransactionProperties m_transaction;
253
    TransformChangesTracker m_changesTracker;
254

255 256
    QScopedPointer<KisWarpTransformStrategy> m_warpStrategy;
    QScopedPointer<KisFreeTransformStrategy> m_freeStrategy;
257

258
private slots:
259
    void slotTrackerChangedConfig();
260
    void slotUiChangedConfig();
261 262
    void slotApplyTransform();
    void slotResetTransform();
263
    void slotRestartTransform();
264
    void slotEditingFinished();
265 266 267 268 269 270
};

class KisToolTransformFactory : public KoToolFactoryBase
{
public:

271 272
    KisToolTransformFactory(const QStringList&)
            : KoToolFactoryBase("KisToolTransform") {
273 274
        setToolTip(i18n("Transform a layer or a selection"));
        setToolType(TOOL_TYPE_TRANSFORM);
Friedrich W. H. Kossebau's avatar
Friedrich W. H. Kossebau committed
275
        setIconName(koIconNameCStr("krita_tool_transform"));
276
        setShortcut(KShortcut( QKeySequence(Qt::CTRL + Qt::Key_T) ));
277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292
        setPriority(11);
        setActivationShapeId(KRITA_TOOL_ACTIVATION_ID);
    }

    virtual ~KisToolTransformFactory() {}

    virtual KoToolBase * createTool(KoCanvasBase *canvas) {
        return new KisToolTransform(canvas);
    }

};



#endif // KIS_TOOL_TRANSFORM_H_