void ScrollView::setInnerContainerPosition(const Vec2 &position) { if(position == _innerContainer->getPosition()) { return; } _innerContainer->setPosition(position); _outOfBoundaryAmountDirty = true; // Process bouncing events if(_bounceEnabled) { for(int direction = (int) MoveDirection::TOP; direction < (int) MoveDirection::RIGHT; ++direction) { if(isOutOfBoundary((MoveDirection) direction)) { processScrollEvent((MoveDirection) direction, true); } } } this->retain(); if (_eventCallback) { _eventCallback(this, EventType::CONTAINER_MOVED); } if (_ccEventCallback) { _ccEventCallback(this, static_cast<int>(EventType::CONTAINER_MOVED)); } this->release(); }
void ScrollView::processAutoScrolling(float deltaTime) { _autoScrollAccumulatedTime += deltaTime; float percentage = _autoScrollAccumulatedTime / _autoScrollDuration; if(percentage >= 1) { moveChildrenToPosition(_autoScrollStartPosition + _autoScrollTargetDelta); _autoScrolling = false; _bouncingBack = false; } else { if(_autoScrollAttenuate) { percentage = tweenfunc::quintEaseOut(percentage); } Vec2 moveDelta = _autoScrollTargetDelta * percentage; moveChildrenToPosition(_autoScrollStartPosition + moveDelta); // Dispatch related events if bouncing if(_bouncingBack) { if(moveDelta.x > 0) { processScrollEvent(MoveDirection::RIGHT, true); } else if(moveDelta.x < 0) { processScrollEvent(MoveDirection::LEFT, true); } if(moveDelta.y > 0) { processScrollEvent(MoveDirection::TOP, true); } else if(moveDelta.y < 0) { processScrollEvent(MoveDirection::BOTTOM, true); } } } }
void ScrollView::scrollChildren(const Vec2& deltaMove) { Vec2 realMove = deltaMove; if(_bounceEnabled) { // If the position of the inner container is out of the boundary, the offsets should be divided by two. Vec2 outOfBoundary = getHowMuchOutOfBoundary(); realMove.x *= (outOfBoundary.x == 0 ? 1 : 0.5f); realMove.y *= (outOfBoundary.y == 0 ? 1 : 0.5f); } if(!_bounceEnabled) { Vec2 outOfBoundary = getHowMuchOutOfBoundary(realMove); realMove += outOfBoundary; } bool scrolledToLeft = false; bool scrolledToRight = false; bool scrolledToTop = false; bool scrolledToBottom = false; if (realMove.y > 0.0f) // up { float icBottomPos = _innerContainer->getBottomBoundary(); if (icBottomPos + realMove.y >= _bottomBoundary) { scrolledToBottom = true; } } else if (realMove.y < 0.0f) // down { float icTopPos = _innerContainer->getTopBoundary(); if (icTopPos + realMove.y <= _topBoundary) { scrolledToTop = true; } } if (realMove.x < 0.0f) // left { float icRightPos = _innerContainer->getRightBoundary(); if (icRightPos + realMove.x <= _rightBoundary) { scrolledToRight = true; } } else if (realMove.x > 0.0f) // right { float icLeftPos = _innerContainer->getLeftBoundary(); if (icLeftPos + realMove.x >= _leftBoundary) { scrolledToLeft = true; } } moveInnerContainer(realMove, false); if(realMove.x != 0 || realMove.y != 0) { processScrollingEvent(); } if(scrolledToBottom) { processScrollEvent(MoveDirection::BOTTOM, false); } if(scrolledToTop) { processScrollEvent(MoveDirection::TOP, false); } if(scrolledToLeft) { processScrollEvent(MoveDirection::LEFT, false); } if(scrolledToRight) { processScrollEvent(MoveDirection::RIGHT, false); } }
int WindowImplAndroid::processEvent(int fd, int events, void* data) { ActivityStates* states = getActivity(NULL); Lock lock(states->mutex); AInputEvent* _event = NULL; if (AInputQueue_getEvent(states->inputQueue, &_event) >= 0) { if (AInputQueue_preDispatchEvent(states->inputQueue, _event)) return 1; int handled = 0; int32_t type = AInputEvent_getType(_event); if (type == AINPUT_EVENT_TYPE_KEY) { int32_t action = AKeyEvent_getAction(_event); int32_t key = AKeyEvent_getKeyCode(_event); if ((action == AKEY_EVENT_ACTION_DOWN || action == AKEY_EVENT_ACTION_UP || action == AKEY_EVENT_ACTION_MULTIPLE) && key != AKEYCODE_VOLUME_UP && key != AKEYCODE_VOLUME_DOWN) { handled = processKeyEvent(_event, states); } } else if (type == AINPUT_EVENT_TYPE_MOTION) { int32_t action = AMotionEvent_getAction(_event); switch (action & AMOTION_EVENT_ACTION_MASK) { case AMOTION_EVENT_ACTION_SCROLL: { handled = processScrollEvent(_event, states); break; } // todo: should hover_move indeed trigger the event? // case AMOTION_EVENT_ACTION_HOVER_MOVE: case AMOTION_EVENT_ACTION_MOVE: { handled = processMotionEvent(_event, states); break; } // todo: investigate AMOTION_EVENT_OUTSIDE case AMOTION_EVENT_ACTION_POINTER_DOWN: case AMOTION_EVENT_ACTION_DOWN: { handled = processPointerEvent(true, _event, states); break; } case AMOTION_EVENT_ACTION_POINTER_UP: case AMOTION_EVENT_ACTION_UP: case AMOTION_EVENT_ACTION_CANCEL: { handled = processPointerEvent(false, _event, states); break; } } } AInputQueue_finishEvent(states->inputQueue, _event, handled); } return 1; }
bool ScrollView::scrollChildren(float touchOffsetX, float touchOffsetY) { touchOffsetX = (_direction == Direction::VERTICAL ? 0 : touchOffsetX); touchOffsetY = (_direction == Direction::HORIZONTAL ? 0 : touchOffsetY); if(_bounceEnabled) { // If the position of the inner container is out of the boundary, the offsets should be divided by two. touchOffsetX *= (isOutOfBoundaryLeftOrRight() ? 0.5f : 1); touchOffsetY *= (isOutOfBoundaryTopOrBottom() ? 0.5f : 1); } float realOffsetX = touchOffsetX; float realOffsetY = touchOffsetY; bool scrolledToLeft = false; bool scrolledToRight = false; bool scrolledToTop = false; bool scrolledToBottom = false; if (touchOffsetY > 0.0f) // up { float icBottomPos = _innerContainer->getBottomBoundary(); if (icBottomPos + touchOffsetY >= _bottomBoundary) { if(!_bounceEnabled) { realOffsetY = _bottomBoundary - icBottomPos; } scrolledToBottom = true; } } else if (touchOffsetY < 0.0f) // down { float icTopPos = _innerContainer->getTopBoundary(); if (icTopPos + touchOffsetY <= _topBoundary) { if(!_bounceEnabled) { realOffsetY = _topBoundary - icTopPos; } scrolledToTop = true; } } if (touchOffsetX < 0.0f) // left { float icRightPos = _innerContainer->getRightBoundary(); if (icRightPos + touchOffsetX <= _rightBoundary) { if(!_bounceEnabled) { realOffsetX = _rightBoundary - icRightPos; } scrolledToRight = true; } } else if (touchOffsetX > 0.0f) // right { float icLeftPos = _innerContainer->getLeftBoundary(); if (icLeftPos + touchOffsetX >= _leftBoundary) { if(!_bounceEnabled) { realOffsetX = _leftBoundary - icLeftPos; } scrolledToLeft = true; } } moveChildren(realOffsetX, realOffsetY); if(realOffsetX != 0 || realOffsetY != 0) { processScrollingEvent(); } if(scrolledToBottom) { processScrollEvent(MoveDirection::BOTTOM, false); } if(scrolledToTop) { processScrollEvent(MoveDirection::TOP, false); } if(scrolledToLeft) { processScrollEvent(MoveDirection::LEFT, false); } if(scrolledToRight) { processScrollEvent(MoveDirection::RIGHT, false); } bool scrollEnabledUpDown = (!scrolledToBottom && !scrolledToTop); bool scrollEnabledLeftRight = (!scrolledToLeft && !scrolledToRight); return scrollEnabledUpDown || scrollEnabledLeftRight; }