Krita Source Code Documentation
Loading...
Searching...
No Matches
TransformStrokeStrategy Class Reference

#include <transform_stroke_strategy.h>

+ Inheritance diagram for TransformStrokeStrategy:

Classes

class  CalculateConvexHullData
 
class  ClearSelectionData
 
class  PreparePreviewData
 
struct  TransformAllData
 
class  TransformData
 

Signals

void sigConvexHullCalculated (QPolygon convexHull, void *cookie)
 
void sigPreviewDeviceReady (KisPaintDeviceSP device)
 
void sigTransactionGenerated (TransformTransactionProperties transaction, ToolTransformArgs args, void *cookie)
 

Public Member Functions

void cancelStrokeCallback () override
 
void doStrokeCallback (KisStrokeJobData *data) override
 
void finishStrokeCallback () override
 
void initStrokeCallback () override
 
 TransformStrokeStrategy (ToolTransformArgs::TransformMode mode, const QString &filterId, bool forceReset, KisNodeList rootNodes, KisSelectionSP selection, KisStrokeUndoFacade *undoFacade, KisUpdatesFacade *updatesFacade)
 
 ~TransformStrokeStrategy () override
 
- Public Member Functions inherited from KisStrokeStrategyUndoCommandBased
 KisStrokeStrategyUndoCommandBased (const KUndo2MagicString &name, bool undo, KisStrokeUndoFacade *undoFacade, KUndo2CommandSP initCommand=KUndo2CommandSP(0), KUndo2CommandSP finishCommand=KUndo2CommandSP(0))
 
void setCommandExtraData (KUndo2CommandExtraData *data)
 
void setMacroId (int value)
 
void setSupportsWrapAroundMode (bool value)
 
void setUsedWhileUndoRedo (bool value)
 
- Public Member Functions inherited from KisRunnableBasedStrokeStrategy
 KisRunnableBasedStrokeStrategy (const KisRunnableBasedStrokeStrategy &rhs)
 
 KisRunnableBasedStrokeStrategy (const QLatin1String &id, const KUndo2MagicString &name=KUndo2MagicString())
 
KisRunnableStrokeJobsInterfacerunnableJobsInterface () const
 
 ~KisRunnableBasedStrokeStrategy ()
 
- Public Member Functions inherited from KisSimpleStrokeStrategy
KisStrokeJobDatacreateCancelData () override
 
KisStrokeJobStrategycreateCancelStrategy () override
 
KisStrokeJobStrategycreateDabStrategy () override
 
KisStrokeJobDatacreateFinishData () override
 
KisStrokeJobStrategycreateFinishStrategy () override
 
KisStrokeJobDatacreateInitData () override
 
KisStrokeJobStrategycreateInitStrategy () override
 
KisStrokeJobDatacreateResumeData () override
 
KisStrokeJobStrategycreateResumeStrategy () override
 
KisStrokeJobDatacreateSuspendData () override
 
KisStrokeJobStrategycreateSuspendStrategy () override
 
 KisSimpleStrokeStrategy (const QLatin1String &id, const KUndo2MagicString &name=KUndo2MagicString())
 
virtual void resumeStrokeCallback ()
 
virtual void suspendStrokeCallback ()
 
- Public Member Functions inherited from KisStrokeStrategy
qreal balancingRatioOverride () const
 
bool canForgetAboutMe () const
 
bool clearsRedoOnStart () const
 
virtual KisStrokeStrategycreateLodClone (int levelOfDetail)
 
KisLodPreferences currentLodPreferences () const
 
bool forceLodModeIfPossible () const
 
QString id () const
 
bool isAsynchronouslyCancellable () const
 
bool isExclusive () const
 
 KisStrokeStrategy (const QLatin1String &id, const KUndo2MagicString &name=KUndo2MagicString())
 
KUndo2MagicString name () const
 
bool needsExplicitCancel () const
 
virtual void notifyUserEndedStroke ()
 
virtual void notifyUserStartedStroke ()
 
bool requestsOtherStrokesToEnd () const
 
void setForceLodModeIfPossible (bool forceLodModeIfPossible)
 
void setMutatedJobsInterface (KisStrokesQueueMutatedJobInterface *mutatedJobsInterface, KisStrokeId strokeId)
 
bool supportsWrapAroundMode () const
 
virtual void tryCancelCurrentStrokeJobAsync ()
 tryCancelCurrentStrokeJobAsync is called by the strokes queue when the stroke is being cancelled. The stroke strategy may or may not handle this request and cancel the currently running long action.
 
virtual ~KisStrokeStrategy ()
 

Protected Member Functions

void postProcessToplevelCommand (KUndo2Command *command) override
 Applies some modifications (e.g. assigning extra data) to the toplevel command.
 
- Protected Member Functions inherited from KisStrokeStrategyUndoCommandBased
void cancelStrokeCallbackImpl (QVector< KisStrokeJobData * > &mutatedJobs)
 
void executeCommand (KUndo2CommandSP command, bool undo)
 
 KisStrokeStrategyUndoCommandBased (const KisStrokeStrategyUndoCommandBased &rhs)
 
void notifyCommandDone (KUndo2CommandSP command, KisStrokeJobData::Sequentiality sequentiality, KisStrokeJobData::Exclusivity exclusivity)
 
void runAndSaveCommand (KUndo2CommandSP command, KisStrokeJobData::Sequentiality sequentiality, KisStrokeJobData::Exclusivity exclusivity)
 
KisStrokeUndoFacadeundoFacade () const
 
- Protected Member Functions inherited from KisSimpleStrokeStrategy
void enableJob (JobType type, bool enable=true, KisStrokeJobData::Sequentiality sequentiality=KisStrokeJobData::SEQUENTIAL, KisStrokeJobData::Exclusivity exclusivity=KisStrokeJobData::NORMAL)
 
 KisSimpleStrokeStrategy (const KisSimpleStrokeStrategy &rhs)
 
- Protected Member Functions inherited from KisStrokeStrategy
void addMutatedJob (KisStrokeJobData *data)
 
void addMutatedJobs (const QVector< KisStrokeJobData * > list)
 
 KisStrokeStrategy (const KisStrokeStrategy &rhs)
 
void setAsynchronouslyCancellable (bool value)
 
void setBalancingRatioOverride (qreal value)
 
void setCanForgetAboutMe (bool value)
 
void setClearsRedoOnStart (bool value)
 
void setExclusive (bool value)
 
void setNeedsExplicitCancel (bool value)
 
void setRequestsOtherStrokesToEnd (bool value)
 
void setSupportsWrapAroundMode (bool value)
 

Private Member Functions

QPolygon calculateConvexHull ()
 
bool checkBelongsToSelection (KisPaintDeviceSP device) const
 
void clearSelection (KisPaintDeviceSP device)
 
KisPaintDeviceSP createDeviceCache (KisPaintDeviceSP src)
 
KoUpdaterPtr fetchUpdater (KisNodeSP node)
 
void finishStrokeImpl (bool applyTransform, const ToolTransformArgs &args)
 
KisPaintDeviceSP getDeviceCache (KisPaintDeviceSP src)
 
bool haveDeviceInCache (KisPaintDeviceSP src)
 
void putDeviceCache (KisPaintDeviceSP src, KisPaintDeviceSP cache)
 

Private Attributes

bool m_convexHullHasBeenCalculated = false
 
int m_currentTime = -1
 
QList< KisSelectionMaskSPm_deactivatedOverlaySelectionMasks
 
QList< KisSelectionSPm_deactivatedSelections
 
QHash< KisPaintDevice *, KisPaintDeviceSPm_devicesCacheHash
 
QMutex m_devicesCacheMutex
 
QVector< KisDecoratedNodeInterface * > m_disabledDecoratedNodes
 
QString m_filterId
 
bool m_finalizingActionsStarted = false
 
bool m_forceReset
 
QList< KisNodeSPm_hiddenProjectionLeaves
 
ToolTransformArgs m_initialTransformArgs
 
ToolTransformArgs::TransformMode m_mode
 
const KisSavedMacroCommandm_overriddenCommand = 0
 
KisNodeList m_processedNodes
 
KisNodeList m_rootNodes
 
boost::optional< ToolTransformArgsm_savedTransformArgs
 
KisSelectionSP m_selection
 
QVector< const KUndo2Command * > m_skippedWhileMergeCommands
 
KisBatchNodeUpdateSP m_updateData
 
bool m_updatesDisabled = false
 
KisUpdatesFacadem_updatesFacade
 
KisTransformMaskSP writeToTransformMask
 

Additional Inherited Members

- Public Types inherited from KisSimpleStrokeStrategy
enum  JobType {
  JOB_INIT = 0 , JOB_CANCEL , JOB_FINISH , JOB_DOSTROKE ,
  JOB_SUSPEND , JOB_RESUME , NJOBS
}
 
- Static Public Member Functions inherited from KisSimpleStrokeStrategy
static QLatin1String jobTypeToString (JobType type)
 

Detailed Description

Definition at line 27 of file transform_stroke_strategy.h.

Constructor & Destructor Documentation

◆ TransformStrokeStrategy()

TransformStrokeStrategy::TransformStrokeStrategy ( ToolTransformArgs::TransformMode mode,
const QString & filterId,
bool forceReset,
KisNodeList rootNodes,
KisSelectionSP selection,
KisStrokeUndoFacade * undoFacade,
KisUpdatesFacade * updatesFacade )

Definition at line 56 of file transform_stroke_strategy.cpp.

64 m_updatesFacade(updatesFacade),
65 m_mode(mode),
66 m_filterId(filterId),
67 m_forceReset(forceReset),
68 m_selection(selection)
69{
70 if (selection) {
71 Q_FOREACH(KisNodeSP node, rootNodes) {
72 KIS_SAFE_ASSERT_RECOVER_NOOP(!dynamic_cast<KisTransformMask*>(node.data()));
73 }
74 }
75
76 m_rootNodes = rootNodes;
78}
KisStrokeStrategyUndoCommandBased(const KUndo2MagicString &name, bool undo, KisStrokeUndoFacade *undoFacade, KUndo2CommandSP initCommand=KUndo2CommandSP(0), KUndo2CommandSP finishCommand=KUndo2CommandSP(0))
ToolTransformArgs::TransformMode m_mode
#define KIS_SAFE_ASSERT_RECOVER_NOOP(cond)
Definition kis_assert.h:130
KUndo2MagicString kundo2_i18n(const char *text)

References KisSharedPtr< T >::data(), KIS_SAFE_ASSERT_RECOVER_NOOP, m_rootNodes, KisStrokeStrategyUndoCommandBased::setMacroId(), and KisCommandUtils::TransformToolId.

◆ ~TransformStrokeStrategy()

TransformStrokeStrategy::~TransformStrokeStrategy ( )
override

Definition at line 80 of file transform_stroke_strategy.cpp.

81{
82}

Member Function Documentation

◆ calculateConvexHull()

QPolygon TransformStrokeStrategy::calculateConvexHull ( )
private

Definition at line 448 of file transform_stroke_strategy.cpp.

449{
450 // Best effort attempt to calculate the convex hull, mimicking the
451 // approach that computes srcRect in initStrokeCallback below
452 QVector<QPoint> points;
453 if (m_selection) {
455 } else {
456 int numContributions = 0;
457 Q_FOREACH (KisNodeSP node, m_processedNodes) {
458 if (node->inherits("KisGroupLayer")) continue;
459
460 if (dynamic_cast<const KisTransformMask*>(node.data())) {
461 return QPolygon(); // Produce no convex hull if a KisTransformMask is present
462 } else {
463 KisPaintDeviceSP device;
464 if (KisExternalLayer *extLayer = dynamic_cast<KisExternalLayer*>(node.data())) {
465 device = extLayer->projection();
466 } else {
467 device = node->paintDevice();
468 }
469 if (device) {
470 KisPaintDeviceSP toUse;
471 // Use the original device to get the cached device containing the original image data
472 if (haveDeviceInCache(device)) {
473 toUse = getDeviceCache(device);
474 } else {
475 toUse = device;
476 }
477 /* This sometimes does not agree with the original exactBounds
478 because of colorspace changes between the original device
479 and cached. E.g. When the defaultPixel changes as follows it
480 triggers different behavior in calculateExactBounds:
481 KoColor ("ALPHA", "Alpha":0) => KoColor ("GRAYA", "Gray":0, "Alpha":255)
482 */
483 const bool isConvertedSelection =
484 node->paintDevice() &&
486 *toUse->colorSpace() == *node->paintDevice()->compositionSourceColorSpace();
487
488 QPolygon polygon = isConvertedSelection ?
491
492 points += polygon;
493 numContributions += 1;
494 } else {
495 // When can this happen? Should it continue instead?
496 ENTER_FUNCTION() << "Bailing out, device was null" << ppVar(node);
497 return QPolygon();
498 }
499 }
500 }
501 if (numContributions > 1) {
502 points = KisConvexHull::findConvexHull(points);
503 }
504 }
505 return QPolygon(points);
506}
const KoID AlphaColorModelID("A", ki18n("Alpha mask"))
virtual const KoColorSpace * compositionSourceColorSpace() const
const KoColorSpace * colorSpace() const
virtual KoID colorModelId() const =0
KisPaintDeviceSP getDeviceCache(KisPaintDeviceSP src)
bool haveDeviceInCache(KisPaintDeviceSP src)
#define ENTER_FUNCTION()
Definition kis_debug.h:178
#define ppVar(var)
Definition kis_debug.h:155
QPolygon findConvexHullSelectionLike(KisPaintDeviceSP device)
QPolygon findConvexHull(const QVector< QPoint > &points)
virtual KisPaintDeviceSP paintDevice() const =0
KisPixelSelectionSP pixelSelection

References AlphaColorModelID, KoColorSpace::colorModelId(), KisPaintDevice::colorSpace(), KisPaintDevice::compositionSourceColorSpace(), KisSharedPtr< T >::data(), ENTER_FUNCTION, KisConvexHull::findConvexHull(), KisConvexHull::findConvexHullSelectionLike(), getDeviceCache(), haveDeviceInCache(), m_processedNodes, m_selection, KisBaseNode::paintDevice(), KisSelection::pixelSelection, and ppVar.

◆ cancelStrokeCallback()

void TransformStrokeStrategy::cancelStrokeCallback ( )
overridevirtual

◆ checkBelongsToSelection()

bool TransformStrokeStrategy::checkBelongsToSelection ( KisPaintDeviceSP device) const
private

Definition at line 125 of file transform_stroke_strategy.cpp.

126{
127 return m_selection &&
128 (device == m_selection->pixelSelection().data() ||
129 device == m_selection->projection().data());
130}
KisPixelSelectionSP projection() const

References KisSharedPtr< T >::data(), m_selection, KisSelection::pixelSelection, and KisSelection::projection().

◆ clearSelection()

void TransformStrokeStrategy::clearSelection ( KisPaintDeviceSP device)
private

Definition at line 421 of file transform_stroke_strategy.cpp.

422{
423 KisTransaction transaction(device);
424 if (m_selection) {
426 } else {
427 device->clear();
428 }
429 runAndSaveCommand(KUndo2CommandSP(transaction.endAndTake()),
432}
virtual void clear()
void clearSelection(KisSelectionSP selection)
void runAndSaveCommand(KUndo2CommandSP command, KisStrokeJobData::Sequentiality sequentiality, KisStrokeJobData::Exclusivity exclusivity)
QSharedPointer< KUndo2Command > KUndo2CommandSP
Definition kis_types.h:262

References KisPaintDevice::clear(), KisPaintDevice::clearSelection(), KisTransaction::endAndTake(), m_selection, KisStrokeJobData::NORMAL, KisStrokeStrategyUndoCommandBased::runAndSaveCommand(), and KisStrokeJobData::SEQUENTIAL.

◆ createDeviceCache()

KisPaintDeviceSP TransformStrokeStrategy::createDeviceCache ( KisPaintDeviceSP src)
private

Definition at line 84 of file transform_stroke_strategy.cpp.

85{
86 KisPaintDeviceSP cache;
87
88 if (m_selection) {
89 QRect srcRect = m_selection->selectedExactRect();
90
91 cache = dev->createCompositionSourceDevice();
92 KisPainter gc(cache);
93 gc.setSelection(m_selection);
94 gc.bitBlt(srcRect.topLeft(), dev, srcRect);
95 } else {
96 cache = dev->createCompositionSourceDevice(dev);
97 }
98
99 return cache;
100}
KisPaintDeviceSP createCompositionSourceDevice() const
QRect selectedExactRect() const
Slow, but exact way of determining the rectangle that encloses the selection.

References KisPainter::bitBlt(), KisPaintDevice::createCompositionSourceDevice(), m_selection, KisSelection::selectedExactRect(), and KisPainter::setSelection().

◆ doStrokeCallback()

void TransformStrokeStrategy::doStrokeCallback ( KisStrokeJobData * data)
overridevirtual

Shape layer's projection may not be yet ready right after transformation, because it need to do that in the GUI thread, so we should approximate that.

We use usual transaction here, because we cannot calculate transformation for perspective and warp workers.

Selection masks might have an overlay enabled, we should disable that

Reimplemented from KisStrokeStrategyUndoCommandBased.

Definition at line 132 of file transform_stroke_strategy.cpp.

133{
134 TransformData *td = dynamic_cast<TransformData*>(data);
135 ClearSelectionData *csd = dynamic_cast<ClearSelectionData*>(data);
136 PreparePreviewData *ppd = dynamic_cast<PreparePreviewData*>(data);
137 TransformAllData *runAllData = dynamic_cast<TransformAllData*>(data);
138 CalculateConvexHullData *cch = dynamic_cast<CalculateConvexHullData*>(data);
139
140
141 if (runAllData) {
142 // here we only save the passed args, actual
143 // transformation will be performed during
144 // finish job
145 m_savedTransformArgs = runAllData->config;
146 } else if (ppd) {
147 KisNodeSP rootNode = m_rootNodes[0];
148 KisNodeList processedNodes = m_processedNodes;
149 KisPaintDeviceSP previewDevice;
150
151
152 if (processedNodes.size() > 1) {
153 const QRect bounds = rootNode->image()->bounds();
154 const int desiredAnimTime = rootNode->image()->animationInterface()->currentTime();
155
156 KisImageSP clonedImage = new KisImage(0,
157 bounds.width(),
158 bounds.height(),
159 rootNode->image()->colorSpace(),
160 "transformed_image");
161
162 // BUG: 413968
163 // Workaround: Group layers wouldn't properly render the right frame
164 // since `clonedImage` would always have a time value of 0.
165 clonedImage->animationInterface()->explicitlySetCurrentTime(desiredAnimTime);
166
167 KisNodeSP cloneRoot = clonedImage->rootLayer();
168
169 Q_FOREACH(KisNodeSP node, processedNodes) {
170 // Masks with unselected parents can't be added.
171 if (!node->inherits("KisMask")) {
172 clonedImage->addNode(node->clone().data(), cloneRoot);
173 }
174 }
175
176 clonedImage->refreshGraphAsync();
177 KisLayerUtils::refreshHiddenAreaAsync(clonedImage, cloneRoot, clonedImage->bounds());
178
180 clonedImage->waitForDone();
181
182 previewDevice = createDeviceCache(clonedImage->projection());
183 previewDevice->setDefaultBounds(cloneRoot->projection()->defaultBounds());
184
185 // we delete the cloned image in GUI thread to ensure
186 // no signals are still pending
187 makeKisDeleteLaterWrapper(clonedImage)->deleteLater();
188 }
189 else if (rootNode->childCount() || !rootNode->paintDevice()) {
190 if (KisTransformMask* tmask =
191 dynamic_cast<KisTransformMask*>(rootNode.data())) {
192 previewDevice = createDeviceCache(tmask->buildPreviewDevice());
193
195 m_selection = 0;
196 }
197
198 } else if (KisGroupLayer *group = dynamic_cast<KisGroupLayer*>(rootNode.data())) {
199 const QRect bounds = group->image()->bounds();
200 const int desiredAnimTime = group->image()->animationInterface()->currentTime();
201
202 KisImageSP clonedImage = new KisImage(0,
203 bounds.width(),
204 bounds.height(),
205 group->colorSpace(),
206 "transformed_image");
207
208 // BUG: 413968
209 // Workaround: Group layers wouldn't properly render the right frame
210 // since `clonedImage` would always have a time value of 0.
211 clonedImage->animationInterface()->explicitlySetCurrentTime(desiredAnimTime);
212
213 KisGroupLayerSP clonedGroup = dynamic_cast<KisGroupLayer*>(group->clone().data());
214
215 // In case the group is pass-through, it needs to be disabled for the preview,
216 // otherwise it will crash (no parent for a preview leaf).
217 // Also it needs to be done before setting the root layer for clonedImage.
218 // Result: preview for pass-through group is the same as for standard group
219 // (i.e. filter layers in the group won't affect the layer stack for a moment).
220 clonedGroup->setPassThroughMode(false);
221 clonedImage->setRootLayer(clonedGroup);
222
223 QQueue<KisNodeSP> linearizedSrcNodes;
224 KisLayerUtils::recursiveApplyNodes(rootNode, [&linearizedSrcNodes] (KisNodeSP node) {
225 linearizedSrcNodes.enqueue(node);
226 });
227
228 KisLayerUtils::recursiveApplyNodes(KisNodeSP(clonedGroup), [&linearizedSrcNodes, processedNodes] (KisNodeSP node) {
229 KisNodeSP srcNode = linearizedSrcNodes.dequeue();
230
231 if (!processedNodes.contains(srcNode)) {
232 node->setVisible(false);
233 }
234 });
235
236 clonedImage->refreshGraphAsync();
237 KisLayerUtils::refreshHiddenAreaAsync(clonedImage, clonedGroup, clonedImage->bounds());
238
240 clonedImage->waitForDone();
241
242 previewDevice = createDeviceCache(clonedImage->projection());
243 previewDevice->setDefaultBounds(group->projection()->defaultBounds());
244
245 // we delete the cloned image in GUI thread to ensure
246 // no signals are still pending
247 makeKisDeleteLaterWrapper(clonedImage)->deleteLater();
248
249 } else {
250 rootNode->projectionLeaf()->explicitlyRegeneratePassThroughProjection();
251 previewDevice = createDeviceCache(rootNode->projection());
252 }
253
254
255
256 } else {
257 KisPaintDeviceSP cacheDevice = createDeviceCache(rootNode->paintDevice());
258
259 if (dynamic_cast<KisSelectionMask*>(rootNode.data())) {
261 cacheDevice->colorSpace()->colorDepthId() == Integer8BitsColorDepthID) {
262
264 }
265
266 previewDevice = new KisPaintDevice(KoColorSpaceRegistry::instance()->rgb8());
267 const QRect srcRect = cacheDevice->exactBounds();
268
269 KisSequentialConstIterator srcIt(cacheDevice, srcRect);
270 KisSequentialIterator dstIt(previewDevice, srcRect);
271
272 const int pixelSize = previewDevice->colorSpace()->pixelSize();
273
274
275 KisImageConfig cfg(true);
276 KoColor pixel(cfg.selectionOverlayMaskColor(), previewDevice->colorSpace());
277
278 const qreal coeff = 1.0 / 255.0;
279 const qreal baseOpacity = 0.5;
280
281 while (srcIt.nextPixel() && dstIt.nextPixel()) {
282 qreal gray = srcIt.rawDataConst()[0];
283 qreal alpha = srcIt.rawDataConst()[1];
284
285 pixel.setOpacity(quint8(gray * alpha * baseOpacity * coeff));
286 memcpy(dstIt.rawData(), pixel.data(), pixelSize);
287 }
288
289 } else {
290 previewDevice = cacheDevice;
291 }
292
293 putDeviceCache(rootNode->paintDevice(), cacheDevice);
294 }
295
296 Q_EMIT sigPreviewDeviceReady(previewDevice);
297 }
298 else if (td) {
299 if (td->destination == TransformData::PAINT_DEVICE) {
300 QRect oldExtent = td->node->projectionPlane()->tightUserVisibleBounds();
301 KisPaintDeviceSP device = td->node->paintDevice();
302
303 if (device && !checkBelongsToSelection(device)) {
304 KisPaintDeviceSP cachedPortion = getDeviceCache(device);
305 Q_ASSERT(cachedPortion);
306
307 KisTransaction transaction(device);
308
310 KisTransformUtils::transformAndMergeDevice(td->config, cachedPortion,
311 device, &helper);
312
313 runAndSaveCommand(KUndo2CommandSP(transaction.endAndTake()),
316
317 m_updateData->addUpdate(td->node, cachedPortion->extent() | oldExtent | td->node->projectionPlane()->tightUserVisibleBounds());
318 } else if (KisExternalLayer *extLayer =
319 dynamic_cast<KisExternalLayer*>(td->node.data())) {
320
321 if (td->config.mode() == ToolTransformArgs::FREE_TRANSFORM ||
322 (td->config.mode() == ToolTransformArgs::PERSPECTIVE_4POINT &&
323 extLayer->supportsPerspectiveTransform())) {
324
325 QRect oldDirtyRect = oldExtent | extLayer->theoreticalBoundingRect();
326
328 QTransform t = w.transform();
329
330 runAndSaveCommand(KUndo2CommandSP(extLayer->transform(t)),
333
339 const QRect theoreticalNewDirtyRect =
340 kisGrowRect(t.mapRect(oldDirtyRect), 1);
341
342 m_updateData->addUpdate(td->node, oldDirtyRect | td->node->projectionPlane()->tightUserVisibleBounds() | extLayer->theoreticalBoundingRect() | theoreticalNewDirtyRect);
343 }
344
345 } else if (KisTransformMask *transformMask =
346 dynamic_cast<KisTransformMask*>(td->node.data())) {
347
349 new KisSimpleModifyTransformMaskCommand(transformMask,
351 new KisTransformMaskAdapter(td->config)))),
354
355 m_updateData->addUpdate(td->node, oldExtent | td->node->extent());
356 }
357 } else if (m_selection) {
358
364
368 &helper);
369
370 runAndSaveCommand(KUndo2CommandSP(transaction.endAndTake()),
373 }
374 } else if (csd) {
375 KisPaintDeviceSP device = csd->node->paintDevice();
376
377 if (device && !checkBelongsToSelection(device)) {
378 if (!haveDeviceInCache(device)) {
379 putDeviceCache(device, createDeviceCache(device));
380 }
381 clearSelection(device);
382
386 if (KisSelectionMask *mask = dynamic_cast<KisSelectionMask*>(csd->node.data())) {
387 KisSelectionSP selection = mask->selection();
388 if (selection) {
389 selection->setVisible(false);
390 m_deactivatedSelections.append(selection);
391 }
392 }
393 } else if (KisExternalLayer *externalLayer = dynamic_cast<KisExternalLayer*>(csd->node.data())) {
394 externalLayer->projectionLeaf()->setTemporaryHiddenFromRendering(true);
395 m_hiddenProjectionLeaves.append(csd->node);
396 } else if (KisTransformMask *transformMask =
397 dynamic_cast<KisTransformMask*>(csd->node.data())) {
398
399 KisTransformMaskParamsInterfaceSP params = transformMask->transformParams();
400 params->setHidden(true);
401
403 new KisSimpleModifyTransformMaskCommand(transformMask,
404 params)),
407 }
408 } else if (cch) {
411 QPolygon hull = calculateConvexHull();
412 if (!hull.isEmpty()) {
413 Q_EMIT sigConvexHullCalculated(hull, this);
414 }
415 }
416 } else {
418 }
419}
KisDeleteLaterWrapper< T > * makeKisDeleteLaterWrapper(T value)
const KoID GrayAColorModelID("GRAYA", ki18n("Grayscale/Alpha"))
const KoID Integer8BitsColorDepthID("U8", ki18n("8-bit integer/channel"))
void waitForDone()
void refreshGraphAsync(KisNodeSP root, const QVector< QRect > &rects, const QRect &cropRect, KisProjectionUpdateFlags flags=KisProjectionUpdateFlag::None) override
KisGroupLayerSP rootLayer() const
const KoColorSpace * colorSpace() const
KisImageAnimationInterface * animationInterface() const
KisPaintDeviceSP projection() const
QRect bounds() const override
void setRootLayer(KisGroupLayerSP rootLayer)
void setDefaultBounds(KisDefaultBoundsBaseSP bounds)
QRect exactBounds() const
QRect extent() const
KisDefaultBoundsBaseSP defaultBounds() const
void convertTo(const KoColorSpace *dstColorSpace, KoColorConversionTransformation::Intent renderingIntent=KoColorConversionTransformation::internalRenderingIntent(), KoColorConversionTransformation::ConversionFlags conversionFlags=KoColorConversionTransformation::internalConversionFlags(), KUndo2Command *parentCommand=nullptr, KoUpdater *progressUpdater=nullptr)
void doStrokeCallback(KisStrokeJobData *data) override
static void transformDevice(const ToolTransformArgs &config, KisPaintDeviceSP device, KisProcessingVisitor::ProgressHelper *helper)
static KisTransformWorker createTransformWorker(const ToolTransformArgs &config, KisPaintDeviceSP device, KoUpdaterPtr updater)
static void transformAndMergeDevice(const ToolTransformArgs &config, KisPaintDeviceSP src, KisPaintDeviceSP dst, KisProcessingVisitor::ProgressHelper *helper)
virtual quint32 pixelSize() const =0
virtual KoID colorDepthId() const =0
QString id() const
Definition KoID.cpp:63
void sigPreviewDeviceReady(KisPaintDeviceSP device)
boost::optional< ToolTransformArgs > m_savedTransformArgs
void sigConvexHullCalculated(QPolygon convexHull, void *cookie)
KisPaintDeviceSP createDeviceCache(KisPaintDeviceSP src)
void clearSelection(KisPaintDeviceSP device)
bool checkBelongsToSelection(KisPaintDeviceSP device) const
void putDeviceCache(KisPaintDeviceSP src, KisPaintDeviceSP cache)
QList< KisNodeSP > m_hiddenProjectionLeaves
QList< KisSelectionSP > m_deactivatedSelections
#define KIS_SAFE_ASSERT_RECOVER(cond)
Definition kis_assert.h:126
#define bounds(x, a, b)
T kisGrowRect(const T &rect, U offset)
Definition kis_global.h:186
QSharedPointer< KisTransformMaskParamsInterface > KisTransformMaskParamsInterfaceSP
KisSharedPtr< KisNode > KisNodeSP
Definition kis_types.h:86
void recursiveApplyNodes(NodePointer node, Functor func)
void refreshHiddenAreaAsync(KisImageSP image, KisNodeSP rootNode, const QRect &preparedArea)
void forceAllDelayedNodesUpdate(KisNodeSP root)
virtual KisPaintDeviceSP projection() const =0
KisImageWSP image
void setPassThroughMode(bool value)
bool addNode(KisNodeSP node, KisNodeSP parent=KisNodeSP(), KisNodeAdditionFlags flags=KisNodeAdditionFlag::None)
KisProjectionLeafSP projectionLeaf
Definition kis_node.cpp:93
virtual KisNodeSP clone() const =0
quint32 childCount() const
Definition kis_node.cpp:414
void setVisible(bool visible)
static KoColorSpaceRegistry * instance()

References KisNodeFacade::addNode(), KisImage::animationInterface(), KisImage::bounds(), bounds, calculateConvexHull(), checkBelongsToSelection(), KisNode::childCount(), clearSelection(), KisNode::clone(), KoColorSpace::colorDepthId(), KoColorSpace::colorModelId(), KisImage::colorSpace(), KisPaintDevice::colorSpace(), KisStrokeJobData::CONCURRENT, TransformStrokeStrategy::TransformAllData::config, TransformStrokeStrategy::TransformData::config, KisPaintDevice::convertTo(), createDeviceCache(), KisTransformUtils::createTransformWorker(), KisImageAnimationInterface::currentTime(), KisSharedPtr< T >::data(), KoColor::data(), KisPaintDevice::defaultBounds(), TransformStrokeStrategy::TransformData::destination, KisStrokeStrategyUndoCommandBased::doStrokeCallback(), KisTransaction::endAndTake(), KisPaintDevice::exactBounds(), KisImageAnimationInterface::explicitlySetCurrentTime(), KisBaseNode::extent(), KisPaintDevice::extent(), KisLayerUtils::forceAllDelayedNodesUpdate(), ToolTransformArgs::FREE_TRANSFORM, getDeviceCache(), GrayAColorModelID, haveDeviceInCache(), KoID::id(), KisBaseNode::image, KoColorSpaceRegistry::instance(), Integer8BitsColorDepthID, KIS_SAFE_ASSERT_RECOVER, kisGrowRect(), m_convexHullHasBeenCalculated, m_deactivatedSelections, m_hiddenProjectionLeaves, m_processedNodes, m_rootNodes, m_savedTransformArgs, m_selection, m_updateData, makeKisDeleteLaterWrapper(), ToolTransformArgs::mode(), KisSequentialIteratorBase< IteratorPolicy, SourcePolicy, ProgressPolicy >::nextPixel(), TransformStrokeStrategy::TransformData::node, TransformStrokeStrategy::ClearSelectionData::node, KisStrokeJobData::NORMAL, TransformStrokeStrategy::TransformData::PAINT_DEVICE, KisBaseNode::paintDevice(), ToolTransformArgs::PERSPECTIVE_4POINT, KisSelection::pixelSelection, KoColorSpace::pixelSize(), KisImage::projection(), KisBaseNode::projection(), KisNode::projectionLeaf, KisNode::projectionPlane(), putDeviceCache(), KisSequentialIteratorBase< IteratorPolicy, SourcePolicy, ProgressPolicy >::rawData(), KisSequentialIteratorBase< IteratorPolicy, SourcePolicy, ProgressPolicy >::rawDataConst(), KisLayerUtils::recursiveApplyNodes(), KisImage::refreshGraphAsync(), KisLayerUtils::refreshHiddenAreaAsync(), KisImage::rootLayer(), KisStrokeStrategyUndoCommandBased::runAndSaveCommand(), KisImageConfig::selectionOverlayMaskColor(), KisStrokeJobData::SEQUENTIAL, KisPaintDevice::setDefaultBounds(), KoColor::setOpacity(), KisGroupLayer::setPassThroughMode(), KisImage::setRootLayer(), KisSelection::setVisible(), sigConvexHullCalculated(), sigPreviewDeviceReady(), KisTransformUtils::transformAndMergeDevice(), KisTransformUtils::transformDevice(), and KisImage::waitForDone().

◆ fetchUpdater()

KoUpdaterPtr TransformStrokeStrategy::fetchUpdater ( KisNodeSP node)
private

◆ finishStrokeCallback()

void TransformStrokeStrategy::finishStrokeCallback ( )
overridevirtual

Reimplemented from KisStrokeStrategyUndoCommandBased.

Definition at line 795 of file transform_stroke_strategy.cpp.

796{
797 if (!m_savedTransformArgs || m_savedTransformArgs->isUnchanging()) {
799 return;
800 }
801
803}

References cancelStrokeCallback(), finishStrokeImpl(), and m_savedTransformArgs.

◆ finishStrokeImpl()

void TransformStrokeStrategy::finishStrokeImpl ( bool applyTransform,
const ToolTransformArgs & args )
private

Since our finishStrokeCallback() initiates new jobs, cancellation request may come even after finishStrokeCallback() (cancellations may be called until there are no jobs left in the stroke's queue).

Therefore we should check for double-entry here and make sure the finalizing jobs are no cancellable.

Definition at line 710 of file transform_stroke_strategy.cpp.

711{
722 if (m_finalizingActionsStarted) return;
724
725 QVector<KisStrokeJobData *> mutatedJobs;
726
727 auto restoreTemporaryHiddenNodes = [this] () {
728 Q_FOREACH (KisNodeSP node, m_hiddenProjectionLeaves) {
729 node->projectionLeaf()->setTemporaryHiddenFromRendering(false);
730 if (KisDelayedUpdateNodeInterface *delayedNode = dynamic_cast<KisDelayedUpdateNodeInterface*>(node.data())) {
731 delayedNode->forceUpdateTimedNode();
732 } else {
733 node->setDirty();
734 }
735 }
736 };
737
738 if (applyTransform) {
740
741 m_updateData.reset(new KisBatchNodeUpdate());
742
743 KritaUtils::addJobBarrier(mutatedJobs, [this] () {
745 m_updatesDisabled = true;
747 });
748
749 Q_FOREACH (KisNodeSP node, m_processedNodes) {
750 mutatedJobs << new TransformData(TransformData::PAINT_DEVICE,
751 args,
752 node);
753 }
754 mutatedJobs << new TransformData(TransformData::SELECTION,
755 args,
756 m_rootNodes[0]);
757
758 KritaUtils::addJobBarrier(mutatedJobs, restoreTemporaryHiddenNodes);
759
760 KritaUtils::addJobBarrier(mutatedJobs, [this] () {
762 m_updatesDisabled = false;
763
764 m_updateData->compress();
766 });
767 } else {
768 KritaUtils::addJobBarrier(mutatedJobs, restoreTemporaryHiddenNodes);
769 }
770
771 KritaUtils::addJobBarrier(mutatedJobs, [this, applyTransform]() {
772 Q_FOREACH (KisSelectionSP selection, m_deactivatedSelections) {
773 selection->setVisible(true);
774 }
775
776 Q_FOREACH(KisSelectionMaskSP deactivatedOverlaySelectionMask, m_deactivatedOverlaySelectionMasks) {
777 deactivatedOverlaySelectionMask->selection()->setVisible(true);
778 deactivatedOverlaySelectionMask->setDirty();
779 }
780
781 if (applyTransform) {
783 } else {
785 }
786 });
787
788 for (auto it = mutatedJobs.begin(); it != mutatedJobs.end(); ++it) {
789 (*it)->setCancellable(false);
790 }
791
792 addMutatedJobs(mutatedJobs);
793}
The KisDelayedUpdateNodeInterface class is an interface for nodes that delay their real updates with ...
void addMutatedJobs(const QVector< KisStrokeJobData * > list)
virtual void disableDirtyRequests()=0
QList< KisSelectionMaskSP > m_deactivatedOverlaySelectionMasks
QSharedPointer< T > toQShared(T *ptr)
void addJobBarrier(QVector< Job * > &jobs, Func func)
KisSelectionSP selection
Definition kis_mask.cc:44
virtual void setDirty()
Definition kis_node.cpp:577
void setDirty(const QVector< QRect > &rects) override

References KritaUtils::addJobBarrier(), KisStrokeStrategy::addMutatedJobs(), KisStrokeJobData::BARRIER, KisStrokeStrategyUndoCommandBased::cancelStrokeCallback(), KisSharedPtr< T >::data(), KisUpdatesFacade::disableDirtyRequests(), KisUpdatesFacade::enableDirtyRequests(), KisCommandUtils::FlipFlopCommand::FINALIZING, KisStrokeStrategyUndoCommandBased::finishStrokeCallback(), KisCommandUtils::FlipFlopCommand::INITIALIZING, m_deactivatedOverlaySelectionMasks, m_deactivatedSelections, m_finalizingActionsStarted, m_hiddenProjectionLeaves, m_processedNodes, m_rootNodes, m_savedTransformArgs, m_updateData, m_updatesDisabled, m_updatesFacade, KisStrokeJobData::NORMAL, TransformStrokeStrategy::TransformData::PAINT_DEVICE, KisNode::projectionLeaf, KisStrokeStrategyUndoCommandBased::runAndSaveCommand(), KisMask::selection, TransformStrokeStrategy::TransformData::SELECTION, KisNode::setDirty(), KisSelectionMask::setDirty(), KisSelection::setVisible(), and toQShared().

◆ getDeviceCache()

KisPaintDeviceSP TransformStrokeStrategy::getDeviceCache ( KisPaintDeviceSP src)
private

Definition at line 114 of file transform_stroke_strategy.cpp.

115{
116 QMutexLocker l(&m_devicesCacheMutex);
117 KisPaintDeviceSP cache = m_devicesCacheHash.value(src.data());
118 if (!cache) {
119 warnKrita << "WARNING: Transform Stroke: the device is absent in cache!";
120 }
121
122 return cache;
123}
QHash< KisPaintDevice *, KisPaintDeviceSP > m_devicesCacheHash
#define warnKrita
Definition kis_debug.h:87

References m_devicesCacheHash, m_devicesCacheMutex, and warnKrita.

◆ haveDeviceInCache()

bool TransformStrokeStrategy::haveDeviceInCache ( KisPaintDeviceSP src)
private

Definition at line 102 of file transform_stroke_strategy.cpp.

103{
104 QMutexLocker l(&m_devicesCacheMutex);
105 return m_devicesCacheHash.contains(src.data());
106}

References m_devicesCacheHash, and m_devicesCacheMutex.

◆ initStrokeCallback()

void TransformStrokeStrategy::initStrokeCallback ( )
overridevirtual

We must request shape layers to rerender areas outside image bounds

We must ensure that the currently selected subtree has finished all its updates.

Disable all decorated nodes to generate outline and preview correctly. We will enable them back as soon as preview generation is finished.

Filter masks have special handling of transparency. Their filter may declare if they affect transparent pixels or not. In case of transformations we don't care about that, we should just transform non-default area of the mask.

We shouldn't include masks or layer styles into the handles rect, in the end, we process the paint device only

recover back visibility of decorated nodes

Reimplemented from KisStrokeStrategyUndoCommandBased.

Definition at line 508 of file transform_stroke_strategy.cpp.

509{
511
513
514 if (m_selection) {
515 m_selection->setVisible(false);
517 }
518
519 Q_FOREACH(KisNodeSP node, m_rootNodes) {
520 KisSelectionMaskSP overlaySelectionMask =
521 dynamic_cast<KisSelectionMask*>(node->graphListener()->graphOverlayNode());
522 if (overlaySelectionMask) {
523 overlaySelectionMask->setDecorationsVisible(false);
524 m_deactivatedOverlaySelectionMasks.append(overlaySelectionMask);
525 }
526 }
527
528 if (m_rootNodes.size() == 1){
529 KisNodeSP rootNode = m_rootNodes[0];
531
532 if (rootNode->inherits("KisTransformMask") && rootNode->projectionLeaf()->isDroppedNode()) {
533 rootNode.clear();
534 m_processedNodes.clear();
535
537 Q_EMIT sigTransactionGenerated(transaction, m_initialTransformArgs, this);
538 return;
539 }
540 }
541
542 ToolTransformArgs initialTransformArgs;
543 bool isExternalSourcePresent = false;
545
546 bool argsAreInitialized = false;
547 QVector<KisStrokeJobData *> lastCommandUndoJobs;
548
550 m_mode,
553 undoFacade(),
555 &lastCommandUndoJobs,
557 argsAreInitialized = true;
558 } else if (!m_forceReset && KisTransformUtils::tryInitArgsFromNode(m_rootNodes, &initialTransformArgs)) {
559 argsAreInitialized = true;
560 }
561
562 QVector<KisStrokeJobData *> extraInitJobs;
563
565
566 extraInitJobs << lastCommandUndoJobs;
567
568 KritaUtils::addJobSequential(extraInitJobs, [this]() {
569 // When dealing with animated transform mask layers, create keyframe and save the command for undo.
570 // NOTE: for transform masks we create a keyframe no matter what the user
571 // settings are
572 Q_FOREACH (KisNodeSP node, m_processedNodes) {
573 if (KisTransformMask* transformMask = dynamic_cast<KisTransformMask*>(node.data())) {
576 }
578 node->hasEditablePaintDevice()){
579
580 KUndo2Command *autoKeyframeCommand =
583 if (autoKeyframeCommand) {
585 }
586 }
587 }
588 });
589
590 KritaUtils::addJobSequential(extraInitJobs, [this]() {
594 Q_FOREACH(KisNodeSP node, m_rootNodes) {
596 }
597 });
598
599 KritaUtils::addJobBarrier(extraInitJobs, [this]() {
604 Q_FOREACH(KisNodeSP node, m_rootNodes) {
606 }
607 });
608
612 KritaUtils::addJobBarrier(extraInitJobs, [this]() {
613 Q_FOREACH (KisNodeSP node, m_processedNodes) {
614 KisDecoratedNodeInterface *decoratedNode = dynamic_cast<KisDecoratedNodeInterface*>(node.data());
615 if (decoratedNode && decoratedNode->decorationsVisible()) {
616 decoratedNode->setDecorationsVisible(false);
617 m_disabledDecoratedNodes << decoratedNode;
618 }
619 }
620 });
621
622 KritaUtils::addJobBarrier(extraInitJobs, [this, initialTransformArgs, argsAreInitialized]() mutable {
623 QRect srcRect;
624
625 if (m_selection) {
626 srcRect = m_selection->selectedExactRect();
627 } else {
628 srcRect = QRect();
629 Q_FOREACH (KisNodeSP node, m_processedNodes) {
630 // group layers may have a projection of layers
631 // that are locked and will not be transformed
632 if (node->inherits("KisGroupLayer")) continue;
633
634 if (const KisTransformMask *mask = dynamic_cast<const KisTransformMask*>(node.data())) {
635 srcRect |= mask->sourceDataBounds();
636 } else if (const KisSelectionMask *mask = dynamic_cast<const KisSelectionMask*>(node.data())) {
637 srcRect |= mask->selection()->selectedExactRect();
638 } else if (const KisTransparencyMask *mask = dynamic_cast<const KisTransparencyMask*>(node.data())) {
639 srcRect |= mask->selection()->selectedExactRect();
640 } else if (const KisFilterMask *mask = dynamic_cast<const KisFilterMask*>(node.data())) {
645 if (mask->paintDevice()) {
646 srcRect |= mask->paintDevice()->nonDefaultPixelArea();
647 }
648 } else {
651 srcRect |= node->paintDevice() ? node->paintDevice()->exactBounds() : node->exactBounds();
652 }
653 }
654 }
655
656 TransformTransactionProperties transaction(srcRect, &initialTransformArgs, m_rootNodes, m_processedNodes);
657 if (!argsAreInitialized) {
658 initialTransformArgs = KisTransformUtils::resetArgsForMode(m_mode, m_filterId, transaction, 0);
659 }
660
661 this->m_initialTransformArgs = initialTransformArgs;
662 if (transaction.currentConfig()->boundsRotation() != 0.0) {
664 transaction.setConvexHull(calculateConvexHull());
665 transaction.setConvexHullHasBeenRequested(true);
666 }
667 Q_EMIT this->sigTransactionGenerated(transaction, initialTransformArgs, this);
668 });
669
670 extraInitJobs << new PreparePreviewData();
671
673
674 KritaUtils::addJobBarrier(extraInitJobs, [this, sharedData]() {
676 Q_FOREACH (KisNodeSP root, filteredRoots) {
677 sharedData->addUpdate(root, root->projectionPlane()->tightUserVisibleBounds());
678 }
679 });
680
681 extraInitJobs << new Data(new KisUpdateCommandEx(sharedData, m_updatesFacade, KisUpdateCommandEx::INITIALIZING), false, Data::BARRIER);
682
683 Q_FOREACH (KisNodeSP node, m_processedNodes) {
684 extraInitJobs << new ClearSelectionData(node);
685 }
686
687 extraInitJobs << new Data(new KisUpdateCommandEx(sharedData, m_updatesFacade, KisUpdateCommandEx::FINALIZING), false, Data::BARRIER);
688
690 KritaUtils::addJobBarrier(extraInitJobs, [this]() {
691 Q_FOREACH (KisDecoratedNodeInterface *decoratedNode, m_disabledDecoratedNodes) {
692 decoratedNode->setDecorationsVisible(true);
693 }
695 });
696
698
699 if (!lastCommandUndoJobs.isEmpty()) {
701
702 for (auto it = extraInitJobs.begin(); it != extraInitJobs.end(); ++it) {
703 (*it)->setCancellable(false);
704 }
705 }
706
707 addMutatedJobs(extraInitJobs);
708}
virtual bool decorationsVisible() const =0
virtual void setDecorationsVisible(bool value, bool update)=0
static ToolTransformArgs resetArgsForMode(ToolTransformArgs::TransformMode mode, const QString &filterId, const TransformTransactionProperties &transaction, KisPaintDeviceSP externalSource)
static int fetchCurrentImageTime(KisNodeList rootNodes)
static QList< KisNodeSP > fetchNodesList(ToolTransformArgs::TransformMode mode, KisNodeList rootNodes, bool isExternalSourcePresent, KisSelectionSP selection)
static KisNodeSP tryOverrideRootToTransformMask(KisNodeSP root)
static bool tryInitArgsFromNode(KisNodeList rootNodes, ToolTransformArgs *args)
static bool tryFetchArgsFromCommandAndUndo(ToolTransformArgs *outArgs, ToolTransformArgs::TransformMode mode, KisNodeList currentNodes, KisNodeList selectedNodes, KisStrokeUndoFacade *undoFacade, int currentTime, QVector< KisStrokeJobData * > *undoJobs, const KisSavedMacroCommand **overriddenCommand)
const KisSavedMacroCommand * m_overriddenCommand
QVector< KisDecoratedNodeInterface * > m_disabledDecoratedNodes
void sigTransactionGenerated(TransformTransactionProperties transaction, ToolTransformArgs args, void *cookie)
KUndo2Command * tryAutoCreateDuplicatedFrame(KisPaintDeviceSP device, AutoCreateKeyframeFlags flags)
create a new duplicated keyframe if auto-keyframe mode is on
KisNodeList sortAndFilterMergeableInternalNodes(KisNodeList nodes, bool allowMasks)
void forceAllHiddenOriginalsUpdate(KisNodeSP root)
void addJobSequential(QVector< Job * > &jobs, Func func)
virtual QRect exactBounds() const
bool hasEditablePaintDevice() const
virtual KisNode * graphOverlayNode() const
virtual KisAbstractProjectionPlaneSP projectionPlane() const
Definition kis_node.cpp:240
KisNodeGraphListener * graphListener
Definition kis_node.cpp:87
void setDecorationsVisible(bool value, bool update) override

References KisAutoKey::activeMode(), KritaUtils::addJobBarrier(), KritaUtils::addJobSequential(), KisStrokeStrategy::addMutatedJobs(), KisStrokeJobData::BARRIER, ToolTransformArgs::boundsRotation(), calculateConvexHull(), KisSharedPtr< T >::clear(), TransformTransactionProperties::currentConfig(), KisSharedPtr< T >::data(), KisDecoratedNodeInterface::decorationsVisible(), KisBaseNode::exactBounds(), KisPaintDevice::exactBounds(), KisTransformUtils::fetchCurrentImageTime(), KisTransformUtils::fetchNodesList(), KisCommandUtils::FlipFlopCommand::FINALIZING, KisLayerUtils::forceAllDelayedNodesUpdate(), KisLayerUtils::forceAllHiddenOriginalsUpdate(), KisNode::graphListener, KisNodeGraphListener::graphOverlayNode(), KisBaseNode::hasEditablePaintDevice(), KisCommandUtils::FlipFlopCommand::INITIALIZING, KisStrokeStrategyUndoCommandBased::initStrokeCallback(), KIS_SAFE_ASSERT_RECOVER_NOOP, m_convexHullHasBeenCalculated, m_currentTime, m_deactivatedOverlaySelectionMasks, m_deactivatedSelections, m_disabledDecoratedNodes, m_filterId, m_forceReset, m_initialTransformArgs, m_mode, m_overriddenCommand, m_processedNodes, m_rootNodes, m_selection, m_updatesFacade, KisLazyCreateTransformMaskKeyframesCommand::maskHasAnimation(), KisAutoKey::NONE, KisStrokeJobData::NORMAL, KisBaseNode::paintDevice(), KisNode::projectionLeaf, KisNode::projectionPlane(), KisTransformUtils::resetArgsForMode(), KisStrokeStrategyUndoCommandBased::runAndSaveCommand(), KisSelection::selectedExactRect(), TransformTransactionProperties::setConvexHull(), TransformTransactionProperties::setConvexHullHasBeenRequested(), KisSelectionMask::setDecorationsVisible(), KisDecoratedNodeInterface::setDecorationsVisible(), KisSelection::setVisible(), sigTransactionGenerated(), KisLayerUtils::sortAndFilterMergeableInternalNodes(), KisAutoKey::SupportsLod, toQShared(), KisAutoKey::tryAutoCreateDuplicatedFrame(), KisTransformUtils::tryFetchArgsFromCommandAndUndo(), KisTransformUtils::tryInitArgsFromNode(), KisTransformUtils::tryOverrideRootToTransformMask(), and KisStrokeStrategyUndoCommandBased::undoFacade().

◆ postProcessToplevelCommand()

void TransformStrokeStrategy::postProcessToplevelCommand ( KUndo2Command * command)
overrideprotectedvirtual

Applies some modifications (e.g. assigning extra data) to the toplevel command.

Reimplemented from KisStrokeStrategyUndoCommandBased.

Definition at line 434 of file transform_stroke_strategy.cpp.

435{
437
444
446}
virtual void postProcessToplevelCommand(KUndo2Command *command)
Applies some modifications (e.g. assigning extra data) to the toplevel command.
static void postProcessToplevelCommand(KUndo2Command *command, const ToolTransformArgs &args, KisNodeList rootNodes, KisNodeList processedNodes, int currentTime, const KisSavedMacroCommand *overriddenCommand)
#define KIS_SAFE_ASSERT_RECOVER_RETURN(cond)
Definition kis_assert.h:128

References KIS_SAFE_ASSERT_RECOVER_RETURN, m_currentTime, m_overriddenCommand, m_processedNodes, m_rootNodes, m_savedTransformArgs, KisStrokeStrategyUndoCommandBased::postProcessToplevelCommand(), and KisTransformUtils::postProcessToplevelCommand().

◆ putDeviceCache()

void TransformStrokeStrategy::putDeviceCache ( KisPaintDeviceSP src,
KisPaintDeviceSP cache )
private

Definition at line 108 of file transform_stroke_strategy.cpp.

109{
110 QMutexLocker l(&m_devicesCacheMutex);
111 m_devicesCacheHash.insert(src.data(), cache);
112}

References m_devicesCacheHash, and m_devicesCacheMutex.

◆ sigConvexHullCalculated

void TransformStrokeStrategy::sigConvexHullCalculated ( QPolygon convexHull,
void * cookie )
signal

◆ sigPreviewDeviceReady

void TransformStrokeStrategy::sigPreviewDeviceReady ( KisPaintDeviceSP device)
signal

◆ sigTransactionGenerated

void TransformStrokeStrategy::sigTransactionGenerated ( TransformTransactionProperties transaction,
ToolTransformArgs args,
void * cookie )
signal

Member Data Documentation

◆ m_convexHullHasBeenCalculated

bool TransformStrokeStrategy::m_convexHullHasBeenCalculated = false
private

Definition at line 156 of file transform_stroke_strategy.h.

◆ m_currentTime

int TransformStrokeStrategy::m_currentTime = -1
private

Definition at line 146 of file transform_stroke_strategy.h.

◆ m_deactivatedOverlaySelectionMasks

QList<KisSelectionMaskSP> TransformStrokeStrategy::m_deactivatedOverlaySelectionMasks
private

Definition at line 149 of file transform_stroke_strategy.h.

◆ m_deactivatedSelections

QList<KisSelectionSP> TransformStrokeStrategy::m_deactivatedSelections
private

Definition at line 147 of file transform_stroke_strategy.h.

◆ m_devicesCacheHash

QHash<KisPaintDevice*, KisPaintDeviceSP> TransformStrokeStrategy::m_devicesCacheHash
private

Definition at line 138 of file transform_stroke_strategy.h.

◆ m_devicesCacheMutex

QMutex TransformStrokeStrategy::m_devicesCacheMutex
private

Definition at line 137 of file transform_stroke_strategy.h.

◆ m_disabledDecoratedNodes

QVector<KisDecoratedNodeInterface*> TransformStrokeStrategy::m_disabledDecoratedNodes
private

Definition at line 150 of file transform_stroke_strategy.h.

◆ m_filterId

QString TransformStrokeStrategy::m_filterId
private

Definition at line 132 of file transform_stroke_strategy.h.

◆ m_finalizingActionsStarted

bool TransformStrokeStrategy::m_finalizingActionsStarted = false
private

Definition at line 155 of file transform_stroke_strategy.h.

◆ m_forceReset

bool TransformStrokeStrategy::m_forceReset
private

Definition at line 133 of file transform_stroke_strategy.h.

◆ m_hiddenProjectionLeaves

QList<KisNodeSP> TransformStrokeStrategy::m_hiddenProjectionLeaves
private

Definition at line 148 of file transform_stroke_strategy.h.

◆ m_initialTransformArgs

ToolTransformArgs TransformStrokeStrategy::m_initialTransformArgs
private

Definition at line 142 of file transform_stroke_strategy.h.

◆ m_mode

ToolTransformArgs::TransformMode TransformStrokeStrategy::m_mode
private

Definition at line 131 of file transform_stroke_strategy.h.

◆ m_overriddenCommand

const KisSavedMacroCommand* TransformStrokeStrategy::m_overriddenCommand = 0
private

Definition at line 152 of file transform_stroke_strategy.h.

◆ m_processedNodes

KisNodeList TransformStrokeStrategy::m_processedNodes
private

Definition at line 145 of file transform_stroke_strategy.h.

◆ m_rootNodes

KisNodeList TransformStrokeStrategy::m_rootNodes
private

Definition at line 144 of file transform_stroke_strategy.h.

◆ m_savedTransformArgs

boost::optional<ToolTransformArgs> TransformStrokeStrategy::m_savedTransformArgs
private

Definition at line 143 of file transform_stroke_strategy.h.

◆ m_selection

KisSelectionSP TransformStrokeStrategy::m_selection
private

Definition at line 135 of file transform_stroke_strategy.h.

◆ m_skippedWhileMergeCommands

QVector<const KUndo2Command*> TransformStrokeStrategy::m_skippedWhileMergeCommands
private

Definition at line 153 of file transform_stroke_strategy.h.

◆ m_updateData

KisBatchNodeUpdateSP TransformStrokeStrategy::m_updateData
private

Definition at line 129 of file transform_stroke_strategy.h.

◆ m_updatesDisabled

bool TransformStrokeStrategy::m_updatesDisabled = false
private

Definition at line 130 of file transform_stroke_strategy.h.

◆ m_updatesFacade

KisUpdatesFacade* TransformStrokeStrategy::m_updatesFacade
private

Definition at line 128 of file transform_stroke_strategy.h.

◆ writeToTransformMask

KisTransformMaskSP TransformStrokeStrategy::writeToTransformMask
private

Definition at line 140 of file transform_stroke_strategy.h.


The documentation for this class was generated from the following files: