Esempio n. 1
0
bool
PointOverlayInteract::onOverlayPenMotion(TimeValue time,
                                         const RenderScale & /*renderScale*/,
                                         ViewIdx view,
                                         const QPointF & /*viewportPos*/,
                                         const QPointF & penPos,
                                         double /*pressure*/,
                                         TimeValue /*timestamp*/)
{
    KnobDoublePtr knob = _imp->param.lock();

    // do not show interact if knob is secret or not enabled
    // see https://github.com/MrKepzie/Natron/issues/932
    if ( !knob || !knob->shouldDrawOverlayInteract() ) {
        return false;
    }

    RenderScale pscale;
    getPixelScale(pscale.x, pscale.y);

    QPointF pos;
    if (_imp->state == ePositionInteractStatePicked) {
        pos = _imp->lastPenPos;
    } else {
        double p[2];
        for (int i = 0; i < 2; ++i) {
            p[i] = knob->getValueAtTime(time, DimIdx(i));
            if (knob->getValueIsNormalized(DimIdx(i)) != eValueIsNormalizedNone) {
                p[i] = knob->denormalize(DimIdx(i), time, p[i]);
            }
        }
        pos.setX(p[0]);
        pos.setY(p[1]);
    }

    bool didSomething = false;
    bool valuesChanged = false;

    switch (_imp->state) {
        case ePositionInteractStateInactive:
        case ePositionInteractStatePoised: {
            // are we in the box, become 'poised'
            PositionInteractState newState;
            if ( ( std::fabs( penPos.x() - pos.x() ) <= _imp->pointTolerance() * pscale.x) &&
                ( std::fabs( penPos.y() - pos.y() ) <= _imp->pointTolerance() * pscale.y) ) {
                newState = ePositionInteractStatePoised;
            } else {
                newState = ePositionInteractStateInactive;
            }

            if (_imp->state != newState) {
                // state changed, must redraw
                redraw();
            }
            _imp->state = newState;
            //}
            break;
        }

        case ePositionInteractStatePicked: {
            valuesChanged = true;
            break;
        }
    }
    didSomething = (_imp->state == ePositionInteractStatePoised) || (_imp->state == ePositionInteractStatePicked);

    if ( (_imp->state != ePositionInteractStateInactive) && _imp->interactiveDrag && valuesChanged ) {
        std::vector<double> p(2);
        p[0] = fround(_imp->lastPenPos.x(), pscale.x);
        p[1] = fround(_imp->lastPenPos.y(), pscale.y);
        for (int i = 0; i < 2; ++i) {
            if (knob->getValueIsNormalized(DimIdx(i)) != eValueIsNormalizedNone) {
                p[i] = knob->normalize(DimIdx(i), time, p[i]);
            }
        }


        knob->setValueAcrossDimensions(p, DimIdx(0), ViewSetSpec(view), eValueChangedReasonUserEdited);
    }

    _imp->lastPenPos = penPos;

    return (didSomething || valuesChanged);
} // onOverlayPenMotion
Esempio n. 2
0
void
PointOverlayInteract::drawOverlay(TimeValue time,
                                  const RenderScale & /*renderScale*/,
                                  ViewIdx /*view*/)
{
    KnobDoublePtr knob = _imp->param.lock();

    // do not show interact if knob is secret or not enabled
    // see https://github.com/MrKepzie/Natron/issues/932
    if ( !knob || !knob->shouldDrawOverlayInteract()) {
        return;
    }

    ColorRgba<double> color;
    if ( !getOverlayColor(color.r, color.g, color.b) ) {
        color.r = color.g = color.b = 0.8;
    }


    RenderScale pscale;
    getPixelScale(pscale.x, pscale.y);

    float pR = 1.f;
    float pG = 1.f;
    float pB = 1.f;
    switch (_imp->state) {
        case ePositionInteractStateInactive:
            pR = (float)color.r; pG = (float)color.g; pB = (float)color.b; break;
        case ePositionInteractStatePoised:
            pR = 0.f; pG = 1.0f; pB = 0.0f; break;
        case ePositionInteractStatePicked:
            pR = 0.f; pG = 1.0f; pB = 0.0f; break;
    }

    QPointF pos;
    if (_imp->state == ePositionInteractStatePicked) {
        pos = _imp->lastPenPos;
    } else {
        double p[2];
        for (int i = 0; i < 2; ++i) {
            p[i] = knob->getValueAtTime(time, DimIdx(i));
            if (knob->getValueIsNormalized(DimIdx(i)) != eValueIsNormalizedNone) {
                p[i] = knob->denormalize(DimIdx(i), time, p[i]);
            }
        }
        pos.setX(p[0]);
        pos.setY(p[1]);
    }
    //glPushAttrib(GL_ALL_ATTRIB_BITS); // caller is responsible for protecting attribs
    GL_GPU::PointSize( (GLfloat)_imp->pointSize() );
    // Draw everything twice
    // l = 0: shadow
    // l = 1: drawing

    double w, h;
    getViewportSize(w, h);

    GLdouble projection[16];
    GL_GPU::GetDoublev( GL_PROJECTION_MATRIX, projection);
    OfxPointD shadow; // how much to translate GL_PROJECTION to get exactly one pixel on screen
    shadow.x = 2. / (projection[0] * w);
    shadow.y = 2. / (projection[5] * h);


    int fmHeight = getLastCallingViewport()->getWidgetFontHeight();
    for (int l = 0; l < 2; ++l) {
        // shadow (uses GL_PROJECTION)
        GL_GPU::MatrixMode(GL_PROJECTION);
        int direction = (l == 0) ? 1 : -1;
        // translate (1,-1) pixels
        GL_GPU::Translated(direction * shadow.x, -direction * shadow.y, 0);
        GL_GPU::MatrixMode(GL_MODELVIEW); // Modelview should be used on Nuke

        GL_GPU::Color3f(pR * l, pG * l, pB * l);
        GL_GPU::Begin(GL_POINTS);
        GL_GPU::Vertex2d( pos.x(), pos.y() );
        GL_GPU::End();
        getLastCallingViewport()->renderText(pos.x(), pos.y() - ( fmHeight + _imp->pointSize() ) * pscale.y, knob->getOriginalName(), pR*l, pG*l, pB*l, 1.);
    }

} // drawOverlay