[prev in list] [next in list] [prev in thread] [next in thread] 

List:       kde-kimageshop
Subject:    Re: [calligra/krita-new-move-tool-kazakov] krita: Made the move tool iterational
From:       Boudewijn Rempt <boud () valdyas ! org>
Date:       2012-11-09 8:19:34
Message-ID: 201211090919.34144.boud () valdyas ! org
[Download RAW message or body]

I'm going to test this now, but because the http://git.reviewboard.kde.org/r/107205/ \
is part of it, we should also discuss it on calligra-devel. Please also find the bug \
numbers for the bugs that you refert to -- because that helps the discussion in the \
wider calligra community.,

On Wednesday 07 November 2012 Nov, Dmitry Kazakov wrote:
> Git commit 40bdd4ab49f58ca46ff8c275878556572116c566 by Dmitry Kazakov.
> Committed on 07/11/2012 at 14:34.
> Pushed by dkazakov into branch 'krita-new-move-tool-kazakov'.
> 
> Made the move tool iterational
> 
> Now the tool does not create new layers and does not create
> numerous undo commands. It works in an iterational way: you move
> the node (or selection) as many times as you wish. After the moving
> done and you switch the tool (or apply any other action) the move
> stroke will be finished and added to your undo history.
> 
> Please test it in 'krita-new-move-tool-kazakov' branch.
> 
> BUG:298584
> CCMAIL:kimageshop@kde.org
> 
> M  +30   -0    krita/image/kis_image.cc
> M  +43   -0    krita/image/kis_image.h
> M  +8    -0    krita/image/kis_stroke_strategy_undo_command_based.cpp
> M  +6    -1    krita/image/kis_stroke_strategy_undo_command_based.h
> M  +1    -0    krita/plugins/tools/defaulttools/CMakeLists.txt
> M  +63   -110  krita/plugins/tools/defaulttools/kis_tool_move.cc
> M  +5    -1    krita/plugins/tools/defaulttools/kis_tool_move.h
> A  +132  -0    krita/plugins/tools/defaulttools/strokes/move_selection_stroke_strategy.cpp \
> [License: GPL (v2+)] A  +49   -0    \
> krita/plugins/tools/defaulttools/strokes/move_selection_stroke_strategy.h     \
> [License: GPL (v2+)] M  +2    -0    krita/ui/kis_doc2_p.h
> M  +8    -0    krita/ui/kis_filter_handler.cc
> M  +12   -0    krita/ui/tool/kis_tool.cc
> M  +14   -0    krita/ui/tool/kis_tool.h
> 
> http://commits.kde.org/calligra/40bdd4ab49f58ca46ff8c275878556572116c566
> 
> diff --git a/krita/image/kis_image.cc b/krita/image/kis_image.cc
> index 0336f01..077d638 100644
> --- a/krita/image/kis_image.cc
> +++ b/krita/image/kis_image.cc
> @@ -149,6 +149,11 @@ KisImage::~KisImage()
> dbgImage << "deleting kisimage" << objectName();
> 
> /**
> +     * Request the tools to end currently running strokes
> +     */
> +    waitForDone();
> +
> +    /**
> * First delete the nodes, while strokes
> * and undo are still alive
> */
> @@ -334,6 +339,8 @@ bool KisImage::locked() const
> void KisImage::barrierLock()
> {
> if (!locked()) {
> +        requestStrokeEnd();
> +
> if (m_d->scheduler) {
> m_d->scheduler->barrierLock();
> }
> @@ -366,6 +373,8 @@ bool KisImage::tryBarrierLock()
> void KisImage::lock()
> {
> if (!locked()) {
> +        requestStrokeEnd();
> +
> if (m_d->scheduler) {
> m_d->scheduler->lock();
> }
> @@ -1321,6 +1330,8 @@ KisImageSignalRouter* KisImage::signalRouter()
> 
> void KisImage::waitForDone()
> {
> +    requestStrokeEnd();
> +
> if (m_d->scheduler) {
> m_d->scheduler->waitForDone();
> }
> @@ -1328,6 +1339,15 @@ void KisImage::waitForDone()
> 
> KisStrokeId KisImage::startStroke(KisStrokeStrategy *strokeStrategy)
> {
> +    /**
> +     * Ask open strokes to end gracefully. All the strokes clients
> +     * (including the one calling this method right now) will get
> +     * a notification that they should probably end their strokes.
> +     * However this is purely their choice whether to end a stroke
> +     * or not.
> +     */
> +    requestStrokeEnd();
> +
> KisStrokeId id;
> 
> if (m_d->scheduler) {
> @@ -1360,6 +1380,16 @@ bool KisImage::cancelStroke(KisStrokeId id)
> return result;
> }
> 
> +void KisImage::requestStrokeCancellation()
> +{
> +    emit sigStrokeCancellationRequested();
> +}
> +
> +void KisImage::requestStrokeEnd()
> +{
> +    emit sigStrokeEndRequested();
> +}
> +
> void KisImage::refreshGraph(KisNodeSP root)
> {
> refreshGraph(root, bounds(), bounds());
> diff --git a/krita/image/kis_image.h b/krita/image/kis_image.h
> index ebd27a7..e2601cb 100644
> --- a/krita/image/kis_image.h
> +++ b/krita/image/kis_image.h
> @@ -576,6 +576,31 @@ signals:
> */
> void sigLayersChangedAsync();
> 
> +    /**
> +     * Emitted when the UI has requested the cancellation of
> +     * the stroke. The point is, we cannot cancel the stroke
> +     * without its creator knowing about it (which most probably
> +     * cause a crash), so we just forward this request from the UI
> +     * to the creator of the stroke.
> +     *
> +     * If your tool supports cancelling of its work in the middle
> +     * of operation, just listen to this signal and cancel
> +     * the stroke when it comes
> +     */
> +    void sigStrokeCancellationRequested();
> +
> +    /**
> +     * Emitted when the image decides that the stroke should better
> +     * be ended. The point is, we cannot just end the stroke
> +     * without its creator knowing about it (which most probably
> +     * cause a crash), so we just forward this request from the UI
> +     * to the creator of the stroke.
> +     *
> +     * If your tool supports long  strokes that may involve multiple
> +     * mouse actions in one stroke, just listen to this signal and
> +     * end the stroke when it comes.
> +     */
> +    void sigStrokeEndRequested();
> 
> public slots:
> KisCompositeProgressProxy* compositeProgressProxy();
> @@ -606,7 +631,25 @@ public slots:
> void refreshGraph(KisNodeSP root, const QRect& rc, const QRect &cropRect);
> void initialRefreshGraph();
> 
> +    /**
> +     * This method is be called by the UI (*not* by the creator
> +     * of the stroke) when it thinks current stroke should be
> +     * cancelled. If the creator of the stroke supports cancelling
> +     * of the stroke, it will be notified about the request and
> +     * the stroke will be cancelled
> +     */
> +    void requestStrokeCancellation();
> +
> private:
> +    /**
> +     * This method is called when image decides that the sroke
> +     * should be ended. If the creator of the stroke supports it,
> +     * it will be notified and the stroke will be cancelled
> +     */
> +    void requestStrokeEnd();
> +
> +private:
> +
> KisImage(const KisImage& rhs);
> KisImage& operator=(const KisImage& rhs);
> void init(KisUndoStore *undoStore, qint32 width, qint32 height, const KoColorSpace \
>                 * colorSpace);
> diff --git a/krita/image/kis_stroke_strategy_undo_command_based.cpp \
> b/krita/image/kis_stroke_strategy_undo_command_based.cpp index 3eb998c..e3f802e \
>                 100644
> --- a/krita/image/kis_stroke_strategy_undo_command_based.cpp
> +++ b/krita/image/kis_stroke_strategy_undo_command_based.cpp
> @@ -97,6 +97,14 @@ void \
> KisStrokeStrategyUndoCommandBased::doStrokeCallback(KisStrokeJobData *data) \
> notifyCommandDone(d->command, d->sequentiality(), d->exclusivity()); }
> 
> +void KisStrokeStrategyUndoCommandBased::runAndSaveCommand(KUndo2CommandSP command,
> +                                                          \
> KisStrokeJobData::Sequentiality sequentiality, +                                    \
> KisStrokeJobData::Exclusivity exclusivity) +{
> +    command->redo();
> +    notifyCommandDone(command, sequentiality, exclusivity);
> +}
> +
> void KisStrokeStrategyUndoCommandBased::notifyCommandDone(KUndo2CommandSP command,
> KisStrokeJobData::Sequentiality sequentiality,
> KisStrokeJobData::Exclusivity exclusivity)
> diff --git a/krita/image/kis_stroke_strategy_undo_command_based.h \
> b/krita/image/kis_stroke_strategy_undo_command_based.h index 0751493..da13b11 \
>                 100644
> --- a/krita/image/kis_stroke_strategy_undo_command_based.h
> +++ b/krita/image/kis_stroke_strategy_undo_command_based.h
> @@ -79,12 +79,17 @@ public:
> void doStrokeCallback(KisStrokeJobData *data);
> 
> protected:
> -    void executeCommand(KUndo2CommandSP command, bool undo);
> +    void runAndSaveCommand(KUndo2CommandSP command,
> +                           KisStrokeJobData::Sequentiality sequentiality,
> +                           KisStrokeJobData::Exclusivity exclusivity);
> void notifyCommandDone(KUndo2CommandSP command,
> KisStrokeJobData::Sequentiality sequentiality,
> KisStrokeJobData::Exclusivity exclusivity);
> 
> private:
> +    void executeCommand(KUndo2CommandSP command, bool undo);
> +
> +private:
> bool m_undo;
> KUndo2CommandSP m_initCommand;
> KUndo2CommandSP m_finishCommand;
> diff --git a/krita/plugins/tools/defaulttools/CMakeLists.txt \
> b/krita/plugins/tools/defaulttools/CMakeLists.txt index d10daea..6a38fc0 100644
> --- a/krita/plugins/tools/defaulttools/CMakeLists.txt
> +++ b/krita/plugins/tools/defaulttools/CMakeLists.txt
> @@ -15,6 +15,7 @@ set(kritadefaulttools_PART_SRCS
> kis_tool_path.cc
> kis_tool_move.cc
> strokes/move_stroke_strategy.cpp
> +    strokes/move_selection_stroke_strategy.cpp
> kis_tool_multihand.cpp
> )
> 
> diff --git a/krita/plugins/tools/defaulttools/kis_tool_move.cc \
> b/krita/plugins/tools/defaulttools/kis_tool_move.cc index fc20250..f2f4c4c 100644
> --- a/krita/plugins/tools/defaulttools/kis_tool_move.cc
> +++ b/krita/plugins/tools/defaulttools/kis_tool_move.cc
> @@ -22,29 +22,17 @@
> #include "kis_tool_move.h"
> 
> #include <QPoint>
> -#include <kundo2command.h>
> -
> -#include <klocale.h>
> 
> #include "KoColorSpace.h"
> -#include "KoColor.h"
> -#include "KoCompositeOp.h"
> 
> #include "kis_cursor.h"
> -#include "kis_layer.h"
> #include "kis_selection.h"
> -#include "kis_paint_layer.h"
> -#include "kis_group_layer.h"
> -#include "kis_painter.h"
> #include "kis_canvas2.h"
> -#include "kis_view2.h"
> -#include "kis_node_manager.h"
> #include "kis_image.h"
> 
> -#include <kis_transaction.h>
> -#include <commands/kis_image_layer_add_command.h>
> -#include <commands/kis_deselect_global_selection_command.h>
> +#include "kis_paint_layer.h"
> #include "strokes/move_stroke_strategy.h"
> +#include "strokes/move_selection_stroke_strategy.h"
> 
> KisToolMove::KisToolMove(KoCanvasBase * canvas)
> > KisTool(canvas, KisCursor::moveCursor())
> @@ -55,6 +43,7 @@ KisToolMove::KisToolMove(KoCanvasBase * canvas)
> 
> KisToolMove::~KisToolMove()
> {
> +    endStroke();
> }
> 
> void KisToolMove::paint(QPainter& gc, const KoViewConverter &converter)
> @@ -63,6 +52,22 @@ void KisToolMove::paint(QPainter& gc, const KoViewConverter \
> &converter) Q_UNUSED(converter);
> }
> 
> +void KisToolMove::deactivate()
> +{
> +    endStroke();
> +    KisTool::deactivate();
> +}
> +
> +void KisToolMove::requestStrokeEnd()
> +{
> +    endStroke();
> +}
> +
> +void KisToolMove::requestStrokeCancellation()
> +{
> +    cancelStroke();
> +}
> +
> // recursively search a node with a non-transparent pixel
> KisNodeSP findNode(KisNodeSP node, const QPoint &point, bool wholeGroup)
> {
> @@ -99,44 +104,6 @@ KisNodeSP findNode(KisNodeSP node, const QPoint &point, bool \
> wholeGroup) return foundNode;
> }
> 
> -KisLayerSP createSelectionCopy(KisLayerSP srcLayer, KisSelectionSP selection, \
>                 KisImageWSP image, KisStrokeId strokeId)
> -{
> -    QRect copyRect = srcLayer->extent() | selection->selectedRect();
> -
> -    KisPaintDeviceSP device = new KisPaintDevice(srcLayer->colorSpace());
> -    KisPainter gc(device);
> -    gc.setSelection(selection);
> -    gc.setCompositeOp(COMPOSITE_OVER);
> -    gc.setOpacity(OPACITY_OPAQUE_U8);
> -    gc.bitBlt(copyRect.topLeft(), srcLayer->paintDevice(), copyRect);
> -    gc.end();
> -
> -    KisTransaction transaction("cut", srcLayer->paintDevice());
> -    srcLayer->paintDevice()->clearSelection(selection);
> -    image->addJob(strokeId,
> -                  new \
>                 KisStrokeStrategyUndoCommandBased::Data(transaction.endAndTake()));
> -
> -    image->addJob(strokeId,
> -        new KisStrokeStrategyUndoCommandBased::Data(
> -            new KisDeselectGlobalSelectionCommand(image)));
> -
> -    KisPaintLayerSP newLayer =
> -        new KisPaintLayer(image, srcLayer->name() + " (moved)",
> -                          srcLayer->opacity(), device);
> -
> -    newLayer->setCompositeOp(srcLayer->compositeOpId());
> -
> -    // No updates while we adding a layer, so let's be "exclusive"
> -    image->addJob(strokeId,
> -        new KisStrokeStrategyUndoCommandBased::Data(
> -            new KisImageLayerAddCommand(image, newLayer,
> -                                        srcLayer->parent(), srcLayer),
> -            false,
> -            KisStrokeJobData::SEQUENTIAL, KisStrokeJobData::EXCLUSIVE));
> -
> -    return newLayer;
> -}
> -
> void KisToolMove::mousePressEvent(KoPointerEvent *event)
> {
> if(PRESS_CONDITION_OM(event, KisTool::HOVER_MODE,
> @@ -145,13 +112,15 @@ void KisToolMove::mousePressEvent(KoPointerEvent *event)
> 
> setMode(KisTool::PAINT_MODE);
> 
> +        QPoint pos = convertToPixelCoord(event).toPoint();
> +        m_dragStart = pos;
> +        m_lastDragPos = m_dragStart;
> +
> +        if (m_strokeId) return;
> +
> KisNodeSP node;
> -        KisImageWSP image = currentImage();
> -        if (!image || !image->rootLayer()) {
> -            return;
> -        }
> +        KisImageSP image = this->image();
> 
> -        QPoint pos = convertToPixelCoord(event).toPoint();
> KisSelectionSP selection = currentSelection();
> 
> if(!m_optionsWidget->radioSelectedLayer->isChecked() &&
> @@ -161,52 +130,33 @@ void KisToolMove::mousePressEvent(KoPointerEvent *event)
> (m_optionsWidget->radioGroup->isChecked() ||
> event->modifiers() == (Qt::ControlModifier | Qt::ShiftModifier));
> 
> -            node = findNode(image->rootLayer(), pos, wholeGroup);
> +            node = findNode(image->root(), pos, wholeGroup);
> }
> 
> -        if(!node) {
> -            node = currentNode();
> -            if (!node) {
> -                return;
> -            }
> -        }
> +        if((!node && !(node = currentNode())) || !node->isEditable()) return;
> 
> -        if (!nodeEditable()) {
> -            return;
> -        }
> 
> -        /**
> -         * NOTE: we use deferred initialization of the node of
> -         * the stroke here. First, we set the node to null in
> -         * the constructor, use jobs of undo-command-based
> -         * strategy to initialize the stroke and then we set up
> -         * the node itself.
> -         */
> -        MoveStrokeStrategy *strategy =
> -            new MoveStrokeStrategy(0, image.data(),
> -                                   image->postExecutionUndoAdapter(),
> -                                   image->undoAdapter());
> +        KisStrokeStrategy *strategy;
> 
> -        m_strokeId = image->startStroke(strategy);
> +        KisPaintLayerSP paintLayer =
> +            dynamic_cast<KisPaintLayer*>(node.data());
> 
> -        if (node->inherits("KisLayer") &&
> -            !node->inherits("KisGroupLayer") &&
> -            node->paintDevice() &&
> -            selection &&
> +        if (paintLayer && selection &&
> !selection->isTotallyUnselected(image->bounds())) {
> 
> -            KisLayerSP oldLayer = dynamic_cast<KisLayer*>(node.data());
> -            KisLayerSP newLayer = createSelectionCopy(oldLayer, selection, image, \
>                 m_strokeId);
> -
> -            node = newLayer;
> +            strategy =
> +                new MoveSelectionStrokeStrategy(paintLayer,
> +                                                selection,
> +                                                image.data(),
> +                                                \
> image->postExecutionUndoAdapter()); +        } else {
> +            strategy =
> +                new MoveStrokeStrategy(node, image.data(),
> +                                       image->postExecutionUndoAdapter(),
> +                                       image->undoAdapter());
> }
> 
> -        // the deferred initialization itself
> -        strategy->setNode(node);
> -        strategy = 0;
> -
> -        m_dragStart = pos;
> -        m_lastDragPos = m_dragStart;
> +        m_strokeId = image->startStroke(strategy);
> }
> else {
> KisTool::mousePressEvent(event);
> @@ -216,16 +166,11 @@ void KisToolMove::mousePressEvent(KoPointerEvent *event)
> void KisToolMove::mouseMoveEvent(KoPointerEvent *event)
> {
> if(MOVE_CONDITION(event, KisTool::PAINT_MODE)) {
> -        if (!m_strokeId)
> -        {
> -            return;
> -        }
> +        if (!m_strokeId) return;
> 
> QPoint pos = convertToPixelCoord(event).toPoint();
> pos = applyModifiers(event->modifiers(), pos);
> drag(pos);
> -
> -        notifyModified();
> }
> else {
> KisTool::mouseMoveEvent(event);
> @@ -236,21 +181,11 @@ void KisToolMove::mouseReleaseEvent(KoPointerEvent *event)
> {
> if(RELEASE_CONDITION(event, KisTool::PAINT_MODE, Qt::LeftButton)) {
> setMode(KisTool::HOVER_MODE);
> -
> -        if (!m_strokeId)
> -        {
> -            return;
> -        }
> +        if (!m_strokeId) return;
> 
> QPoint pos = convertToPixelCoord(event).toPoint();
> pos = applyModifiers(event->modifiers(), pos);
> drag(pos);
> -
> -        KisImageWSP image = currentImage();
> -        image->endStroke(m_strokeId);
> -        m_strokeId.clear();
> -
> -        currentImage()->setModified();
> }
> else {
> KisTool::mouseReleaseEvent(event);
> @@ -268,6 +203,24 @@ void KisToolMove::drag(const QPoint& newPos)
> new MoveStrokeStrategy::Data(offset));
> }
> 
> +void KisToolMove::endStroke()
> +{
> +    if (!m_strokeId) return;
> +
> +    KisImageWSP image = currentImage();
> +    image->endStroke(m_strokeId);
> +    m_strokeId.clear();
> +}
> +
> +void KisToolMove::cancelStroke()
> +{
> +    if (!m_strokeId) return;
> +
> +    KisImageWSP image = currentImage();
> +    image->cancelStroke(m_strokeId);
> +    m_strokeId.clear();
> +}
> +
> QWidget* KisToolMove::createOptionWidget()
> {
> m_optionsWidget = new MoveToolOptionsWidget(0);
> diff --git a/krita/plugins/tools/defaulttools/kis_tool_move.h \
> b/krita/plugins/tools/defaulttools/kis_tool_move.h index 4ec1788..4d11710 100644
> --- a/krita/plugins/tools/defaulttools/kis_tool_move.h
> +++ b/krita/plugins/tools/defaulttools/kis_tool_move.h
> @@ -54,6 +54,9 @@ public:
> KisToolMove(KoCanvasBase * canvas);
> virtual ~KisToolMove();
> 
> +    void deactivate();
> +    void requestStrokeEnd();
> +    void requestStrokeCancellation();
> 
> public:
> 
> @@ -67,7 +70,8 @@ public:
> 
> private:
> void drag(const QPoint& newPos);
> -
> +    void endStroke();
> +    void cancelStroke();
> QPoint applyModifiers(Qt::KeyboardModifiers modifiers, QPoint pos);
> 
> private:
> diff --git a/krita/plugins/tools/defaulttools/strokes/move_selection_stroke_strategy.cpp \
> b/krita/plugins/tools/defaulttools/strokes/move_selection_stroke_strategy.cpp new \
> file mode 100644 index 0000000..9089f02
> --- /dev/null
> +++ b/krita/plugins/tools/defaulttools/strokes/move_selection_stroke_strategy.cpp
> @@ -0,0 +1,132 @@
> +/*
> + *  Copyright (c) 2012 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 "move_selection_stroke_strategy.h"
> +
> +#include <KoColorSpace.h>
> +#include "kis_image.h"
> +#include "kis_paint_layer.h"
> +#include "kis_painter.h"
> +#include "kis_transaction.h"
> +#include <commands/kis_deselect_global_selection_command.h>
> +
> +
> +MoveSelectionStrokeStrategy::MoveSelectionStrokeStrategy(KisPaintLayerSP \
> paintLayer, +                                                         \
> KisSelectionSP selection, +                                                         \
> KisUpdatesFacade *updatesFacade, +                                                  \
> KisPostExecutionUndoAdapter *undoAdapter) +    : \
> KisStrokeStrategyUndoCommandBased("Move Selection Stroke", false, undoAdapter), +   \
> m_paintLayer(paintLayer), +      m_selection(selection),
> +      m_updatesFacade(updatesFacade),
> +      m_undoAdapter(undoAdapter)
> +{
> +    enableJob(KisSimpleStrokeStrategy::JOB_INIT);
> +    enableJob(KisSimpleStrokeStrategy::JOB_FINISH);
> +    enableJob(KisSimpleStrokeStrategy::JOB_CANCEL);
> +}
> +
> +void MoveSelectionStrokeStrategy::initStrokeCallback()
> +{
> +    KisStrokeStrategyUndoCommandBased::initStrokeCallback();
> +
> +    KisPaintDeviceSP paintDevice = m_paintLayer->paintDevice();
> +
> +    KisPaintDeviceSP movedDevice = new KisPaintDevice(m_paintLayer.data(), \
> paintDevice->colorSpace()); +
> +
> +    QRect copyRect = m_selection->selectedRect();
> +    KisPainter gc(movedDevice);
> +    gc.setSelection(m_selection);
> +    gc.bitBlt(copyRect.topLeft(), paintDevice, copyRect);
> +    gc.end();
> +
> +    KisTransaction cutTransaction(name(), paintDevice);
> +    paintDevice->clearSelection(m_selection);
> +    runAndSaveCommand(KUndo2CommandSP(cutTransaction.endAndTake()),
> +                      KisStrokeJobData::SEQUENTIAL,
> +                      KisStrokeJobData::NORMAL);
> +
> +    KisIndirectPaintingSupport *indirect =
> +        static_cast<KisIndirectPaintingSupport*>(m_paintLayer.data());
> +    indirect->setTemporaryTarget(movedDevice);
> +    indirect->setTemporaryCompositeOp(paintDevice->colorSpace()->compositeOp(COMPOSITE_OVER));
>  +    indirect->setTemporaryOpacity(OPACITY_OPAQUE_U8);
> +
> +    m_updatesFacade->blockUpdates();
> +    runAndSaveCommand(
> +        KUndo2CommandSP(new \
> KisDeselectGlobalSelectionCommand(m_paintLayer->image())), +        \
> KisStrokeJobData::SEQUENTIAL, +        KisStrokeJobData::EXCLUSIVE);
> +    m_updatesFacade->unblockUpdates();
> +}
> +
> +void MoveSelectionStrokeStrategy::finishStrokeCallback()
> +{
> +    KisIndirectPaintingSupport *indirect =
> +        static_cast<KisIndirectPaintingSupport*>(m_paintLayer.data());
> +
> +    KisTransaction transaction(name(), m_paintLayer->paintDevice());
> +    indirect->mergeToLayer(m_paintLayer, (KisUndoAdapter*)0, "");
> +    runAndSaveCommand(KUndo2CommandSP(transaction.endAndTake()),
> +                      KisStrokeJobData::SEQUENTIAL,
> +                      KisStrokeJobData::NORMAL);
> +
> +    indirect->setTemporaryTarget(0);
> +
> +    KisStrokeStrategyUndoCommandBased::finishStrokeCallback();
> +}
> +
> +void MoveSelectionStrokeStrategy::cancelStrokeCallback()
> +{
> +    KisIndirectPaintingSupport *indirect =
> +        static_cast<KisIndirectPaintingSupport*>(m_paintLayer.data());
> +
> +    QRegion dirtyRegion = indirect->temporaryTarget()->region();
> +
> +    indirect->setTemporaryTarget(0);
> +
> +    m_paintLayer->setDirty(dirtyRegion);
> +
> +    KisStrokeStrategyUndoCommandBased::cancelStrokeCallback();
> +}
> +
> +#include "move_stroke_strategy.h"
> +
> +void MoveSelectionStrokeStrategy::doStrokeCallback(KisStrokeJobData *data)
> +{
> +    MoveStrokeStrategy::Data *d = dynamic_cast<MoveStrokeStrategy::Data*>(data);
> +
> +    if (d) {
> +        KisIndirectPaintingSupport *indirect =
> +            static_cast<KisIndirectPaintingSupport*>(m_paintLayer.data());
> +
> +        KisPaintDeviceSP movedDevice = indirect->temporaryTarget();
> +
> +        QRegion dirtyRegion = movedDevice->region();
> +        dirtyRegion |= dirtyRegion.translated(d->offset);
> +
> +        movedDevice->setX(movedDevice->x() + d->offset.x());
> +        movedDevice->setY(movedDevice->y() + d->offset.y());
> +
> +        m_paintLayer->setDirty(dirtyRegion);
> +    } else {
> +        KisStrokeStrategyUndoCommandBased::doStrokeCallback(data);
> +    }
> +}
> +
> diff --git a/krita/plugins/tools/defaulttools/strokes/move_selection_stroke_strategy.h \
> b/krita/plugins/tools/defaulttools/strokes/move_selection_stroke_strategy.h new \
> file mode 100644 index 0000000..440f2bf
> --- /dev/null
> +++ b/krita/plugins/tools/defaulttools/strokes/move_selection_stroke_strategy.h
> @@ -0,0 +1,49 @@
> +/*
> + *  Copyright (c) 2012 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 __MOVE_SELECTION_STROKE_STRATEGY_H
> +#define __MOVE_SELECTION_STROKE_STRATEGY_H
> +
> +#include "kis_stroke_strategy_undo_command_based.h"
> +#include "kis_types.h"
> +
> +class KisPostExecutionUndoAdapter;
> +class KisUpdatesFacade;
> +
> +
> +class MoveSelectionStrokeStrategy : public KisStrokeStrategyUndoCommandBased
> +{
> +public:
> +    MoveSelectionStrokeStrategy(KisPaintLayerSP paintLayer,
> +                                KisSelectionSP selection,
> +                                KisUpdatesFacade *updatesFacade,
> +                                KisPostExecutionUndoAdapter *undoAdapter);
> +
> +    void initStrokeCallback();
> +    void finishStrokeCallback();
> +    void cancelStrokeCallback();
> +    void doStrokeCallback(KisStrokeJobData *data);
> +
> +private:
> +    KisPaintLayerSP m_paintLayer;
> +    KisSelectionSP m_selection;
> +    KisUpdatesFacade *m_updatesFacade,;
> +    KisPostExecutionUndoAdapter *m_undoAdapter;
> +};
> +
> +#endif /* __MOVE_SELECTION_STROKE_STRATEGY_H */
> diff --git a/krita/ui/kis_doc2_p.h b/krita/ui/kis_doc2_p.h
> index 19a3e5f..e7ec1c4 100644
> --- a/krita/ui/kis_doc2_p.h
> +++ b/krita/ui/kis_doc2_p.h
> @@ -32,6 +32,7 @@ public:
> 
> void setIndex(int idx) {
> KisImageWSP image = this->image();
> +        image->requestStrokeCancellation();
> if(image->tryBarrierLock()) {
> KUndo2Stack::setIndex(idx);
> image->unlock();
> @@ -40,6 +41,7 @@ public:
> 
> void undo() {
> KisImageWSP image = this->image();
> +        image->requestStrokeCancellation();
> if(image->tryBarrierLock()) {
> KUndo2Stack::undo();
> image->unlock();
> diff --git a/krita/ui/kis_filter_handler.cc b/krita/ui/kis_filter_handler.cc
> index 2705b9d..e472a40 100644
> --- a/krita/ui/kis_filter_handler.cc
> +++ b/krita/ui/kis_filter_handler.cc
> @@ -102,6 +102,14 @@ KisFilterHandler::~KisFilterHandler()
> 
> void KisFilterHandler::showDialog()
> {
> +    /**
> +     * HACK ALERT:
> +     * Until filters are ported to strokes, there should be a barrier
> +     * to finish all the running strokes in the system
> +     */
> +    m_d->view->image()->barrierLock();
> +    m_d->view->image()->unlock();
> +
> KisPaintDeviceSP dev = m_d->view->activeDevice();
> if (dev->colorSpace()->willDegrade(m_d->filter->colorSpaceIndependence())) {
> // Warning bells!
> diff --git a/krita/ui/tool/kis_tool.cc b/krita/ui/tool/kis_tool.cc
> index 86b04ba..cde18c0 100644
> --- a/krita/ui/tool/kis_tool.cc
> +++ b/krita/ui/tool/kis_tool.cc
> @@ -161,14 +161,26 @@ void KisTool::activate(ToolActivation, const QSet<KoShape*> \
> &) 
> connect(actions().value("toggle_fg_bg"), SIGNAL(triggered()), \
> SLOT(slotToggleFgBg()), Qt::UniqueConnection); \
> connect(actions().value("reset_fg_bg"), SIGNAL(triggered()), SLOT(slotResetFgBg()), \
> Qt::UniqueConnection); +    connect(image(), \
> SIGNAL(sigStrokeCancellationRequested()), SLOT(requestStrokeCancellation())); +    \
> connect(image(), SIGNAL(sigStrokeEndRequested()), SLOT(requestStrokeEnd())); }
> 
> void KisTool::deactivate()
> {
> +    disconnect(image().data(), SIGNAL(sigStrokeCancellationRequested()));
> +    disconnect(image().data(), SIGNAL(sigStrokeEndRequested()));
> disconnect(actions().value("toggle_fg_bg"), 0, this, 0);
> disconnect(actions().value("reset_fg_bg"), 0, this, 0);
> }
> 
> +void KisTool::requestStrokeCancellation()
> +{
> +}
> +
> +void KisTool::requestStrokeEnd()
> +{
> +}
> +
> void KisTool::resourceChanged(int key, const QVariant & v)
> {
> 
> diff --git a/krita/ui/tool/kis_tool.h b/krita/ui/tool/kis_tool.h
> index 073c9cb..a2ea4b6 100644
> --- a/krita/ui/tool/kis_tool.h
> +++ b/krita/ui/tool/kis_tool.h
> @@ -224,6 +224,20 @@ protected slots:
> */
> virtual void resetCursorStyle();
> 
> +    /**
> +     * Called when the user requested the cancellation of the current
> +     * stroke. If you tool supports cancelling, override this method
> +     * and do the needed work there
> +     */
> +    virtual void requestStrokeCancellation();
> +
> +    /**
> +     * Called when the image decided that the stroke should better be
> +     * ended. If you tool supports long strokes, override this method
> +     * and do the needed work there
> +     */
> +    virtual void requestStrokeEnd();
> +
> private slots:
> void slotToggleFgBg();
> void slotResetFgBg();
> _______________________________________________
> kimageshop mailing list
> kimageshop@kde.org
> https://mail.kde.org/mailman/listinfo/kimageshop
> 
> 


-- 
Boudewijn Rempt
http://www.valdyas.org, http://www.krita.org, http://www.boudewijnrempt.nl
_______________________________________________
kimageshop mailing list
kimageshop@kde.org
https://mail.kde.org/mailman/listinfo/kimageshop


[prev in list] [next in list] [prev in thread] [next in thread] 

Configure | About | News | Add a list | Sponsored by KoreLogic