[calligra] krita: Added an ability to transform layers recursively with a Transform Tool
Dmitry Kazakov
dimula73 at gmail.com
Thu Jan 31 15:39:58 UTC 2013
Git commit e30395b251684b8cfdbbcce6606d9e2b0edb30e1 by Dmitry Kazakov.
Committed on 31/01/2013 at 16:16.
Pushed by dkazakov into branch 'master'.
Added an ability to transform layers recursively with a Transform Tool
Now the transform tool supports transforming of a group of layers or
masks recursively in a single pass. You can use it for transforming a
set of layers grouped into a Group Layer or just transform a single
layer with all its masks (e.g. with transparency masks). This option
is enabled by default, but you can disable it by switching a small
button in the transform tool configuration docker. This button has a
icon of a small spider (the tool "crawls" through the layers :) ) [0].
It would be cool, if someone tested it a bit ;)
[0] - you can suggest any other icon for this, actually =)
BUG:297927,314176
CCMAIL:kimageshop at kde.org
M +5 -4 krita/image/kis_processing_visitor.cpp
M +4 -2 krita/image/kis_processing_visitor.h
M +1 -0 krita/plugins/tools/tool_transform2/CMakeLists.txt
M +56 -40 krita/plugins/tools/tool_transform2/kis_tool_transform.cc
M +5 -5 krita/plugins/tools/tool_transform2/kis_tool_transform.h
M +11 -0 krita/plugins/tools/tool_transform2/kis_tool_transform_config_widget.cpp
M +3 -0 krita/plugins/tools/tool_transform2/kis_tool_transform_config_widget.h
A +- -- krita/plugins/tools/tool_transform2/krita_tool_transform_recursive.png
M +96 -44 krita/plugins/tools/tool_transform2/strokes/transform_stroke_strategy.cpp
M +31 -15 krita/plugins/tools/tool_transform2/strokes/transform_stroke_strategy.h
M +35 -16 krita/plugins/tools/tool_transform2/wdg_tool_transform.ui
http://commits.kde.org/calligra/e30395b251684b8cfdbbcce6606d9e2b0edb30e1
diff --git a/krita/image/kis_processing_visitor.cpp b/krita/image/kis_processing_visitor.cpp
index 00e1993..5761544 100644
--- a/krita/image/kis_processing_visitor.cpp
+++ b/krita/image/kis_processing_visitor.cpp
@@ -30,23 +30,24 @@ KisProcessingVisitor::ProgressHelper::ProgressHelper(const KisNode *node)
if(progressProxy) {
m_progressUpdater = new KoProgressUpdater(progressProxy);
m_progressUpdater->start();
- m_updater = m_progressUpdater->startSubtask();
m_progressUpdater->moveToThread(node->thread());
}
else {
m_progressUpdater = 0;
- m_updater = 0;
}
}
KisProcessingVisitor::ProgressHelper::~ProgressHelper()
{
- m_progressUpdater->deleteLater();
+ if (m_progressUpdater) {
+ m_progressUpdater->deleteLater();
+ }
}
KoUpdater* KisProcessingVisitor::ProgressHelper::updater() const
{
- return m_updater;
+ QMutexLocker l(&m_progressMutex);
+ return m_progressUpdater ? m_progressUpdater->startSubtask() : 0;
}
diff --git a/krita/image/kis_processing_visitor.h b/krita/image/kis_processing_visitor.h
index 9984d3c..dc3aef2 100644
--- a/krita/image/kis_processing_visitor.h
+++ b/krita/image/kis_processing_visitor.h
@@ -22,6 +22,8 @@
#include "krita_export.h"
#include "kis_shared.h"
+#include <QMutex>
+
class KisNode;
class KoUpdater;
class KoProgressUpdater;
@@ -57,7 +59,7 @@ public:
virtual void visit(KisTransparencyMask *mask, KisUndoAdapter *undoAdapter) = 0;
virtual void visit(KisSelectionMask *mask, KisUndoAdapter *undoAdapter) = 0;
-protected:
+public:
class ProgressHelper {
public:
ProgressHelper(const KisNode *node);
@@ -66,7 +68,7 @@ protected:
KoUpdater* updater() const;
private:
KoProgressUpdater *m_progressUpdater;
- KoUpdater *m_updater;
+ mutable QMutex m_progressMutex;
};
};
diff --git a/krita/plugins/tools/tool_transform2/CMakeLists.txt b/krita/plugins/tools/tool_transform2/CMakeLists.txt
index 598c009..7a6c19b 100644
--- a/krita/plugins/tools/tool_transform2/CMakeLists.txt
+++ b/krita/plugins/tools/tool_transform2/CMakeLists.txt
@@ -25,5 +25,6 @@ install(TARGETS kritatooltransform DESTINATION ${PLUGIN_INSTALL_DIR})
install( FILES rotate_cursor.xpm
krita_tool_transform.png
+ krita_tool_transform_recursive.png
DESTINATION ${DATA_INSTALL_DIR}/krita/pics)
install( FILES kritatooltransform.desktop DESTINATION ${SERVICES_INSTALL_DIR})
diff --git a/krita/plugins/tools/tool_transform2/kis_tool_transform.cc b/krita/plugins/tools/tool_transform2/kis_tool_transform.cc
index 63300c2..7e14215 100644
--- a/krita/plugins/tools/tool_transform2/kis_tool_transform.cc
+++ b/krita/plugins/tools/tool_transform2/kis_tool_transform.cc
@@ -859,11 +859,11 @@ void KisToolTransform::mousePressEvent(KoPointerEvent *event)
KisImageWSP kisimage = image();
- if (!currentNode() || !currentNode()->paintDevice())
+ if (!currentNode())
return;
setMode(KisTool::PAINT_MODE);
- if (kisimage && currentNode()->paintDevice() && event->button() == Qt::LeftButton) {
+ if (kisimage && event->button() == Qt::LeftButton) {
QPointF mousePos = QPointF(event->point.x() * kisimage->xRes(), event->point.y() * kisimage->yRes());
if (!m_strokeId) {
startStroke(m_currentArgs.mode());
@@ -1932,8 +1932,7 @@ void KisToolTransform::updateSelectionPath()
if (selection) {
selectionOutline = selection->outline();
} else {
- KisPaintDeviceSP dev = currentNode()->paintDevice();
- selectionOutline << dev->exactBounds();
+ selectionOutline << m_selectedPortionCache->exactBounds();
}
const KisCoordinatesConverter *converter = m_canvas->coordinatesConverter();
@@ -1946,32 +1945,16 @@ void KisToolTransform::updateSelectionPath()
}
}
-void KisToolTransform::initThumbnailImage()
+void KisToolTransform::initThumbnailImage(KisPaintDeviceSP previewDevice)
{
m_transform = QTransform();
m_origImg = QImage();
m_currImg = QImage();
-
- KisPaintDeviceSP dev;
- KisSelectionSP selection = currentSelection();
-
- if (!currentNode() || !(dev = currentNode()->paintDevice())) {
- return;
- }
-
- QRect srcRect(m_transaction.originalRect().toAlignedRect());
-
- if (selection) {
- m_selectedPortionCache = new KisPaintDevice(dev->colorSpace());
- KisPainter gc(m_selectedPortionCache);
- gc.setSelection(selection);
- gc.bitBlt(srcRect.topLeft(), dev, srcRect);
- } else {
- m_selectedPortionCache = new KisPaintDevice(*dev);
- }
+ m_selectedPortionCache = previewDevice;
const int maxSize = 2000;
+ QRect srcRect(m_transaction.originalRect().toAlignedRect());
int x, y, w, h;
srcRect.getRect(&x, &y, &w, &h);
@@ -2039,7 +2022,7 @@ void KisToolTransform::startStroke(ToolTransformArgs::TransformMode mode)
KisPaintDeviceSP dev;
- if (!currentNode() || !(dev = currentNode()->paintDevice())) {
+ if (!currentNode()) {
return;
}
@@ -2058,25 +2041,25 @@ void KisToolTransform::startStroke(ToolTransformArgs::TransformMode mode)
return;
}
- KisSelectionSP selection = currentSelection();
+ m_optWidget->setRecursiveOptionEnabled(false);
+ m_workRecursively = m_optWidget->workRecursively() ||
+ !currentNode()->paintDevice();
+
+ TransformStrokeStrategy *strategy = new TransformStrokeStrategy(currentNode(), currentSelection(), image()->postExecutionUndoAdapter(), image()->undoAdapter());
+ KisPaintDeviceSP previewDevice = strategy->previewDevice();
- QRectF originalRect;
- originalRect = selection ?
- selection->selectedExactRect() : dev->exactBounds();
+ KisSelectionSP selection = currentSelection();
+ QRect srcRect = selection ? selection->selectedExactRect() : previewDevice->exactBounds();
- m_transaction = TransformTransactionProperties(originalRect, &m_currentArgs);
+ m_transaction = TransformTransactionProperties(srcRect, &m_currentArgs);
- initThumbnailImage();
+ initThumbnailImage(previewDevice);
updateSelectionPath();
initTransformMode(mode);
- KisStrokeStrategy *strategy = new TransformStrokeStrategy(currentNode(), currentSelection(), m_selectedPortionCache, image()->postExecutionUndoAdapter(), image()->undoAdapter());
-
m_strokeId = image()->startStroke(strategy);
-
- image()->addJob(m_strokeId,
- new TransformStrokeStrategy::ClearSelectionData());
+ clearDevices(currentNode(), m_workRecursively);
Q_ASSERT(m_changesTracker.isEmpty());
commitChanges();
@@ -2087,15 +2070,13 @@ void KisToolTransform::endStroke()
if (!m_strokeId) return;
if (!m_currentArgs.isIdentity()) {
- image()->addJob(m_strokeId,
- new TransformStrokeStrategy::TransformData(
- TransformStrokeStrategy::TransformData::PAINT_DEVICE,
- m_currentArgs));
+ transformDevices(currentNode(), m_workRecursively);
image()->addJob(m_strokeId,
new TransformStrokeStrategy::TransformData(
TransformStrokeStrategy::TransformData::SELECTION,
- m_currentArgs));
+ m_currentArgs,
+ currentNode()));
image()->endStroke(m_strokeId);
} else {
@@ -2104,6 +2085,7 @@ void KisToolTransform::endStroke()
m_strokeId.clear();
m_changesTracker.reset();
+ m_optWidget->setRecursiveOptionEnabled(true);
}
void KisToolTransform::cancelStroke()
@@ -2113,6 +2095,7 @@ void KisToolTransform::cancelStroke()
image()->cancelStroke(m_strokeId);
m_strokeId.clear();
m_changesTracker.reset();
+ m_optWidget->setRecursiveOptionEnabled(true);
}
void KisToolTransform::commitChanges()
@@ -2128,6 +2111,39 @@ void KisToolTransform::slotTrackerChangedConfig()
updateOptionWidget();
}
+void KisToolTransform::clearDevices(KisNodeSP node, bool recursive)
+{
+ if (recursive) {
+ // simple tail-recursive iteration
+ KisNodeSP prevNode = node->lastChild();
+ while(prevNode) {
+ clearDevices(prevNode, recursive);
+ prevNode = prevNode->prevSibling();
+ }
+ }
+
+ image()->addJob(m_strokeId,
+ new TransformStrokeStrategy::ClearSelectionData(node));
+}
+
+void KisToolTransform::transformDevices(KisNodeSP node, bool recursive)
+{
+ if (recursive) {
+ // simple tail-recursive iteration
+ KisNodeSP prevNode = node->lastChild();
+ while(prevNode) {
+ transformDevices(prevNode, recursive);
+ prevNode = prevNode->prevSibling();
+ }
+ }
+
+ image()->addJob(m_strokeId,
+ new TransformStrokeStrategy::TransformData(
+ TransformStrokeStrategy::TransformData::PAINT_DEVICE,
+ m_currentArgs,
+ node));
+}
+
QWidget* KisToolTransform::createOptionWidget() {
m_optWidget = new KisToolTransformConfigWidget(&m_transaction, m_canvas, 0);
Q_CHECK_PTR(m_optWidget);
diff --git a/krita/plugins/tools/tool_transform2/kis_tool_transform.h b/krita/plugins/tools/tool_transform2/kis_tool_transform.h
index 9e6fca9..16e043c 100644
--- a/krita/plugins/tools/tool_transform2/kis_tool_transform.h
+++ b/krita/plugins/tools/tool_transform2/kis_tool_transform.h
@@ -97,6 +97,9 @@ protected:
void requestStrokeCancellation();
private:
+ void clearDevices(KisNodeSP node, bool recursive);
+ void transformDevices(KisNodeSP node, bool recursive);
+
void startStroke(ToolTransformArgs::TransformMode mode);
void endStroke();
void cancelStroke();
@@ -271,13 +274,9 @@ private:
void initTransformMode(ToolTransformArgs::TransformMode mode);
- void initThumbnailImage();
+ void initThumbnailImage(KisPaintDeviceSP previewDevice);
void updateSelectionPath();
void updateApplyResetAvailability();
- void transformDevice(KisPaintDeviceSP device,
- KoUpdaterPtr warpUpdater,
- KoUpdaterPtr affineUpdater,
- KoUpdaterPtr perspectiveUpdater);
private:
enum function {ROTATE = 0, MOVE, RIGHTSCALE, TOPRIGHTSCALE, TOPSCALE, TOPLEFTSCALE,
@@ -311,6 +310,7 @@ private:
QImage m_currImg; // origImg transformed using m_transform
KisPaintDeviceSP m_selectedPortionCache;
KisStrokeId m_strokeId;
+ bool m_workRecursively;
QPainterPath m_selectionPath; // original (unscaled) selection outline, used for painting decorations
diff --git a/krita/plugins/tools/tool_transform2/kis_tool_transform_config_widget.cpp b/krita/plugins/tools/tool_transform2/kis_tool_transform_config_widget.cpp
index c98556b..3e65c72 100644
--- a/krita/plugins/tools/tool_transform2/kis_tool_transform_config_widget.cpp
+++ b/krita/plugins/tools/tool_transform2/kis_tool_transform_config_widget.cpp
@@ -39,6 +39,7 @@ KisToolTransformConfigWidget::KisToolTransformConfigWidget(TransformTransactionP
{
setupUi(this);
showDecorationsBox->setIcon(koIcon("krita_tool_transform"));
+ chkWorkRecursively->setIcon(koIcon("krita_tool_transform_recursive.png"));
label_shearX->setPixmap(koIcon("shear_horizontal").pixmap(16, 16));
label_shearY->setPixmap(koIcon("shear_vertical").pixmap(16, 16));
@@ -272,6 +273,16 @@ void KisToolTransformConfigWidget::resetRotationCenterButtons()
}
}
+void KisToolTransformConfigWidget::setRecursiveOptionEnabled(bool value)
+{
+ chkWorkRecursively->setEnabled(value);
+}
+
+bool KisToolTransformConfigWidget::workRecursively() const
+{
+ return chkWorkRecursively->isChecked();;
+}
+
void KisToolTransformConfigWidget::setTooBigLabelVisible(bool value)
{
tooBigLabelWidget->setVisible(value);
diff --git a/krita/plugins/tools/tool_transform2/kis_tool_transform_config_widget.h b/krita/plugins/tools/tool_transform2/kis_tool_transform_config_widget.h
index 2d3b0b6..f905fc9 100644
--- a/krita/plugins/tools/tool_transform2/kis_tool_transform_config_widget.h
+++ b/krita/plugins/tools/tool_transform2/kis_tool_transform_config_widget.h
@@ -39,6 +39,9 @@ public:
void setTooBigLabelVisible(bool value);
bool showDecorations() const;
+ bool workRecursively() const;
+ void setRecursiveOptionEnabled(bool value);
+
public slots:
void updateConfig(const ToolTransformArgs &config);
diff --git a/krita/plugins/tools/tool_transform2/krita_tool_transform_recursive.png b/krita/plugins/tools/tool_transform2/krita_tool_transform_recursive.png
new file mode 100644
index 0000000..b5d5c73
Binary files /dev/null and b/krita/plugins/tools/tool_transform2/krita_tool_transform_recursive.png differ
diff --git a/krita/plugins/tools/tool_transform2/strokes/transform_stroke_strategy.cpp b/krita/plugins/tools/tool_transform2/strokes/transform_stroke_strategy.cpp
index 7e5b20e..0e9d13d 100644
--- a/krita/plugins/tools/tool_transform2/strokes/transform_stroke_strategy.cpp
+++ b/krita/plugins/tools/tool_transform2/strokes/transform_stroke_strategy.cpp
@@ -32,26 +32,79 @@
#include <kis_warptransform_worker.h>
-TransformStrokeStrategy::TransformStrokeStrategy(KisNodeSP node,
+TransformStrokeStrategy::TransformStrokeStrategy(KisNodeSP rootNode,
KisSelectionSP selection,
- KisPaintDeviceSP selectedPortionCache,
KisPostExecutionUndoAdapter *undoAdapter,
KisUndoAdapter *legacyUndoAdapter)
: KisStrokeStrategyUndoCommandBased(i18n("Transform Stroke"), false, undoAdapter),
- m_node(node),
m_selection(selection),
- m_selectedPortionCache(selectedPortionCache),
- m_legacyUndoAdapter(legacyUndoAdapter),
- m_progressUpdater(0)
+ m_legacyUndoAdapter(legacyUndoAdapter)
{
- Q_ASSERT(m_node);
+ if (rootNode->childCount() || !rootNode->paintDevice()) {
+ m_previewDevice = createDeviceCache(rootNode->projection());
+ } else {
+ m_previewDevice = createDeviceCache(rootNode->paintDevice());
+ putDeviceCache(rootNode->paintDevice(), m_previewDevice);
+ }
+
+ Q_ASSERT(m_previewDevice);
}
TransformStrokeStrategy::~TransformStrokeStrategy()
{
- if (m_progressUpdater) {
- m_progressUpdater->deleteLater();
+}
+
+KisPaintDeviceSP TransformStrokeStrategy::previewDevice() const
+{
+ return m_previewDevice;
+}
+
+KisPaintDeviceSP TransformStrokeStrategy::createDeviceCache(KisPaintDeviceSP dev)
+{
+ KisPaintDeviceSP cache;
+
+ if (m_selection) {
+ QRect srcRect = m_selection->selectedExactRect();
+
+ cache = new KisPaintDevice(dev->colorSpace());
+ KisPainter gc(cache);
+ gc.setSelection(m_selection);
+ gc.bitBlt(srcRect.topLeft(), dev, srcRect);
+ } else {
+ cache = new KisPaintDevice(*dev);
}
+
+ return cache;
+}
+
+bool TransformStrokeStrategy::haveDeviceInCache(KisPaintDeviceSP src)
+{
+ QMutexLocker l(&m_devicesCacheMutex);
+ return m_devicesCacheHash.contains(src.data());
+}
+
+void TransformStrokeStrategy::putDeviceCache(KisPaintDeviceSP src, KisPaintDeviceSP cache)
+{
+ QMutexLocker l(&m_devicesCacheMutex);
+ m_devicesCacheHash.insert(src.data(), cache);
+}
+
+KisPaintDeviceSP TransformStrokeStrategy::getDeviceCache(KisPaintDeviceSP src)
+{
+ QMutexLocker l(&m_devicesCacheMutex);
+ KisPaintDeviceSP cache = m_devicesCacheHash.value(src.data());
+ if (!cache) {
+ qWarning() << "WARNING: Transform Stroke: the device is absent in cache!";
+ }
+
+ return cache;
+}
+
+bool TransformStrokeStrategy::checkBelongsToSelection(KisPaintDeviceSP device) const
+{
+ return m_selection &&
+ (device == m_selection->pixelSelection().data() ||
+ device == m_selection->projection().data());
}
void TransformStrokeStrategy::doStrokeCallback(KisStrokeJobData *data)
@@ -61,20 +114,25 @@ void TransformStrokeStrategy::doStrokeCallback(KisStrokeJobData *data)
if(td) {
if (td->destination == TransformData::PAINT_DEVICE) {
- QRect oldExtent = m_node->extent();
+ QRect oldExtent = td->node->extent();
+ KisPaintDeviceSP device = td->node->paintDevice();
- KisPaintDeviceSP device = m_node->paintDevice();
+ if (device && !checkBelongsToSelection(device)) {
+ KisPaintDeviceSP cachedPortion = getDeviceCache(device);
+ Q_ASSERT(cachedPortion);
- KisTransaction transaction("Transform Device", device);
+ KisTransaction transaction("Transform Device", device);
- transformAndMergeDevice(td->config, m_selectedPortionCache,
- device);
+ KisProcessingVisitor::ProgressHelper helper(td->node);
+ transformAndMergeDevice(td->config, cachedPortion,
+ device, &helper);
- runAndSaveCommand(KUndo2CommandSP(transaction.endAndTake()),
- KisStrokeJobData::CONCURRENT,
- KisStrokeJobData::NORMAL);
+ runAndSaveCommand(KUndo2CommandSP(transaction.endAndTake()),
+ KisStrokeJobData::CONCURRENT,
+ KisStrokeJobData::NORMAL);
- m_node->setDirty(oldExtent | m_node->extent());
+ td->node->setDirty(oldExtent | td->node->extent());
+ }
} else if (m_selection) {
// FIXME: do it undoable
m_selection->flatten();
@@ -82,8 +140,10 @@ void TransformStrokeStrategy::doStrokeCallback(KisStrokeJobData *data)
KisSelectionTransaction transaction("Transform Selection", m_legacyUndoAdapter, m_selection);
+ KisProcessingVisitor::ProgressHelper helper(td->node);
transformDevice(td->config,
- m_selection->pixelSelection());
+ m_selection->pixelSelection(),
+ &helper);
runAndSaveCommand(KUndo2CommandSP(transaction.endAndTake()),
KisStrokeJobData::CONCURRENT,
@@ -92,17 +152,20 @@ void TransformStrokeStrategy::doStrokeCallback(KisStrokeJobData *data)
m_legacyUndoAdapter->emitSelectionChanged();
}
} else if (csd) {
- clearSelection();
+ KisPaintDeviceSP device = csd->node->paintDevice();
+ if (device && !checkBelongsToSelection(device)) {
+ if (!haveDeviceInCache(device)) {
+ putDeviceCache(device, createDeviceCache(device));
+ }
+ clearSelection(device);
+ }
} else {
KisStrokeStrategyUndoCommandBased::doStrokeCallback(data);
}
}
-void TransformStrokeStrategy::clearSelection()
+void TransformStrokeStrategy::clearSelection(KisPaintDeviceSP device)
{
- KisPaintDeviceSP device = m_node->paintDevice();
- Q_ASSERT(device);
-
KisTransaction transaction("Clear Selection", device);
if (m_selection) {
device->clearSelection(m_selection);
@@ -118,11 +181,12 @@ void TransformStrokeStrategy::clearSelection()
void TransformStrokeStrategy::transformAndMergeDevice(const ToolTransformArgs &config,
KisPaintDeviceSP src,
- KisPaintDeviceSP dst)
+ KisPaintDeviceSP dst,
+ KisProcessingVisitor::ProgressHelper *helper)
{
- KoUpdaterPtr mergeUpdater = src != dst ? fetchUpdater() : 0;
+ KoUpdaterPtr mergeUpdater = src != dst ? helper->updater() : 0;
- transformDevice(config, src);
+ transformDevice(config, src, helper);
if (src != dst) {
QRect mergeRect = src->extent();
KisPainter painter(dst);
@@ -132,24 +196,12 @@ void TransformStrokeStrategy::transformAndMergeDevice(const ToolTransformArgs &c
}
}
-KoUpdaterPtr TransformStrokeStrategy::fetchUpdater()
-{
- QMutexLocker l(&m_progressMutex);
-
- if (!m_progressUpdater) {
- KisNodeProgressProxy *progressProxy = m_node->nodeProgressProxy();
- m_progressUpdater = new KoProgressUpdater(progressProxy);
- m_progressUpdater->moveToThread(m_node->thread());
- }
-
- return m_progressUpdater->startSubtask();
-}
-
void TransformStrokeStrategy::transformDevice(const ToolTransformArgs &config,
- KisPaintDeviceSP device)
+ KisPaintDeviceSP device,
+ KisProcessingVisitor::ProgressHelper *helper)
{
if (config.mode() == ToolTransformArgs::WARP) {
- KoUpdaterPtr updater = fetchUpdater();
+ KoUpdaterPtr updater = helper->updater();
KisWarpTransformWorker worker(config.warpType(),
device,
@@ -178,8 +230,8 @@ void TransformStrokeStrategy::transformDevice(const ToolTransformArgs &config,
QPointF translation = config.transformedCenter() - transformedCenter.toPointF();
- KoUpdaterPtr updater1 = fetchUpdater();
- KoUpdaterPtr updater2 = fetchUpdater();
+ KoUpdaterPtr updater1 = helper->updater();
+ KoUpdaterPtr updater2 = helper->updater();
KisTransformWorker transformWorker(device,
config.scaleX(), config.scaleY(),
diff --git a/krita/plugins/tools/tool_transform2/strokes/transform_stroke_strategy.h b/krita/plugins/tools/tool_transform2/strokes/transform_stroke_strategy.h
index 7eb5bf0..c56857e 100644
--- a/krita/plugins/tools/tool_transform2/strokes/transform_stroke_strategy.h
+++ b/krita/plugins/tools/tool_transform2/strokes/transform_stroke_strategy.h
@@ -24,6 +24,7 @@
#include "kis_stroke_strategy_undo_command_based.h"
#include "kis_types.h"
#include "tool_transform_args.h"
+#include <kis_processing_visitor.h>
class KisUndoAdapter;
@@ -42,56 +43,71 @@ public:
};
public:
- TransformData(Destination _destination, const ToolTransformArgs &_config)
+ TransformData(Destination _destination, const ToolTransformArgs &_config, KisNodeSP _node)
: KisStrokeJobData(CONCURRENT, NORMAL),
destination(_destination),
- config(_config)
+ config(_config),
+ node(_node)
{
}
Destination destination;
ToolTransformArgs config;
+ KisNodeSP node;
};
class KDE_EXPORT ClearSelectionData : public KisStrokeJobData {
public:
- ClearSelectionData()
- : KisStrokeJobData(SEQUENTIAL, NORMAL)
+ ClearSelectionData(KisNodeSP _node)
+ : KisStrokeJobData(SEQUENTIAL, NORMAL),
+ node(_node)
{
}
+ KisNodeSP node;
};
public:
- TransformStrokeStrategy(KisNodeSP node,
+ TransformStrokeStrategy(KisNodeSP rootNode,
KisSelectionSP selection,
- KisPaintDeviceSP selectedPortionCache,
KisPostExecutionUndoAdapter *undoAdapter,
KisUndoAdapter *legacyUndoAdapter);
~TransformStrokeStrategy();
+ KisPaintDeviceSP previewDevice() const;
+
void doStrokeCallback(KisStrokeJobData *data);
private:
- KoUpdaterPtr fetchUpdater();
+ KoUpdaterPtr fetchUpdater(KisNodeSP node);
void transformAndMergeDevice(const ToolTransformArgs &config,
KisPaintDeviceSP src,
- KisPaintDeviceSP dst);
+ KisPaintDeviceSP dst,
+ KisProcessingVisitor::ProgressHelper *helper);
void transformDevice(const ToolTransformArgs &config,
- KisPaintDeviceSP device);
+ KisPaintDeviceSP device,
+ KisProcessingVisitor::ProgressHelper *helper);
+
+ void clearSelection(KisPaintDeviceSP device);
+ //void transformDevice(KisPaintDeviceSP src, KisPaintDeviceSP dst, KisProcessingVisitor::ProgressHelper *helper);
+
+ bool checkBelongsToSelection(KisPaintDeviceSP device) const;
- void clearSelection();
- void transformDevice(KisPaintDeviceSP src, KisPaintDeviceSP dst);
+ KisPaintDeviceSP createDeviceCache(KisPaintDeviceSP src);
+
+ bool haveDeviceInCache(KisPaintDeviceSP src);
+ void putDeviceCache(KisPaintDeviceSP src, KisPaintDeviceSP cache);
+ KisPaintDeviceSP getDeviceCache(KisPaintDeviceSP src);
private:
- KisNodeSP m_node;
KisSelectionSP m_selection;
- KisPaintDeviceSP m_selectedPortionCache;
KisUndoAdapter *m_legacyUndoAdapter;
- QMutex m_progressMutex;
- KoProgressUpdater *m_progressUpdater;
+ QMutex m_devicesCacheMutex;
+ QHash<KisPaintDevice*, KisPaintDeviceSP> m_devicesCacheHash;
+
+ KisPaintDeviceSP m_previewDevice;
};
#endif /* __TRANSFORM_STROKE_STRATEGY_H */
diff --git a/krita/plugins/tools/tool_transform2/wdg_tool_transform.ui b/krita/plugins/tools/tool_transform2/wdg_tool_transform.ui
index 9b8519c..17254be 100644
--- a/krita/plugins/tools/tool_transform2/wdg_tool_transform.ui
+++ b/krita/plugins/tools/tool_transform2/wdg_tool_transform.ui
@@ -6,8 +6,8 @@
<rect>
<x>0</x>
<y>0</y>
- <width>225</width>
- <height>258</height>
+ <width>294</width>
+ <height>266</height>
</rect>
</property>
<property name="sizePolicy">
@@ -38,17 +38,8 @@
<enum>Qt::LeftToRight</enum>
</property>
<layout class="QVBoxLayout" name="verticalLayout_5">
- <property name="spacing">
- <number>0</number>
- </property>
- <property name="margin">
- <number>0</number>
- </property>
<item>
<layout class="QHBoxLayout" name="horizontalLayout">
- <property name="spacing">
- <number>0</number>
- </property>
<item>
<spacer name="horizontalSpacer_2">
<property name="orientation">
@@ -56,7 +47,7 @@
</property>
<property name="sizeHint" stdset="0">
<size>
- <width>0</width>
+ <width>13</width>
<height>20</height>
</size>
</property>
@@ -125,7 +116,7 @@
</property>
<property name="sizeHint" stdset="0">
<size>
- <width>0</width>
+ <width>13</width>
<height>20</height>
</size>
</property>
@@ -1105,7 +1096,7 @@ big!</string>
</property>
<property name="maximumSize">
<size>
- <width>40</width>
+ <width>32</width>
<height>16777215</height>
</size>
</property>
@@ -1124,14 +1115,42 @@ big!</string>
</widget>
</item>
<item>
+ <widget class="QPushButton" name="chkWorkRecursively">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Fixed" vsizetype="Fixed">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="maximumSize">
+ <size>
+ <width>32</width>
+ <height>16777215</height>
+ </size>
+ </property>
+ <property name="toolTip">
+ <string>Work Recursively</string>
+ </property>
+ <property name="text">
+ <string/>
+ </property>
+ <property name="checkable">
+ <bool>true</bool>
+ </property>
+ <property name="checked">
+ <bool>true</bool>
+ </property>
+ </widget>
+ </item>
+ <item>
<spacer name="horizontalSpacer_5">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
- <width>0</width>
- <height>10</height>
+ <width>13</width>
+ <height>13</height>
</size>
</property>
</spacer>
More information about the kimageshop
mailing list