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

Made the Wrap-Around Mode be activated on per-tool basis

Now the stroke strategy will report whether the stoke supports the
wrap around mode or not. And the image will activate it only if two
conditions are met: the mode is permitted by the user and the stroke
supports it.
parent 68b55bb7
......@@ -57,7 +57,7 @@ QRect KisDefaultBounds::bounds() const
bool KisDefaultBounds::wrapAroundMode() const
{
return m_d->image ? m_d->image->wrapAroundMode() : false;
return m_d->image ? m_d->image->wrapAroundModeActive() : false;
}
/******************************************************************/
......
......@@ -111,7 +111,7 @@ public:
QList<KisLayer*> dirtyLayers; // for thumbnails
QList<KisLayerComposition*> compositions;
KisNodeSP isolatedRootNode;
bool wrapAroundMode;
bool wrapAroundModePermitted;
KisNameServer *nserver;
......@@ -1535,7 +1535,13 @@ void KisImage::requestProjectionUpdate(KisNode *node, const QRect& rect)
{
if (m_d->disableDirtyRequests) return;
if (m_d->wrapAroundMode) {
/**
* Here we use 'permitted' instead of 'active' intentively,
* because the updates may come after the actual stroke has been
* finished. And having some more updates for the stroke not
* supporting the wrap-around mode will not make much harm.
*/
if (m_d->wrapAroundModePermitted) {
QRect boundRect = bounds();
KisWrappedRect splitRect(rect, boundRect);
......@@ -1563,14 +1569,20 @@ void KisImage::removeComposition(KisLayerComposition* composition)
delete composition;
}
void KisImage::setWrapAroundMode(bool value)
void KisImage::setWrapAroundModePermitted(bool value)
{
m_d->wrapAroundModePermitted = value;
}
bool KisImage::wrapAroundModePermitted() const
{
m_d->wrapAroundMode = value;
return m_d->wrapAroundModePermitted;
}
bool KisImage::wrapAroundMode() const
bool KisImage::wrapAroundModeActive() const
{
return m_d->wrapAroundMode;
return m_d->wrapAroundModePermitted && m_d->scheduler &&
m_d->scheduler->wrapAroundModeSupported();
}
#include "kis_image.moc"
......
......@@ -491,17 +491,32 @@ public:
void removeComposition(KisLayerComposition* composition);
/**
* Enables/Disables the wrap-around mode on all the paint
* devices of the image
* Permit or deny the wrap-around mode for all the paint devices
* of the image. Note that permitting the wraparound mode will not
* necessarily activate it right now. To be activated the wrap
* around mode should be 1) permitted; 2) supported by the
* currently running stroke.
*/
void setWrapAroundMode(bool value);
void setWrapAroundModePermitted(bool value);
/**
* \return whether the wrap-around mode is active
* \return whether the wrap-around mode is permitted for this
* image. If the wrap around mode is permitted and the
* currently running stroke supports it, the mode will be
* activated for all paint devices of the image.
*
* \see setWrapAroundMode
*/
bool wrapAroundMode() const;
bool wrapAroundModePermitted() const;
/**
* \return whether the wraparound mode is activated for all the
* devices of the image. The mode is activated when both
* factors are true: the user permitted it and the stroke
* supports it
*/
bool wrapAroundModeActive() const;
public:
void startIsolatedMode(KisNodeSP node);
......
......@@ -157,6 +157,11 @@ bool KisStroke::isExclusive() const
return m_strokeStrategy->isExclusive();
}
bool KisStroke::supportsWrapAroundMode() const
{
return m_strokeStrategy->supportsWrapAroundMode();
}
bool KisStroke::prevJobSequential() const
{
return m_prevJobSequential;
......
......@@ -47,6 +47,7 @@ public:
bool isEnded() const;
bool isExclusive() const;
bool supportsWrapAroundMode() const;
bool prevJobSequential() const;
bool nextJobSequential() const;
......
......@@ -22,6 +22,7 @@
KisStrokeStrategy::KisStrokeStrategy(QString id, QString name)
: m_exclusive(false),
m_supportsWrapAroundMode(false),
m_needsIndirectPainting(false),
m_indirectPaintingCompositeOp(COMPOSITE_ALPHA_DARKEN),
m_id(id),
......@@ -74,6 +75,11 @@ bool KisStrokeStrategy::isExclusive() const
return m_exclusive;
}
bool KisStrokeStrategy::supportsWrapAroundMode() const
{
return m_supportsWrapAroundMode;
}
bool KisStrokeStrategy::needsIndirectPainting() const
{
return m_needsIndirectPainting;
......@@ -99,6 +105,11 @@ void KisStrokeStrategy::setExclusive(bool value)
m_exclusive = value;
}
void KisStrokeStrategy::setSupportsWrapAroundMode(bool value)
{
m_supportsWrapAroundMode = value;
}
void KisStrokeStrategy::setNeedsIndirectPainting(bool value)
{
m_needsIndirectPainting = value;
......
......@@ -42,6 +42,7 @@ public:
virtual KisStrokeJobData* createCancelData();
bool isExclusive() const;
bool supportsWrapAroundMode() const;
bool needsIndirectPainting() const;
QString indirectPaintingCompositeOp() const;
......@@ -68,11 +69,13 @@ protected:
// after the KisStroke object has been created
void setExclusive(bool value);
void setSupportsWrapAroundMode(bool value);
void setNeedsIndirectPainting(bool value);
void setIndirectPaintingCompositeOp(const QString &id);
private:
bool m_exclusive;
bool m_supportsWrapAroundMode;
bool m_needsIndirectPainting;
QString m_indirectPaintingCompositeOp;
......
......@@ -25,10 +25,13 @@
#include "kis_updater_context.h"
struct KisStrokesQueue::Private {
Private() : needsExclusiveAccess(false) {}
Private()
: needsExclusiveAccess(false),
wrapAroundModeSupported(false) {}
QQueue<KisStrokeSP> strokesQueue;
bool needsExclusiveAccess;
bool wrapAroundModeSupported;
QMutex mutex;
};
......@@ -105,6 +108,11 @@ bool KisStrokesQueue::needsExclusiveAccess() const
return m_d->needsExclusiveAccess;
}
bool KisStrokesQueue::wrapAroundModeSupported() const
{
return m_d->wrapAroundModeSupported;
}
bool KisStrokesQueue::isEmpty() const
{
QMutexLocker locker(&m_d->mutex);
......@@ -169,6 +177,7 @@ bool KisStrokesQueue::checkStrokeState(bool hasStrokeJobsRunning)
if(!stroke->isInitialized() && stroke->hasJobs()) {
m_d->needsExclusiveAccess = stroke->isExclusive();
m_d->wrapAroundModeSupported = stroke->supportsWrapAroundMode();
result = true;
}
else if(stroke->hasJobs()){
......@@ -177,6 +186,7 @@ bool KisStrokesQueue::checkStrokeState(bool hasStrokeJobsRunning)
else if(stroke->isEnded() && !hasStrokeJobsRunning) {
m_d->strokesQueue.dequeue(); // deleted by shared pointer
m_d->needsExclusiveAccess = false;
m_d->wrapAroundModeSupported = false;
if(!m_d->strokesQueue.isEmpty()) {
result = checkStrokeState(false);
......
......@@ -46,6 +46,8 @@ public:
qint32 sizeMetric() const;
QString currentStrokeName() const;
bool wrapAroundModeSupported() const;
private:
bool processOneJob(KisUpdaterContext &updaterContext, bool externalJobsPending);
bool checkStrokeState(bool hasStrokeJobsRunning);
......
......@@ -199,6 +199,11 @@ bool KisUpdateScheduler::cancelStroke(KisStrokeId id)
return result;
}
bool KisUpdateScheduler::wrapAroundModeSupported() const
{
return m_d->strokesQueue->wrapAroundModeSupported();
}
void KisUpdateScheduler::updateSettings()
{
if(m_d->updatesQueue) {
......
......@@ -130,6 +130,8 @@ public:
void endStroke(KisStrokeId id);
bool cancelStroke(KisStrokeId id);
bool wrapAroundModeSupported() const;
protected:
// Trivial constructor for testing support
KisUpdateScheduler();
......
......@@ -151,5 +151,5 @@ void KisCanvasController::slotToggleWrapAroundMode(bool value)
Q_ASSERT(kritaCanvas);
kritaCanvas->setWrapAroundViewingMode(value);
kritaCanvas->image()->setWrapAroundMode(value);
kritaCanvas->image()->setWrapAroundModePermitted(value);
}
......@@ -52,6 +52,7 @@ void FreehandStrokeStrategy::init(bool needsIndirectPainting,
{
setNeedsIndirectPainting(needsIndirectPainting);
setIndirectPaintingCompositeOp(indirectPaintingCompositeOp);
setSupportsWrapAroundMode(true);
enableJob(KisSimpleStrokeStrategy::JOB_DOSTROKE);
}
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment