void TBScroller::OnScrollBy(int dx, int dy, bool accumulative) { if (!IsStarted()) Start(); float ppms_x = m_func.GetSpeedFromDistance((float)dx); float ppms_y = m_func.GetSpeedFromDistance((float)dy); if (accumulative && IsScrolling()) { TBWidget::ScrollInfo info = m_target->GetScrollInfo(); // If new direction is the same as the current direction, // calculate the speed needed for the remaining part and // add that to the new scroll speed. if (ppms_x < 0 == m_scroll_start_speed_ppms_x < 0) { int distance_x = m_func.GetDistanceAtTimeInt(m_scroll_start_speed_ppms_x, m_func.GetDurationFromSpeed(m_scroll_start_speed_ppms_x)); int distance_remaining_x = m_scroll_start_scroll_x + distance_x - info.x; distance_remaining_x += m_func.GetDistanceAtTimeInt(ppms_x, m_func.GetDurationFromSpeed(ppms_x)); ppms_x = m_func.GetSpeedFromDistance((float)distance_remaining_x); } if (ppms_y < 0 == m_scroll_start_speed_ppms_y < 0) { int distance_y = m_func.GetDistanceAtTimeInt(m_scroll_start_speed_ppms_y, m_func.GetDurationFromSpeed(m_scroll_start_speed_ppms_y)); int distance_remaining_y = m_scroll_start_scroll_y + distance_y - info.y; distance_remaining_y += m_func.GetDistanceAtTimeInt(ppms_y, m_func.GetDurationFromSpeed(ppms_y)); ppms_y = m_func.GetSpeedFromDistance((float)distance_remaining_y); } } AdjustToSnappingAndScroll(ppms_x, ppms_y); }
void OvrScrollManager::Frame( float deltaSeconds, unsigned int controllerState ) { // -- // Controller Input Handling bool forwardScrolling = false; bool backwardScrolling = false; if( CurrentScrollType == HORIZONTAL_SCROLL ) { forwardScrolling = ( controllerState & ( BUTTON_LSTICK_RIGHT | BUTTON_DPAD_RIGHT ) ) != 0; backwardScrolling = ( controllerState & ( BUTTON_LSTICK_LEFT | BUTTON_DPAD_LEFT ) ) != 0; } else if( CurrentScrollType == VERTICAL_SCROLL ) { forwardScrolling = ( controllerState & ( BUTTON_LSTICK_DOWN | BUTTON_DPAD_DOWN ) ) != 0; backwardScrolling = ( controllerState & ( BUTTON_LSTICK_UP | BUTTON_DPAD_UP ) ) != 0; } if ( forwardScrolling || backwardScrolling ) { CurrentScrollState = SMOOTH_SCROLL; } SetEnableAutoForwardScrolling( forwardScrolling ); SetEnableAutoBackwardScrolling( backwardScrolling ); // -- // Logic update for the current scroll state switch( CurrentScrollState ) { case SMOOTH_SCROLL: { // Auto scroll during wrap around initiation. if( ( !RestrictedScrolling ) || // Either not restricted scrolling ( RestrictedScrolling && ( TouchDirectionLocked != NO_LOCK ) ) ) // or restricted scrolling with touch direction locked { if ( TouchIsDown ) { if ( ( Position < 0.0f ) || ( Position > MaxPosition ) ) { // When scrolled out of bounds and touch is still down, // auto-scroll to initiate wrap around easily. float totalDistance = 0.0f; for ( int i = 0; i < Deltas.GetNum(); ++i ) { totalDistance += Deltas[i].d; } if ( totalDistance < -EPSILON_VEL ) { Velocity = -1.0f; } else if ( totalDistance > EPSILON_VEL ) { Velocity = 1.0f; } else { Velocity = PrevAutoScrollVelocity; } } else { Velocity = 0.0f; } PrevAutoScrollVelocity = Velocity; } } if ( !IsScrolling() && IsOutOfBounds() ) { CurrentScrollState = BOUNCE_SCROLL; const float bounceBackVelocity = ScrollBehavior.BounceBackVelocity; if ( Position < 0.0f ) { Velocity = bounceBackVelocity; } else if ( Position > MaxPosition ) { Velocity = -bounceBackVelocity; } Velocity = GetModifiedVelocity( Velocity ); } } break; case BOUNCE_SCROLL: { if( !IsOutOfBounds() ) { CurrentScrollState = SMOOTH_SCROLL; if( Velocity > 0.0f ) // Pulled at the beginning { Position = 0.0f; } else if( Velocity < 0.0f ) // Pulled at the end { Position = MaxPosition; } Velocity = 0.0f; } } break; } // -- // Scrolling physics update AccumulatedDeltaTimeInSeconds += deltaSeconds; OVR_ASSERT( AccumulatedDeltaTimeInSeconds <= 10.0f ); while( true ) { if( AccumulatedDeltaTimeInSeconds < 0.016f ) { break; } AccumulatedDeltaTimeInSeconds -= 0.016f; if( CurrentScrollState == SMOOTH_SCROLL || CurrentScrollState == BOUNCE_SCROLL ) // While wrap around don't slow down scrolling { Velocity -= Velocity * ScrollBehavior.FrictionPerSec * 0.016f; if( fabsf(Velocity) < EPSILON_VEL ) { Velocity = 0.0f; } } Position += Velocity * 0.016f; if( CurrentScrollState == BOUNCE_SCROLL ) { if( Velocity > 0.0f ) { Position = Alg::Clamp( Position, -ScrollBehavior.Padding, MaxPosition ); } else { Position = Alg::Clamp( Position, 0.0f, MaxPosition + ScrollBehavior.Padding ); } } else { Position = Alg::Clamp( Position, -ScrollBehavior.Padding, MaxPosition + ScrollBehavior.Padding ); } } }
void TBScroller::StopOrSnapScroll() { AdjustToSnappingAndScroll(0, 0); if (!IsScrolling()) Stop(); }