void KnobGuiChoice::updateGUI(int /*dimension*/) { ///we don't use setCurrentIndex because the signal emitted by combobox will call onCurrentIndexChanged and ///change the internal value of the knob again... ///The slot connected to onCurrentIndexChanged is reserved to catch user interaction with the combobox. ///This function is called in response to an internal change. KnobChoicePtr knob = _knob.lock(); std::string activeEntry = knob->getActiveEntryText_mt_safe(); if ( !activeEntry.empty() ) { bool activeIndexPresent = knob->isActiveEntryPresentInEntries(); if (!activeIndexPresent) { QString error = tr("The value set to this parameter no longer exist in the menu. Right click and press Refresh Menu to update the menu and then pick a new value."); setWarningValue( KnobGui::eKnobWarningChoiceMenuOutOfDate, GuiUtils::convertFromPlainText(error, Qt::WhiteSpaceNormal) ); } else { setWarningValue( KnobGui::eKnobWarningChoiceMenuOutOfDate, QString() ); } } if ( _comboBox->isCascading() || activeEntry.empty() ) { _comboBox->setCurrentIndex_no_emit( knob->getValue() ); } else { _comboBox->setCurrentText( QString::fromUtf8( activeEntry.c_str() ) ); } }
void ViewerNodePrivate::swapViewerProcessInputs() { NodePtr viewerProcessNodesInputs[2]; for (int i = 0; i < 2; ++i) { viewerProcessNodesInputs[i] = getInputRecursive(i); } NodePtr input0 = viewerProcessNodesInputs[0]->getInput(0); NodePtr input1 = viewerProcessNodesInputs[1]->getInput(0); viewerProcessNodesInputs[0]->swapInput(input1, 0); viewerProcessNodesInputs[1]->swapInput(input0, 0); try { KnobChoicePtr aChoice = aInputNodeChoiceKnob.lock(); KnobChoicePtr bChoice = bInputNodeChoiceKnob.lock(); ChoiceOption aCurChoice = aChoice->getActiveEntry(); ChoiceOption bCurChoice = bChoice->getActiveEntry(); aChoice->blockValueChanges(); aChoice->setValueFromID(bCurChoice.id); aChoice->unblockValueChanges(); bChoice->blockValueChanges(); bChoice->setValueFromID(aCurChoice.id); bChoice->unblockValueChanges(); } catch (...) { } }
void ViewerNodePrivate::refreshInputChoiceMenu(int internalIndex, int groupInputIndex) { KnobChoicePtr inputChoiceKnob = internalIndex == 0 ? aInputNodeChoiceKnob.lock() : bInputNodeChoiceKnob.lock(); assert(groupInputIndex >= 0 && groupInputIndex < _publicInterface->getMaxInputCount()); std::string groupInputID; { std::stringstream ss; ss << groupInputIndex; groupInputID = ss.str(); } std::vector<ChoiceOption> entries = inputChoiceKnob->getEntries(); for (std::size_t i = 0; i < entries.size(); ++i) { if (entries[i].id == groupInputID) { inputChoiceKnob->setValue(i); return; } } // Input is no longer connected fallback on first input in the list if any, otherwise on None ("-") inputChoiceKnob->setValue(entries.size() > 1 ? 1 : 0, ViewSetSpec::all(), DimIdx(0), eValueChangedReasonPluginEdited); }
void KnobGuiChoice::createWidget(QHBoxLayout* layout) { KnobChoicePtr knob = _knob.lock(); if (!knob) { return; } KnobGuiPtr knobUI = getKnobGui(); _comboBox = new KnobComboBox( knobUI, DimIdx(0), getView(), layout->parentWidget() ); _comboBox->setCascading( knob->isCascading() ); onEntriesPopulated(); std::string textToFitHorizontally = knob->getTextToFitHorizontally(); if (!textToFitHorizontally.empty()) { QFontMetrics fm = _comboBox->fontMetrics(); _comboBox->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Preferred); _comboBox->setFixedWidth(fm.width(QString::fromUtf8(textToFitHorizontally.c_str())) + 3 * TO_DPIX(DROP_DOWN_ICON_SIZE)); } QObject::connect( _comboBox, SIGNAL(currentIndexChanged(int)), this, SLOT(onCurrentIndexChanged(int)) ); QObject::connect( _comboBox, SIGNAL(itemNewSelected()), this, SLOT(onItemNewSelected()) ); ///set the copy/link actions in the right click menu KnobGuiWidgets::enableRightClickMenu(knobUI, _comboBox, DimIdx(0), getView()); layout->addWidget(_comboBox); }
void KnobGuiChoice::setEnabled() { KnobChoicePtr knob = _knob.lock(); bool b = knob->isEnabled(0) && knob->getExpression(0).empty(); _comboBox->setEnabled_natron(b); }
bool getUseFromPoints(TimeValue time) const { KnobChoicePtr knob = overlayPoints.lock(); assert(knob); return knob->getValueAtTime(time) == 1; }
void KnobGuiChoice::onRefreshMenuActionTriggered() { KnobChoicePtr knob = _knob.lock(); if (knob) { knob->refreshMenu(); } }
QString KnobGuiChoice::getPixmapPathFromFilePath(const QString &filePath) const { KnobChoicePtr knob = _knob.lock(); if (!knob) { return QString(); } return getPixmapPathFromFilePath(knob->getHolder(),filePath); }
void KnobGuiChoice::reflectModificationsState() { KnobChoicePtr knob = _knob.lock(); if (!knob) { return; } bool hasModif = knob->hasModifications(); _comboBox->setIsModified(hasModif); }
void KnobGuiChoice::onCurrentIndexChanged(int i) { KnobGuiPtr knobUI = getKnobGui(); knobUI->setWarningValue( KnobGui::eKnobWarningChoiceMenuOutOfDate, QString() ); KnobChoicePtr knob = _knob.lock(); if (!knob) { return; } knobUI->pushUndoCommand( new KnobUndoCommand<int>(knob, knob->getValue(DimIdx(0), getView()), i, DimIdx(0), getView())); }
KnobGuiChoice::KnobGuiChoice(const KnobGuiPtr& knob, ViewIdx view) : KnobGuiWidgets(knob, view) , _comboBox(0) { KnobChoicePtr k = toKnobChoice(knob->getKnob()); QObject::connect( k.get(), SIGNAL(populated()), this, SLOT(onEntriesPopulated()) ); QObject::connect( k.get(), SIGNAL(entryAppended()), this, SLOT(onEntryAppended()) ); QObject::connect( k.get(), SIGNAL(entriesReset()), this, SLOT(onEntriesReset()) ); _knob = k; }
KnobGuiChoice::KnobGuiChoice(KnobIPtr knob, KnobGuiContainerI *container) : KnobGui(knob, container) , _comboBox(0) { KnobChoicePtr k = toKnobChoice(knob); QObject::connect( k.get(), SIGNAL(populated()), this, SLOT(onEntriesPopulated()) ); QObject::connect( k.get(), SIGNAL(entryAppended(QString,QString)), this, SLOT(onEntryAppended(QString,QString)) ); QObject::connect( k.get(), SIGNAL(entriesReset()), this, SLOT(onEntriesReset()) ); _knob = k; }
void ViewerNodePrivate::setDisplayChannels(int index, bool setBoth) { for (int i = 0; i < 2; ++i) { if (i == 1 && !setBoth) { break; } KnobChoicePtr displayChoice = displayChannelsKnob[i].lock(); displayChoice->setValue(index); } }
void ViewerNodePrivate::toggleDownscaleLevel(int index) { assert(index > 0); KnobChoicePtr downscaleChoice = downscaleChoiceKnob.lock(); int curChoice_i = downscaleChoice->getValue(); if (curChoice_i != index) { downscaleChoice->setValue(index); } else { // Reset back to auto downscaleChoice->setValue(0); } }
void KnobGuiChoice::onItemNewSelected() { KnobChoicePtr knob = _knob.lock(); if (!knob) { return; } ChoiceKnobDimView::KnobChoiceNewItemCallback callback = knob->getNewOptionCallback(); if (!callback) { return; } callback(knob); }
void ViewerNode::refreshViewsKnobVisibility() { KnobChoicePtr knob = _imp->activeViewKnob.lock(); if (knob) { const std::vector<std::string>& views = getApp()->getProject()->getProjectViewNames(); std::vector<ChoiceOption> entries(views.size()); for (std::size_t i = 0; i < views.size(); ++i) { entries[i] = ChoiceOption(views[i], "", ""); } knob->populateChoices(entries); knob->setInViewerContextSecret(views.size() <= 1); } }
void ViewerNodeOverlay::showRightClickMenu() { KnobChoicePtr menu = _imp->rightClickMenu.lock(); std::vector<ChoiceOption> entries, showHideEntries; std::vector<KnobButtonPtr> entriesButtons; entriesButtons.push_back(_imp->rightClickToggleWipe.lock()); entriesButtons.push_back(_imp->rightClickCenterWipe.lock()); entriesButtons.push_back(_imp->centerViewerButtonKnob.lock()); entriesButtons.push_back(_imp->zoomScaleOneAction.lock()); entriesButtons.push_back(_imp->zoomInAction.lock()); entriesButtons.push_back(_imp->zoomOutAction.lock()); entriesButtons.push_back(_imp->rightClickPreviousLayer.lock()); entriesButtons.push_back(_imp->rightClickNextLayer.lock()); entriesButtons.push_back(_imp->rightClickPreviousView.lock()); entriesButtons.push_back(_imp->rightClickNextView.lock()); entriesButtons.push_back(_imp->rightClickSwitchAB.lock()); entriesButtons.push_back(_imp->rightClickShowHideOverlays.lock()); entriesButtons.push_back(_imp->enableStatsAction.lock()); for (std::size_t i = 0; i < entriesButtons.size(); ++i) { entries.push_back(ChoiceOption(entriesButtons[i]->getName(), "", "")); } entries.push_back(ChoiceOption(kViewerNodeParamRightClickMenuShowHideSubMenu, "", "")); KnobChoicePtr showHideMenu = _imp->rightClickShowHideSubMenu.lock(); showHideEntries.push_back(ChoiceOption(kViewerNodeParamRightClickMenuHideAll, "", "")); showHideEntries.push_back(ChoiceOption(kViewerNodeParamRightClickMenuHideAllTop, "", "")); showHideEntries.push_back(ChoiceOption(kViewerNodeParamRightClickMenuHideAllBottom, "", "")); showHideEntries.push_back(ChoiceOption(kViewerNodeParamRightClickMenuShowHideTopToolbar, "", "")); showHideEntries.push_back(ChoiceOption(kViewerNodeParamRightClickMenuShowHideLeftToolbar, "", "")); showHideEntries.push_back(ChoiceOption(kViewerNodeParamRightClickMenuShowHidePlayer, "", "")); showHideEntries.push_back(ChoiceOption(kViewerNodeParamRightClickMenuShowHideTimeline, "", "")); showHideEntries.push_back(ChoiceOption(kViewerNodeParamRightClickMenuShowHideTabHeader, "", "")); showHideEntries.push_back(ChoiceOption(kViewerNodeParamEnableColorPicker, "", "")); { std::vector<int> separators; separators.push_back(2); showHideMenu->setSeparators(separators); } showHideMenu->populateChoices(showHideEntries); menu->populateChoices(entries); }
void KnobGuiChoice::reflectAnimationLevel(DimIdx /*dimension*/, AnimationLevelEnum level) { KnobChoicePtr knob = _knob.lock(); if (!knob) { return; } bool isEnabled = knob->isEnabled(); _comboBox->setEnabled_natron(level != eAnimationLevelExpression && isEnabled); if ( level != (AnimationLevelEnum)_comboBox->getAnimation() ) { _comboBox->setAnimation((int)level); } }
FramesNeededMap OneViewNode::getFramesNeeded(double time, ViewIdx /*view*/) { FramesNeededMap ret; FrameRangesMap& rangeMap = ret[0]; KnobChoicePtr viewKnob = _imp->viewKnob.lock(); int view_i = viewKnob->getValue(); std::vector<RangeD>& ranges = rangeMap[ViewIdx(view_i)]; ranges.resize(1); ranges[0].min = ranges[0].max = time; return ret; }
bool OneViewNode::isIdentity(double time, const RenderScale & /*scale*/, const RectI & /*roi*/, ViewIdx /*view*/, double* inputTime, ViewIdx* inputView, int* inputNb) { KnobChoicePtr viewKnob = _imp->viewKnob.lock(); int view_i = viewKnob->getValue(); *inputView = ViewIdx(view_i); *inputNb = 0; *inputTime = time; return true; }
void OneViewNode::initializeKnobs() { KnobPagePtr page = AppManager::createKnob<KnobPage>( shared_from_this(), tr("Controls") ); page->setName("controls"); KnobChoicePtr viewKnob = AppManager::createKnob<KnobChoice>( shared_from_this(), tr("View") ); viewKnob->setName("view"); viewKnob->setHintToolTip( tr("View to take from the input") ); page->addKnob(viewKnob); const std::vector<std::string>& views = getApp()->getProject()->getProjectViewNames(); std::string currentView = viewKnob->getActiveEntryText_mt_safe(); viewKnob->populateChoices(views); _imp->viewKnob = viewKnob; }
void TrackMarker::setMotionModelFromGui(int index) { KnobChoicePtr knob = _imp->motionModel.lock(); if (!knob) { return; } KeyFrame k; std::pair<int, KnobIPtr> master = knob->getMaster(0); if (master.second) { knob->unSlave(0, true); } knob->onValueChanged(index, ViewSpec::all(), 0, eValueChangedReasonNatronGuiEdited, &k); if (master.second) { master.second->cloneAndUpdateGui(knob); knob->slaveTo(0, master.second, master.first); } }
void OneViewNode::onProjectViewsChanged() { const std::vector<std::string>& views = getApp()->getProject()->getProjectViewNames(); KnobChoicePtr viewKnob = _imp->viewKnob.lock(); std::string currentView = viewKnob->getActiveEntryText_mt_safe(); viewKnob->populateChoices(views); bool foundView = false; for (std::size_t i = 0; i < views.size(); ++i) { if (views[i] == currentView) { foundView = true; viewKnob->setValue(i); break; } } if (!foundView) { viewKnob->setValue(0); } }
void KnobComboBox::paintEvent(QPaintEvent* event) { ComboBox::paintEvent(event); KnobChoicePtr knob = _knob.lock(); if (!knob) { return; } RGBAColourD color; if (_drawLinkedFrame) { appPTR->getCurrentSettings()->getExprColor(&color.r, &color.g, &color.b); color.a = 1.; } else { int idx = activeIndex(); if (!knob->getColorForIndex(idx, &color)) { return; } } QPainter p(this); QPen pen; QColor c; c.setRgbF(Image::clamp(color.r,0.,1.), Image::clamp(color.g,0.,1.), Image::clamp(color.b,0.,1.)); c.setAlphaF(Image::clamp(color.a,0.,1.)); pen.setColor(c); p.setPen(pen); QRectF bRect = rect(); QRectF roundedRect = bRect.adjusted(1., 1., -2., -2.); double roundPixels = 3; QPainterPath path; path.addRoundedRect(roundedRect, roundPixels, roundPixels); p.drawPath(path); } // paintEvent
void KnobGuiChoice::onEntryAppended() { KnobChoicePtr knob = _knob.lock(); if (!knob) { return; } std::vector<ChoiceOption> options = knob->getEntries(); for (int i = _comboBox->count(); i < (int)options.size(); ++i) { if ( knob->getNewOptionCallback()) { _comboBox->insertItem(_comboBox->count() - 1, QString::fromUtf8(options[i].label.c_str()), QIcon(), QKeySequence(), QString::fromUtf8(options[i].tooltip.c_str())); } else { _comboBox->addItem(QString::fromUtf8(options[i].label.c_str()), QIcon(), QKeySequence(), QString::fromUtf8(options[i].tooltip.c_str())); } } updateGUI(); }
void KnobGuiChoice::onEntriesPopulated() { KnobChoicePtr knob = _knob.lock(); _comboBox->clear(); std::vector<std::string> entries = knob->getEntries_mt_safe(); const std::vector<std::string> help = knob->getEntriesHelp_mt_safe(); std::string activeEntry = knob->getActiveEntryText_mt_safe(); for (U32 i = 0; i < entries.size(); ++i) { std::string helpStr; if ( !help.empty() && !help[i].empty() ) { helpStr = help[i]; } _comboBox->addItem( QString::fromUtf8( entries[i].c_str() ), QIcon(), QKeySequence(), QString::fromUtf8( helpStr.c_str() ) ); } // the "New" menu is only added to known parameters (e.g. the choice of output channels) if ( knob->getHostCanAddOptions() && ( ( knob->getName() == kNatronOfxParamOutputChannels) || ( knob->getName() == kOutputChannelsKnobName) ) ) { _comboBox->addItemNew(); } ///we don't use setCurrentIndex because the signal emitted by combobox will call onCurrentIndexChanged and ///we don't want that to happen because the index actually didn't change. if ( _comboBox->isCascading() || activeEntry.empty() ) { _comboBox->setCurrentIndex_no_emit( knob->getValue() ); } else { _comboBox->setCurrentText_no_emit( QString::fromUtf8( activeEntry.c_str() ) ); } if ( !activeEntry.empty() ) { bool activeIndexPresent = knob->isActiveEntryPresentInEntries(); if (!activeIndexPresent) { QString error = tr("The value set to this parameter no longer exist in the menu. Right click and press Refresh Menu to update the menu and then pick a new value."); setWarningValue( KnobGui::eKnobWarningChoiceMenuOutOfDate, GuiUtils::convertFromPlainText(error, Qt::WhiteSpaceNormal) ); } else { setWarningValue( KnobGui::eKnobWarningChoiceMenuOutOfDate, QString() ); } } }
void KnobGuiChoice::updateGUI() { ///we don't use setCurrentIndex because the signal emitted by combobox will call onCurrentIndexChanged and ///change the internal value of the knob again... ///The slot connected to onCurrentIndexChanged is reserved to catch user interaction with the combobox. ///This function is called in response to an internal change. KnobChoicePtr knob = _knob.lock(); if (!knob) { return; } ChoiceOption activeEntry = knob->getCurrentEntry(); QString activeEntryLabel; if (!activeEntry.label.empty()) { activeEntryLabel = QString::fromUtf8(activeEntry.label.c_str()); } else { activeEntryLabel = QString::fromUtf8(activeEntry.id.c_str()); } if ( !activeEntry.id.empty() ) { bool activeIndexPresent = knob->isActiveEntryPresentInEntries(getView()); if (!activeIndexPresent) { QString error = tr("The value %1 no longer exists in the menu").arg(activeEntryLabel); getKnobGui()->setWarningValue( KnobGui::eKnobWarningChoiceMenuOutOfDate, NATRON_NAMESPACE::convertFromPlainText(error, NATRON_NAMESPACE::WhiteSpaceNormal) ); } else { getKnobGui()->setWarningValue( KnobGui::eKnobWarningChoiceMenuOutOfDate, QString() ); } } if ( _comboBox->isCascading() || activeEntry.id.empty() ) { _comboBox->setCurrentIndex( knob->getValue(), false ); } else { ensureUnknownChocieIsNotInternalPlaneID(activeEntryLabel); _comboBox->setCurrentIndexFromLabel( activeEntryLabel, false /*emitSignal*/ ); } }
void ViewerNodePrivate::setAlphaChannelFromLayerIfRGBA() { ImagePlaneDesc selectedLayer, selectedAlphaLayer, selectedDisplayLayer; int alphaChannelIndex; ViewerInstancePtr internalViewer = internalViewerProcessNode[0].lock()->isEffectViewerInstance(); internalViewer->getChannelOptions(_publicInterface->getTimelineCurrentTime(), &selectedLayer, &selectedAlphaLayer, &alphaChannelIndex, &selectedDisplayLayer); // Set the alpha channel to the selected layer's alpha channel if it is not pointing to anything if (selectedLayer.getNumComponents() == 4 && selectedAlphaLayer.getNumComponents() == 0) { ChoiceOption newOption = selectedLayer.getChannelOption(3); KnobChoicePtr alphaChoice = alphaChannelKnob.lock(); std::vector<ChoiceOption> options = alphaChoice->getEntries(); for (std::size_t i = 0; i < options.size(); ++i) { if (options[i].id == newOption.id) { alphaChoice->setValue(i); break; } } } }
void DiskCacheNode::initializeKnobs() { KnobPagePtr page = createKnob<KnobPage>("controlsPage"); page->setLabel(tr("Controls") ); KnobChoicePtr frameRange = createKnob<KnobChoice>(kDiskCacheNodeFrameRange); frameRange->setLabel(tr(kDiskCacheNodeFrameRangeLabel) ); frameRange->setHintToolTip(tr(kDiskCacheNodeFrameRangeHint)); frameRange->setAnimationEnabled(false); { std::vector<ChoiceOption> choices; choices.push_back(ChoiceOption("Input frame range", "", "")); choices.push_back(ChoiceOption("Project frame range", "", "")); choices.push_back(ChoiceOption("Manual","", "")); frameRange->populateChoices(choices); } frameRange->setEvaluateOnChange(false); frameRange->setDefaultValue(0); page->addKnob(frameRange); _imp->frameRange = frameRange; KnobIntPtr firstFrame = createKnob<KnobInt>(kDiskCacheNodeFirstFrame); firstFrame->setLabel(tr(kDiskCacheNodeFirstFrameLabel) ); firstFrame->setHintToolTip(tr(kDiskCacheNodeFirstFrameHint)); firstFrame->setAnimationEnabled(false); firstFrame->disableSlider(); firstFrame->setEvaluateOnChange(false); firstFrame->setAddNewLine(false); firstFrame->setDefaultValue(1); firstFrame->setSecret(true); page->addKnob(firstFrame); _imp->firstFrame = firstFrame; KnobIntPtr lastFrame = createKnob<KnobInt>(kDiskCacheNodeLastFrame); lastFrame->setAnimationEnabled(false); lastFrame->setLabel(tr(kDiskCacheNodeLastFrameLabel)); lastFrame->setHintToolTip(tr(kDiskCacheNodeLastFrameHint)); lastFrame->disableSlider(); lastFrame->setEvaluateOnChange(false); lastFrame->setDefaultValue(100); lastFrame->setSecret(true); page->addKnob(lastFrame); _imp->lastFrame = lastFrame; KnobButtonPtr preRender = createKnob<KnobButton>("preRender"); preRender->setLabel(tr("Pre-cache")); preRender->setEvaluateOnChange(false); preRender->setHintToolTip( tr("Cache the frame range specified by rendering images at zoom-level 100% only.") ); page->addKnob(preRender); _imp->preRender = preRender; }
void DiskCacheNode::initializeKnobs() { KnobPagePtr page = AppManager::createKnob<KnobPage>( shared_from_this(), tr("Controls") ); KnobChoicePtr frameRange = AppManager::createKnob<KnobChoice>( shared_from_this(), tr("Frame range") ); frameRange->setName("frameRange"); frameRange->setAnimationEnabled(false); std::vector<std::string> choices; choices.push_back("Input frame range"); choices.push_back("Project frame range"); choices.push_back("Manual"); frameRange->populateChoices(choices); frameRange->setEvaluateOnChange(false); frameRange->setDefaultValue(0); page->addKnob(frameRange); _imp->frameRange = frameRange; KnobIntPtr firstFrame = AppManager::createKnob<KnobInt>( shared_from_this(), tr("First Frame") ); firstFrame->setAnimationEnabled(false); firstFrame->setName("firstFrame"); firstFrame->disableSlider(); firstFrame->setEvaluateOnChange(false); firstFrame->setAddNewLine(false); firstFrame->setDefaultValue(1); firstFrame->setSecret(true); page->addKnob(firstFrame); _imp->firstFrame = firstFrame; KnobIntPtr lastFrame = AppManager::createKnob<KnobInt>( shared_from_this(), tr("Last Frame") ); lastFrame->setAnimationEnabled(false); lastFrame->setName("LastFrame"); lastFrame->disableSlider(); lastFrame->setEvaluateOnChange(false); lastFrame->setDefaultValue(100); lastFrame->setSecret(true); page->addKnob(lastFrame); _imp->lastFrame = lastFrame; KnobButtonPtr preRender = AppManager::createKnob<KnobButton>( shared_from_this(), tr("Pre-cache") ); preRender->setName("preRender"); preRender->setEvaluateOnChange(false); preRender->setHintToolTip( tr("Cache the frame range specified by rendering images at zoom-level 100% only.") ); page->addKnob(preRender); _imp->preRender = preRender; }