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 EditExpressionDialog::setTitle() { KnobPtr k = _knob->getKnob(); QString title( tr("Set expression on ") ); title.append( QString::fromUtf8( k->getName().c_str() ) ); if ( (_dimension != -1) && (k->getDimension() > 1) ) { title.append( QLatin1Char('.') ); title.append( QString::fromUtf8( k->getDimensionName(_dimension).c_str() ) ); } setWindowTitle(title); }
void KnobGuiValue::createWidget(QHBoxLayout* layout) { connectKnobSignalSlots(); _imp->container = new QWidget(layout->parentWidget()); QHBoxLayout *containerLayout = new QHBoxLayout(_imp->container); layout->addWidget(_imp->container); containerLayout->setContentsMargins(0, 0, 0, 0); containerLayout->setSpacing(3); if (getKnobsCountOnSameLine() > 1) { disableSlider(); } if (!isSliderDisabled()) { layout->parentWidget()->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Fixed); } KnobPtr knob = _imp->getKnob(); const int nDims = knob->getDimension(); std::vector<double> increments, displayMins, displayMaxs, mins, maxs; std::vector<int> decimals; boost::shared_ptr<Knob<double> > doubleKnob = _imp->getKnobAsDouble(); boost::shared_ptr<Knob<int> > intKnob = _imp->getKnobAsInt(); if (doubleKnob) { displayMins = doubleKnob->getDisplayMinimums(); displayMaxs = doubleKnob->getDisplayMaximums(); mins = doubleKnob->getMinimums(); maxs = doubleKnob->getMaximums(); } else { const std::vector<int>& intDmins = intKnob->getDisplayMinimums(); const std::vector<int>& intDMaxs = intKnob->getDisplayMaximums(); const std::vector<int>& intMins = intKnob->getMinimums(); const std::vector<int>& intMaxs = intKnob->getMaximums(); assert(intDMaxs.size() == intDmins.size() && intDmins.size() == intMins.size() && intMins.size() == intMaxs.size()); displayMins.resize(intDmins.size()); displayMaxs.resize(intDmins.size()); mins.resize(intDmins.size()); maxs.resize(intDmins.size()); for (std::size_t i = 0; i < intMins.size(); ++i) { displayMins[i] = intDmins[i]; displayMaxs[i] = intDMaxs[i]; mins[i] = intMins[i]; maxs[i] = intMaxs[i]; } } getIncrements(&increments); getDecimals(&decimals); std::vector<std::string> dimensionLabels(nDims); bool isRectangleParam = isRectangleType(); // This is a rectangle parameter if (isRectangleParam) { dimensionLabels[0] = "x"; dimensionLabels[1] = "y"; dimensionLabels[2] = "w"; dimensionLabels[3] = "h"; } else { for (int i = 0; i < nDims; ++i) { dimensionLabels[i] = knob->getDimensionName(i); } } KnobGuiPtr thisShared = shared_from_this(); SpinBox::SpinBoxTypeEnum type; if (doubleKnob) { type = SpinBox::eSpinBoxTypeDouble; } else { type = SpinBox::eSpinBoxTypeInt; } int nItemsPerRow = nDims; if (std::floor(nDims / 3. + 0.5) == nDims / 3.) { nItemsPerRow = 3; } if (std::floor(nDims / 4. + 0.5) == nDims / 4.) { nItemsPerRow = 4; } int nbRows = nDims / nItemsPerRow; assert(nbRows >= 1); QWidget* allSpinBoxesContainer = 0; QGridLayout* spinBoxesGrid = 0; if (nbRows == 1) { allSpinBoxesContainer = _imp->container; } else { allSpinBoxesContainer = new QWidget(_imp->container); spinBoxesGrid = new QGridLayout(allSpinBoxesContainer); spinBoxesGrid->setContentsMargins(0, 0, 0, 0); spinBoxesGrid->setVerticalSpacing(TO_DPIY(1)); spinBoxesGrid->setHorizontalSpacing(TO_DPIX(1)); } _imp->spinBoxes.resize(nDims); int rowIndex = 0; int columnIndex = 0; for (std::size_t i = 0; i < _imp->spinBoxes.size(); ++i) { QWidget *boxContainer = new QWidget(allSpinBoxesContainer); boxContainer->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed); QHBoxLayout *boxContainerLayout = 0; boxContainerLayout = new QHBoxLayout(boxContainer); boxContainerLayout->setContentsMargins(0, 0, 0, 0); boxContainerLayout->setSpacing(3); Label *subDesc = 0; if (nDims != 1 && nbRows == 1) { subDesc = new Label(QString::fromUtf8(dimensionLabels[i].c_str()), boxContainer); boxContainerLayout->addWidget(subDesc); } SpinBox *box = new KnobSpinBox(layout->parentWidget(), type, thisShared , i); NumericKnobValidator* validator = new NumericKnobValidator(box,thisShared); box->setValidator(validator); QObject::connect( box, SIGNAL(valueChanged(double)), this, SLOT(onSpinBoxValueChanged()) ); // Set the copy/link actions in the right click menu of the SpinBox enableRightClickMenu(box,i); #ifdef SPINBOX_TAKE_PLUGIN_RANGE_INTO_ACCOUNT double min = mins[i]; double max = maxs[i]; valueAccordingToType(false, i, &min); valueAccordingToType(false, i, &max); box->setMaximum(max); box->setMinimum(min); #endif if (type == SpinBox::eSpinBoxTypeDouble) { // Set the number of digits after the decimal point if (i < decimals.size()) { box->decimals(decimals[i]); } } if (i < increments.size()) { double incr = 1; incr = increments[i]; valueAccordingToType(false, i, &incr); box->setIncrement(incr); } boxContainerLayout->addWidget(box); if (!spinBoxesGrid) { containerLayout->addWidget(boxContainer); } else { spinBoxesGrid->addWidget(boxContainer, rowIndex, columnIndex); } _imp->spinBoxes[i] = std::make_pair(box, subDesc); ++columnIndex; if (columnIndex >= nItemsPerRow) { columnIndex = 0; ++rowIndex; } } if (spinBoxesGrid) { containerLayout->addWidget(allSpinBoxesContainer); } bool sliderVisible = false; if (!isSliderDisabled() && !isRectangleParam) { double dispmin = displayMins[0]; double dispmax = displayMaxs[0]; if (dispmin == -DBL_MAX) { dispmin = mins[0]; } if (dispmax == DBL_MAX) { dispmax = maxs[0]; } // denormalize if necessary double dispminGui = dispmin; double dispmaxGui = dispmax; valueAccordingToType(false, 0, &dispminGui); valueAccordingToType(false, 0, &dispmaxGui); bool spatial = isSpatialType(); Format f; if (spatial) { getKnob()->getHolder()->getApp()->getProject()->getProjectDefaultFormat(&f); } if (dispminGui < -SLIDER_MAX_RANGE) { if (spatial) { dispminGui = -f.width(); } else { dispminGui = -SLIDER_MAX_RANGE; } } if (dispmaxGui > SLIDER_MAX_RANGE) { if (spatial) { dispmaxGui = f.width(); } else { dispmaxGui = SLIDER_MAX_RANGE; } } double value0 = _imp->getKnobValue(0); ScaleSliderQWidget::DataTypeEnum sliderType; if (doubleKnob) { sliderType = ScaleSliderQWidget::eDataTypeDouble; } else { sliderType = ScaleSliderQWidget::eDataTypeInt; } _imp->slider = new ScaleSliderQWidget(dispminGui, dispmaxGui, value0,knob->getEvaluateOnChange(), sliderType,getGui(), eScaleTypeLinear, layout->parentWidget()); _imp->slider->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Fixed); if (hasToolTip()) { _imp->slider->setToolTip( toolTip() ); } QObject::connect(_imp->slider, SIGNAL(positionChanged(double)), this, SLOT(onSliderValueChanged(double))); QObject::connect(_imp->slider, SIGNAL(editingFinished(bool)), this, SLOT(onSliderEditingFinished(bool))); containerLayout->addWidget(_imp->slider); sliderVisible = shouldSliderBeVisible(dispminGui, dispmaxGui); // onDisplayMinMaxChanged takes original (maybe normalized) values onDisplayMinMaxChanged(dispmin, dispmax); }
QString KnobGui::toolTip() const { KnobPtr knob = getKnob(); KnobChoice* isChoice = dynamic_cast<KnobChoice*>( knob.get() ); bool isMarkdown = knob.get()->isHintInMarkdown(); QString tt; QString realTt; if (isMarkdown) { tt = QString::fromUtf8( knob.get()->getName().c_str() ); tt.append( QString::fromUtf8("\n==========\n\n") ); } else { tt = getScriptNameHtml(); } if (!isChoice) { realTt.append( QString::fromUtf8( knob->getHintToolTip().c_str() ) ); } else { realTt.append( QString::fromUtf8( isChoice->getHintToolTipFull().c_str() ) ); } std::vector<std::string> expressions; bool exprAllSame = true; for (int i = 0; i < knob->getDimension(); ++i) { expressions.push_back( knob->getExpression(i) ); if ( (i > 0) && (expressions[i] != expressions[0]) ) { exprAllSame = false; } } QString exprTt; if (exprAllSame) { if ( !expressions[0].empty() ) { if (isMarkdown) { exprTt = QString::fromUtf8("ret = **%1**\n\n").arg( QString::fromUtf8( expressions[0].c_str() ) ); } else { exprTt = QString::fromUtf8("ret = <b>%1</b><br />").arg( QString::fromUtf8( expressions[0].c_str() ) ); } } } else { for (int i = 0; i < knob->getDimension(); ++i) { std::string dimName = knob->getDimensionName(i); QString toAppend; if (isMarkdown) { toAppend = QString::fromUtf8("%1 = **%2**\n\n").arg( QString::fromUtf8( dimName.c_str() ) ).arg( QString::fromUtf8( expressions[i].c_str() ) ); } else { toAppend = QString::fromUtf8("%1 = <b>%2</b><br />").arg( QString::fromUtf8( dimName.c_str() ) ).arg( QString::fromUtf8( expressions[i].c_str() ) ); } exprTt.append(toAppend); } } if ( !exprTt.isEmpty() ) { tt.append(exprTt); if (!isMarkdown) { tt += QLatin1String("<br/>"); } } if ( !realTt.isEmpty() ) { if (!isMarkdown) { realTt = GuiUtils::convertFromPlainText(realTt.trimmed(), Qt::WhiteSpaceNormal); } tt.append(realTt); } if (isMarkdown) { tt = Markdown::convert2html(tt); // Shrink H1/H2 (Can't do it in qt stylesheet) tt.replace( QString::fromUtf8("<h1>"), QString::fromUtf8("<h1 style=\"font-size:large;\">") ); tt.replace( QString::fromUtf8("<h2>"), QString::fromUtf8("<h2 style=\"font-size:large;\">") ); } return tt; } // KnobGui::toolTip