Skip to content

Commit 45992aa

Browse files
AIGRIND-LLCminggo
authored andcommitted
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
1 parent 9f15e34 commit 45992aa

File tree

4 files changed

+230
-5
lines changed

4 files changed

+230
-5
lines changed

cocos/ui/UIScrollView.cpp

Lines changed: 66 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -116,6 +116,20 @@ void ScrollView::onEnter()
116116
scheduleUpdate();
117117
}
118118

119+
void ScrollView::onExit()
120+
{
121+
#if CC_ENABLE_SCRIPT_BINDING
122+
if (_scriptType == kScriptTypeJavascript)
123+
{
124+
if (ScriptEngineManager::sendNodeEventToJSExtended(this, kNodeOnExit))
125+
return;
126+
}
127+
#endif
128+
129+
Layout::onExit();
130+
stopOverallScroll();
131+
}
132+
119133
bool ScrollView::init()
120134
{
121135
if (Layout::init())
@@ -482,12 +496,54 @@ void ScrollView::startAutoScroll(const Vec2& deltaMove, float timeInSec, bool at
482496
}
483497
}
484498

499+
void ScrollView::stopScroll()
500+
{
501+
if (_scrolling)
502+
{
503+
if (_verticalScrollBar != nullptr)
504+
{
505+
_verticalScrollBar->onTouchEnded();
506+
}
507+
if (_horizontalScrollBar != nullptr)
508+
{
509+
_horizontalScrollBar->onTouchEnded();
510+
}
511+
512+
_scrolling = false;
513+
_bePressed = false;
514+
515+
startBounceBackIfNeeded();
516+
517+
dispatchEvent(SCROLLVIEW_EVENT_SCROLLING_ENDED, EventType::SCROLLING_ENDED);
518+
}
519+
}
520+
485521
void ScrollView::stopAutoScroll()
486522
{
487-
_autoScrolling = false;
488-
_autoScrollAttenuate = true;
489-
_autoScrollTotalTime = 0;
490-
_autoScrollAccumulatedTime = 0;
523+
if (_autoScrolling)
524+
{
525+
if (_verticalScrollBar != nullptr)
526+
{
527+
_verticalScrollBar->onTouchEnded();
528+
}
529+
if (_horizontalScrollBar != nullptr)
530+
{
531+
_horizontalScrollBar->onTouchEnded();
532+
}
533+
534+
_autoScrolling = false;
535+
_autoScrollAttenuate = true;
536+
_autoScrollTotalTime = 0;
537+
_autoScrollAccumulatedTime = 0;
538+
539+
dispatchEvent(SCROLLVIEW_EVENT_AUTOSCROLL_ENDED, EventType::AUTOSCROLL_ENDED);
540+
}
541+
}
542+
543+
void ScrollView::stopOverallScroll()
544+
{
545+
stopScroll();
546+
stopAutoScroll();
491547
}
492548

493549
bool ScrollView::isNecessaryAutoScrollBrake()
@@ -900,6 +956,9 @@ void ScrollView::handlePressLogic(Touch* /*touch*/)
900956

901957
void ScrollView::handleMoveLogic(Touch *touch)
902958
{
959+
if (!_bePressed)
960+
return;
961+
903962
Vec3 currPt, prevPt;
904963
if(!calculateCurrAndPrevTouchPoints(touch, &currPt, &prevPt))
905964
{
@@ -915,6 +974,9 @@ void ScrollView::handleMoveLogic(Touch *touch)
915974

916975
void ScrollView::handleReleaseLogic(Touch *touch)
917976
{
977+
if (!_bePressed)
978+
return;
979+
918980
// Gather the last touch information when released
919981
{
920982
Vec3 currPt, prevPt;

cocos/ui/UIScrollView.h

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -160,11 +160,21 @@ class CC_GUI_DLL ScrollView : public Layout
160160
*/
161161
Layout* getInnerContainer()const;
162162

163+
/**
164+
* Immediately stops inner container scroll (auto scrolling is not affected).
165+
*/
166+
virtual void stopScroll();
167+
163168
/**
164169
* Immediately stops inner container scroll initiated by any of the "scrollTo*" member functions
165170
*/
166171
virtual void stopAutoScroll();
167172

173+
/**
174+
* Immediately stops inner container scroll if any.
175+
*/
176+
virtual void stopOverallScroll();
177+
168178
/**
169179
* Scroll inner container to bottom boundary of scrollview.
170180
* @param timeInSec Time in seconds.
@@ -569,6 +579,11 @@ class CC_GUI_DLL ScrollView : public Layout
569579
*/
570580
virtual void onEnter() override;
571581

582+
/**
583+
* @lua NA
584+
*/
585+
virtual void onExit() override;
586+
572587
/**
573588
* When a widget is in a layout, you could call this method to get the next focused widget within a specified direction.
574589
* If the widget is not in a layout, it will return itself

tests/cpp-tests/Classes/UITest/CocoStudioGUITest/UIScrollViewTest/UIScrollViewTest.cpp

Lines changed: 132 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ UIScrollViewTests::UIScrollViewTests()
1515
ADD_TEST_CASE(UIScrollViewDisableTest);
1616
ADD_TEST_CASE(UIScrollViewInnerSize);
1717
ADD_TEST_CASE(UIScrollViewTestEvents);
18+
ADD_TEST_CASE(UIScrollViewStopScrollingTest);
1819
}
1920
// UIScrollViewTest_Vertical
2021

@@ -684,8 +685,10 @@ bool UIScrollViewInnerSize::init()
684685
return false;
685686
}
686687

688+
// UIScrollViewTestEvents
689+
687690
UIScrollViewTestEvents::UIScrollViewTestEvents()
688-
: _displayValueLabel(nullptr)
691+
: _displayValueLabel(nullptr)
689692
{
690693

691694
}
@@ -762,3 +765,131 @@ bool UIScrollViewTestEvents::init()
762765
return false;
763766
}
764767

768+
// UIScrollViewStopScrollingTest
769+
770+
UIScrollViewStopScrollingTest::UIScrollViewStopScrollingTest()
771+
: _displayValueLabel(nullptr)
772+
, _scrollView(nullptr)
773+
, _remainingTime(0.0f)
774+
{
775+
776+
}
777+
778+
bool UIScrollViewStopScrollingTest::init()
779+
{
780+
if (UIScene::init())
781+
{
782+
Size widgetSize = _widget->getContentSize();
783+
784+
// Add a label in which the time remaining till scrolling stop will be displayed.
785+
_displayValueLabel = Text::create("Scrolling stop isn't scheduled", "fonts/Marker Felt.ttf", 32);
786+
_displayValueLabel->setAnchorPoint(Vec2(0.5f, -1.0f));
787+
_displayValueLabel->setPosition(Vec2(widgetSize.width / 2.0f, widgetSize.height / 2.0f + _displayValueLabel->getContentSize().height * 1.5f));
788+
_uiLayer->addChild(_displayValueLabel);
789+
790+
// Add the alert
791+
Text* alert = Text::create("Click the button and start to scroll", "fonts/Marker Felt.ttf", 30);
792+
alert->setColor(Color3B(159, 168, 176));
793+
alert->setPosition(Vec2(widgetSize.width / 2.0f, widgetSize.height / 2.0f - alert->getContentSize().height * 3.075f));
794+
_uiLayer->addChild(alert);
795+
796+
Layout* root = static_cast<Layout*>(_uiLayer->getChildByTag(81));
797+
798+
Layout* background = static_cast<Layout*>(root->getChildByName("background_Panel"));
799+
800+
// Create the dragpanel
801+
_scrollView = ui::ScrollView::create();
802+
_scrollView->setDirection(ui::ScrollView::Direction::BOTH);
803+
_scrollView->setTouchEnabled(true);
804+
_scrollView->setBounceEnabled(true);
805+
_scrollView->setBackGroundImageScale9Enabled(true);
806+
_scrollView->setBackGroundImage("cocosui/green_edit.png");
807+
_scrollView->setContentSize(Size(210, 122.5));
808+
_scrollView->setScrollBarWidth(4);
809+
_scrollView->setScrollBarPositionFromCorner(Vec2(6, 6));
810+
Size backgroundSize = background->getContentSize();
811+
_scrollView->setPosition(Vec2((widgetSize.width - backgroundSize.width) / 2.0f +
812+
(backgroundSize.width - _scrollView->getContentSize().width) / 2.0f,
813+
(widgetSize.height - backgroundSize.height) / 2.0f +
814+
(backgroundSize.height - _scrollView->getContentSize().height) / 2.0f));
815+
ImageView* imageView = ImageView::create("Hello.png");
816+
_scrollView->addChild(imageView);
817+
_scrollView->setInnerContainerSize(imageView->getContentSize());
818+
Size innerSize = _scrollView->getInnerContainerSize();
819+
imageView->setPosition(Vec2(innerSize.width / 2.0f, innerSize.height / 2.0f));
820+
_uiLayer->addChild(_scrollView);
821+
822+
// Log some ScrollView events.
823+
_scrollView->addEventListener([&] (Ref*, ui::ScrollView::EventType e)
824+
{
825+
switch (e)
826+
{
827+
case ui::ScrollView::EventType::SCROLLING_BEGAN:
828+
CCLOG("scrolling began!");
829+
break;
830+
case ui::ScrollView::EventType::SCROLLING_ENDED:
831+
CCLOG("scrolling ended!");
832+
break;
833+
case ui::ScrollView::EventType::AUTOSCROLL_ENDED:
834+
CCLOG("auto-scrolling ended!");
835+
break;
836+
default: break;
837+
}
838+
});
839+
840+
// Jump to right bottom
841+
_scrollView->jumpToBottomRight();
842+
843+
// Add button that will schedule scrolling stop when it is clicked.
844+
Button* button_scale9 = Button::create("cocosui/button.png", "cocosui/buttonHighlighted.png");
845+
button_scale9->setTitleText("Stop scrolling in 3 sec.");
846+
button_scale9->setScale9Enabled(true);
847+
button_scale9->setContentSize(Size(120.0f, button_scale9->getVirtualRendererSize().height));
848+
button_scale9->setPosition(Vec2(innerSize.width / 2.0f, innerSize.height / 2.0f));
849+
button_scale9->addClickEventListener([this] (Ref*) { this->_remainingTime = 3.0f; });
850+
_scrollView->addChild(button_scale9);
851+
852+
// Schedule update for this scene.
853+
Director::getInstance()->getScheduler()->scheduleUpdate(this, 0, false);
854+
855+
return true;
856+
}
857+
858+
return false;
859+
}
860+
861+
void UIScrollViewStopScrollingTest::update(float dt)
862+
{
863+
UIScene::update(dt);
864+
865+
if (_remainingTime > 0.0f)
866+
{
867+
_remainingTime -= dt;
868+
869+
if (_remainingTime > 0.0f)
870+
{
871+
// Update timer caption.
872+
char strRemainingTime[100];
873+
sprintf(strRemainingTime, "Stop scrolling in %.1f sec.", _remainingTime);
874+
_displayValueLabel->setString(std::string(strRemainingTime));
875+
}
876+
else
877+
{
878+
_scrollView->stopOverallScroll();
879+
880+
// Update timer caption.
881+
std::string strRemainingTime = "Scrolling stop isn't scheduled";
882+
_displayValueLabel->setString(strRemainingTime);
883+
884+
// Show hint label.
885+
auto hintLabel = Label::createWithTTF("Stopped!", "fonts/Marker Felt.ttf", 32.0f);
886+
Size contentSize = _uiLayer->getContentSize();
887+
hintLabel->setPosition(Vec2(contentSize.width / 2.0f, contentSize.height / 2.0f));
888+
hintLabel->runAction(Spawn::createWithTwoActions(
889+
FadeOut::create(0.3f),
890+
ScaleTo::create(0.3f, 2.0f)
891+
));
892+
_uiLayer->addChild(hintLabel);
893+
}
894+
}
895+
}

tests/cpp-tests/Classes/UITest/CocoStudioGUITest/UIScrollViewTest/UIScrollViewTest.h

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -167,4 +167,21 @@ class UIScrollViewTestEvents : public UIScene
167167

168168
cocos2d::ui::Text* _displayValueLabel;
169169
};
170+
171+
class UIScrollViewStopScrollingTest : public UIScene
172+
{
173+
public:
174+
CREATE_FUNC(UIScrollViewStopScrollingTest);
175+
176+
UIScrollViewStopScrollingTest();
177+
virtual bool init() override;
178+
179+
virtual void update(float dt) override;
180+
181+
protected:
182+
183+
cocos2d::ui::Text* _displayValueLabel;
184+
cocos2d::ui::ScrollView* _scrollView;
185+
float _remainingTime;
186+
};
170187
#endif /* defined(__TestCpp__UIScrollViewTest__) */

0 commit comments

Comments
 (0)