void ScaleSliderQWidget::paintEvent(QPaintEvent* /*e*/) { if (_imp->mustInitializeSliderPosition) { if (_imp->minimum < _imp->maximum) { centerOn(_imp->minimum, _imp->maximum); } _imp->mustInitializeSliderPosition = false; seekScalePosition(_imp->value); _imp->initialized = true; } ///fill the background with the appropriate style color QStyleOption opt; opt.init(this); QPainter p(this); p.setOpacity(1); style()->drawPrimitive(QStyle::PE_Widget, &opt, &p, this); double txtR, txtG, txtB; if (_imp->altered) { appPTR->getCurrentSettings()->getAltTextColor(&txtR, &txtG, &txtB); } else { appPTR->getCurrentSettings()->getTextColor(&txtR, &txtG, &txtB); } QColor textColor; textColor.setRgbF( Image::clamp<qreal>(txtR, 0., 1.), Image::clamp<qreal>(txtG, 0., 1.), Image::clamp<qreal>(txtB, 0., 1.) ); QColor scaleColor; scaleColor.setRgbF(textColor.redF() / 2., textColor.greenF() / 2., textColor.blueF() / 2.); QFontMetrics fontM(_imp->font, 0); if (!_imp->useLineColor) { p.setPen(scaleColor); } else { p.setPen(_imp->lineColor); } QPointF btmLeft = _imp->zoomCtx.toZoomCoordinates(0, height() - 1); QPointF topRight = _imp->zoomCtx.toZoomCoordinates(width() - 1, 0); if ( btmLeft.x() == topRight.x() ) { return; } /*drawing X axis*/ double lineYpos = height() - 1 - fontM.height() - TO_DPIY(TICK_HEIGHT) / 2; p.drawLine(0, lineYpos, width() - 1, lineYpos); double tickBottom = _imp->zoomCtx.toZoomCoordinates( 0, height() - 1 - fontM.height() ).y(); double tickTop = _imp->zoomCtx.toZoomCoordinates( 0, height() - 1 - fontM.height() - TO_DPIY(TICK_HEIGHT) ).y(); const double smallestTickSizePixel = 10.; // tick size (in pixels) for alpha = 0. const double largestTickSizePixel = 1000.; // tick size (in pixels) for alpha = 1. const double rangePixel = width(); const double range_min = btmLeft.x(); const double range_max = topRight.x(); const double range = range_max - range_min; double smallTickSize; bool half_tick; ticks_size(range_min, range_max, rangePixel, smallestTickSizePixel, &smallTickSize, &half_tick); if ( (_imp->dataType == eDataTypeInt) && (smallTickSize < 1.) ) { smallTickSize = 1.; half_tick = false; } int m1, m2; const int ticks_max = 1000; double offset; ticks_bounds(range_min, range_max, smallTickSize, half_tick, ticks_max, &offset, &m1, &m2); std::vector<int> ticks; ticks_fill(half_tick, ticks_max, m1, m2, &ticks); const double smallestTickSize = range * smallestTickSizePixel / rangePixel; const double largestTickSize = range * largestTickSizePixel / rangePixel; const double minTickSizeTextPixel = fontM.width( QLatin1String("00") ); // AXIS-SPECIFIC const double minTickSizeText = range * minTickSizeTextPixel / rangePixel; for (int i = m1; i <= m2; ++i) { double value = i * smallTickSize + offset; const double tickSize = ticks[i - m1] * smallTickSize; const double alpha = ticks_alpha(smallestTickSize, largestTickSize, tickSize); QColor color(textColor); color.setAlphaF(alpha); QPen pen(color); pen.setWidthF(1.9); p.setPen(pen); // for Int slider, because smallTickSize is at least 1, isFloating can never be true bool isFloating = std::abs(std::floor(0.5 + value) - value) != 0.; assert( !(_imp->dataType == eDataTypeInt && isFloating) ); bool renderFloating = _imp->dataType == eDataTypeDouble || !isFloating; if (renderFloating) { QPointF tickBottomPos = _imp->zoomCtx.toWidgetCoordinates(value, tickBottom); QPointF tickTopPos = _imp->zoomCtx.toWidgetCoordinates(value, tickTop); p.drawLine(tickBottomPos, tickTopPos); } if ( renderFloating && (tickSize > minTickSizeText) ) { const int tickSizePixel = rangePixel * tickSize / range; const QString s = QString::number(value); const int sSizePixel = fontM.width(s); if (tickSizePixel > sSizePixel) { const int sSizeFullPixel = sSizePixel + minTickSizeTextPixel; double alphaText = 1.0; //alpha; if (tickSizePixel < sSizeFullPixel) { // when the text size is between sSizePixel and sSizeFullPixel, // draw it with a lower alpha alphaText *= (tickSizePixel - sSizePixel) / (double)minTickSizeTextPixel; } QColor c = _imp->readOnly || !isEnabled() ? Qt::black : textColor; c.setAlphaF(alphaText); p.setFont(_imp->font); p.setPen(c); QPointF textPos = _imp->zoomCtx.toWidgetCoordinates( value, btmLeft.y() ); p.drawText(textPos, s); } } } double positionValue = _imp->zoomCtx.toWidgetCoordinates(_imp->value, 0).x(); QPointF sliderBottomLeft(positionValue - TO_DPIX(SLIDER_WIDTH) / 2, height() - 1 - fontM.height() / 2); QPointF sliderTopRight( positionValue + TO_DPIX(SLIDER_WIDTH) / 2, height() - 1 - fontM.height() / 2 - TO_DPIY(SLIDER_HEIGHT) ); /*draw the slider*/ p.setPen(_imp->sliderColor); p.fillRect(sliderBottomLeft.x(), sliderBottomLeft.y(), sliderTopRight.x() - sliderBottomLeft.x(), sliderTopRight.y() - sliderBottomLeft.y(), _imp->sliderColor); /*draw a black rect around the slider for contrast or orange when focused*/ if ( !hasFocus() ) { p.setPen(Qt::black); } else { QPen pen = p.pen(); pen.setColor( QColor(243, 137, 0) ); QVector<qreal> dashStyle; qreal space = 2; dashStyle << 1 << space; pen.setDashPattern(dashStyle); p.setOpacity(0.8); p.setPen(pen); } p.drawLine( sliderBottomLeft.x(), sliderBottomLeft.y(), sliderBottomLeft.x(), sliderTopRight.y() ); p.drawLine( sliderBottomLeft.x(), sliderTopRight.y(), sliderTopRight.x(), sliderTopRight.y() ); p.drawLine( sliderTopRight.x(), sliderTopRight.y(), sliderTopRight.x(), sliderBottomLeft.y() ); p.drawLine( sliderTopRight.x(), sliderBottomLeft.y(), sliderBottomLeft.x(), sliderBottomLeft.y() ); } // paintEvent
void ScaleSliderQWidget::paintEvent(QPaintEvent* /*e*/) { if (_imp->mustInitializeSliderPosition) { centerOn(_imp->minimum, _imp->maximum); _imp->mustInitializeSliderPosition = false; seekScalePosition(_imp->value); _imp->initialized = true; } ///fill the background with the appropriate style color QStyleOption opt; opt.init(this); QPainter p(this); style()->drawPrimitive(QStyle::PE_Widget, &opt, &p, this); double txtR,txtG,txtB; appPTR->getCurrentSettings()->getTextColor(&txtR, &txtG, &txtB); QColor textColor; textColor.setRgbF(Natron::clamp(txtR), Natron::clamp(txtG), Natron::clamp(txtB)); QColor scaleColor; scaleColor.setRgbF(textColor.redF() / 2., textColor.greenF() / 2., textColor.blueF() / 2.); QFontMetrics fontM(*_imp->font); p.setPen(scaleColor); QPointF btmLeft = _imp->zoomCtx.toZoomCoordinates(0,height() - 1); QPointF topRight = _imp->zoomCtx.toZoomCoordinates(width() - 1, 0); if ( btmLeft.x() == topRight.x() ) { return; } /*drawing X axis*/ double lineYpos = height() - 1 - fontM.height() - TICK_HEIGHT / 2; p.drawLine(0, lineYpos, width() - 1, lineYpos); double tickBottom = _imp->zoomCtx.toZoomCoordinates( 0,height() - 1 - fontM.height() ).y(); double tickTop = _imp->zoomCtx.toZoomCoordinates(0,height() - 1 - fontM.height() - TICK_HEIGHT).y(); const double smallestTickSizePixel = 5.; // tick size (in pixels) for alpha = 0. const double largestTickSizePixel = 1000.; // tick size (in pixels) for alpha = 1. std::vector<double> acceptedDistances; acceptedDistances.push_back(1.); acceptedDistances.push_back(5.); acceptedDistances.push_back(10.); acceptedDistances.push_back(50.); const double rangePixel = width(); const double range_min = btmLeft.x(); const double range_max = topRight.x(); const double range = range_max - range_min; double smallTickSize; bool half_tick; ticks_size(range_min, range_max, rangePixel, smallestTickSizePixel, &smallTickSize, &half_tick); int m1, m2; const int ticks_max = 1000; double offset; ticks_bounds(range_min, range_max, smallTickSize, half_tick, ticks_max, &offset, &m1, &m2); std::vector<int> ticks; ticks_fill(half_tick, ticks_max, m1, m2, &ticks); const double smallestTickSize = range * smallestTickSizePixel / rangePixel; const double largestTickSize = range * largestTickSizePixel / rangePixel; const double minTickSizeTextPixel = fontM.width( QString("00") ); // AXIS-SPECIFIC const double minTickSizeText = range * minTickSizeTextPixel / rangePixel; for (int i = m1; i <= m2; ++i) { double value = i * smallTickSize + offset; const double tickSize = ticks[i - m1] * smallTickSize; const double alpha = ticks_alpha(smallestTickSize, largestTickSize, tickSize); QColor color(textColor); color.setAlphaF(alpha); QPen pen(color); pen.setWidthF(1.9); p.setPen(pen); QPointF tickBottomPos = _imp->zoomCtx.toWidgetCoordinates(value, tickBottom); QPointF tickTopPos = _imp->zoomCtx.toWidgetCoordinates(value, tickTop); p.drawLine(tickBottomPos,tickTopPos); bool renderText = _imp->dataType == eDataTypeDouble || std::abs(std::floor(0.5 + value) - value) == 0.; if (renderText && tickSize > minTickSizeText) { const int tickSizePixel = rangePixel * tickSize / range; const QString s = QString::number(value); const int sSizePixel = fontM.width(s); if (tickSizePixel > sSizePixel) { const int sSizeFullPixel = sSizePixel + minTickSizeTextPixel; double alphaText = 1.0; //alpha; if (tickSizePixel < sSizeFullPixel) { // when the text size is between sSizePixel and sSizeFullPixel, // draw it with a lower alpha alphaText *= (tickSizePixel - sSizePixel) / (double)minTickSizeTextPixel; } QColor c = _imp->readOnly || !isEnabled() ? Qt::black : textColor; c.setAlphaF(alphaText); p.setFont(*_imp->font); p.setPen(c); QPointF textPos = _imp->zoomCtx.toWidgetCoordinates( value, btmLeft.y() ); p.drawText(textPos, s); } } } double positionValue = _imp->zoomCtx.toWidgetCoordinates(_imp->value,0).x(); QPointF sliderBottomLeft(positionValue - SLIDER_WIDTH / 2,height() - 1 - fontM.height() / 2); QPointF sliderTopRight(positionValue + SLIDER_WIDTH / 2,height() - 1 - fontM.height() / 2 - SLIDER_HEIGHT); /*draw the slider*/ p.setPen(_imp->sliderColor); p.fillRect(sliderBottomLeft.x(), sliderBottomLeft.y(), sliderTopRight.x() - sliderBottomLeft.x(), sliderTopRight.y() - sliderBottomLeft.y(),_imp->sliderColor); /*draw a black rect around the slider for contrast*/ p.setPen(Qt::black); p.drawLine( sliderBottomLeft.x(),sliderBottomLeft.y(),sliderBottomLeft.x(),sliderTopRight.y() ); p.drawLine( sliderBottomLeft.x(),sliderTopRight.y(),sliderTopRight.x(),sliderTopRight.y() ); p.drawLine( sliderTopRight.x(),sliderTopRight.y(),sliderTopRight.x(),sliderBottomLeft.y() ); p.drawLine( sliderTopRight.x(),sliderBottomLeft.y(),sliderBottomLeft.x(),sliderBottomLeft.y() ); } // paintEvent
void AnimationModuleViewPrivate::drawCurveEditorScale() { glCheckError(GL_GPU); // always running in the main thread assert( qApp && qApp->thread() == QThread::currentThread() ); QPointF btmLeft = curveEditorZoomContext.toZoomCoordinates(0, _publicInterface->height() - 1); QPointF topRight = curveEditorZoomContext.toZoomCoordinates(_publicInterface->width() - 1, 0); ///don't attempt to draw a scale on a widget with an invalid height/width if ( (_publicInterface->height() <= 1) || (_publicInterface->width() <= 1) ) { return; } QFontMetrics fontM = _publicInterface->fontMetrics(); const double smallestTickSizePixel = 10.; // tick size (in pixels) for alpha = 0. const double largestTickSizePixel = 500.; // tick size (in pixels) for alpha = 1. double gridR, gridG, gridB; SettingsPtr sett = appPTR->getCurrentSettings(); sett->getAnimationModuleEditorGridColor(&gridR, &gridG, &gridB); double scaleR, scaleG, scaleB; sett->getAnimationModuleEditorScaleColor(&scaleR, &scaleG, &scaleB); QColor scaleColor; scaleColor.setRgbF( Image::clamp(scaleR, 0., 1.), Image::clamp(scaleG, 0., 1.), Image::clamp(scaleB, 0., 1.) ); { GLProtectAttrib<GL_GPU> a(GL_CURRENT_BIT | GL_COLOR_BUFFER_BIT | GL_ENABLE_BIT); GL_GPU::Enable(GL_BLEND); GL_GPU::BlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); for (int axis = 0; axis < 2; ++axis) { const double rangePixel = (axis == 0) ? _publicInterface->width() : _publicInterface->height(); // AXIS-SPECIFIC const double range_min = (axis == 0) ? btmLeft.x() : btmLeft.y(); // AXIS-SPECIFIC const double range_max = (axis == 0) ? topRight.x() : topRight.y(); // AXIS-SPECIFIC const double range = range_max - range_min; double smallTickSize; bool half_tick; ticks_size(range_min, range_max, rangePixel, smallestTickSizePixel, &smallTickSize, &half_tick); int m1, m2; const int ticks_max = 1000; double offset; ticks_bounds(range_min, range_max, smallTickSize, half_tick, ticks_max, &offset, &m1, &m2); std::vector<int> ticks; ticks_fill(half_tick, ticks_max, m1, m2, &ticks); const double smallestTickSize = range * smallestTickSizePixel / rangePixel; const double largestTickSize = range * largestTickSizePixel / rangePixel; const double minTickSizeTextPixel = (axis == 0) ? fontM.width( QLatin1String("00") ) : fontM.height(); // AXIS-SPECIFIC const double minTickSizeText = range * minTickSizeTextPixel / rangePixel; for (int i = m1; i <= m2; ++i) { double value = i * smallTickSize + offset; const double tickSize = ticks[i - m1] * smallTickSize; const double alpha = ticks_alpha(smallestTickSize, largestTickSize, tickSize); glCheckError(GL_GPU); GL_GPU::Color4f(gridR, gridG, gridB, alpha); GL_GPU::Begin(GL_LINES); if (axis == 0) { GL_GPU::Vertex2f( value, btmLeft.y() ); // AXIS-SPECIFIC GL_GPU::Vertex2f( value, topRight.y() ); // AXIS-SPECIFIC } else { GL_GPU::Vertex2f(btmLeft.x(), value); // AXIS-SPECIFIC GL_GPU::Vertex2f(topRight.x(), value); // AXIS-SPECIFIC } GL_GPU::End(); glCheckErrorIgnoreOSXBug(GL_GPU); if (tickSize > minTickSizeText) { const int tickSizePixel = rangePixel * tickSize / range; const QString s = QString::number(value); const int sSizePixel = (axis == 0) ? fontM.width(s) : fontM.height(); // AXIS-SPECIFIC if (tickSizePixel > sSizePixel) { const int sSizeFullPixel = sSizePixel + minTickSizeTextPixel; double alphaText = 1.0; //alpha; if (tickSizePixel < sSizeFullPixel) { // when the text size is between sSizePixel and sSizeFullPixel, // draw it with a lower alpha alphaText *= (tickSizePixel - sSizePixel) / (double)minTickSizeTextPixel; } alphaText = std::min(alphaText, alpha); // don't draw more opaque than tcks QColor c = scaleColor; c.setAlpha(255 * alphaText); if (axis == 0) { _publicInterface->renderText(value, btmLeft.y(), s.toStdString(), c.redF(), c.greenF(), c.blueF(), c.alphaF(), Qt::AlignHCenter); } else { _publicInterface->renderText(btmLeft.x(), value, s.toStdString(), c.redF(), c.greenF(), c.blueF(), c.alphaF(), Qt::AlignVCenter); } } } } } } // GLProtectAttrib a(GL_CURRENT_BIT | GL_COLOR_BUFFER_BIT | GL_ENABLE_BIT); glCheckError(GL_GPU); GL_GPU::Color4f(gridR, gridG, gridB, 1.); GL_GPU::Begin(GL_LINES); GL_GPU::Vertex2f(AXIS_MIN, 0); GL_GPU::Vertex2f(AXIS_MAX, 0); GL_GPU::Vertex2f(0, AXIS_MIN); GL_GPU::Vertex2f(0, AXIS_MAX); GL_GPU::End(); glCheckErrorIgnoreOSXBug(GL_GPU); } // drawCurveEditorScale