void KnobGuiColor::addExtraWidgets(QHBoxLayout* containerLayout) { containerLayout->addSpacing( TO_DPIX(10) ); KnobColorPtr knob = _knob.lock(); _colorLabel = new ColorPickerLabel( _useSimplifiedUI ? NULL : this, containerLayout->widget() ); if (!_useSimplifiedUI) { _colorLabel->setToolTip( GuiUtils::convertFromPlainText(tr("To pick a color on a viewer, click this and then press control + left click on any viewer.\n" "You can also pick the average color of a given rectangle by holding control + shift + left click\n. " "To deselect the picker left click anywhere." "Note that by default %1 converts to linear the color picked\n" "because all the processing pipeline is linear, but you can turn this off in the\n" "preferences panel.").arg( QString::fromUtf8(NATRON_APPLICATION_NAME) ), Qt::WhiteSpaceNormal) ); } QSize medSize( TO_DPIX(NATRON_MEDIUM_BUTTON_SIZE), TO_DPIY(NATRON_MEDIUM_BUTTON_SIZE) ); QSize medIconSize( TO_DPIX(NATRON_MEDIUM_BUTTON_ICON_SIZE), TO_DPIY(NATRON_MEDIUM_BUTTON_ICON_SIZE) ); _colorLabel->setFixedSize(medSize); QObject::connect( _colorLabel, SIGNAL(pickingEnabled(bool)), this, SLOT(onPickingEnabled(bool)) ); containerLayout->addWidget(_colorLabel); if (_useSimplifiedUI) { containerLayout->addSpacing( TO_DPIX(5) ); } QPixmap buttonPix; appPTR->getIcon(NATRON_PIXMAP_COLORWHEEL, NATRON_MEDIUM_BUTTON_ICON_SIZE, &buttonPix); _colorDialogButton = new Button( QIcon(buttonPix), QString(), containerLayout->widget() ); _colorDialogButton->setFixedSize(medSize); _colorDialogButton->setIconSize(medIconSize); _colorDialogButton->setToolTip( GuiUtils::convertFromPlainText(tr("Open the color dialog."), Qt::WhiteSpaceNormal) ); _colorDialogButton->setFocusPolicy(Qt::NoFocus); QObject::connect( _colorDialogButton, SIGNAL(clicked()), this, SLOT(showColorDialog()) ); containerLayout->addWidget(_colorDialogButton); if (_useSimplifiedUI) { KnobGuiValue::_hide(); enableRightClickMenu(_colorLabel, -1); } }
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); }