void DSRightTrimReaderCommand::trimRight(double lastFrame) { DSNodePtr nodeContext = _readerContext.lock(); if (!nodeContext) { return; } NodePtr node = nodeContext->getInternalNode(); KnobIntBase *lastFrameKnob = dynamic_cast<KnobIntBase *>( node->getKnobByName(kReaderParamNameLastFrame).get() ); assert(lastFrameKnob); if (!lastFrameKnob) { return; } KnobHolderPtr holder = lastFrameKnob->getHolder(); EffectInstancePtr effectInstance = toEffectInstance(holder); assert(effectInstance); if (!effectInstance) { return; } effectInstance->beginChanges(); KnobHelper::ValueChangedReturnCodeEnum r = lastFrameKnob->setValue(lastFrame, ViewSpec::all(), 0, eValueChangedReasonNatronGuiEdited, 0); effectInstance->endChanges(); Q_UNUSED(r); }
void KnobGuiFile::createWidget(QHBoxLayout* layout) { KnobGuiPtr knobUI = getKnobGui(); if (!knobUI) { return; } Gui* gui = knobUI->getGui(); if (!gui) { return; } GuiAppInstancePtr app = gui->getApp(); if (!app) { return; } KnobFilePtr knob = _knob.lock(); if (!knob) { return; } EffectInstancePtr holderIsEffect = toEffectInstance( knob->getHolder() ); if ( holderIsEffect && holderIsEffect->isReader() && (knob->getName() == kOfxImageEffectFileParamName) ) { TimeLinePtr timeline = app->getTimeLine(); QObject::connect( timeline.get(), SIGNAL(frameChanged(SequenceTime,int)), this, SLOT(onTimelineFrameChanged(SequenceTime,int)) ); }
void RestoreDefaultsCommand::redo() { KnobIPtr first = _knobs.front().lock(); AppInstancePtr app; KnobHolderPtr holder = first->getHolder(); EffectInstancePtr isEffect = toEffectInstance(holder); if (holder) { app = holder->getApp(); holder->beginChanges(); } // First reset all knobs values, this will not call instanceChanged action for (std::list<KnobIWPtr >::iterator it = _knobs.begin(); it != _knobs.end(); ++it) { KnobIPtr itKnob = it->lock(); if (!itKnob) { continue; } if ( itKnob->getHolder() ) { itKnob->getHolder()->beginChanges(); } itKnob->resetToDefaultValue(_targetDim, _targetView); if ( itKnob->getHolder() ) { itKnob->getHolder()->endChanges(true); } } // 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<KnobIWPtr >::iterator it = _knobs.begin(); it != _knobs.end(); ++it) { KnobIPtr itKnob = it->lock(); if (!itKnob) { continue; } if ( itKnob->getHolder() ) { itKnob->getHolder()->onKnobValueChanged_public(itKnob, eValueChangedReasonRestoreDefault, time, ViewIdx(0), true); } } if ( holder && holder->getApp() ) { holder->endChanges(); } if ( first->getHolder() ) { if ( first->getHolder()->getApp() ) { first->getHolder()->getApp()->redrawAllViewers(); } } } // RestoreDefaultsCommand::redo
MultipleKnobEditsUndoCommand::MultipleKnobEditsUndoCommand(const KnobIPtr& knob, const QString& commandName, ValueChangedReasonEnum reason, ValueChangedReturnCodeEnum setValueRetCode, bool createNew, bool setKeyFrame, const PerDimViewVariantMap& oldValue, const Variant & newValue, DimSpec dimension, double time, ViewSetSpec view) : QUndoCommand() , knobs() , createNew(createNew) , firstRedoCalled(false) { assert(knob); std::list<ValueToSet>& vlist = knobs[knob]; vlist.push_back(ValueToSet()); // Add the new value to set to the list (which may be not empty) ValueToSet &v = vlist.back(); v.newValue = newValue; v.dimension = dimension; assert(dimension != -1); if (!setKeyFrame) { // Ensure the time is correct in case auto-keying is on and we add a keyframe v.time = knob->getCurrentTime(); } else { v.time = time; } v.setKeyFrame = setKeyFrame; v.view = view; v.setValueRetCode = setValueRetCode; v.reason = reason; v.oldValues = oldValue; KnobHolderPtr holder = knob->getHolder(); EffectInstancePtr effect = toEffectInstance(holder); QString holderName; if (effect) { holderName = QString::fromUtf8( effect->getNode()->getLabel().c_str() ); } // Set the command name in the Edit menu if (!commandName.isEmpty()) { setText(QString::fromUtf8("%1: ").arg(holderName) + commandName); } else { // If no command name passed, make up a generic command name setText( tr("%1: Multiple Parameters Edits").arg(holderName) ); } }
void moveGroupNode(DopeSheetEditor* model, const NodePtr& node, double dt) { NodeGroupPtr group = node->isEffectNodeGroup(); assert(group); NodesList nodes; group->getNodes_recursive(nodes, true); for (NodesList::iterator it = nodes.begin(); it != nodes.end(); ++it) { NodeGuiPtr nodeGui = boost::dynamic_pointer_cast<NodeGui>( (*it)->getNodeGui() ); assert(nodeGui); std::string pluginID = (*it)->getPluginID(); NodeGroupPtr isChildGroup = (*it)->isEffectNodeGroup(); // Move readers #ifndef NATRON_ENABLE_IO_META_NODES if ( ReadNode::isBundledReader( pluginID, node->getApp()->wasProjectCreatedWithLowerCaseIDs() ) ) { #else if (pluginID == PLUGINID_NATRON_READ) { #endif moveReader(*it, dt); } else if (pluginID == PLUGINID_OFX_TIMEOFFSET) { moveTimeOffset(*it, dt); } else if (pluginID == PLUGINID_OFX_FRAMERANGE) { moveFrameRange(*it, dt); } else if (isChildGroup) { moveGroupNode(model, *it, dt); } // Move keyframes const KnobsVec &knobs = (*it)->getKnobs(); for (KnobsVec::const_iterator knobIt = knobs.begin(); knobIt != knobs.end(); ++knobIt) { const KnobIPtr& knob = *knobIt; if ( !knob->hasAnimation() ) { continue; } for (int dim = 0; dim < knob->getDimension(); ++dim) { if ( !knob->isAnimated( dim, ViewIdx(0) ) ) { continue; } KeyFrameSet keyframes = knob->getCurve(ViewIdx(0), dim)->getKeyFrames_mt_safe(); for (KeyFrameSet::iterator kfIt = keyframes.begin(); kfIt != keyframes.end(); ++kfIt) { KeyFrame kf = (*kfIt); KeyFrame fake; knob->moveValueAtTime(eCurveChangeReasonDopeSheet, kf.getTime(), ViewSpec::all(), dim, dt, 0, &fake); } } } } } // moveGroupNode NATRON_NAMESPACE_ANONYMOUS_EXIT ////////////////////////// DSMoveKeysCommand ////////////////////////// DSMoveKeysAndNodesCommand::DSMoveKeysAndNodesCommand(const DSKeyPtrList &keys, const std::vector<DSNodePtr >& nodes, double dt, DopeSheetEditor *model, QUndoCommand *parent) : QUndoCommand(parent), _keys(keys), _nodes(), _dt(dt), _model(model) { setText( tr("Move selected keys") ); std::set<NodePtr > nodesSet; for (std::vector<DSNodePtr >::const_iterator it = nodes.begin(); it != nodes.end(); ++it) { DopeSheetItemType type = (*it)->getItemType(); if ( (type != eDopeSheetItemTypeReader) && ( type != eDopeSheetItemTypeGroup) && ( type != eDopeSheetItemTypeTimeOffset) && ( type != eDopeSheetItemTypeFrameRange) ) { //Note that Retime nodes cannot be moved continue; } _nodes.push_back(*it); nodesSet.insert( (*it)->getInternalNode() ); NodeGroupPtr isGroup = (*it)->getInternalNode()->isEffectNodeGroup(); if (isGroup) { NodesList recurseNodes; isGroup->getNodes_recursive(recurseNodes, true); for (NodesList::iterator it = recurseNodes.begin(); it != recurseNodes.end(); ++it) { nodesSet.insert(*it); } } } for (DSKeyPtrList::iterator it = _keys.begin(); it != _keys.end(); ++it) { KnobHolderPtr holder = (*it)->getContext()->getInternalKnob()->getHolder(); assert(holder); EffectInstancePtr isEffect = toEffectInstance(holder); if (isEffect) { nodesSet.insert( isEffect->getNode() ); } } for (std::set<NodePtr >::iterator it = nodesSet.begin(); it != nodesSet.end(); ++it) { _allDifferentNodes.push_back(*it); } } void DSMoveKeysAndNodesCommand::undo() { moveSelection(-_dt); }
void DSSlipReaderCommand::slipReader(double dt) { DSNodePtr nodeContext = _readerContext.lock(); if (!nodeContext) { return; } NodePtr node = nodeContext->getInternalNode(); KnobIntBase *firstFrameKnob = dynamic_cast<KnobIntBase *>( node->getKnobByName(kReaderParamNameFirstFrame).get() ); assert(firstFrameKnob); KnobIntBase *lastFrameKnob = dynamic_cast<KnobIntBase *>( node->getKnobByName(kReaderParamNameLastFrame).get() ); assert(lastFrameKnob); KnobIntBase *timeOffsetKnob = dynamic_cast<KnobIntBase *>( node->getKnobByName(kReaderParamNameTimeOffset).get() ); assert(timeOffsetKnob); KnobIntBase *startingTimeKnob = dynamic_cast<KnobIntBase *>( node->getKnobByName(kReaderParamNameStartingTime).get() ); assert(startingTimeKnob); if (!firstFrameKnob || !lastFrameKnob || !timeOffsetKnob || !startingTimeKnob) { return; } /* Since the lastFrameKnob and startingTimeKnob have their signal connected to the computeNodeRange function in DopeSheetview We disconnect them beforehand and reconnect them afterwards, otherwise the dopesheet view is going to get many redraw() calls for nothing. */ DopeSheetView* view = _model->getDopesheetView(); QObject::disconnect( lastFrameKnob->getSignalSlotHandler().get(), SIGNAL(valueChanged(ViewSpec,int,int)), view, SLOT(onRangeNodeChanged(ViewSpec,int,int)) ); QObject::disconnect( startingTimeKnob->getSignalSlotHandler().get(), SIGNAL(valueChanged(ViewSpec,int,int)), view, SLOT(onRangeNodeChanged(ViewSpec,int,int)) ); KnobHolderPtr holder = lastFrameKnob->getHolder(); EffectInstancePtr effectInstance = toEffectInstance(holder); assert(effectInstance); if (!effectInstance) { return; } effectInstance->beginChanges(); { KnobHelper::ValueChangedReturnCodeEnum r; r = firstFrameKnob->setValue(firstFrameKnob->getValue() - dt, ViewSpec::all(), 0, eValueChangedReasonNatronGuiEdited, 0); Q_UNUSED(r); r = lastFrameKnob->setValue(lastFrameKnob->getValue() - dt, ViewSpec::all(), 0, eValueChangedReasonNatronGuiEdited, 0); Q_UNUSED(r); r = timeOffsetKnob->setValue(timeOffsetKnob->getValue() + dt, ViewSpec::all(), 0, eValueChangedReasonNatronGuiEdited, 0); Q_UNUSED(r); } effectInstance->endChanges(); QObject::connect( lastFrameKnob->getSignalSlotHandler().get(), SIGNAL(valueChanged(ViewSpec,int,int)), view, SLOT(onRangeNodeChanged(ViewSpec,int,int)) ); QObject::connect( startingTimeKnob->getSignalSlotHandler().get(), SIGNAL(valueChanged(ViewSpec,int,int)), view, SLOT(onRangeNodeChanged(ViewSpec,int,int)) ); view->update(); } // DSSlipReaderCommand::slipReader
void ProjectGuiSerialization::initialize(const ProjectGui* projectGui) { NodesList activeNodes; projectGui->getInternalProject()->getActiveNodesExpandGroups(&activeNodes); _serializedNodes.clear(); for (NodesList::iterator it = activeNodes.begin(); it != activeNodes.end(); ++it) { NodeGuiIPtr nodegui_i = (*it)->getNodeGui(); if (!nodegui_i) { continue; } NodeGuiPtr nodegui = boost::dynamic_pointer_cast<NodeGui>(nodegui_i); if ( nodegui->isVisible() ) { NodeCollectionPtr isInCollection = (*it)->getGroup(); NodeGroupPtr isCollectionAGroup = toNodeGroup( isInCollection ); if (!isCollectionAGroup) { ///Nodes within a group will be serialized recursively in the node group serialization NodeGuiSerialization state; nodegui->serialize(&state); _serializedNodes.push_back(state); } ViewerInstancePtr viewer = (*it)->isEffectViewerInstance(); if (viewer) { ViewerTab* tab = projectGui->getGui()->getViewerTabForInstance(viewer); assert(tab); ViewerData viewerData; double zoompar; tab->getViewer()->getProjection(&viewerData.zoomLeft, &viewerData.zoomBottom, &viewerData.zoomFactor, &zoompar); viewerData.userRoI = tab->getViewer()->getUserRegionOfInterest(); viewerData.userRoIenabled = tab->getViewer()->isUserRegionOfInterestEnabled(); viewerData.isClippedToProject = tab->isClippedToProject(); viewerData.autoContrastEnabled = tab->isAutoContrastEnabled(); viewerData.gain = tab->getGain(); viewerData.gamma = tab->getGamma(); viewerData.colorSpace = tab->getColorSpace(); viewerData.channels = tab->getChannelsString(); viewerData.renderScaleActivated = tab->getRenderScaleActivated(); viewerData.mipMapLevel = tab->getMipMapLevel(); viewerData.zoomOrPanSinceLastFit = tab->getZoomOrPannedSinceLastFit(); viewerData.wipeCompositingOp = (int)tab->getCompositingOperator(); viewerData.leftToolbarVisible = tab->isLeftToolbarVisible(); viewerData.rightToolbarVisible = tab->isRightToolbarVisible(); viewerData.topToolbarVisible = tab->isTopToolbarVisible(); viewerData.infobarVisible = tab->isInfobarVisible(); viewerData.playerVisible = tab->isPlayerVisible(); viewerData.timelineVisible = tab->isTimelineVisible(); viewerData.checkerboardEnabled = tab->isCheckerboardEnabled(); viewerData.isFullFrameProcessEnabled = tab->isFullFrameProcessingEnabled(); viewerData.fps = tab->getDesiredFps(); viewerData.fpsLocked = tab->isFPSLocked(); viewerData.isPauseEnabled[0] = tab->isViewerPaused(0); viewerData.isPauseEnabled[1] = tab->isViewerPaused(1); viewerData.layerName = tab->getCurrentLayerName().toStdString(); viewerData.alphaLayerName = tab->getCurrentAlphaLayerName().toStdString(); tab->getTimelineBounds(&viewerData.leftBound, &viewerData.rightBound); tab->getActiveInputs(&viewerData.aChoice, &viewerData.bChoice); viewerData.version = VIEWER_DATA_SERIALIZATION_VERSION; _viewersData.insert( std::make_pair(viewer->getNode()->getScriptName_mt_safe(), viewerData) ); } } } ///Init windows _layoutSerialization.initialize( projectGui->getGui() ); ///save histograms std::list<Histogram*> histograms = projectGui->getGui()->getHistograms_mt_safe(); for (std::list<Histogram*>::const_iterator it = histograms.begin(); it != histograms.end(); ++it) { _histograms.push_back( (*it)->objectName().toStdString() ); } ///save opened panels by order std::list<DockablePanel*> panels = projectGui->getGui()->getVisiblePanels_mt_safe(); for (std::list<DockablePanel*>::iterator it = panels.begin(); it != panels.end(); ++it) { if ( (*it)->isVisible() ) { KnobHolderPtr holder = (*it)->getHolder(); assert(holder); EffectInstancePtr isEffect = toEffectInstance(holder); ProjectPtr isProj = toProject(holder); if (isProj) { _openedPanelsOrdered.push_back(kNatronProjectSettingsPanelSerializationName); } else if (isEffect) { _openedPanelsOrdered.push_back( isEffect->getNode()->getFullyQualifiedName() ); } } } _scriptEditorInput = projectGui->getGui()->getScriptEditor()->getAutoSavedScript().toStdString(); std::map<NATRON_PYTHON_NAMESPACE::PyPanel*, std::string> pythonPanels = projectGui->getGui()->getPythonPanels(); for (std::map<NATRON_PYTHON_NAMESPACE::PyPanel*, std::string>::iterator it = pythonPanels.begin(); it != pythonPanels.end(); ++it) { boost::shared_ptr<PythonPanelSerialization> s(new PythonPanelSerialization); s->initialize(it->first, it->second); _pythonPanels.push_back(s); } } // initialize
std::string PasteKnobClipBoardUndoCommand::makeLinkExpression(const std::vector<std::string>& projectViewNames, const KnobIPtr& targetKnob, bool multCurve, const KnobIPtr& fromKnob, DimSpec fromDimension, ViewSetSpec fromView, DimSpec targetDimension, ViewSetSpec targetView) { EffectInstancePtr fromEffect = toEffectInstance( fromKnob->getHolder() ); EffectInstancePtr toEffect = toEffectInstance( targetKnob->getHolder() ); assert(fromEffect && toEffect); if (!fromEffect || !toEffect) { return std::string(); } std::stringstream ss; if (fromEffect == toEffect) { // Same node, use thisNode ss << "thisNode."; } else { // If the container of the effect is a group, prepend thisGroup, otherwise use // the canonical app prefix NodeGroupPtr isEffectContainerGroup; { NodeCollectionPtr effectContainer = fromEffect->getNode()->getGroup(); isEffectContainerGroup = toNodeGroup(effectContainer); } if (isEffectContainerGroup) { ss << "thisGroup."; } else { ss << fromEffect->getApp()->getAppIDString() << "."; } ss << fromEffect->getNode()->getScriptName_mt_safe() << "."; } // Call getValue on the fromKnob ss << fromKnob->getName(); ss << ".getValue("; if (fromKnob->getNDimensions() > 1) { if (fromDimension.isAll()) { ss << "dimension"; } else { ss << fromDimension; } } std::list<ViewIdx> sourceViews = fromKnob->getViewsList(); if (sourceViews.size() > 1) { ss << ", "; if (fromView.isAll()) { ss << "view"; } else { if (fromView >= 0 && fromView < (int)projectViewNames.size()) { ss << projectViewNames[fromView]; } else { ss << "Main"; } } } ss << ")"; // Also check if we need to multiply by the target knob's curve if (multCurve) { ss << " * curve(frame, "; if (targetDimension.isAll()) { ss << "dimension"; } else { ss << targetDimension; } std::list<ViewIdx> targetKnobViews = targetKnob->getViewsList(); if (targetKnobViews.size() > 1) { ss << ", "; if (targetView.isAll()) { ss << "view"; } else { if (targetView >= 0 && targetView < (int)projectViewNames.size()) { ss << projectViewNames[targetView]; } else { ss << "Main"; } } } ss << ")"; } return ss.str(); } // makeLinkExpression