Exemplo n.º 1
0
void
KnobGui::setInterpolationForDimensions(QAction* action,
                                       KeyframeTypeEnum interp)
{
    if (!action) {
        return;
    }
    int dimension = action->data().toInt();
    KnobPtr knob = getKnob();


    for (int i = 0; i < knob->getDimension(); ++i) {
        if ( (dimension == -1) || (dimension == i) ) {
            boost::shared_ptr<Curve> c = knob->getCurve(ViewIdx(0), i);
            if (c) {
                int kfCount = c->getKeyFramesCount();
                for (int j = 0; j < kfCount; ++j) {
                    c->setKeyFrameInterpolation(interp, j);
                }
                boost::shared_ptr<Curve> guiCurve = getCurve(ViewIdx(0), i);
                if (guiCurve) {
                    guiCurve->clone(*c);
                }
            }
        }
    }
    if ( knob->getHolder() ) {
        knob->getHolder()->incrHashAndEvaluate(knob->getEvaluateOnChange(), false);
    }
    Q_EMIT keyInterpolationChanged();
}
Exemplo n.º 2
0
void
SetExpressionCommand::redo()
{
    KnobPtr knob = _knob.lock();

    if (!knob) {
        return;
    }
    if (_dimension == -1) {
        for (int i = 0; i < knob->getDimension(); ++i) {
            try {
                knob->setExpression(i, _newExpr, _hasRetVar, false);
            } catch (...) {
                Dialogs::errorDialog( tr("Expression").toStdString(), tr("The expression is invalid.").toStdString() );
                break;
            }
        }
    } else {
        try {
            knob->setExpression(_dimension, _newExpr, _hasRetVar, false);
        } catch (...) {
            Dialogs::errorDialog( tr("Expression").toStdString(), tr("The expression is invalid.").toStdString() );
        }
    }
    knob->evaluateValueChange(_dimension == -1 ? 0 : _dimension, knob->getCurrentTime(), ViewIdx(0), eValueChangedReasonNatronGuiEdited);
    setText( tr("Set expression") );
}
Exemplo n.º 3
0
void
KnobGui::onRemoveAnimationActionTriggered()
{
    QAction* action = qobject_cast<QAction*>( sender() );

    assert(action);
    int dim = action->data().toInt();
    KnobPtr knob = getKnob();
    std::map<boost::shared_ptr<CurveGui>, std::vector<KeyFrame > > toRemove;
    KnobGuiPtr thisShared = shared_from_this();
    for (int i = 0; i < knob->getDimension(); ++i) {
        if ( (dim == -1) || (dim == i) ) {
            std::list<boost::shared_ptr<CurveGui> > curves = getGui()->getCurveEditor()->findCurve(thisShared, i);
            for (std::list<boost::shared_ptr<CurveGui> >::iterator it = curves.begin(); it != curves.end(); ++it) {
                KeyFrameSet keys = (*it)->getInternalCurve()->getKeyFrames_mt_safe();
                std::vector<KeyFrame > vect;
                for (KeyFrameSet::const_iterator it2 = keys.begin(); it2 != keys.end(); ++it2) {
                    vect.push_back(*it2);
                }
                toRemove.insert( std::make_pair(*it, vect) );
            }
        }
    }
    pushUndoCommand( new RemoveKeysCommand(getGui()->getCurveEditor()->getCurveWidget(),
                                           toRemove) );
    //refresh the gui so it doesn't indicate the parameter is animated anymore
    updateGUI(dim);
}
Exemplo n.º 4
0
void
KnobSerialization::restoreExpressions(const KnobPtr & knob,
                                      const std::map<std::string,std::string>& oldNewScriptNamesMapping)
{
    int dims = std::min(knob->getDimension(), _knob->getDimension());
    try {
        for (int i = 0; i < dims; ++i) {
            if (!_expressions[i].first.empty()) {
                QString expr(QString::fromUtf8(_expressions[i].first.c_str()));
                
                //Replace all occurrences of script-names that we know have changed
                for (std::map<std::string,std::string>::const_iterator it = oldNewScriptNamesMapping.begin();
                     it != oldNewScriptNamesMapping.end(); ++it) {
                    expr.replace(QString::fromUtf8(it->first.c_str()), QString::fromUtf8(it->second.c_str()));
                }
                knob->restoreExpression(i, expr.toStdString(), _expressions[i].second);
            }
            
        }
    } catch (const std::exception& e) {
        QString err = QString::fromUtf8("Failed to restore expression on %1: %2").arg(QString::fromUtf8(knob->getName().c_str())).arg(QString::fromUtf8(e.what()));
        appPTR->writeToErrorLog_mt_safe(err);
    }
    
}
Exemplo n.º 5
0
void
KnobGui::setAllKeyframeMarkersOnTimeline(int dimension)
{
    KnobPtr knob = getKnob();
    AppInstPtr app = knob->getHolder()->getApp();

    assert(app);
    std::list<SequenceTime> times;

    if (dimension == -1) {
        int dim = knob->getDimension();
        for (int i = 0; i < dim; ++i) {
            KeyFrameSet kfs = knob->getCurve(ViewIdx(0), i)->getKeyFrames_mt_safe();
            for (KeyFrameSet::iterator it = kfs.begin(); it != kfs.end(); ++it) {
                times.push_back( it->getTime() );
            }
        }
    } else {
        KeyFrameSet kfs = knob->getCurve(ViewIdx(0), dimension)->getKeyFrames_mt_safe();
        for (KeyFrameSet::iterator it = kfs.begin(); it != kfs.end(); ++it) {
            times.push_back( it->getTime() );
        }
    }
    app->addMultipleKeyframeIndicatorsAdded(times, true);
}
Exemplo n.º 6
0
void
KnobGui::onRemoveKeyActionTriggered()
{
    QAction* action = qobject_cast<QAction*>( sender() );

    assert(action);
    int dim = action->data().toInt();
    KnobPtr knob = getKnob();

    assert( knob->getHolder()->getApp() );
    //get the current time on the global timeline
    SequenceTime time = knob->getHolder()->getApp()->getTimeLine()->currentFrame();
    std::map<boost::shared_ptr<CurveGui>, std::vector<KeyFrame > > toRemove;
    KnobGuiPtr thisShared = shared_from_this();

    for (int i = 0; i < knob->getDimension(); ++i) {
        if ( (dim == -1) || (i == dim) ) {
            std::list<boost::shared_ptr<CurveGui> > curves = getGui()->getCurveEditor()->findCurve(thisShared, i);
            for (std::list<boost::shared_ptr<CurveGui> >::iterator it = curves.begin(); it != curves.end(); ++it) {
                KeyFrame kf;
                bool foundKey = knob->getCurve(ViewIdx(0), i)->getKeyFrameWithTime(time, &kf);

                if (foundKey) {
                    std::vector<KeyFrame > vect;
                    vect.push_back(kf);
                    toRemove.insert( std::make_pair(*it, vect) );
                }
            }
        }
    }
    pushUndoCommand( new RemoveKeysCommand(getGui()->getCurveEditor()->getCurveWidget(),
                                           toRemove) );
}
Exemplo n.º 7
0
void
KnobGui::onUnlinkActionTriggered()
{
    QAction* action = qobject_cast<QAction*>( sender() );

    if (!action) {
        return;
    }
    int dim = action->data().toInt();
    KnobPtr thisKnob = getKnob();
    int dims = thisKnob->getDimension();
    KnobPtr aliasMaster = thisKnob->getAliasMaster();
    if (aliasMaster) {
        thisKnob->setKnobAsAliasOfThis(aliasMaster, false);
    } else {
        thisKnob->beginChanges();
        for (int i = 0; i < dims; ++i) {
            if ( (dim == -1) || (i == dim) ) {
                std::pair<int, KnobPtr > other = thisKnob->getMaster(i);
                thisKnob->onKnobUnSlaved(i);
                onKnobSlavedChanged(i, false);
            }
        }
        thisKnob->endChanges();
    }
    getKnob()->getHolder()->getApp()->triggerAutoSave();
}
Exemplo n.º 8
0
void
KnobGui::onExprChanged(int dimension)
{
    if (_imp->guiRemoved) {
        return;
    }
    KnobPtr knob = getKnob();
    std::string exp = knob->getExpression(dimension);
    reflectExpressionState(dimension,!exp.empty());
    if (exp.empty()) {
        reflectAnimationLevel(dimension, knob->getAnimationLevel(dimension));
    } else {
        
        NodeSettingsPanel* isNodeSettings = dynamic_cast<NodeSettingsPanel*>(_imp->container);
        if (isNodeSettings) {
            NodeGuiPtr node = isNodeSettings->getNode();
            if (node) {
                node->onKnobExpressionChanged(this);
            }
        }
        
        if (_imp->warningIndicator) {
            bool invalid = false;
            QString fullErrTooltip;
            int dims = knob->getDimension();
            for (int i = 0; i < dims; ++i) {
                std::string err;
                if (!knob->isExpressionValid(i, &err)) {
                    invalid = true;
                }
                if (dims > 1 && invalid) {
                    fullErrTooltip += QString::fromUtf8("<p><b>");
                    fullErrTooltip += QString::fromUtf8(knob->getDimensionName(i).c_str());
                    fullErrTooltip += QString::fromUtf8("</b></p>");
                }
                if (!err.empty()) {
                    fullErrTooltip += QString::fromUtf8(err.c_str());
                }
            }
            if (invalid) {
                QString toPrepend;
                toPrepend += QString::fromUtf8("<p>");
                toPrepend += QObject::tr("Invalid expression(s), value returned is the underlying curve:");
                toPrepend += QString::fromUtf8("</p>");
                fullErrTooltip.prepend(toPrepend);
                
                setWarningValue(eKnobWarningExpressionInvalid, fullErrTooltip);
            } else {
                setWarningValue(eKnobWarningExpressionInvalid, QString());
            }
        }
        onHelpChanged();
        Q_EMIT expressionChanged();
        
    }
    updateGUI(dimension);
    
}
Exemplo n.º 9
0
void
KnobGui::pasteClipBoard(int targetDimension)
{
    KnobPtr knob = getKnob();
    if (!knob) {
        return;
    }
    
    //the dimension from which it was copied from
    int cbDim;
    KnobClipBoardType type;
    KnobPtr fromKnob;
    appPTR->getKnobClipBoard(&type, &fromKnob, &cbDim);
    if (!fromKnob) {
        return;
    }
    
    if (targetDimension == 0 && !getAllDimensionsVisible()) {
        targetDimension = -1;
    }
    
    if (!knob->isAnimationEnabled() && type == eKnobClipBoardTypeCopyAnim) {
        Dialogs::errorDialog(tr("Paste").toStdString(), tr("This parameter does not support animation").toStdString());
        return;
    }

    if (!KnobI::areTypesCompatibleForSlave(fromKnob.get(),knob.get())) {
        Dialogs::errorDialog(tr("Paste").toStdString(), tr("You can only copy/paste between parameters of the same type. To overcome this, use an expression instead.").toStdString());
        return;
    }
    
    if (cbDim != -1 && targetDimension == -1) {
        Dialogs::errorDialog(tr("Paste").toStdString(), tr("When copy/pasting on all dimensions, original and target parameters must have the same dimension.").toStdString());
        return;
    }
    
    if ((targetDimension == -1 || cbDim == -1) && fromKnob->getDimension() != knob->getDimension()) {
        Dialogs::errorDialog(tr("Paste").toStdString(), tr("When copy/pasting on all dimensions, original and target parameters must have the same dimension.").toStdString());
        return;
    }

    pushUndoCommand(new PasteUndoCommand(shared_from_this(),type, cbDim, targetDimension, fromKnob));
} // pasteClipBoard
Exemplo n.º 10
0
void
EditExpressionDialog::setTitle()
{
    KnobPtr k = _knob->getKnob();
    QString title( tr("Set expression on ") );

    title.append( QString::fromUtf8( k->getName().c_str() ) );
    if ( (_dimension != -1) && (k->getDimension() > 1) ) {
        title.append( QLatin1Char('.') );
        title.append( QString::fromUtf8( k->getDimensionName(_dimension).c_str() ) );
    }
    setWindowTitle(title);
}
Exemplo n.º 11
0
void
KnobGui::onAnimationLevelChanged(ViewSpec /*idx*/,
                                 int dimension)
{
    if (!_imp->customInteract) {
        KnobPtr knob = getKnob();
        int dim = knob->getDimension();
        for (int i = 0; i < dim; ++i) {
            if ( (i == dimension) || (dimension == -1) ) {
                reflectAnimationLevel( i, knob->getAnimationLevel(i) );
            }
        }
    }
}
Exemplo n.º 12
0
void
KnobGui::onSetKeyActionTriggered()
{
    QAction* action = qobject_cast<QAction*>( sender() );

    assert(action);
    int dim = action->data().toInt();
    KnobPtr knob = getKnob();

    assert( knob->getHolder()->getApp() );
    //get the current time on the global timeline
    SequenceTime time = knob->getHolder()->getApp()->getTimeLine()->currentFrame();
    AddKeysCommand::KeysToAddList toAdd;
    KnobGuiPtr thisShared = shared_from_this();
    for (int i = 0; i < knob->getDimension(); ++i) {
        if ( (dim == -1) || (i == dim) ) {
            std::list<boost::shared_ptr<CurveGui> > curves = getGui()->getCurveEditor()->findCurve(thisShared, i);
            for (std::list<boost::shared_ptr<CurveGui> >::iterator it = curves.begin(); it != curves.end(); ++it) {
                AddKeysCommand::KeyToAdd keyToAdd;
                KeyFrame kf;
                kf.setTime(time);
                Knob<int>* isInt = dynamic_cast<Knob<int>*>( knob.get() );
                Knob<bool>* isBool = dynamic_cast<Knob<bool>*>( knob.get() );
                AnimatingKnobStringHelper* isString = dynamic_cast<AnimatingKnobStringHelper*>( knob.get() );
                Knob<double>* isDouble = dynamic_cast<Knob<double>*>( knob.get() );

                if (isInt) {
                    kf.setValue( isInt->getValue(i) );
                } else if (isBool) {
                    kf.setValue( isBool->getValue(i) );
                } else if (isDouble) {
                    kf.setValue( isDouble->getValue(i) );
                } else if (isString) {
                    std::string v = isString->getValue(i);
                    double dv;
                    isString->stringToKeyFrameValue(time, ViewIdx(0), v, &dv);
                    kf.setValue(dv);
                }

                keyToAdd.keyframes.push_back(kf);
                keyToAdd.curveUI = *it;
                keyToAdd.knobUI = thisShared;
                keyToAdd.dimension = i;
                toAdd.push_back(keyToAdd);
            }
        }
    }
    pushUndoCommand( new AddKeysCommand(getGui()->getCurveEditor()->getCurveWidget(), toAdd) );
}
Exemplo n.º 13
0
void
RestoreDefaultsCommand::undo()
{
    assert( _clones.size() == _knobs.size() );

    std::list<SequenceTime> times;
    KnobPtr first = _knobs.front().lock();
    AppInstance* app = first->getHolder()->getApp();
    assert(app);
    std::list<KnobWPtr >::const_iterator itClone = _clones.begin();
    for (std::list<KnobWPtr >::const_iterator it = _knobs.begin(); it != _knobs.end(); ++it, ++itClone) {
        KnobPtr itKnob = it->lock();
        if (!itKnob) {
            continue;
        }
        KnobPtr itCloneKnob = itClone->lock();
        if (!itCloneKnob) {
            continue;
        }
        itKnob->cloneAndUpdateGui( itCloneKnob.get() );

        if ( itKnob->getHolder()->getApp() ) {
            int dim = itKnob->getDimension();
            for (int i = 0; i < dim; ++i) {
                if ( (i == _targetDim) || (_targetDim == -1) ) {
                    boost::shared_ptr<Curve> c = itKnob->getCurve(ViewIdx(0), i);
                    if (c) {
                        KeyFrameSet kfs = c->getKeyFrames_mt_safe();
                        for (KeyFrameSet::iterator it = kfs.begin(); it != kfs.end(); ++it) {
                            times.push_back( std::floor(it->getTime() + 0.5) );
                        }
                    }
                }
            }
        }
    }
    app->addMultipleKeyframeIndicatorsAdded(times, true);

    first->getHolder()->incrHashAndEvaluate(true, true);
    if ( first->getHolder()->getApp() ) {
        first->getHolder()->getApp()->redrawAllViewers();
    }

    setText( tr("Restore default value(s)") );
}
Exemplo n.º 14
0
void
KnobGui::onShowInCurveEditorActionTriggered()
{
    KnobPtr knob = getKnob();

    assert( knob->getHolder()->getApp() );
    getGui()->setCurveEditorOnTop();
    std::vector<boost::shared_ptr<Curve> > curves;
    for (int i = 0; i < knob->getDimension(); ++i) {
        boost::shared_ptr<Curve> c = getCurve(ViewIdx(0), i);
        if ( c->isAnimated() ) {
            curves.push_back(c);
        }
    }
    if ( !curves.empty() ) {
        getGui()->getCurveEditor()->centerOn(curves);
    }
}
Exemplo n.º 15
0
SetExpressionCommand::SetExpressionCommand(const KnobPtr & knob,
                                           bool hasRetVar,
                                           int dimension,
                                           const std::string& expr,
                                           QUndoCommand *parent)
    : QUndoCommand(parent)
    , _knob(knob)
    , _oldExprs()
    , _hadRetVar()
    , _newExpr(expr)
    , _hasRetVar(hasRetVar)
    , _dimension(dimension)
{
    for (int i = 0; i < knob->getDimension(); ++i) {
        _oldExprs.push_back( knob->getExpression(i) );
        _hadRetVar.push_back( knob->isExpressionUsingRetVariable(i) );
    }
}
Exemplo n.º 16
0
void
KnobGui::onFrozenChanged(bool frozen)
{
    KnobPtr knob = getKnob();
    KnobButton* isBtn = dynamic_cast<KnobButton*>(knob.get());
    if (isBtn && !isBtn->isRenderButton()) {
        return;
    }
    int dims = knob->getDimension();

    for (int i = 0; i < dims; ++i) {
        ///Do not unset read only if the knob is slaved in this dimension because we are still using it.
        if ( !frozen && knob->isSlave(i) ) {
            continue;
        }
        if (knob->isEnabled(i)) {
            setReadOnly_(frozen, i);
        }
    }
}
Exemplo n.º 17
0
KnobPtr
MultipleKnobEditsUndoCommand::createCopyForKnob(const KnobPtr & originalKnob)
{
    const std::string & typeName = originalKnob->typeName();
    KnobPtr copy;
    int dimension = originalKnob->getDimension();

    if ( typeName == KnobInt::typeNameStatic() ) {
        copy.reset( new KnobInt(NULL, std::string(), dimension, false) );
    } else if ( typeName == KnobBool::typeNameStatic() ) {
        copy.reset( new KnobBool(NULL, std::string(), dimension, false) );
    } else if ( typeName == KnobDouble::typeNameStatic() ) {
        copy.reset( new KnobDouble(NULL, std::string(), dimension, false) );
    } else if ( typeName == KnobChoice::typeNameStatic() ) {
        copy.reset( new KnobChoice(NULL, std::string(), dimension, false) );
    } else if ( typeName == KnobString::typeNameStatic() ) {
        copy.reset( new KnobString(NULL, std::string(), dimension, false) );
    } else if ( typeName == KnobParametric::typeNameStatic() ) {
        copy.reset( new KnobParametric(NULL, std::string(), dimension, false) );
    } else if ( typeName == KnobColor::typeNameStatic() ) {
        copy.reset( new KnobColor(NULL, std::string(), dimension, false) );
    } else if ( typeName == KnobPath::typeNameStatic() ) {
        copy.reset( new KnobPath(NULL, std::string(), dimension, false) );
    } else if ( typeName == KnobFile::typeNameStatic() ) {
        copy.reset( new KnobFile(NULL, std::string(), dimension, false) );
    } else if ( typeName == KnobOutputFile::typeNameStatic() ) {
        copy.reset( new KnobOutputFile(NULL, std::string(), dimension, false) );
    }

    ///If this is another type of knob this is wrong since they do not hold any value
    assert(copy);
    if (!copy) {
        return KnobPtr();
    }
    copy->populate();

    ///make a clone of the original knob at that time and stash it
    copy->clone(originalKnob);

    return copy;
}
Exemplo n.º 18
0
void
KnobGui::removeAllKeyframeMarkersOnTimeline(int dimension)
{
    KnobPtr knob = getKnob();

    if ( knob->getHolder() && knob->getHolder()->getApp() && !knob->getIsSecret() && ( knob->isDeclaredByPlugin() || knob->isUserKnob() ) ) {
        AppInstPtr app = knob->getHolder()->getApp();
        assert(app);
        std::list<SequenceTime> times;
        std::set<SequenceTime> tmpTimes;
        if (dimension == -1) {
            int dim = knob->getDimension();
            for (int i = 0; i < dim; ++i) {
                boost::shared_ptr<Curve> curve = knob->getCurve(ViewIdx(0), i);
                if (curve) {
                    KeyFrameSet kfs = curve->getKeyFrames_mt_safe();
                    for (KeyFrameSet::iterator it = kfs.begin(); it != kfs.end(); ++it) {
                        tmpTimes.insert( it->getTime() );
                    }
                }
            }
            for (std::set<SequenceTime>::iterator it = tmpTimes.begin(); it != tmpTimes.end(); ++it) {
                times.push_back(*it);
            }
        } else {
            boost::shared_ptr<Curve> curve = knob->getCurve(ViewIdx(0), dimension);
            if (curve) {
                KeyFrameSet kfs = curve->getKeyFrames_mt_safe();
                for (KeyFrameSet::iterator it = kfs.begin(); it != kfs.end(); ++it) {
                    times.push_back( it->getTime() );
                }
            }
        }
        if ( !times.empty() ) {
            app->removeMultipleKeyframeIndicator(times, true);
        }
    }
}
Exemplo n.º 19
0
void
KnobGui::setEnabledSlot()
{
    if ( !getGui() ) {
        return;
    }
    if (!_imp->customInteract) {
        setEnabled();
    }
    KnobPtr knob = getKnob();
    if (_imp->descriptionLabel) {
        _imp->descriptionLabel->setReadOnly( !knob->isEnabled(0) );
    }
    KnobGuiPtr thisShared = shared_from_this();
    if ( knob->getHolder() && knob->getHolder()->getApp() ) {
        for (int i = 0; i < knob->getDimension(); ++i) {
            if ( !knob->isEnabled(i) ) {
                getGui()->getCurveEditor()->hideCurve(thisShared, i);
            } else {
                getGui()->getCurveEditor()->showCurve(thisShared, i);
            }
        }
    }
}
Exemplo n.º 20
0
void
KnobGui::linkTo(int dimension)
{
    KnobPtr thisKnob = getKnob();

    assert(thisKnob);
    EffectInstance* isEffect = dynamic_cast<EffectInstance*>( thisKnob->getHolder() );
    if (!isEffect) {
        return;
    }


    for (int i = 0; i < thisKnob->getDimension(); ++i) {
        if ( (i == dimension) || (dimension == -1) ) {
            std::string expr = thisKnob->getExpression(dimension);
            if ( !expr.empty() ) {
                Dialogs::errorDialog( tr("Param Link").toStdString(), tr("This parameter already has an expression set, edit or clear it.").toStdString() );

                return;
            }
        }
    }

    LinkToKnobDialog dialog( shared_from_this(), _imp->copyRightClickMenu->parentWidget() );

    if ( dialog.exec() ) {
        KnobPtr otherKnob = dialog.getSelectedKnobs();
        if (otherKnob) {
            if ( !thisKnob->isTypeCompatible(otherKnob) ) {
                Dialogs::errorDialog( tr("Param Link").toStdString(), tr("Types are incompatible!").toStdString() );

                return;
            }


            for (int i = 0; i < thisKnob->getDimension(); ++i) {
                std::pair<int, KnobPtr > existingLink = thisKnob->getMaster(i);
                if (existingLink.second) {
                    Dialogs::errorDialog( tr("Param Link").toStdString(),
                                          tr("Cannot link %1 because the knob is already linked to %2.")
                                          .arg( QString::fromUtf8( thisKnob->getLabel().c_str() ) )
                                          .arg( QString::fromUtf8( existingLink.second->getLabel().c_str() ) )
                                          .toStdString() );

                    return;
                }
            }

            EffectInstance* otherEffect = dynamic_cast<EffectInstance*>( otherKnob->getHolder() );
            if (!otherEffect) {
                return;
            }

            std::stringstream expr;
            boost::shared_ptr<NodeCollection> thisCollection = isEffect->getNode()->getGroup();
            NodeGroup* otherIsGroup = dynamic_cast<NodeGroup*>(otherEffect);
            if ( otherIsGroup == thisCollection.get() ) {
                expr << "thisGroup"; // make expression generic if possible
            } else {
                expr << otherEffect->getNode()->getFullyQualifiedName();
            }
            expr << "." << otherKnob->getName() << ".get()";
            if (otherKnob->getDimension() > 1) {
                expr << "[dimension]";
            }

            thisKnob->beginChanges();
            for (int i = 0; i < thisKnob->getDimension(); ++i) {
                if ( (i == dimension) || (dimension == -1) ) {
                    thisKnob->setExpression(i, expr.str(), false, false);
                }
            }
            thisKnob->endChanges();


            thisKnob->getHolder()->getApp()->triggerAutoSave();
        }
    }
} // KnobGui::linkTo
Exemplo n.º 21
0
void
KnobGuiValue::createWidget(QHBoxLayout* layout)
{
    
    connectKnobSignalSlots();
    
    _imp->container = new QWidget(layout->parentWidget());
    QHBoxLayout *containerLayout = new QHBoxLayout(_imp->container);
    layout->addWidget(_imp->container);
    
    containerLayout->setContentsMargins(0, 0, 0, 0);
    containerLayout->setSpacing(3);
    
    if (getKnobsCountOnSameLine() > 1) {
        disableSlider();
    }
    
    if (!isSliderDisabled()) {
        layout->parentWidget()->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Fixed);
    }
    
    KnobPtr knob = _imp->getKnob();
    const int nDims = knob->getDimension();
    
    std::vector<double> increments, displayMins, displayMaxs, mins, maxs;
    std::vector<int> decimals;
    boost::shared_ptr<Knob<double> > doubleKnob = _imp->getKnobAsDouble();
    boost::shared_ptr<Knob<int> > intKnob = _imp->getKnobAsInt();
    if (doubleKnob) {
        displayMins = doubleKnob->getDisplayMinimums();
        displayMaxs = doubleKnob->getDisplayMaximums();
        mins = doubleKnob->getMinimums();
        maxs = doubleKnob->getMaximums();
    } else {
        const std::vector<int>& intDmins = intKnob->getDisplayMinimums();
        const std::vector<int>& intDMaxs = intKnob->getDisplayMaximums();
        const std::vector<int>& intMins = intKnob->getMinimums();
        const std::vector<int>& intMaxs = intKnob->getMaximums();
        assert(intDMaxs.size() == intDmins.size() && intDmins.size() == intMins.size() && intMins.size() == intMaxs.size());
        displayMins.resize(intDmins.size());
        displayMaxs.resize(intDmins.size());
        mins.resize(intDmins.size());
        maxs.resize(intDmins.size());
        
        for (std::size_t i = 0; i < intMins.size(); ++i) {
            displayMins[i] = intDmins[i];
            displayMaxs[i] = intDMaxs[i];
            mins[i] = intMins[i];
            maxs[i] = intMaxs[i];
        }
    }
    
    getIncrements(&increments);
    getDecimals(&decimals);
    
    std::vector<std::string> dimensionLabels(nDims);
    
    bool isRectangleParam = isRectangleType();
    // This is a rectangle parameter
    if (isRectangleParam) {
        dimensionLabels[0] = "x";
        dimensionLabels[1] = "y";
        dimensionLabels[2] = "w";
        dimensionLabels[3] = "h";
    } else {
        for (int i = 0; i < nDims; ++i) {
            dimensionLabels[i] = knob->getDimensionName(i);
        }
    }
    
    KnobGuiPtr thisShared = shared_from_this();
    
    SpinBox::SpinBoxTypeEnum type;
    if (doubleKnob) {
        type = SpinBox::eSpinBoxTypeDouble;
    } else {
        type = SpinBox::eSpinBoxTypeInt;
    }
    
    
    int nItemsPerRow = nDims;
    if (std::floor(nDims / 3. + 0.5) == nDims / 3.) {
        nItemsPerRow = 3;
    }
    if (std::floor(nDims / 4. + 0.5) == nDims / 4.) {
        nItemsPerRow = 4;
    }
    
    int nbRows = nDims / nItemsPerRow;
    assert(nbRows >= 1);
    QWidget* allSpinBoxesContainer = 0;
    QGridLayout* spinBoxesGrid = 0;
    if (nbRows == 1) {
        allSpinBoxesContainer = _imp->container;
    } else {
        allSpinBoxesContainer = new QWidget(_imp->container);
        spinBoxesGrid = new QGridLayout(allSpinBoxesContainer);
        spinBoxesGrid->setContentsMargins(0, 0, 0, 0);
        spinBoxesGrid->setVerticalSpacing(TO_DPIY(1));
        spinBoxesGrid->setHorizontalSpacing(TO_DPIX(1));
    }
    
    _imp->spinBoxes.resize(nDims);
    
    int rowIndex = 0;
    int columnIndex = 0;
    for (std::size_t i = 0; i < _imp->spinBoxes.size(); ++i) {
        
        QWidget *boxContainer = new QWidget(allSpinBoxesContainer);
        boxContainer->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed);
        
        QHBoxLayout *boxContainerLayout = 0;
        boxContainerLayout = new QHBoxLayout(boxContainer);
        boxContainerLayout->setContentsMargins(0, 0, 0, 0);
        boxContainerLayout->setSpacing(3);
        
        
        Label *subDesc = 0;
        if (nDims != 1 && nbRows == 1) {
            subDesc = new Label(QString::fromUtf8(dimensionLabels[i].c_str()), boxContainer);
            boxContainerLayout->addWidget(subDesc);
        }
        
        SpinBox *box = new KnobSpinBox(layout->parentWidget(), type, thisShared , i);
        NumericKnobValidator* validator = new NumericKnobValidator(box,thisShared);
        box->setValidator(validator);
        QObject::connect( box, SIGNAL(valueChanged(double)), this, SLOT(onSpinBoxValueChanged()) );
        
        // Set the copy/link actions in the right click menu of the SpinBox
        enableRightClickMenu(box,i);
        
#ifdef SPINBOX_TAKE_PLUGIN_RANGE_INTO_ACCOUNT
        double min = mins[i];
        double max = maxs[i];
        valueAccordingToType(false, i, &min);
        valueAccordingToType(false, i, &max);
        box->setMaximum(max);
        box->setMinimum(min);
#endif
        
        
        
        if (type == SpinBox::eSpinBoxTypeDouble) {
            // Set the number of digits after the decimal point
            if (i < decimals.size()) {
                box->decimals(decimals[i]);
            }
        }
        
        if (i < increments.size()) {    
            double incr = 1;
            incr = increments[i];
            valueAccordingToType(false, i, &incr);
            box->setIncrement(incr);
        }
        boxContainerLayout->addWidget(box);
        if (!spinBoxesGrid) {
            containerLayout->addWidget(boxContainer);
        } else {
            spinBoxesGrid->addWidget(boxContainer, rowIndex, columnIndex);
        }
        _imp->spinBoxes[i] = std::make_pair(box, subDesc);
        
        ++columnIndex;
        if (columnIndex >= nItemsPerRow) {
            columnIndex = 0;
            ++rowIndex;
        }
    }
    
    if (spinBoxesGrid) {
        containerLayout->addWidget(allSpinBoxesContainer);
    }
    
    bool sliderVisible = false;
    if (!isSliderDisabled() && !isRectangleParam) {
        double dispmin = displayMins[0];
        double dispmax = displayMaxs[0];
        if (dispmin == -DBL_MAX) {
            dispmin = mins[0];
        }
        if (dispmax == DBL_MAX) {
            dispmax = maxs[0];
        }
        
        // denormalize if necessary
        double dispminGui = dispmin;
        double dispmaxGui = dispmax;
        valueAccordingToType(false, 0, &dispminGui);
        valueAccordingToType(false, 0, &dispmaxGui);
        
        bool spatial = isSpatialType();
        Format f;
        if (spatial) {
            getKnob()->getHolder()->getApp()->getProject()->getProjectDefaultFormat(&f);
        }
        if (dispminGui < -SLIDER_MAX_RANGE) {
            if (spatial) {
                dispminGui = -f.width();
            } else {
                dispminGui = -SLIDER_MAX_RANGE;
            }
        }
        if (dispmaxGui > SLIDER_MAX_RANGE) {
            if (spatial) {
                dispmaxGui = f.width();
            } else {
                dispmaxGui = SLIDER_MAX_RANGE;
            }
        }
        
        double value0 = _imp->getKnobValue(0);

        ScaleSliderQWidget::DataTypeEnum sliderType;
        if (doubleKnob) {
            sliderType = ScaleSliderQWidget::eDataTypeDouble;
        } else {
            sliderType = ScaleSliderQWidget::eDataTypeInt;
        }

        
        _imp->slider = new ScaleSliderQWidget(dispminGui, dispmaxGui, value0,knob->getEvaluateOnChange(),
                                         sliderType,getGui(), eScaleTypeLinear, layout->parentWidget());
        _imp->slider->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Fixed);
        if (hasToolTip()) {
            _imp->slider->setToolTip( toolTip() );
        }
        QObject::connect(_imp->slider, SIGNAL(positionChanged(double)), this, SLOT(onSliderValueChanged(double)));
        QObject::connect(_imp->slider, SIGNAL(editingFinished(bool)), this, SLOT(onSliderEditingFinished(bool)));
        containerLayout->addWidget(_imp->slider);
        
        sliderVisible = shouldSliderBeVisible(dispminGui, dispmaxGui);
        
        // onDisplayMinMaxChanged takes original (maybe normalized) values
        onDisplayMinMaxChanged(dispmin, dispmax);
    }
Exemplo n.º 22
0
void
RestoreDefaultsCommand::redo()
{
    std::list<SequenceTime> times;
    KnobPtr first = _knobs.front().lock();
    AppInstance* app = 0;
    KnobHolder* holder = first->getHolder();
    EffectInstance* isEffect = dynamic_cast<EffectInstance*>(holder);

    if (holder) {
        app = holder->getApp();
        holder->beginChanges();
    }


    /*
       First reset all knobs values, this will not call instanceChanged action
     */
    for (std::list<KnobWPtr >::iterator it = _knobs.begin(); it != _knobs.end(); ++it) {
        KnobPtr itKnob = it->lock();
        if (!itKnob) {
            continue;
        }
        if ( itKnob->getHolder() && itKnob->getHolder()->getApp() ) {
            int dim = itKnob->getDimension();
            for (int i = 0; i < dim; ++i) {
                if ( (i == _targetDim) || (_targetDim == -1) ) {
                    boost::shared_ptr<Curve> c = itKnob->getCurve(ViewIdx(0), i);
                    if (c) {
                        KeyFrameSet kfs = c->getKeyFrames_mt_safe();
                        for (KeyFrameSet::iterator it = kfs.begin(); it != kfs.end(); ++it) {
                            times.push_back( std::floor(it->getTime() + 0.5) );
                        }
                    }
                }
            }
        }

        if ( itKnob->getHolder() ) {
            itKnob->getHolder()->beginChanges();
        }
        itKnob->blockValueChanges();

        for (int d = 0; d < itKnob->getDimension(); ++d) {
            itKnob->resetToDefaultValue(d);
        }

        itKnob->unblockValueChanges();

        if ( itKnob->getHolder() ) {
            itKnob->getHolder()->endChanges(true);
        }
    }

    /*
       Block value changes and call instanceChange on all knobs  afterwards to put back the plug-in
       in a correct state
     */
    double time = 0;
    if (app) {
        time = app->getTimeLine()->currentFrame();
    }
    for (std::list<KnobWPtr >::iterator it = _knobs.begin(); it != _knobs.end(); ++it) {
        KnobPtr itKnob = it->lock();
        if (!itKnob) {
            continue;
        }
        if ( itKnob->getHolder() ) {
            itKnob->getHolder()->onKnobValueChanged_public(itKnob.get(), eValueChangedReasonRestoreDefault, time, ViewIdx(0), true);
        }
    }

    if (app) {
        app->removeMultipleKeyframeIndicator(times, true);
    }


    if ( holder && holder->getApp() ) {
        holder->endChanges();
    }

    if (_isNodeReset && isEffect) {
        isEffect->purgeCaches();
    }


    if ( first->getHolder() ) {
        first->getHolder()->incrHashAndEvaluate(true, true);
        if ( first->getHolder()->getApp() ) {
            first->getHolder()->getApp()->redrawAllViewers();
        }
    }
    setText( tr("Restore default value(s)") );
} // RestoreDefaultsCommand::redo
Exemplo n.º 23
0
void
PasteUndoCommand::copyFrom(const KnobPtr& serializedKnob,
                           bool isRedo)
{
    KnobPtr internalKnob = _imp->knob.lock()->getKnob();

    switch (_imp->type) {
    case eKnobClipBoardTypeCopyAnim: {
        internalKnob->beginChanges();
        for (int i = 0; i < internalKnob->getDimension(); ++i) {
            if ( ( _imp->targetDimension == -1) || ( i == _imp->targetDimension) ) {
                boost::shared_ptr<Curve> fromCurve;
                if ( ( i == _imp->targetDimension) && ( _imp->fromDimension != -1) ) {
                    fromCurve = serializedKnob->getCurve(ViewIdx(0), _imp->fromDimension);
                } else {
                    fromCurve = serializedKnob->getCurve(ViewIdx(0), i);
                }
                if (!fromCurve) {
                    continue;
                }
                internalKnob->cloneCurve(ViewIdx(0), i, *fromCurve);
            }
        }
        internalKnob->endChanges();
        break;
    }
    case eKnobClipBoardTypeCopyValue: {
        Knob<int>* isInt = dynamic_cast<Knob<int>*>( internalKnob.get() );
        Knob<bool>* isBool = dynamic_cast<Knob<bool>*>( internalKnob.get() );
        Knob<double>* isDouble = dynamic_cast<Knob<double>*>( internalKnob.get() );
        Knob<std::string>* isString = dynamic_cast<Knob<std::string>*>( internalKnob.get() );

        Knob<int>* isFromInt = dynamic_cast<Knob<int>*>( serializedKnob.get() );
        Knob<bool>* isFromBool = dynamic_cast<Knob<bool>*>( serializedKnob.get() );
        Knob<double>* isFromDouble = dynamic_cast<Knob<double>*>( serializedKnob.get() );
        Knob<std::string>* isFromString = dynamic_cast<Knob<std::string>*>( serializedKnob.get() );

        internalKnob->beginChanges();
        for (int i = 0; i < internalKnob->getDimension(); ++i) {
            if ( ( _imp->targetDimension == -1) || ( i == _imp->targetDimension) ) {
                if (isInt && isFromInt) {
                    int f = (i == _imp->targetDimension && _imp->fromDimension != -1) ? isFromInt->getValue(_imp->fromDimension) : isFromInt->getValue(i);
                    isInt->setValue(f, ViewIdx(0), i, eValueChangedReasonNatronInternalEdited, 0);
                } else if (isBool && isFromBool) {
                    bool f = (i == _imp->targetDimension && _imp->fromDimension != -1) ? isFromBool->getValue(_imp->fromDimension) : isFromBool->getValue(i);
                    isBool->setValue(f, ViewIdx(0), i, eValueChangedReasonNatronInternalEdited, 0);
                } else if (isDouble && isFromDouble) {
                    double f = (i == _imp->targetDimension && _imp->fromDimension != -1) ? isFromDouble->getValue(_imp->fromDimension) : isFromDouble->getValue(i);
                    isDouble->setValue(f, ViewIdx(0), i, eValueChangedReasonNatronInternalEdited, 0);
                } else if (isString && isFromString) {
                    std::string f = (i == _imp->targetDimension && _imp->fromDimension != -1) ? isFromString->getValue(_imp->fromDimension) : isFromString->getValue(i);
                    isString->setValue(f, ViewIdx(0), i, eValueChangedReasonNatronInternalEdited, 0);
                }
            }
        }
        internalKnob->endChanges();
        break;
    }
    case eKnobClipBoardTypeCopyLink: {
        //bool useExpression = !KnobI::areTypesCompatibleForSlave(internalKnob.get(), serializedKnob.get());

        internalKnob->beginChanges();
        for (int i = 0; i < internalKnob->getDimension(); ++i) {
            if ( ( _imp->targetDimension == -1) || ( i == _imp->targetDimension) ) {
                if (isRedo) {
                    if (_imp->fromDimension != -1) {
                        internalKnob->slaveTo(i, serializedKnob, _imp->fromDimension);
                    } else {
                        internalKnob->slaveTo(i, serializedKnob, i);
                    }
                } else {
                    internalKnob->unSlave(i, false);
                }
            }
        }
        internalKnob->endChanges();
        break;
    }
    } // switch
} // redo
Exemplo n.º 24
0
QString
KnobGui::toolTip() const
{
    KnobPtr knob = getKnob();
    KnobChoice* isChoice = dynamic_cast<KnobChoice*>( knob.get() );
    bool isMarkdown = knob.get()->isHintInMarkdown();
    QString tt;
    QString realTt;

    if (isMarkdown) {
        tt = QString::fromUtf8( knob.get()->getName().c_str() );
        tt.append( QString::fromUtf8("\n==========\n\n") );
    } else {
        tt = getScriptNameHtml();
    }

    if (!isChoice) {
        realTt.append( QString::fromUtf8( knob->getHintToolTip().c_str() ) );
    } else {
        realTt.append( QString::fromUtf8( isChoice->getHintToolTipFull().c_str() ) );
    }

    std::vector<std::string> expressions;
    bool exprAllSame = true;
    for (int i = 0; i < knob->getDimension(); ++i) {
        expressions.push_back( knob->getExpression(i) );
        if ( (i > 0) && (expressions[i] != expressions[0]) ) {
            exprAllSame = false;
        }
    }

    QString exprTt;
    if (exprAllSame) {
        if ( !expressions[0].empty() ) {
            if (isMarkdown) {
                exprTt = QString::fromUtf8("ret = **%1**\n\n").arg( QString::fromUtf8( expressions[0].c_str() ) );
            } else {
                exprTt = QString::fromUtf8("ret = <b>%1</b><br />").arg( QString::fromUtf8( expressions[0].c_str() ) );
            }
        }
    } else {
        for (int i = 0; i < knob->getDimension(); ++i) {
            std::string dimName = knob->getDimensionName(i);
            QString toAppend;
            if (isMarkdown) {
                toAppend = QString::fromUtf8("%1 = **%2**\n\n").arg( QString::fromUtf8( dimName.c_str() ) ).arg( QString::fromUtf8( expressions[i].c_str() ) );
            } else {
                toAppend = QString::fromUtf8("%1 = <b>%2</b><br />").arg( QString::fromUtf8( dimName.c_str() ) ).arg( QString::fromUtf8( expressions[i].c_str() ) );
            }
            exprTt.append(toAppend);
        }
    }

    if ( !exprTt.isEmpty() ) {
        tt.append(exprTt);
        if (!isMarkdown) {
            tt += QLatin1String("<br/>");
        }
    }

    if ( !realTt.isEmpty() ) {
        if (!isMarkdown) {
            realTt = GuiUtils::convertFromPlainText(realTt.trimmed(), Qt::WhiteSpaceNormal);
        }
        tt.append(realTt);
    }

    if (isMarkdown) {
        tt = Markdown::convert2html(tt);
        // Shrink H1/H2 (Can't do it in qt stylesheet)
        tt.replace( QString::fromUtf8("<h1>"), QString::fromUtf8("<h1 style=\"font-size:large;\">") );
        tt.replace( QString::fromUtf8("<h2>"), QString::fromUtf8("<h2 style=\"font-size:large;\">") );
    }

    return tt;
} // KnobGui::toolTip