ScrollView API to stop overall scroll (#18552)

* ScrollView API to stop overall scroll

* ScrollView API to stop overall scroll

* ScrollView API to stop overall scroll

Cancel current touch handling after stopScroll() is called

* New test for scrolling stop in UIScrollView

* New test for scrolling stop in UIScrollView
This commit is contained in:
AIGRIND 2017-12-14 07:38:03 +02:00 committed by minggo
parent 9f15e34257
commit 45992aa80e
4 changed files with 230 additions and 5 deletions

View File

@ -116,6 +116,20 @@ void ScrollView::onEnter()
scheduleUpdate();
}
void ScrollView::onExit()
{
#if CC_ENABLE_SCRIPT_BINDING
if (_scriptType == kScriptTypeJavascript)
{
if (ScriptEngineManager::sendNodeEventToJSExtended(this, kNodeOnExit))
return;
}
#endif
Layout::onExit();
stopOverallScroll();
}
bool ScrollView::init()
{
if (Layout::init())
@ -482,12 +496,54 @@ void ScrollView::startAutoScroll(const Vec2& deltaMove, float timeInSec, bool at
}
}
void ScrollView::stopScroll()
{
if (_scrolling)
{
if (_verticalScrollBar != nullptr)
{
_verticalScrollBar->onTouchEnded();
}
if (_horizontalScrollBar != nullptr)
{
_horizontalScrollBar->onTouchEnded();
}
_scrolling = false;
_bePressed = false;
startBounceBackIfNeeded();
dispatchEvent(SCROLLVIEW_EVENT_SCROLLING_ENDED, EventType::SCROLLING_ENDED);
}
}
void ScrollView::stopAutoScroll()
{
_autoScrolling = false;
_autoScrollAttenuate = true;
_autoScrollTotalTime = 0;
_autoScrollAccumulatedTime = 0;
if (_autoScrolling)
{
if (_verticalScrollBar != nullptr)
{
_verticalScrollBar->onTouchEnded();
}
if (_horizontalScrollBar != nullptr)
{
_horizontalScrollBar->onTouchEnded();
}
_autoScrolling = false;
_autoScrollAttenuate = true;
_autoScrollTotalTime = 0;
_autoScrollAccumulatedTime = 0;
dispatchEvent(SCROLLVIEW_EVENT_AUTOSCROLL_ENDED, EventType::AUTOSCROLL_ENDED);
}
}
void ScrollView::stopOverallScroll()
{
stopScroll();
stopAutoScroll();
}
bool ScrollView::isNecessaryAutoScrollBrake()
@ -900,6 +956,9 @@ void ScrollView::handlePressLogic(Touch* /*touch*/)
void ScrollView::handleMoveLogic(Touch *touch)
{
if (!_bePressed)
return;
Vec3 currPt, prevPt;
if(!calculateCurrAndPrevTouchPoints(touch, &currPt, &prevPt))
{
@ -915,6 +974,9 @@ void ScrollView::handleMoveLogic(Touch *touch)
void ScrollView::handleReleaseLogic(Touch *touch)
{
if (!_bePressed)
return;
// Gather the last touch information when released
{
Vec3 currPt, prevPt;

View File

@ -160,11 +160,21 @@ public:
*/
Layout* getInnerContainer()const;
/**
* Immediately stops inner container scroll (auto scrolling is not affected).
*/
virtual void stopScroll();
/**
* Immediately stops inner container scroll initiated by any of the "scrollTo*" member functions
*/
virtual void stopAutoScroll();
/**
* Immediately stops inner container scroll if any.
*/
virtual void stopOverallScroll();
/**
* Scroll inner container to bottom boundary of scrollview.
* @param timeInSec Time in seconds.
@ -569,6 +579,11 @@ public:
*/
virtual void onEnter() override;
/**
* @lua NA
*/
virtual void onExit() override;
/**
* When a widget is in a layout, you could call this method to get the next focused widget within a specified direction.
* If the widget is not in a layout, it will return itself

View File

@ -15,6 +15,7 @@ UIScrollViewTests::UIScrollViewTests()
ADD_TEST_CASE(UIScrollViewDisableTest);
ADD_TEST_CASE(UIScrollViewInnerSize);
ADD_TEST_CASE(UIScrollViewTestEvents);
ADD_TEST_CASE(UIScrollViewStopScrollingTest);
}
// UIScrollViewTest_Vertical
@ -684,8 +685,10 @@ bool UIScrollViewInnerSize::init()
return false;
}
// UIScrollViewTestEvents
UIScrollViewTestEvents::UIScrollViewTestEvents()
: _displayValueLabel(nullptr)
: _displayValueLabel(nullptr)
{
}
@ -762,3 +765,131 @@ bool UIScrollViewTestEvents::init()
return false;
}
// UIScrollViewStopScrollingTest
UIScrollViewStopScrollingTest::UIScrollViewStopScrollingTest()
: _displayValueLabel(nullptr)
, _scrollView(nullptr)
, _remainingTime(0.0f)
{
}
bool UIScrollViewStopScrollingTest::init()
{
if (UIScene::init())
{
Size widgetSize = _widget->getContentSize();
// Add a label in which the time remaining till scrolling stop will be displayed.
_displayValueLabel = Text::create("Scrolling stop isn't scheduled", "fonts/Marker Felt.ttf", 32);
_displayValueLabel->setAnchorPoint(Vec2(0.5f, -1.0f));
_displayValueLabel->setPosition(Vec2(widgetSize.width / 2.0f, widgetSize.height / 2.0f + _displayValueLabel->getContentSize().height * 1.5f));
_uiLayer->addChild(_displayValueLabel);
// Add the alert
Text* alert = Text::create("Click the button and start to scroll", "fonts/Marker Felt.ttf", 30);
alert->setColor(Color3B(159, 168, 176));
alert->setPosition(Vec2(widgetSize.width / 2.0f, widgetSize.height / 2.0f - alert->getContentSize().height * 3.075f));
_uiLayer->addChild(alert);
Layout* root = static_cast<Layout*>(_uiLayer->getChildByTag(81));
Layout* background = static_cast<Layout*>(root->getChildByName("background_Panel"));
// Create the dragpanel
_scrollView = ui::ScrollView::create();
_scrollView->setDirection(ui::ScrollView::Direction::BOTH);
_scrollView->setTouchEnabled(true);
_scrollView->setBounceEnabled(true);
_scrollView->setBackGroundImageScale9Enabled(true);
_scrollView->setBackGroundImage("cocosui/green_edit.png");
_scrollView->setContentSize(Size(210, 122.5));
_scrollView->setScrollBarWidth(4);
_scrollView->setScrollBarPositionFromCorner(Vec2(6, 6));
Size backgroundSize = background->getContentSize();
_scrollView->setPosition(Vec2((widgetSize.width - backgroundSize.width) / 2.0f +
(backgroundSize.width - _scrollView->getContentSize().width) / 2.0f,
(widgetSize.height - backgroundSize.height) / 2.0f +
(backgroundSize.height - _scrollView->getContentSize().height) / 2.0f));
ImageView* imageView = ImageView::create("Hello.png");
_scrollView->addChild(imageView);
_scrollView->setInnerContainerSize(imageView->getContentSize());
Size innerSize = _scrollView->getInnerContainerSize();
imageView->setPosition(Vec2(innerSize.width / 2.0f, innerSize.height / 2.0f));
_uiLayer->addChild(_scrollView);
// Log some ScrollView events.
_scrollView->addEventListener([&] (Ref*, ui::ScrollView::EventType e)
{
switch (e)
{
case ui::ScrollView::EventType::SCROLLING_BEGAN:
CCLOG("scrolling began!");
break;
case ui::ScrollView::EventType::SCROLLING_ENDED:
CCLOG("scrolling ended!");
break;
case ui::ScrollView::EventType::AUTOSCROLL_ENDED:
CCLOG("auto-scrolling ended!");
break;
default: break;
}
});
// Jump to right bottom
_scrollView->jumpToBottomRight();
// Add button that will schedule scrolling stop when it is clicked.
Button* button_scale9 = Button::create("cocosui/button.png", "cocosui/buttonHighlighted.png");
button_scale9->setTitleText("Stop scrolling in 3 sec.");
button_scale9->setScale9Enabled(true);
button_scale9->setContentSize(Size(120.0f, button_scale9->getVirtualRendererSize().height));
button_scale9->setPosition(Vec2(innerSize.width / 2.0f, innerSize.height / 2.0f));
button_scale9->addClickEventListener([this] (Ref*) { this->_remainingTime = 3.0f; });
_scrollView->addChild(button_scale9);
// Schedule update for this scene.
Director::getInstance()->getScheduler()->scheduleUpdate(this, 0, false);
return true;
}
return false;
}
void UIScrollViewStopScrollingTest::update(float dt)
{
UIScene::update(dt);
if (_remainingTime > 0.0f)
{
_remainingTime -= dt;
if (_remainingTime > 0.0f)
{
// Update timer caption.
char strRemainingTime[100];
sprintf(strRemainingTime, "Stop scrolling in %.1f sec.", _remainingTime);
_displayValueLabel->setString(std::string(strRemainingTime));
}
else
{
_scrollView->stopOverallScroll();
// Update timer caption.
std::string strRemainingTime = "Scrolling stop isn't scheduled";
_displayValueLabel->setString(strRemainingTime);
// Show hint label.
auto hintLabel = Label::createWithTTF("Stopped!", "fonts/Marker Felt.ttf", 32.0f);
Size contentSize = _uiLayer->getContentSize();
hintLabel->setPosition(Vec2(contentSize.width / 2.0f, contentSize.height / 2.0f));
hintLabel->runAction(Spawn::createWithTwoActions(
FadeOut::create(0.3f),
ScaleTo::create(0.3f, 2.0f)
));
_uiLayer->addChild(hintLabel);
}
}
}

View File

@ -167,4 +167,21 @@ protected:
cocos2d::ui::Text* _displayValueLabel;
};
class UIScrollViewStopScrollingTest : public UIScene
{
public:
CREATE_FUNC(UIScrollViewStopScrollingTest);
UIScrollViewStopScrollingTest();
virtual bool init() override;
virtual void update(float dt) override;
protected:
cocos2d::ui::Text* _displayValueLabel;
cocos2d::ui::ScrollView* _scrollView;
float _remainingTime;
};
#endif /* defined(__TestCpp__UIScrollViewTest__) */