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(); }
void KnobGui::onEditExprDialogFinished() { EditExpressionDialog* dialog = dynamic_cast<EditExpressionDialog*>( sender() ); if (dialog) { QDialog::DialogCode ret = (QDialog::DialogCode)dialog->result(); switch (ret) { case QDialog::Accepted: { bool hasRetVar; QString expr = dialog->getExpression(&hasRetVar); std::string stdExpr = expr.toStdString(); int dim = dialog->getDimension(); std::string existingExpr = getKnob()->getExpression(dim); if (existingExpr != stdExpr) { pushUndoCommand( new SetExpressionCommand(getKnob(), hasRetVar, dim, stdExpr) ); } break; } case QDialog::Rejected: break; } dialog->deleteLater(); } }
void KnobGui::hide() { if (!_imp->customInteract) { _hide(); } else { _imp->customInteract->hide(); } //also hide the curve from the curve editor if there's any and the knob is not inside a group KnobPtr knob = getKnob(); if ( knob && knob->getHolder() && knob->getHolder()->getApp() ) { KnobPtr parent = getKnob()->getParentKnob(); bool isSecret = true; while (parent) { if ( !parent->getIsSecret() ) { isSecret = false; break; } parent = parent->getParentKnob(); } if (isSecret) { getGui()->getCurveEditor()->hideCurves( shared_from_this() ); } } ////In order to remove the row of the layout we have to make sure ALL the knobs on the row ////are hidden. bool shouldRemoveWidget = true; for (U32 i = 0; i < _imp->knobsOnSameLine.size(); ++i) { KnobGuiPtr sibling = _imp->container->getKnobGui( _imp->knobsOnSameLine[i].lock() ); if ( sibling && !sibling->isSecretRecursive() ) { shouldRemoveWidget = false; } } if (shouldRemoveWidget) { if (_imp->field) { _imp->field->hide(); } if (_imp->container) { _imp->container->refreshTabWidgetMaxHeight(); } } else { if ( _imp->field && !_imp->field->isVisible() ) { _imp->field->show(); } } if (_imp->labelContainer) { _imp->labelContainer->hide(); } else if (_imp->descriptionLabel) { _imp->descriptionLabel->hide(); } } // KnobGui::hide
void KnobGui::onLabelChanged() { if (_imp->descriptionLabel) { KnobPtr knob = getKnob(); if (!knob) { return; } const std::string& iconLabel = knob->getIconLabel(); if (!iconLabel.empty()) { return; } std::string descriptionLabel; KnobString* isStringKnob = dynamic_cast<KnobString*>(knob.get()); bool isLabelKnob = isStringKnob && isStringKnob->isLabel(); if (isLabelKnob) { descriptionLabel = isStringKnob->getValue(); } else { descriptionLabel = knob->getLabel(); } _imp->descriptionLabel->setText_overload(QString::fromUtf8(descriptionLabel.c_str())); onLabelChangedInternal(); } }
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) ); }
void KnobGui::onLabelChanged() { if (_imp->descriptionLabel) { KnobPtr knob = getKnob(); if (!knob) { return; } const std::string& iconLabel = knob->getIconLabel(); if ( !iconLabel.empty() ) { return; } std::string descriptionLabel = getDescriptionLabel(); if (descriptionLabel.empty()) { _imp->descriptionLabel->hide(); } else { _imp->descriptionLabel->setText_overload( QString::fromUtf8( descriptionLabel.c_str() ) ); _imp->descriptionLabel->show(); } onLabelChangedInternal(); } else { onLabelChangedInternal(); } }
void KnobGui::show(int /*index*/) { if ( !getGui() ) { return; } if (!_imp->customInteract) { _show(); } else { _imp->customInteract->show(); } //also show the curve from the curve editor if there's any KnobPtr knob = getKnob(); if ( knob && knob->getHolder() && knob->getHolder()->getApp() ) { getGui()->getCurveEditor()->showCurves( shared_from_this() ); } //if (_imp->isOnNewLine) { if (_imp->field) { _imp->field->show(); } if (_imp->container) { _imp->container->refreshTabWidgetMaxHeight(); } //} if (_imp->labelContainer) { _imp->labelContainer->show(); } else if (_imp->descriptionLabel) { _imp->descriptionLabel->show(); } }
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); }
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(); }
bool KnobGui::isSecretRecursive() const { // If the Knob is within a group, only show it if the group is unfolded! // To test it: // try TuttlePinning: fold all groups, then switch from perspective to affine to perspective. // VISIBILITY is different from SECRETNESS. The code considers that both things are equivalent, which is wrong. // Of course, this check has to be *recursive* (in case the group is within a folded group) KnobPtr knob = getKnob(); bool isViewerKnob = _imp->container->isInViewerUIKnob(); bool showit = isViewerKnob ? !knob->getInViewerContextSecret() : !knob->getIsSecret(); KnobPtr parentKnob = knob->getParentKnob(); KnobGroup* parentIsGroup = dynamic_cast<KnobGroup*>( parentKnob.get() ); while (showit && parentKnob && parentIsGroup) { KnobGuiGroup* parentGui = dynamic_cast<KnobGuiGroup*>( _imp->container->getKnobGui(parentKnob).get() ); // check for secretness and visibility of the group bool parentSecret = isViewerKnob ? parentKnob->getInViewerContextSecret() : parentKnob->getIsSecret(); if ( parentSecret || ( parentGui && !parentGui->isChecked() ) ) { showit = false; // one of the including groups is folder, so this item is hidden } // prepare for next loop iteration parentKnob = parentKnob->getParentKnob(); parentIsGroup = dynamic_cast<KnobGroup*>( parentKnob.get() ); } return !showit; }
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); }
void KnobGui::setKeyframeMarkerOnTimeline(double time) { KnobPtr knob = getKnob(); if (knob->isDeclaredByPlugin() || knob->isUserKnob()) { knob->getHolder()->getApp()->addKeyframeIndicator(time); } }
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); }
void KnobGui::setReadOnly_(bool readOnly, int dimension) { if (!_imp->customInteract) { setReadOnly(readOnly, dimension); } ///This code doesn't work since the knob dimensions are still enabled even if readonly bool hasDimensionEnabled = false; for (int i = 0; i < getKnob()->getDimension(); ++i) { if ( getKnob()->isEnabled(i) ) { hasDimensionEnabled = true; } } if (_imp->descriptionLabel) { _imp->descriptionLabel->setReadOnly(!hasDimensionEnabled); } }
void KnobGui::onClearExprActionTriggered() { QAction* act = qobject_cast<QAction*>( sender() ); assert(act); int dim = act->data().toInt(); pushUndoCommand( new SetExpressionCommand(getKnob(), false, dim, "") ); }
void KnobGui::copyToClipBoard(KnobClipBoardType type, int dimension) const { KnobPtr knob = getKnob(); if (!knob) { return; } appPTR->setKnobClipBoard(type, knob, dimension); }
void KnobGuiColor::onPickingEnabled(bool enabled) { if ( getKnob()->getHolder()->getApp() ) { if (enabled) { getGui()->registerNewColorPicker( _knob.lock() ); } else { getGui()->removeColorPicker( _knob.lock() ); } } }
void KnobGui::onInternalKeyRemoved(double time, ViewSpec /*view*/, int /*dimension*/, int /*reason*/) { KnobPtr knob = getKnob(); if ( !knob->getIsSecret() && (knob->isDeclaredByPlugin() || knob->isUserKnob())) { knob->getHolder()->getApp()->removeKeyFrameIndicator(time); } Q_EMIT keyFrameRemoved(); }
void KnobGui::onHasModificationsChanged() { if (_imp->guiRemoved) { return; } if (_imp->descriptionLabel) { bool hasModif = getKnob()->hasModifications(); _imp->descriptionLabel->setAltered(!hasModif); } reflectModificationsState(); }
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) ); } } } }
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) ); }
void KnobGui::onSetExprActionTriggered() { QAction* action = qobject_cast<QAction*>( sender() ); assert(action); int dim = action->data().toInt(); EditExpressionDialog* dialog = new EditExpressionDialog(getGui(), dim, shared_from_this(), _imp->field); dialog->create(QString::fromUtf8( getKnob()->getExpression(dim == -1 ? 0 : dim).c_str() ), true); QObject::connect( dialog, SIGNAL(accepted()), this, SLOT(onEditExprDialogFinished()) ); QObject::connect( dialog, SIGNAL(rejected()), this, SLOT(onEditExprDialogFinished()) ); dialog->show(); }
void KnobGui::onInternalValueChanged(ViewSpec /*view*/, int dimension, int reason) { if (_imp->guiRemoved) { return; } if ( _imp->widgetCreated && ( (ValueChangedReasonEnum)reason != eValueChangedReasonUserEdited ) ) { updateGuiInternal(dimension); if ( !getKnob()->getExpression(dimension).empty() ) { Q_EMIT refreshCurveEditor(); } } }
void KnobGui::resetDefault(int dimension) { KnobPtr knob = getKnob(); KnobButton* isBtn = dynamic_cast<KnobButton*>( knob.get() ); KnobPage* isPage = dynamic_cast<KnobPage*>( knob.get() ); KnobGroup* isGroup = dynamic_cast<KnobGroup*>( knob.get() ); KnobSeparator* isSeparator = dynamic_cast<KnobSeparator*>( knob.get() ); if (!isBtn && !isPage && !isGroup && !isSeparator) { std::list<KnobPtr > knobs; knobs.push_back(knob); pushUndoCommand( new RestoreDefaultsCommand(false, knobs, dimension) ); } }
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
void KnobGui::setKeyframe(double time, const KeyFrame& key, int dimension, ViewSpec view) { KnobPtr knob = getKnob(); assert( knob->getHolder()->getApp() ); bool keyAdded = knob->onKeyFrameSet(time, view, key, dimension); Q_EMIT keyFrameSet(); if ( !knob->getIsSecret() && keyAdded && knob->isDeclaredByPlugin() ) { knob->getHolder()->getApp()->addKeyframeIndicator(time); } }
void KnobGui::removeKeyFrame(double time, int dimension, ViewSpec view) { KnobPtr knob = getKnob(); knob->onKeyFrameRemoved(time, view, dimension); Q_EMIT keyFrameRemoved(); assert( knob->getHolder()->getApp() ); if ( !knob->getIsSecret() ) { knob->getHolder()->getApp()->removeKeyFrameIndicator(time); } updateGUI(dimension); }
void KnobGui::onCreateAliasOnGroupActionTriggered() { KnobHolder* holder = getKnob()->getHolder(); EffectInstance* isEffect = dynamic_cast<EffectInstance*>(holder); assert(isEffect); if (!isEffect) { throw std::logic_error(""); } boost::shared_ptr<NodeCollection> collec = isEffect->getNode()->getGroup(); NodeGroup* isCollecGroup = dynamic_cast<NodeGroup*>( collec.get() ); assert(isCollecGroup); if (isCollecGroup) { createDuplicateOnNode(isCollecGroup, true, boost::shared_ptr<KnobPage>(), boost::shared_ptr<KnobGroup>(), -1); } }
void KnobGui::onKeyFrameMoved(ViewSpec /*view*/, int /*dimension*/, double oldTime, double newTime) { KnobPtr knob = getKnob(); if ( !knob->isAnimationEnabled() || !knob->canAnimate() ) { return; } if ( knob->isDeclaredByPlugin() || knob->isUserKnob() ) { AppInstPtr app = knob->getHolder()->getApp(); assert(app); app->removeKeyFrameIndicator(oldTime); app->addKeyframeIndicator(newTime); } }
void KnobGui::onInternalKeySet(double time, ViewSpec /*view*/, int /*dimension*/, int reason, bool added ) { if ( (ValueChangedReasonEnum)reason != eValueChangedReasonUserEdited ) { if (added) { KnobPtr knob = getKnob(); if ( !knob->getIsSecret() && ( knob->isDeclaredByPlugin() || knob->isUserKnob() ) ) { knob->getHolder()->getApp()->addKeyframeIndicator(time); } } } updateCurveEditorKeyframes(); }