Ejemplo n.º 1
0
uint8_t AsyncServoClass::goTo(uint8_t position, short maxIncrementDegrees, short incrementDelay)
{
	if(!_running)
	{
		_previousStep = getPosition();
		_currentStep = position;
		_readIndex = _writeIndex;
		_totalIncrements = getIncrements(_previousStep, _currentStep);
		_currentIncrement = 1;
		_loop = false;
		play();
	}
}
Ejemplo n.º 2
0
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);
    }
Ejemplo n.º 3
0
// Update function to be called in loop.
void AsyncServoClass::update()
{
	unsigned long currentMillis = millis();

	// Check for unpause
	if (_unpauseMillis > 0 && currentMillis >= _unpauseMillis)
	{
#if (ASYNCSERVO_DEBUG == 1)
		Serial.println("-----------------------");
		Serial.println("Un-paused");
		Serial.println("-----------------------");
#endif
		_unpauseMillis = 0;
		play();
	}

	if (currentMillis >= _nextUpdateMillis)
	{
		if (_running)
		{
			// Start
			if (_readIndex == -1)
			{
#if (ASYNCSERVO_DEBUG == 1)
				Serial.println("-----------------------");
				Serial.println("Play start");
				Serial.println("-----------------------");
#endif
				// Get the current position of the servo and set that to the previous step
				_previousStep = getPosition();

				// Set read index tot he begining of the steps array
				_readIndex = 0;

				// Get the current step at readIndex
				_currentStep = _steps[_readIndex];
			}


			// Calculate increments to complete step if not already calculated
			if (_totalIncrements == -1)
			{
				_totalIncrements = getIncrements(_previousStep, _currentStep);
				_currentIncrement = 1;
			}

			move(_previousStep,_currentStep);

#if (ASYNCSERVO_DEBUG == 1)
			Serial.print("Moved: ");
			Serial.print(_previousStep);
			Serial.print("-->");
			Serial.print(_currentStep);
			Serial.print(" inc ");
			Serial.print(_currentIncrement);
			Serial.print("/");
			Serial.println(_totalIncrements);
#endif

			// Check if the increments and hence step are complete
			if (_currentIncrement == _totalIncrements)
			{
				// Reset the increment counters
				_currentIncrement = -1;
				_totalIncrements = -1;

				// Proceed to next step
				_readIndex++;

				// Check if we have finished the steps
				if (_readIndex > _writeIndex)
				{
					// If looping then reset and pause for loop delay
					if (_loop == true)
					{
						reset();
						pause(_loopDelay);
					}
					else
					{
						stop();
#if (ASYNCSERVO_DEBUG == 1)
						Serial.println("-----------------------");
						Serial.println("Done!");
						Serial.println("-----------------------");
#endif
					}
				}
				else
				{
					_previousStep = _currentStep;
					_currentStep = _steps[_readIndex];

#if (ASYNCSERVO_DEBUG == 1)
					Serial.println("-----------------------");
					Serial.print("Next Step: ");
					Serial.println(_readIndex);
					Serial.println("-----------------------");
#endif
				}
			}
			else
			{
				// Increment _currentIncrement for the next update
				_currentIncrement++;
			}
		}

		// Update the update Timer by _incrementDelay
		_nextUpdateMillis = currentMillis + _incrementDelay;
	}
}