mirror of
https://github.com/MaurycyLiebner/enve.git
synced 2024-12-22 00:22:24 +00:00
Compare commits
4 Commits
ce2e6b04da
...
88171af028
Author | SHA1 | Date | |
---|---|---|---|
|
88171af028 | ||
|
96b918b8b0 | ||
|
2d20230608 | ||
|
96eae885e6 |
src
app/GUI/ColorWidgets
core
@ -18,6 +18,10 @@
|
||||
|
||||
#include "colorvaluerect.h"
|
||||
#include "colorlabel.h"
|
||||
#include "colorpickingwidget.h"
|
||||
#include "GUI/mainwindow.h"
|
||||
#include "GUI/actionbutton.h"
|
||||
#include <QWindow>
|
||||
|
||||
#include <QVBoxLayout>
|
||||
|
||||
@ -75,7 +79,15 @@ PaintColorWidget::PaintColorWidget(QWidget* const parent) :
|
||||
|
||||
layout->addWidget(aRect);
|
||||
|
||||
layout->addWidget(mColorLabel);
|
||||
const QString pickIcon = "toolbarButtons/pickUnchecked.png";
|
||||
const auto pickingButton = new ActionButton(pickIcon, "", this);
|
||||
connect(pickingButton, &ActionButton::released,
|
||||
this, &PaintColorWidget::startColorPicking);
|
||||
|
||||
const auto colorPickLay = new QHBoxLayout();
|
||||
colorPickLay->addWidget(mColorLabel);
|
||||
colorPickLay->addWidget(pickingButton);
|
||||
layout->addLayout(colorPickLay);
|
||||
|
||||
setLayout(layout);
|
||||
}
|
||||
@ -111,6 +123,16 @@ void PaintColorWidget::setDisplayedColor(const QColor& color) {
|
||||
mColorLabel->setAlpha(color.alphaF());
|
||||
}
|
||||
|
||||
void PaintColorWidget::startColorPicking() {
|
||||
const auto parent = MainWindow::sGetInstance();
|
||||
const auto screen = parent->windowHandle()->screen();
|
||||
const auto wid = new ColorPickingWidget(screen, parent);
|
||||
connect(wid, &ColorPickingWidget::colorSelected,
|
||||
[this](const QColor & color) {
|
||||
setColor(color);
|
||||
});
|
||||
}
|
||||
|
||||
void PaintColorWidget::setColor(const QColor& color) {
|
||||
setDisplayedColor(color);
|
||||
emit colorChanged(color);
|
||||
|
@ -32,6 +32,7 @@ public:
|
||||
signals:
|
||||
void colorChanged(const QColor& color);
|
||||
private:
|
||||
void startColorPicking();
|
||||
void setColor(const QColor& color);
|
||||
|
||||
void updateFromRGB();
|
||||
|
@ -186,16 +186,8 @@ void BasicTransformAnimator::moveByAbs(const QPointF &absTrans) {
|
||||
if(!mParentTransform) return;
|
||||
const auto savedRelPos = mPosAnimator->getSavedValue();
|
||||
const auto savedAbsPos = mParentTransform->mapRelPosToAbs(savedRelPos);
|
||||
moveToAbs(savedAbsPos + absTrans);
|
||||
}
|
||||
|
||||
void BasicTransformAnimator::moveToAbs(const QPointF &absPos) {
|
||||
setAbsolutePos(absPos);
|
||||
}
|
||||
|
||||
void BasicTransformAnimator::setAbsolutePos(const QPointF &pos) {
|
||||
if(!mParentTransform) return;
|
||||
setRelativePos(mParentTransform->mapAbsPosToRel(pos));
|
||||
const auto relPos = mParentTransform->mapAbsPosToRel(savedAbsPos + absTrans);
|
||||
setRelativePos(relPos);
|
||||
}
|
||||
|
||||
void BasicTransformAnimator::setRelativePos(const QPointF &relPos) {
|
||||
|
@ -54,8 +54,6 @@ public:
|
||||
void startScaleTransform();
|
||||
|
||||
void setRelativePos(const QPointF &relPos);
|
||||
void setAbsolutePos(const QPointF &pos);
|
||||
void moveToAbs(const QPointF &absPos);
|
||||
void moveByAbs(const QPointF &absTrans);
|
||||
|
||||
void rotateRelativeToSavedValue(const qreal rotRel);
|
||||
|
@ -52,8 +52,10 @@ QList<BrushStrokeSet> BrushStrokeSet::sFromSkPath(
|
||||
if(segLists.isEmpty()) return result;
|
||||
for(auto& segs : segLists) {
|
||||
if(segs.isEmpty()) continue;
|
||||
const double totLen = segs.getTotalLength();
|
||||
if(isZero4Dec(totLen)) continue;
|
||||
const double minL = 0;
|
||||
const double maxL = segs.isClosed() ? 1 + 10/segs.getTotalLength() : 1;
|
||||
const double maxL = segs.isClosed() ? 1 + 10/totLen : 1;
|
||||
auto segsT = segs.getFragmentUnbound(minL, maxL);
|
||||
result << sFromCubicList(segsT, timeCurve,
|
||||
pressureCurve, widthCurve, spacingCurve);
|
||||
|
@ -29,6 +29,8 @@ BoundingBox* BoxTargetProperty::getTarget() const {
|
||||
|
||||
void BoxTargetProperty::setTargetAction(BoundingBox* const box) {
|
||||
if(box == mTarget_d) return;
|
||||
const auto oldValue = mTarget_d.get();
|
||||
emit setActionStarted(oldValue, box);
|
||||
{
|
||||
prp_pushUndoRedoName("Set Box Target");
|
||||
UndoRedo ur;
|
||||
@ -44,6 +46,7 @@ void BoxTargetProperty::setTargetAction(BoundingBox* const box) {
|
||||
}
|
||||
|
||||
setTarget(box);
|
||||
emit setActionFinished(oldValue, box);
|
||||
}
|
||||
|
||||
void BoxTargetProperty::setTarget(BoundingBox* const box) {
|
||||
|
@ -53,6 +53,8 @@ public:
|
||||
void setValidator(const Validator& validator)
|
||||
{ mValidator = validator; }
|
||||
signals:
|
||||
void setActionStarted(BoundingBox*, BoundingBox*);
|
||||
void setActionFinished(BoundingBox*, BoundingBox*);
|
||||
void targetSet(BoundingBox*);
|
||||
private:
|
||||
std::function<bool(BoundingBox*)> mValidator = nullptr;
|
||||
|
@ -34,10 +34,12 @@ CubicList::CubicList(const CubicList &src) {
|
||||
CubicList CubicList::getFragment(const qreal minLenFrac,
|
||||
const qreal maxLenFrac) const {
|
||||
if(minLenFrac > maxLenFrac) return CubicList();
|
||||
const qreal totLen = getTotalLength();
|
||||
if(isZero4Dec(totLen)) return *this;
|
||||
//Q_ASSERT(minLenFrac > 0);
|
||||
//Q_ASSERT(maxLenFrac < 1);
|
||||
const qreal minLen = getTotalLength()*CLAMP01(minLenFrac);
|
||||
const qreal maxLen = getTotalLength()*CLAMP01(maxLenFrac);
|
||||
const qreal minLen = totLen*CLAMP01(minLenFrac);
|
||||
const qreal maxLen = totLen*CLAMP01(maxLenFrac);
|
||||
qreal minT = 0, maxT = 1;
|
||||
int minI = -1, maxI = mSegments.count() - 1;
|
||||
qreal currLen = 0;
|
||||
@ -58,6 +60,7 @@ CubicList CubicList::getFragment(const qreal minLenFrac,
|
||||
break;
|
||||
}
|
||||
}
|
||||
if(minI == -1) return CubicList();
|
||||
|
||||
QList<qCubicSegment2D> fragSegs;
|
||||
if(minI == maxI) {
|
||||
|
@ -38,6 +38,51 @@ FollowObjectTransformEffect::FollowObjectTransformEffect() :
|
||||
ca_addChild(mRotInfluence);
|
||||
}
|
||||
|
||||
void FollowObjectTransformEffect::setRotScaleAfterTargetChange(
|
||||
BoundingBox* const oldTarget, BoundingBox* const newTarget) {
|
||||
const auto parent = getFirstAncestor<BoundingBox>();
|
||||
if(!parent) return;
|
||||
|
||||
const qreal scaleXInfl = mScaleInfluence->getEffectiveXValue();
|
||||
const qreal scaleYInfl = mScaleInfluence->getEffectiveYValue();
|
||||
const qreal rotInfl = mRotInfluence->getEffectiveValue();
|
||||
|
||||
qreal rot = 0.;
|
||||
qreal scaleX = 1.;
|
||||
qreal scaleY = 1.;
|
||||
if(oldTarget) {
|
||||
const auto trans = oldTarget->getTransformAnimator();
|
||||
const auto rotAnim = trans->getRotAnimator();
|
||||
const auto scaleAnim = trans->getScaleAnimator();
|
||||
|
||||
rot += rotAnim->getEffectiveValue()*rotInfl;
|
||||
scaleX *= 1 + (scaleAnim->getEffectiveXValue() - 1)*scaleXInfl;
|
||||
scaleY *= 1 + (scaleAnim->getEffectiveYValue() - 1)*scaleYInfl;
|
||||
}
|
||||
|
||||
if(newTarget) {
|
||||
const auto trans = newTarget->getTransformAnimator();
|
||||
const auto rotAnim = trans->getRotAnimator();
|
||||
const auto scaleAnim = trans->getScaleAnimator();
|
||||
|
||||
rot -= rotAnim->getEffectiveValue()*rotInfl;
|
||||
const qreal scaleXDiv = 1 + (scaleAnim->getEffectiveXValue() - 1)*scaleXInfl;
|
||||
const qreal scaleYDiv = 1 + (scaleAnim->getEffectiveYValue() - 1)*scaleYInfl;
|
||||
if(!isZero4Dec(scaleXDiv)) {
|
||||
scaleX /= scaleXDiv;
|
||||
}
|
||||
|
||||
if(!isZero4Dec(scaleYDiv)) {
|
||||
scaleY /= scaleYDiv;
|
||||
}
|
||||
}
|
||||
|
||||
parent->startRotTransform();
|
||||
parent->rotateBy(rot);
|
||||
|
||||
parent->startScaleTransform();
|
||||
parent->scale(scaleX, scaleY);
|
||||
}
|
||||
|
||||
void FollowObjectTransformEffect::applyEffect(
|
||||
const qreal relFrame,
|
||||
|
@ -33,6 +33,11 @@ public:
|
||||
qreal &shearX, qreal &shearY,
|
||||
BoundingBox* const parent) override;
|
||||
private:
|
||||
void setRotScaleAfterTargetChange(
|
||||
BoundingBox* const oldTarget,
|
||||
BoundingBox* const newTarget) override;
|
||||
|
||||
|
||||
qsptr<QPointFAnimator> mPosInfluence;
|
||||
qsptr<QPointFAnimator> mScaleInfluence;
|
||||
qsptr<QrealAnimator> mRotInfluence;
|
||||
|
@ -35,6 +35,95 @@ FollowPathTransformEffect::FollowPathTransformEffect() :
|
||||
ca_addChild(mInfluence);
|
||||
}
|
||||
|
||||
void calculateFollowRotPosChange(
|
||||
const SkPath relPath,
|
||||
const QMatrix transform,
|
||||
const bool lengthBased,
|
||||
const bool rotate,
|
||||
const qreal infl,
|
||||
qreal per,
|
||||
qreal& rotChange,
|
||||
qreal& posXChange,
|
||||
qreal& posYChange) {
|
||||
SkPath path;
|
||||
relPath.transform(toSkMatrix(transform), &path);
|
||||
const QPainterPath qpath = toQPainterPath(path);
|
||||
|
||||
if(lengthBased) {
|
||||
const qreal length = qpath.length();
|
||||
per = qpath.percentAtLength(per*length);
|
||||
}
|
||||
const auto p1 = qpath.pointAtPercent(per);
|
||||
|
||||
if(rotate) {
|
||||
qreal t2 = per + 0.0001;
|
||||
const bool reverse = t2 > 1;
|
||||
if(reverse) t2 = 0.9999;
|
||||
const auto p2 = qpath.pointAtPercent(t2);
|
||||
|
||||
const QLineF baseLine(QPointF(0., 0.), QPointF(100., 0.));
|
||||
QLineF l;
|
||||
if(reverse) l = QLineF(p2, p1);
|
||||
else l = QLineF(p1, p2);
|
||||
qreal trackAngle = l.angleTo(baseLine);
|
||||
if(trackAngle > 180) trackAngle -= 360;
|
||||
|
||||
rotChange = trackAngle*infl;
|
||||
} else rotChange = 0;
|
||||
posXChange = p1.x();
|
||||
posYChange = p1.y();
|
||||
}
|
||||
|
||||
void FollowPathTransformEffect::setRotScaleAfterTargetChange(
|
||||
BoundingBox* const oldTarget, BoundingBox* const newTarget) {
|
||||
const bool rotate = mRotate->getValue();
|
||||
if(!rotate) return;
|
||||
const auto parent = getFirstAncestor<BoundingBox>();
|
||||
if(!parent) return;
|
||||
const auto oldTargetP = static_cast<PathBox*>(oldTarget);
|
||||
const auto newTargetP = static_cast<PathBox*>(newTarget);
|
||||
|
||||
const qreal infl = mInfluence->getEffectiveValue();
|
||||
const qreal per = mComplete->getEffectiveValue();
|
||||
const bool lengthBased = mLengthBased->getValue();
|
||||
const qreal relFrame = parent->anim_getCurrentRelFrame();
|
||||
const auto parentTransform = parent->getInheritedTransformAtFrame(relFrame);
|
||||
|
||||
qreal rot = 0.;
|
||||
if(oldTargetP) {
|
||||
const auto relPath = oldTargetP->getRelativePath();
|
||||
const auto targetTransform = oldTargetP->getTotalTransform();
|
||||
const auto transform = targetTransform*parentTransform.inverted();
|
||||
|
||||
qreal rotChange;
|
||||
qreal posXChange;
|
||||
qreal posYChange;
|
||||
calculateFollowRotPosChange(relPath, transform,
|
||||
lengthBased, rotate, infl, per,
|
||||
rotChange, posXChange, posYChange);
|
||||
|
||||
rot += rotChange;
|
||||
}
|
||||
|
||||
if(newTargetP) {
|
||||
const auto relPath = newTargetP->getRelativePath();
|
||||
const auto targetTransform = newTargetP->getTotalTransform();
|
||||
const auto transform = targetTransform*parentTransform.inverted();
|
||||
|
||||
qreal rotChange;
|
||||
qreal posXChange;
|
||||
qreal posYChange;
|
||||
calculateFollowRotPosChange(relPath, transform,
|
||||
lengthBased, rotate, infl, per,
|
||||
rotChange, posXChange, posYChange);
|
||||
|
||||
rot -= rotChange;
|
||||
}
|
||||
|
||||
parent->startRotTransform();
|
||||
parent->rotateBy(rot);
|
||||
}
|
||||
|
||||
void FollowPathTransformEffect::applyEffect(
|
||||
const qreal relFrame,
|
||||
qreal& pivotX, qreal& pivotY,
|
||||
@ -63,38 +152,22 @@ void FollowPathTransformEffect::applyEffect(
|
||||
|
||||
const auto transform = targetTransform*parentTransform.inverted();
|
||||
|
||||
SkPath path;
|
||||
const auto relPath = target->getRelativePath(targetRelFrame);
|
||||
relPath.transform(toSkMatrix(transform), &path);
|
||||
const QPainterPath qpath = toQPainterPath(path);
|
||||
|
||||
const qreal infl = mInfluence->getEffectiveValue(relFrame);
|
||||
qreal per = mComplete->getEffectiveValue(relFrame);
|
||||
const bool rotate = mRotate->getValue();
|
||||
const bool lengthBased = mLengthBased->getValue();
|
||||
|
||||
if(lengthBased) {
|
||||
const qreal length = qpath.length();
|
||||
per = qpath.percentAtLength(per*length);
|
||||
}
|
||||
const auto p1 = qpath.pointAtPercent(per);
|
||||
qreal rotChange;
|
||||
qreal posXChange;
|
||||
qreal posYChange;
|
||||
|
||||
if(rotate) {
|
||||
qreal t2 = per + 0.0001;
|
||||
const bool reverse = t2 > 1;
|
||||
if(reverse) t2 = 0.9999;
|
||||
const auto p2 = qpath.pointAtPercent(t2);
|
||||
calculateFollowRotPosChange(relPath, transform,
|
||||
lengthBased, rotate, infl, per,
|
||||
rotChange, posXChange, posYChange);
|
||||
|
||||
const QLineF baseLine(QPointF(0., 0.), QPointF(100., 0.));
|
||||
QLineF l;
|
||||
if(reverse) l = QLineF(p2, p1);
|
||||
else l = QLineF(p1, p2);
|
||||
qreal trackAngle = l.angleTo(baseLine);
|
||||
if(trackAngle > 180) trackAngle -= 360;
|
||||
if(rotate) rot += rotChange;
|
||||
|
||||
rot += trackAngle*infl;
|
||||
}
|
||||
|
||||
posX += p1.x()*infl;
|
||||
posY += p1.y()*infl;
|
||||
posX += posXChange; //p1.x()*infl;
|
||||
posY += posYChange; //p1.y()*infl;
|
||||
}
|
||||
|
@ -33,6 +33,10 @@ public:
|
||||
qreal &shearX, qreal &shearY,
|
||||
BoundingBox* const parent) override;
|
||||
private:
|
||||
void setRotScaleAfterTargetChange(
|
||||
BoundingBox* const oldTarget,
|
||||
BoundingBox* const newTarget) override;
|
||||
|
||||
qsptr<BoolProperty> mRotate;
|
||||
qsptr<BoolProperty> mLengthBased;
|
||||
qsptr<QrealAnimator> mComplete;
|
||||
|
@ -18,6 +18,8 @@
|
||||
|
||||
#include "Boxes/boundingbox.h"
|
||||
#include "Animators/transformanimator.h"
|
||||
#include "Animators/qrealanimator.h"
|
||||
#include "Animators/qpointfanimator.h"
|
||||
|
||||
TargetTransformEffect::TargetTransformEffect(
|
||||
const QString& name,
|
||||
@ -50,6 +52,28 @@ TargetTransformEffect::TargetTransformEffect(
|
||||
}
|
||||
});
|
||||
|
||||
connect(mTarget.get(), &BoxTargetProperty::setActionStarted,
|
||||
this, [this]() {
|
||||
const auto parent = getFirstAncestor<BoundingBox>();
|
||||
if(!parent) return;
|
||||
mPosBeforeTargetChange = parent->getPivotAbsPos();
|
||||
});
|
||||
|
||||
connect(mTarget.get(), &BoxTargetProperty::setActionFinished,
|
||||
this, [this](BoundingBox* const oldTarget,
|
||||
BoundingBox* const newTarget) {
|
||||
const auto parent = getFirstAncestor<BoundingBox>();
|
||||
if(!parent) return;
|
||||
const auto posAfter = parent->getPivotAbsPos();
|
||||
|
||||
parent->startPosTransform();
|
||||
parent->moveByAbs(mPosBeforeTargetChange - posAfter);
|
||||
|
||||
setRotScaleAfterTargetChange(oldTarget, newTarget);
|
||||
|
||||
parent->finishTransform();
|
||||
});
|
||||
|
||||
ca_addChild(mTarget);
|
||||
}
|
||||
|
||||
@ -66,6 +90,12 @@ FrameRange TargetTransformEffect::prp_getIdenticalRelRange(
|
||||
return thisIdent*prp_absRangeToRelRange(absParentIdent);
|
||||
}
|
||||
|
||||
void TargetTransformEffect::setRotScaleAfterTargetChange(
|
||||
BoundingBox* const oldTarget, BoundingBox* const newTarget) {
|
||||
Q_UNUSED(oldTarget)
|
||||
Q_UNUSED(newTarget)
|
||||
}
|
||||
|
||||
BoxTargetProperty* TargetTransformEffect::targetProperty() const {
|
||||
return mTarget.get();
|
||||
}
|
||||
|
@ -28,8 +28,13 @@ public:
|
||||
|
||||
FrameRange prp_getIdenticalRelRange(const int relFrame) const;
|
||||
protected:
|
||||
virtual void setRotScaleAfterTargetChange(
|
||||
BoundingBox* const oldTarget,
|
||||
BoundingBox* const newTarget);
|
||||
|
||||
BoxTargetProperty* targetProperty() const;
|
||||
private:
|
||||
QPointF mPosBeforeTargetChange;
|
||||
ConnContextQPtr<BoundingBox> mTargetConn;
|
||||
qsptr<BoxTargetProperty> mTarget;
|
||||
};
|
||||
|
@ -27,6 +27,43 @@ TrackTransformEffect::TrackTransformEffect() :
|
||||
ca_prependChild(targetProperty(), mInfluence);
|
||||
}
|
||||
|
||||
qreal calculateTrackAngle(const QPointF& parentPos,
|
||||
const QPointF& targetPos) {
|
||||
const QLineF baseLine(parentPos, parentPos + QPointF(100., 0.));
|
||||
const QLineF trackLine(parentPos, targetPos);
|
||||
qreal trackAngle = trackLine.angleTo(baseLine);
|
||||
if(trackAngle > 180) trackAngle -= 360;
|
||||
return trackAngle;
|
||||
}
|
||||
|
||||
void TrackTransformEffect::setRotScaleAfterTargetChange(
|
||||
BoundingBox* const oldTarget, BoundingBox* const newTarget) {
|
||||
const auto parent = getFirstAncestor<BoundingBox>();
|
||||
if(!parent) return;
|
||||
|
||||
const qreal infl = mInfluence->getEffectiveValue();
|
||||
|
||||
qreal rot = 0.;
|
||||
if(oldTarget) {
|
||||
const auto targetPos = oldTarget->getPivotAbsPos();
|
||||
const auto parentPos = parent->getPivotAbsPos();
|
||||
|
||||
const qreal trackAngle = calculateTrackAngle(parentPos, targetPos);
|
||||
rot += trackAngle*infl;
|
||||
}
|
||||
|
||||
if(newTarget) {
|
||||
const auto targetPos = newTarget->getPivotAbsPos();
|
||||
const auto parentPos = parent->getPivotAbsPos();
|
||||
|
||||
const qreal trackAngle = calculateTrackAngle(parentPos, targetPos);
|
||||
rot -= trackAngle*infl;
|
||||
}
|
||||
|
||||
parent->startRotTransform();
|
||||
parent->rotateBy(rot);
|
||||
}
|
||||
|
||||
void TrackTransformEffect::applyEffect(
|
||||
const qreal relFrame,
|
||||
qreal& pivotX, qreal& pivotY,
|
||||
@ -54,12 +91,7 @@ void TrackTransformEffect::applyEffect(
|
||||
const auto targetPos = target->getPivotAbsPos(targetRelFrame);
|
||||
const auto parentPos = parent->getPivotAbsPos(relFrame);
|
||||
|
||||
const QLineF baseLine(parentPos, parentPos + QPointF(100., 0.));
|
||||
const QLineF trackLine(parentPos, targetPos);
|
||||
qreal trackAngle = trackLine.angleTo(baseLine);
|
||||
if(trackAngle > 180) trackAngle -= 360;
|
||||
|
||||
const qreal infl = mInfluence->getEffectiveValue(relFrame);
|
||||
|
||||
const qreal trackAngle = calculateTrackAngle(parentPos, targetPos);
|
||||
rot += trackAngle*infl;
|
||||
}
|
||||
|
@ -31,6 +31,10 @@ public:
|
||||
qreal &shearX, qreal &shearY,
|
||||
BoundingBox* const parent) override;
|
||||
private:
|
||||
void setRotScaleAfterTargetChange(
|
||||
BoundingBox* const oldTarget,
|
||||
BoundingBox* const newTarget) override;
|
||||
|
||||
qsptr<QrealAnimator> mInfluence;
|
||||
};
|
||||
|
||||
|
@ -305,8 +305,9 @@ public:
|
||||
}
|
||||
|
||||
QRect getCurrentBounds() const {
|
||||
if(mClipToCanvasSize) return getCanvasBounds();
|
||||
else return getMaxBounds();
|
||||
//if(mClipToCanvasSize) return getCanvasBounds();
|
||||
//else return getMaxBounds();
|
||||
return getMaxBounds();
|
||||
}
|
||||
|
||||
int getCanvasHeight() const {
|
||||
|
Loading…
Reference in New Issue
Block a user