예제 #1
0
void
ViewerNodePrivate::getAllViewerNodes(bool inGroupOnly, std::list<ViewerNodePtr>& viewerNodes) const
{
    NodeCollectionPtr collection;
    if (inGroupOnly) {
        collection = _publicInterface->getNode()->getGroup();
    } else {
        collection = _publicInterface->getApp()->getProject();
    }
    NodesList nodes;
    if (inGroupOnly) {
        nodes = collection->getNodes();
    } else {
        collection->getNodes_recursive(nodes, false);
    }
    for (NodesList::iterator it = nodes.begin(); it != nodes.end(); ++it) {
        if (!(*it)->isActivated()) {
            continue;
        }
        ViewerNodePtr isViewer = (*it)->isEffectViewerNode();
        if (isViewer) {
            viewerNodes.push_back(isViewer);
        }
    }
}
예제 #2
0
std::vector<NodeAnimPtr > AnimationModule::getChildrenNodes(const NodeAnimPtr& node) const
{
    std::vector<NodeAnimPtr > children;
    AnimatedItemTypeEnum nodeType = node->getItemType();
    if (nodeType == eAnimatedItemTypeGroup) {

        // If the node is a group, make all its children to be a child in the tree view
        NodeGroupPtr nodeGroup = node->getInternalNode()->isEffectNodeGroup();
        assert(nodeGroup);

        NodesList nodes = nodeGroup->getNodes();
        for (NodesList::const_iterator it = nodes.begin(); it != nodes.end(); ++it) {
            NodePtr childNode = (*it);
            NodeAnimPtr isInDopeSheet = findNodeAnim( childNode );
            if (isInDopeSheet) {
                children.push_back(isInDopeSheet);
            }
        }

    } else if ( node->isTimeNode() ) {
        // If the node is a time node, all input nodes recursively are considered to be a child
        std::list<NodePtr> markedNodes;
        _imp->getInputs_recursive(node->getInternalNode(), markedNodes, &children);
    }

    return children;
}
예제 #3
0
bool
GuiAppInstance::checkAllReadersModificationDate(bool errorAndWarn)
{
    NodesList allNodes;
    SequenceTime time = getProject()->getCurrentTime();

    getProject()->getNodes_recursive(allNodes, true);
    bool changed =  false;
    for (NodesList::iterator it = allNodes.begin(); it != allNodes.end(); ++it) {
        if ( (*it)->getEffectInstance()->isReader() ) {
            KnobPtr fileKnobI = (*it)->getKnobByName(kOfxImageEffectFileParamName);
            if (!fileKnobI) {
                continue;
            }
            boost::shared_ptr<KnobGuiI> knobUi_i = fileKnobI->getKnobGuiPointer();
            KnobGuiFile* isFileKnob = dynamic_cast<KnobGuiFile*>( knobUi_i.get() );

            if (!isFileKnob) {
                continue;
            }
            changed |= isFileKnob->checkFileModificationAndWarn(time, errorAndWarn);
        }
    }

    return changed;
}
예제 #4
0
static KnobPtr findMaster(const KnobPtr & knob,
                          const NodesList & allNodes,
                          const std::string& masterKnobName,
                          const std::string& masterNodeName,
                          const std::string& masterTrackName,
                          const std::map<std::string,std::string>& oldNewScriptNamesMapping)
{
    ///we need to cycle through all the nodes of the project to find the real master
    NodePtr masterNode;
    
    std::string masterNodeNameToFind = masterNodeName;
    
    /*
     When copy pasting, the new node copied has a script-name different from what is inside the serialization because 2
     nodes cannot co-exist with the same script-name. We keep in the map the script-names mapping
     */
    std::map<std::string,std::string>::const_iterator foundMapping = oldNewScriptNamesMapping.find(masterNodeName);
    if (foundMapping != oldNewScriptNamesMapping.end()) {
        masterNodeNameToFind = foundMapping->second;
    }
    
    for (NodesList::const_iterator it2 = allNodes.begin(); it2 != allNodes.end(); ++it2) {
        if ((*it2)->getScriptName() == masterNodeNameToFind) {
            masterNode = *it2;
            break;
        }
    }
    if (!masterNode) {
        qDebug() << "Link slave/master for " << knob->getName().c_str() <<   " failed to restore the following linkage: " << masterNodeNameToFind.c_str();
        return KnobPtr();
    }
    
    if (!masterTrackName.empty()) {
        boost::shared_ptr<TrackerContext> context = masterNode->getTrackerContext();
        if (context) {
            TrackMarkerPtr marker = context->getMarkerByName(masterTrackName);
            if (marker) {
                return marker->getKnobByName(masterKnobName);
            }
        }
    } else {
        
        ///now that we have the master node, find the corresponding knob
        const std::vector< KnobPtr > & otherKnobs = masterNode->getKnobs();
        for (std::size_t j = 0; j < otherKnobs.size(); ++j) {
            if ( (otherKnobs[j]->getName() == masterKnobName) && otherKnobs[j]->getIsPersistant() ) {
                return otherKnobs[j];
                break;
            }
        }
    }
    
    qDebug() << "Link slave/master for " << knob->getName().c_str() <<   " failed to restore the following linkage: " << masterNodeNameToFind.c_str();
    return KnobPtr();
}
예제 #5
0
void
Gui::renderViewersAndRefreshKnobsAfterTimelineTimeChange(SequenceTime time,
                                                         int reason)
{
    TimeLine* timeline = qobject_cast<TimeLine*>( sender() );

    if ( timeline != getApp()->getTimeLine().get() ) {
        return;
    }

    assert( QThread::currentThread() == qApp->thread() );
    if ( (reason == eTimelineChangeReasonUserSeek) ||
         ( reason == eTimelineChangeReasonDopeSheetEditorSeek) ||
         ( reason == eTimelineChangeReasonCurveEditorSeek) ) {
        if ( getApp()->checkAllReadersModificationDate(true) ) {
            return;
        }
    }

    boost::shared_ptr<Project> project = getApp()->getProject();
    bool isPlayback = reason == eTimelineChangeReasonPlaybackSeek;

    ///Refresh all visible knobs at the current time
    if ( !getApp()->isGuiFrozen() ) {
        for (std::list<DockablePanel*>::const_iterator it = _imp->openedPanels.begin(); it != _imp->openedPanels.end(); ++it) {
            NodeSettingsPanel* nodePanel = dynamic_cast<NodeSettingsPanel*>(*it);
            if (nodePanel) {
                NodePtr node = nodePanel->getNode()->getNode();
                node->getEffectInstance()->refreshAfterTimeChange(isPlayback, time);

                NodesList children;
                node->getChildrenMultiInstance(&children);
                for (NodesList::iterator it2 = children.begin(); it2 != children.end(); ++it2) {
                    (*it2)->getEffectInstance()->refreshAfterTimeChange(isPlayback, time);
                }
            }
        }
    }


    ViewerInstance* leadViewer = getApp()->getLastViewerUsingTimeline();
    const std::list<ViewerTab*>& viewers = getViewersList();
    ///Syncrhronize viewers
    for (std::list<ViewerTab*>::const_iterator it = viewers.begin(); it != viewers.end(); ++it) {
        if ( ( (*it)->getInternalNode() == leadViewer ) && isPlayback ) {
            continue;
        }
        if ( (*it)->getInternalNode()->isDoingPartialUpdates() ) {
            //When tracking, we handle rendering separatly
            continue;
        }
        (*it)->getInternalNode()->renderCurrentFrame(!isPlayback);
    }
} // Gui::renderViewersAndRefreshKnobsAfterTimelineTimeChange
예제 #6
0
std::list<Effect*>
Group::getChildren() const
{
    std::list<Effect*> ret;

    if ( !_collection.lock() ) {
        PythonSetNullError();
        return ret;
    }

    NodesList nodes = _collection.lock()->getNodes();

    for (NodesList::iterator it = nodes.begin(); it != nodes.end(); ++it) {
        if ( (*it)->isActivated() ) {
            Effect* effect = App::createEffectFromNodeWrapper(*it);
            assert(effect);
            ret.push_back(effect);
        }
    }

    return ret;
}
예제 #7
0
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);
}
예제 #8
0
void
ViewerNode::loadSubGraph(const SERIALIZATION_NAMESPACE::NodeSerialization* projectSerialization,
                         const SERIALIZATION_NAMESPACE::NodeSerialization* pyPlugSerialization)
{


    if (getNode()->isPyPlug()) {
        assert(pyPlugSerialization);
        // Handle the pyplug case on NodeGroup implementation
        NodeGroup::loadSubGraph(projectSerialization, pyPlugSerialization);
    } else if (projectSerialization) {
        // If there's a project serialization load it. There will be children only if the user edited the Viewer group
        if (!projectSerialization->_children.empty()) {

            // The subgraph was not initialized in this case
            assert(getNodes().empty());

            EffectInstancePtr thisShared = shared_from_this();

            // Clear nodes that were created if any
            clearGroupWithoutViewerProcess();

            // Restore group
            createNodesFromSerialization(projectSerialization->_children, eCreateNodesFromSerializationFlagsNone, 0);

            setSubGraphEditedByUser(true);
        } else {

            // We are loading a non edited default viewer, just ensure the initial setup was done
            if (!_imp->internalViewerProcessNode[0].lock()) {
                setupGraph(true);
            }

            setSubGraphEditedByUser(false);
        }
    }



    // Ensure the internal viewer process node exists
    if (!_imp->internalViewerProcessNode[0].lock()) {
        NodePtr internalViewerNode[2];
        NodesList nodes = getNodes();
        int viewerProcessNode_i = 0;
        for (NodesList::iterator it = nodes.begin(); it != nodes.end(); ++it) {
            if ((*it)->isEffectViewerInstance()) {
                internalViewerNode[viewerProcessNode_i] = *it;
                ++viewerProcessNode_i;
                if (viewerProcessNode_i == 2) {
                    break;
                }
            }
        }
        assert(internalViewerNode[0] && internalViewerNode[1]);
        if (!internalViewerNode[0] || !internalViewerNode[1]) {
            throw std::invalid_argument("Viewer: No internal viewer process!");
        }
        _imp->internalViewerProcessNode[0] = internalViewerNode[0];
        _imp->internalViewerProcessNode[1] = internalViewerNode[1];
        Q_EMIT internalViewerCreated();
        

    }
    assert(getViewerProcessNode(0));
    assert(getViewerProcessNode(1));

    _imp->refreshInputChoices(true);
    refreshInputFromChoiceMenu(0);
    refreshInputFromChoiceMenu(1);
}
void
ProjectGuiSerialization::initialize(const ProjectGui* projectGui)
{
    NodesList activeNodes;

    projectGui->getInternalProject()->getActiveNodesExpandGroups(&activeNodes);

    _serializedNodes.clear();
    for (NodesList::iterator it = activeNodes.begin(); it != activeNodes.end(); ++it) {
        boost::shared_ptr<NodeGuiI> nodegui_i = (*it)->getNodeGui();
        if (!nodegui_i) {
            continue;
        }
        NodeGuiPtr nodegui = boost::dynamic_pointer_cast<NodeGui>(nodegui_i);

        if ( nodegui->isVisible() ) {
            boost::shared_ptr<NodeCollection> isInCollection = (*it)->getGroup();
            NodeGroup* isCollectionAGroup = dynamic_cast<NodeGroup*>( isInCollection.get() );
            if (!isCollectionAGroup) {
                ///Nodes within a group will be serialized recursively in the node group serialization
                NodeGuiSerialization state;
                nodegui->serialize(&state);
                _serializedNodes.push_back(state);
            }
            ViewerInstance* viewer = (*it)->isEffectViewer();
            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.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() ) {
            KnobHolder* holder = (*it)->getHolder();
            assert(holder);

            EffectInstance* isEffect = dynamic_cast<EffectInstance*>(holder);
            Project* isProject = dynamic_cast<Project*>(holder);

            if (isProject) {
                _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
예제 #10
0
NodeSerialization::NodeSerialization(const NodePtr & n,
                                     bool serializeInputs)
    : _isNull(true)
      , _nbKnobs(0)
      , _knobsValues()
      , _knobsAge(0)
      , _nodeLabel()
      , _nodeScriptName()
      , _pluginID()
      , _pluginMajorVersion(-1)
      , _pluginMinorVersion(-1)
      , _hasRotoContext(false)
      , _hasTrackerContext(false)
      , _node()
      , _pythonModuleVersion(0)
{
    if (n) {
        _node = n;

        ///All this code is MT-safe

        _knobsValues.clear();
        _inputs.clear();

        if ( n->isOpenFXNode() ) {
            OfxEffectInstance* effect = dynamic_cast<OfxEffectInstance*>( n->getEffectInstance().get() );
            assert(effect);
            if (effect) {
                effect->syncPrivateData_other_thread();
            }
        }

        std::vector< KnobPtr >  knobs = n->getEffectInstance()->getKnobs_mt_safe();
        std::list<KnobPtr > userPages;
        for (U32 i  = 0; i < knobs.size(); ++i) {
            KnobGroup* isGroup = dynamic_cast<KnobGroup*>( knobs[i].get() );
            KnobPage* isPage = dynamic_cast<KnobPage*>( knobs[i].get() );

            if (isPage) {
                _pagesIndexes.push_back( knobs[i]->getName() );
                if ( knobs[i]->isUserKnob() ) {
                    userPages.push_back(knobs[i]);
                }
            }

            if ( !knobs[i]->isUserKnob() &&
                 knobs[i]->getIsPersistant() &&
                 !isGroup && !isPage
                 && knobs[i]->hasModificationsForSerialization() ) {
                ///For choice do a deepclone because we need entries
                //bool doCopyKnobs = isChoice ? true : copyKnobs;

                boost::shared_ptr<KnobSerialization> newKnobSer( new KnobSerialization(knobs[i]) );
                _knobsValues.push_back(newKnobSer);
            }
        }

        _nbKnobs = (int)_knobsValues.size();

        for (std::list<KnobPtr >::const_iterator it = userPages.begin(); it != userPages.end(); ++it) {
            boost::shared_ptr<GroupKnobSerialization> s( new GroupKnobSerialization(*it) );
            _userPages.push_back(s);
        }

        _knobsAge = n->getKnobsAge();

        _nodeLabel = n->getLabel_mt_safe();

        _nodeScriptName = n->getScriptName_mt_safe();

        _cacheID = n->getCacheID();

        _pluginID = n->getPluginID();

        if ( !n->hasPyPlugBeenEdited() ) {
            _pythonModule = n->getPluginPythonModule();
            _pythonModuleVersion = n->getMajorVersion();
        }

        _pluginMajorVersion = n->getMajorVersion();

        _pluginMinorVersion = n->getMinorVersion();

        if (serializeInputs) {
            n->getInputNames(_inputs);
        }

        NodePtr masterNode = n->getMasterNode();
        if (masterNode) {
            _masterNodeName = masterNode->getFullyQualifiedName();
        }

        boost::shared_ptr<RotoContext> roto = n->getRotoContext();
        if ( roto && !roto->isEmpty() ) {
            _hasRotoContext = true;
            roto->save(&_rotoContext);
        } else {
            _hasRotoContext = false;
        }

        boost::shared_ptr<TrackerContext> tracker = n->getTrackerContext();
        if (tracker) {
            _hasTrackerContext = true;
            tracker->save(&_trackerContext);
        } else {
            _hasTrackerContext = false;
        }


        NodeGroup* isGrp = n->isEffectGroup();
        if (isGrp) {
            NodesList nodes;
            isGrp->getActiveNodes(&nodes);

            _children.clear();

            for (NodesList::iterator it = nodes.begin(); it != nodes.end(); ++it) {
                if ( (*it)->isPartOfProject() ) {
                    boost::shared_ptr<NodeSerialization> state( new NodeSerialization(*it) );
                    _children.push_back(state);
                }
            }
        }

        _multiInstanceParentName = n->getParentMultiInstanceName();

        NodesList childrenMultiInstance;
        _node->getChildrenMultiInstance(&childrenMultiInstance);
        if ( !childrenMultiInstance.empty() ) {
            assert(!isGrp);
            for (NodesList::iterator it = childrenMultiInstance.begin(); it != childrenMultiInstance.end(); ++it) {
                assert( (*it)->getParentMultiInstance() );
                if ( (*it)->isActivated() ) {
                    boost::shared_ptr<NodeSerialization> state( new NodeSerialization(*it) );
                    _children.push_back(state);
                }
            }
        }

        n->getUserCreatedComponents(&_userComponents);

        _isNull = false;
    }
}
예제 #11
0
PickKnobDialog::PickKnobDialog(DockablePanel* panel,
                               QWidget* parent)
    : QDialog(parent)
    , _imp( new PickKnobDialogPrivate(panel) )
{
    NodeSettingsPanel* nodePanel = dynamic_cast<NodeSettingsPanel*>(panel);

    assert(nodePanel);
    if (!nodePanel) {
        throw std::logic_error("PickKnobDialog::PickKnobDialog()");
    }
    NodeGuiPtr nodeGui = nodePanel->getNodeGui();
    NodePtr node = nodeGui->getNode();
    NodeGroupPtr isGroup = node->isEffectNodeGroup();
    NodeCollectionPtr collec = node->getGroup();
    NodeGroupPtr isCollecGroup = toNodeGroup(collec);
    NodesList collectNodes = collec->getNodes();
    for (NodesList::iterator it = collectNodes.begin(); it != collectNodes.end(); ++it) {
        if ((*it)->isActivated() && (*it)->getNodeGui() && ( (*it)->getKnobs().size() > 0 ) ) {
            _imp->allNodes.push_back(*it);
        }
    }
    if (isCollecGroup) {
        _imp->allNodes.push_back( isCollecGroup->getNode() );
    }
    if (isGroup) {
        NodesList groupnodes = isGroup->getNodes();
        for (NodesList::iterator it = groupnodes.begin(); it != groupnodes.end(); ++it) {
            if ( (*it)->getNodeGui() &&
                (*it)->isActivated() &&
                ( (*it)->getKnobs().size() > 0 ) ) {
                _imp->allNodes.push_back(*it);
            }
        }
    }
    QStringList nodeNames;
    for (NodesList::iterator it = _imp->allNodes.begin(); it != _imp->allNodes.end(); ++it) {
        QString name = QString::fromUtf8( (*it)->getLabel().c_str() );
        nodeNames.push_back(name);
    }
    nodeNames.sort();

    _imp->mainLayout = new QGridLayout(this);
    _imp->selectNodeLabel = new Label( tr("Node:") );
    _imp->nodeSelectionCombo = new CompleterLineEdit(nodeNames, nodeNames, false, this);
    _imp->nodeSelectionCombo->setToolTip( NATRON_NAMESPACE::convertFromPlainText(tr("Input the name of a node in the current project."), NATRON_NAMESPACE::WhiteSpaceNormal) );
    _imp->nodeSelectionCombo->setFocus(Qt::PopupFocusReason);

    _imp->knobSelectionCombo = new ComboBox(this);
    QObject::connect( _imp->knobSelectionCombo, SIGNAL(currentIndexChanged(int)), this, SLOT(onKnobComboIndexChanged(int)) );
    QString useAliasTt = NATRON_NAMESPACE::convertFromPlainText(tr("If checked, an alias of the selected parameter will be created, coyping entirely its state. "
                                                           "Only the script-name, label and tooltip will be editable.\n"
                                                           "For choice parameters this will also "
                                                           "dynamically refresh the menu entries when the original parameter's menu is changed.\n"
                                                           "When unchecked, a simple expression will be set linking the two parameters, but things such as dynamic menus "
                                                           "will be disabled."), NATRON_NAMESPACE::WhiteSpaceNormal);
    _imp->useAliasLabel = new Label(tr("Make Alias:"), this);
    _imp->useAliasLabel->setToolTip(useAliasTt);
    _imp->useAliasCheckBox = new QCheckBox(this);
    _imp->useAliasCheckBox->setToolTip(useAliasTt);
    _imp->useAliasCheckBox->setChecked(true);

    QObject::connect( _imp->nodeSelectionCombo, SIGNAL(itemCompletionChosen()), this, SLOT(onNodeComboEditingFinished()) );

    _imp->destPageLabel = new Label(tr("Page:"), this);
    QString pagett = NATRON_NAMESPACE::convertFromPlainText(tr("Select the page into which the parameter will be created."), NATRON_NAMESPACE::WhiteSpaceNormal);
    _imp->destPageLabel->setToolTip(pagett);
    _imp->destPageCombo = new ComboBox(this);
    _imp->destPageCombo->setToolTip(pagett);
    QObject::connect( _imp->destPageCombo, SIGNAL(currentIndexChanged(int)), this, SLOT(onPageComboIndexChanged(int)) );
    const KnobsVec& knobs = node->getKnobs();
    for (std::size_t i = 0; i < knobs.size(); ++i) {
        if ( knobs[i]->isUserKnob() ) {
            KnobPagePtr isPage = toKnobPage(knobs[i]);
            if (isPage) {
                _imp->pages.push_back(isPage);
                _imp->destPageCombo->addItem( QString::fromUtf8( isPage->getName().c_str() ) );
            } else {
                KnobGroupPtr isGrp = toKnobGroup(knobs[i]);
                if (isGrp) {
                    _imp->groups.push_back(isGrp);
                }
            }
        }
    }
    if (_imp->destPageCombo->count() == 0) {
        _imp->destPageLabel->hide();
        _imp->destPageCombo->hide();
    }


    _imp->groupLabel = new Label(tr("Group:"), this);
    QString grouptt = NATRON_NAMESPACE::convertFromPlainText(tr("Select the group into which the parameter will be created."), NATRON_NAMESPACE::WhiteSpaceNormal);
    _imp->groupCombo = new ComboBox(this);
    _imp->groupLabel->setToolTip(grouptt);
    _imp->groupCombo->setToolTip(grouptt);
    onPageComboIndexChanged(0);

    _imp->buttons = new DialogButtonBox(QDialogButtonBox::StandardButtons(QDialogButtonBox::Ok | QDialogButtonBox::Cancel),
                                         Qt::Horizontal, this);
    QObject::connect( _imp->buttons, SIGNAL(accepted()), this, SLOT(accept()) );
    QObject::connect( _imp->buttons, SIGNAL(rejected()), this, SLOT(reject()) );

    _imp->mainLayout->addWidget(_imp->selectNodeLabel, 0, 0, 1, 1);
    _imp->mainLayout->addWidget(_imp->nodeSelectionCombo, 0, 1, 1, 1);
    _imp->mainLayout->addWidget(_imp->knobSelectionCombo, 0, 2, 1, 1);
    _imp->mainLayout->addWidget(_imp->useAliasLabel, 1, 0, 1, 1);
    _imp->mainLayout->addWidget(_imp->useAliasCheckBox, 1, 1, 1, 1);
    _imp->mainLayout->addWidget(_imp->destPageLabel, 2, 0, 1, 1);
    _imp->mainLayout->addWidget(_imp->destPageCombo, 2, 1, 1, 1);
    _imp->mainLayout->addWidget(_imp->groupLabel, 2, 2, 1, 1);
    _imp->mainLayout->addWidget(_imp->groupCombo, 2, 3, 1, 1);
    _imp->mainLayout->addWidget(_imp->buttons, 3, 0, 1, 3);

    QTimer::singleShot( 25, _imp->nodeSelectionCombo, SLOT(showCompleter()) );
}
예제 #12
0
파일: NodeAnim.cpp 프로젝트: azerupi/Natron
void
NodeAnimPrivate::computeGroupRange()
{

    NodeGuiPtr nodeUI = nodeGui.lock();
    NodePtr node = nodeUI->getNode();
    if (!node) {
        return;
    }

    AnimationModulePtr isAnimModel = toAnimationModule(model.lock());
    if (!isAnimModel) {
        return;
    }
    NodeGroupPtr nodegroup = node->isEffectNodeGroup();
    assert(nodegroup);
    if (!nodegroup) {
        return;
    }


    AnimationModuleTreeView* treeView = isAnimModel->getEditor()->getTreeView();

    NodesList nodes = nodegroup->getNodes();

    std::set<double> times;

    for (NodesList::const_iterator it = nodes.begin(); it != nodes.end(); ++it) {
        NodeAnimPtr childAnim = isAnimModel->findNodeAnim(*it);

        if (!childAnim) {
            continue;
        }

        if (!treeView->isItemVisibleRecursive(childAnim->getTreeItem())) {
            continue;
        }

        childAnim->refreshFrameRange();
        RangeD childRange = childAnim->getFrameRange();
        times.insert(childRange.min);
        times.insert(childRange.max);

        // Also check the child knobs keyframes
        NodeGuiPtr childGui = childAnim->getNodeGui();
        const KnobsVec &knobs = childGui->getNode()->getKnobs();

        for (KnobsVec::const_iterator it2 = knobs.begin(); it2 != knobs.end(); ++it2) {

            if ( !(*it2)->isAnimationEnabled() || !(*it2)->hasAnimation() ) {
                continue;
            } else {
                // For each dimension and for each split view get the first/last keyframe (if any)
                int nDims = (*it2)->getNDimensions();
                std::list<ViewIdx> views = (*it2)->getViewsList();
                for (std::list<ViewIdx>::const_iterator it3 = views.begin(); it3 != views.end(); ++it3) {
                    for (int i = 0; i < nDims; ++i) {
                        CurvePtr curve = (*it2)->getCurve(*it3, DimIdx(i));
                        if (!curve) {
                            continue;
                        }
                        int nKeys = curve->getKeyFramesCount();
                        if (nKeys > 0) {
                            KeyFrame k;
                            if (curve->getKeyFrameWithIndex(0, &k)) {
                                times.insert( k.getTime() );
                            }
                            if (curve->getKeyFrameWithIndex(nKeys - 1, &k)) {
                                times.insert( k.getTime() );
                            }
                        }
                    }
                }
            }
        } // for all knobs
    } // for all children nodes

    if (times.size() <= 1) {
        frameRange.min = 0;
        frameRange.max = 0;
    } else {
        frameRange.min = *times.begin();
        frameRange.max = *times.rbegin();
    }

} // computeGroupRange
예제 #13
0
파일: Gui20.cpp 프로젝트: azerupi/Natron
void
Gui::removeViewerTab(ViewerTab* tab,
                     bool initiatedFromNode,
                     bool deleteData)
{
    assert(tab);
    unregisterTab(tab);

    if (tab == _imp->_activeViewer) {
        _imp->_activeViewer = 0;
    }
    NodeGraph* graph = 0;
    NodeGroupPtr isGrp;
    NodeCollectionPtr collection;
    if ( tab->getInternalNode() && tab->getInternalNode()->getNode() ) {
        NodeCollectionPtr collection = tab->getInternalNode()->getNode()->getGroup();
        isGrp = toNodeGroup(collection);
    }


    if (isGrp) {
        NodeGraphI* graph_i = isGrp->getNodeGraph();
        assert(graph_i);
        graph = dynamic_cast<NodeGraph*>(graph_i);
    } else {
        graph = getNodeGraph();
    }
    assert(graph);
    if (!graph) {
        throw std::logic_error("");
    }

    ViewerTab* lastSelectedViewer = graph->getLastSelectedViewer();

    if (lastSelectedViewer == tab) {
        bool foundOne = false;
        NodesList nodes;
        if (collection) {
            nodes = collection->getNodes();
        }
        for (NodesList::iterator it = nodes.begin(); it != nodes.end(); ++it) {
            ViewerNodePtr isViewer = (*it)->isEffectViewerNode();
            if ( !isViewer || ( isViewer == tab->getInternalNode() ) || !(*it)->isActivated() ) {
                continue;
            }
            OpenGLViewerI* viewerI = isViewer->getUiContext();
            assert(viewerI);
            ViewerGL* glViewer = dynamic_cast<ViewerGL*>(viewerI);
            assert(glViewer);
            if (glViewer) {
                graph->setLastSelectedViewer( glViewer->getViewerTab() );
            }
            foundOne = true;
            break;
        }
        if (!foundOne) {
            graph->setLastSelectedViewer(0);
        }
    }

    ViewerNodePtr viewerNode = tab->getInternalNode();
    ViewerInstancePtr internalViewer;
    if (viewerNode) {
        internalViewer = viewerNode->getInternalViewerNode();
    }
    if (internalViewer) {
        internalViewer->abortAnyEvaluation();
        if (getApp()->getLastViewerUsingTimeline() == internalViewer) {
            getApp()->discardLastViewerUsingTimeline();
        }
    }

    if (!initiatedFromNode) {
        assert(_imp->_nodeGraphArea);
        ///call the deleteNode which will call this function again when the node will be deactivated.
        NodePtr internalNode = tab->getInternalNode()->getNode();
        NodeGuiIPtr guiI = internalNode->getNodeGui();
        NodeGuiPtr gui = boost::dynamic_pointer_cast<NodeGui>(guiI);
        assert(gui);
        NodeGraphI* graph_i = internalNode->getGroup()->getNodeGraph();
        assert(graph_i);
        NodeGraph* graph = dynamic_cast<NodeGraph*>(graph_i);
        assert(graph);
        if (graph) {
            graph->removeNode(gui);
        }
    } else {
        tab->hide();


        TabWidget* container = dynamic_cast<TabWidget*>( tab->parentWidget() );
        if (container) {
            container->removeTab(tab, false);
        }

        if (deleteData) {
            QMutexLocker l(&_imp->_viewerTabsMutex);
            std::list<ViewerTab*>::iterator it = std::find(_imp->_viewerTabs.begin(), _imp->_viewerTabs.end(), tab);
            if ( it != _imp->_viewerTabs.end() ) {
                _imp->_viewerTabs.erase(it);
            }
            tab->notifyGuiClosingPublic();
            tab->deleteLater();
        }
    }
    Q_EMIT viewersChanged();
} // Gui::removeViewerTab