示例#1
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);
    
}
示例#2
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
示例#3
0
static KnobGuiPtr
getKnobGuiForKnob(const NodePtr& selectedNode,
                  const KnobIPtr& knob)
{
    NodeGuiIPtr selectedNodeGuiI = selectedNode->getNodeGui();

    assert(selectedNodeGuiI);
    if (!selectedNodeGuiI) {
        return KnobGuiPtr();
    }
    NodeGui* selectedNodeGui = dynamic_cast<NodeGui*>( selectedNodeGuiI.get() );
    assert(selectedNodeGui);
    if (!selectedNodeGui) {
        return KnobGuiPtr();
    }
    NodeSettingsPanel* selectedPanel = selectedNodeGui->getSettingPanel();
    bool hadPanelVisible = selectedPanel && !selectedPanel->isClosed();
    if (!selectedPanel) {
        selectedNodeGui->ensurePanelCreated();
        selectedPanel = selectedNodeGui->getSettingPanel();
        selectedNodeGui->setVisibleSettingsPanel(false);
    }
    if (!selectedPanel) {
        return KnobGuiPtr();
    }
    if (!hadPanelVisible && selectedPanel) {
        selectedPanel->setClosed(true);
    }


    const std::list<std::pair<KnobIWPtr, KnobGuiPtr> >& knobsMap = selectedPanel->getKnobsMapping();
    for (std::list<std::pair<KnobIWPtr, KnobGuiPtr> >::const_iterator it = knobsMap.begin(); it != knobsMap.end(); ++it) {
        if (it->first.lock() == knob) {
            return it->second;
        }
    }

    return KnobGuiPtr();
}
示例#4
0
文件: Gui10.cpp 项目: haebler/Natron
void
Gui::restoreLayout(bool wipePrevious,
                   bool enableOldProjectCompatibility,
                   const GuiLayoutSerialization & layoutSerialization)
{
    ///Wipe the current layout
    if (wipePrevious) {
        wipeLayout();
    }

    ///For older projects prior to the layout change, just set default layout.
    if (enableOldProjectCompatibility) {
        createDefaultLayout1();
    } else {
        std::list<ApplicationWindowSerialization*> floatingDockablePanels;
        QDesktopWidget* desktop = QApplication::desktop();
        QRect screen = desktop->screenGeometry();

        ///now restore the gui layout
        for (std::list<ApplicationWindowSerialization*>::const_iterator it = layoutSerialization._windows.begin();
             it != layoutSerialization._windows.end(); ++it) {
            QWidget* mainWidget = 0;

            ///The window contains only a pane (for the main window it also contains the toolbar)
            if ( (*it)->child_asPane ) {
                TabWidget* centralWidget = new TabWidget(this);
                registerPane(centralWidget);
                restoreTabWidget(centralWidget, *(*it)->child_asPane);
                mainWidget = centralWidget;
            }
            ///The window contains a splitter as central widget
            else if ( (*it)->child_asSplitter ) {
                Splitter* centralWidget = new Splitter(this);
                restoreSplitterRecursive(this, centralWidget, *(*it)->child_asSplitter);
                mainWidget = centralWidget;
            }
            ///The child is a dockable panel, restore it later
            else if ( !(*it)->child_asDockablePanel.empty() ) {
                assert(!(*it)->isMainWindow);
                floatingDockablePanels.push_back(*it);
                continue;
            }

            assert(mainWidget);
            if (!mainWidget) {
                continue;
            }
            QWidget* window;
            if ( (*it)->isMainWindow ) {
                // mainWidget->setParent(_imp->_leftRightSplitter);
                _imp->_leftRightSplitter->addWidget_mt_safe(mainWidget);
                window = this;
            } else {
                FloatingWidget* floatingWindow = new FloatingWidget(this, this);
                floatingWindow->setWidget(mainWidget);
                registerFloatingWindow(floatingWindow);
                window = floatingWindow;
            }

            ///Restore geometry
            int w = std::min( (*it)->w, screen.width() );
            int h = std::min( (*it)->h, screen.height() );
            window->resize(w, h);
            // If the screen size changed, make sure at least 50x50 pixels of the window are visible
            int x = boost::algorithm::clamp( (*it)->x, screen.left(), screen.right() - 50 );
            int y = boost::algorithm::clamp( (*it)->y, screen.top(), screen.bottom() - 50 );
            window->move( QPoint(x, y) );
        }

        for (std::list<ApplicationWindowSerialization*>::iterator it = floatingDockablePanels.begin();
             it != floatingDockablePanels.end(); ++it) {
            ///Find the node associated to the floating panel if any and float it
            assert( !(*it)->child_asDockablePanel.empty() );
            if ( (*it)->child_asDockablePanel == kNatronProjectSettingsPanelSerializationName ) {
                _imp->_projectGui->getPanel()->floatPanel();
            } else {
                ///Find a node with the dockable panel name
                const NodesGuiList & nodes = getNodeGraph()->getAllActiveNodes();
                DockablePanel* panel = 0;
                for (NodesGuiList::const_iterator it2 = nodes.begin(); it2 != nodes.end(); ++it2) {
                    if ( (*it2)->getNode()->getScriptName() == (*it)->child_asDockablePanel ) {
                        (*it2)->ensurePanelCreated();
                        NodeSettingsPanel* nodeSettings = (*it2)->getSettingPanel();
                        if (nodeSettings) {
                            nodeSettings->floatPanel();
                            panel = nodeSettings;
                        }
                        break;
                    }
                }
                if (panel) {
                    FloatingWidget* fWindow = 0;
                    QWidget* w = panel->parentWidget();
                    while (!fWindow && w) {
                        fWindow = dynamic_cast<FloatingWidget*>(w);
                        w = w->parentWidget();
                    }

                    assert(fWindow);
                    fWindow->move( QPoint( (*it)->x, (*it)->y ) );
                    fWindow->resize( std::min( (*it)->w, screen.width() ), std::min( (*it)->h, screen.height() ) );
                }
            }
        }
    }
} // restoreLayout
示例#5
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()) );
}