|
@@ -0,0 +1,359 @@
|
|
|
+//
|
|
|
+// PurchaseBannerView.cpp
|
|
|
+// merge6
|
|
|
+//
|
|
|
+// Created by Black Homles on 2024/9/23.
|
|
|
+//
|
|
|
+
|
|
|
+#include "PurchaseBannerView.hpp"
|
|
|
+
|
|
|
+PurchaseBannerView* PurchaseBannerView::create(Size& viewSize, sDotCfg& dotCfg, bool cachePages,bool isHor) {
|
|
|
+ PurchaseBannerView* ret = new PurchaseBannerView();
|
|
|
+ ret->init(viewSize, dotCfg, cachePages, isHor);
|
|
|
+ ret->autorelease();
|
|
|
+ return ret;
|
|
|
+}
|
|
|
+
|
|
|
+void PurchaseBannerView::setDelegate(PurchaseBannerViewDelegate* delegate) {
|
|
|
+ _pageViewDelegate = delegate;
|
|
|
+}
|
|
|
+
|
|
|
+void PurchaseBannerView::init(Size& viewSize, sDotCfg& dotCfg, bool cachePages, bool isHor) {
|
|
|
+ Layer::init();
|
|
|
+ _dotCfg = dotCfg;
|
|
|
+ _viewSize = viewSize;
|
|
|
+ _cachePages = cachePages;
|
|
|
+ _isHori = isHor;
|
|
|
+ _currentPageIndex = 0;
|
|
|
+ _pageCount = 0;
|
|
|
+ this->setContentSize(_viewSize);
|
|
|
+ //get scrollview
|
|
|
+ _scrollView = cocos2d::extension::ScrollView::create();
|
|
|
+ _scrollView->setViewSize(_viewSize);
|
|
|
+ if (isHor) {
|
|
|
+ _scrollView->setDirection(cocos2d::extension::ScrollView::Direction::HORIZONTAL);
|
|
|
+ } else {
|
|
|
+ _scrollView->setDirection(cocos2d::extension::ScrollView::Direction::VERTICAL);
|
|
|
+ }
|
|
|
+ _scrollView->setBounceable(false);
|
|
|
+ _scrollView->setDelegate(this);
|
|
|
+ this->addChild(_scrollView);
|
|
|
+ auto listener = EventListenerTouchOneByOne::create();
|
|
|
+ listener->setSwallowTouches(true);
|
|
|
+ listener->onTouchBegan = CC_CALLBACK_2(PurchaseBannerView::onTouchBegan,this);
|
|
|
+ listener->onTouchMoved = CC_CALLBACK_2(PurchaseBannerView::onTouchMoved,this);
|
|
|
+ listener->onTouchEnded = CC_CALLBACK_2(PurchaseBannerView::onTouchEnded,this);
|
|
|
+ listener->onTouchCancelled = CC_CALLBACK_2(PurchaseBannerView::onTouchCancelled,this);
|
|
|
+ Director::getInstance()->getEventDispatcher()->addEventListenerWithSceneGraphPriority(listener,this);
|
|
|
+}
|
|
|
+
|
|
|
+void PurchaseBannerView::_initDotInd() {
|
|
|
+ if (!_initedDot) {
|
|
|
+ _initedDot = true;
|
|
|
+ if (_dotCfg.sepWidth != 0) {
|
|
|
+ int sepWidth = _dotCfg.sepWidth;
|
|
|
+ int yStart = _dotCfg.yStart;
|
|
|
+ auto tmpSp = Sprite::createWithSpriteFrameName(_dotCfg.normalSp);
|
|
|
+ int contentWidth = tmpSp->getContentSize().width;
|
|
|
+ int xStart = (_viewSize.width - _pageCount * contentWidth - (_pageCount - 1) * sepWidth) / 2;
|
|
|
+ for (int i = 0; i < _pageCount; i++) {
|
|
|
+ tmpSp = Sprite::createWithSpriteFrameName(_dotCfg.normalSp);
|
|
|
+ tmpSp->setPosition(Vec2(xStart + i * (contentWidth + sepWidth), yStart));
|
|
|
+ this->addChild(tmpSp, 1);
|
|
|
+ _dotSpArr.push_back(tmpSp);
|
|
|
+ }
|
|
|
+ _updateIndSp();
|
|
|
+ }
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+void PurchaseBannerView::_initDotAdded() {
|
|
|
+ if (_dotSpArr.size() < _pageCount && _dotCfg.sepWidth != 0) {
|
|
|
+ int sepWidth = _dotCfg.sepWidth;
|
|
|
+ int yStart = _dotCfg.yStart;
|
|
|
+ auto tmpSp = Sprite::createWithSpriteFrameName(_dotCfg.normalSp);
|
|
|
+ int contentWidth = tmpSp->getContentSize().width;
|
|
|
+ int xStart = (_viewSize.width - _pageCount * contentWidth - (_pageCount - 1) * sepWidth) / 2;
|
|
|
+ for (int i = (int)_dotSpArr.size(); i < _pageCount; i++) {
|
|
|
+ tmpSp = Sprite::createWithSpriteFrameName(_dotCfg.normalSp);
|
|
|
+ tmpSp->setPosition(Vec2(xStart + i * (contentWidth + sepWidth), yStart));
|
|
|
+ this->addChild(tmpSp, 1);
|
|
|
+ _dotSpArr.push_back(tmpSp);
|
|
|
+ }
|
|
|
+ for (int i = 0; i < _dotSpArr.size(); i++) {
|
|
|
+ tmpSp = _dotSpArr[i];
|
|
|
+ tmpSp->setPosition(Vec2(xStart + i * (contentWidth + sepWidth), yStart));
|
|
|
+ }
|
|
|
+ _updateIndSp();
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+void PurchaseBannerView::_updateIndSp() {
|
|
|
+ if (_dotSpArr.size() > 0) {
|
|
|
+ for (int i = 0; i < _pageCount; i++) {
|
|
|
+ string spname = i == _currentPageIndex ? _dotCfg.highSp : _dotCfg.normalSp;
|
|
|
+ _dotSpArr[i]->setSpriteFrame(spname);
|
|
|
+ }
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+void PurchaseBannerView::_resizeView() {
|
|
|
+ if (_scrollView == nullptr) {
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ if (_isHori) {
|
|
|
+ _scrollView->setContentSize(Size(_viewSize.width * _pageCount, _viewSize.height));
|
|
|
+ _scrollView->setContentOffset(Vec2(-_currentPageIndex * _viewSize.width, 0));
|
|
|
+ } else {
|
|
|
+ _scrollView->setContentSize(Size(_viewSize.width, _viewSize.height * _pageCount));
|
|
|
+ _scrollView->getContainer()->setPositionY(-_viewSize.height * (_pageCount - 1));
|
|
|
+ _scrollView->setContentOffset(Vec2(0, -(_pageCount - 1 - _currentPageIndex) * _viewSize.height));
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+void PurchaseBannerView::onEnter() {
|
|
|
+ Layer::onEnter();
|
|
|
+ _touchedCount = 0;
|
|
|
+ _scrollView->setTouchEnabled(true);
|
|
|
+ _scrollView->setSwallowTouches(false);
|
|
|
+}
|
|
|
+
|
|
|
+void PurchaseBannerView::onExit() {
|
|
|
+ Layer::onExit();
|
|
|
+ //log("PageView ~ onExit");
|
|
|
+}
|
|
|
+
|
|
|
+void PurchaseBannerView::addBanner(PurchaseBannerCell* tmpNode) {
|
|
|
+ if (tmpNode == nullptr) {
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ _pageCount++;
|
|
|
+ _currentPageIndex = 0;
|
|
|
+ this->_resizeView();
|
|
|
+ int addInIdx = _pageCount - 1;
|
|
|
+ if (_isHori) {
|
|
|
+ tmpNode->setPositionX(_viewSize.width * addInIdx);
|
|
|
+ } else {
|
|
|
+ tmpNode->setPositionY(_viewSize.height * (_pageCount - addInIdx - 1));
|
|
|
+ }
|
|
|
+ tmpNode->setAnchorPoint(Vec2(0,0));
|
|
|
+ _scrollView->getContainer()->addChild(tmpNode,0,addInIdx);
|
|
|
+ tmpNode->setIdx(addInIdx);
|
|
|
+ this->_initDotAdded();
|
|
|
+}
|
|
|
+
|
|
|
+void PurchaseBannerView::reloadData(int pageCount, int defaultIndex) {
|
|
|
+ _scrollView->getContainer()->removeAllChildren();
|
|
|
+ _currentPageIndex = defaultIndex;
|
|
|
+ _pageCount = pageCount;
|
|
|
+ this->_resizeView();
|
|
|
+ this->_generatePage();
|
|
|
+ if (_pageViewDelegate != nullptr) {
|
|
|
+ _pageViewDelegate->onPageChanged(_currentPageIndex, defaultIndex > 0);
|
|
|
+ }
|
|
|
+ this->_initDotInd();
|
|
|
+}
|
|
|
+
|
|
|
+void PurchaseBannerView::setCurrentPageIndex(int index) {
|
|
|
+ if (index != _currentPageIndex && index >= 0 && index < _pageCount) {
|
|
|
+ _currentPageIndex = index;
|
|
|
+ this->_generatePage();
|
|
|
+ this->_removeExpirePage();
|
|
|
+ _scrollView->setContentOffset(Vec2(-_currentPageIndex * _viewSize.width, 0));
|
|
|
+ this->_notifyPageChanged(true);
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+PurchaseBannerCell* PurchaseBannerView::getCurrentPage() {
|
|
|
+ return dynamic_cast<PurchaseBannerCell*>(_scrollView->getContainer()->getChildByTag(_currentPageIndex));
|
|
|
+}
|
|
|
+
|
|
|
+int PurchaseBannerView::getCurrentPageIdx() {
|
|
|
+ return _currentPageIndex;
|
|
|
+}
|
|
|
+
|
|
|
+void PurchaseBannerView::moveToPrePage() {
|
|
|
+ if (_currentPageIndex > 0) {
|
|
|
+ --_currentPageIndex;
|
|
|
+ this->_beginNewMoveToAnimation(0);
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+void PurchaseBannerView::moveToNextPage() {
|
|
|
+ if (_currentPageIndex < _pageCount - 1) {
|
|
|
+ ++_currentPageIndex;
|
|
|
+ this->_beginNewMoveToAnimation(0);
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+void PurchaseBannerView::moveReferToPageIndex(int delta) {
|
|
|
+ if (delta > 0 && _currentPageIndex + delta < _pageCount - 1) {
|
|
|
+ _currentPageIndex += delta;
|
|
|
+ this->_beginNewMoveToAnimation(0);
|
|
|
+ } else if (delta < 0 && delta + _currentPageIndex >= 0) {
|
|
|
+ _currentPageIndex += delta;
|
|
|
+ this->_beginNewMoveToAnimation(0);
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+void PurchaseBannerView::moveToFirstPage() {
|
|
|
+ _currentPageIndex = 0;
|
|
|
+ this->_beginNewMoveToAnimation(0);
|
|
|
+}
|
|
|
+
|
|
|
+int PurchaseBannerView::getPageCount() {
|
|
|
+ return _pageCount;
|
|
|
+}
|
|
|
+
|
|
|
+void PurchaseBannerView::_generatePage() {
|
|
|
+ if (_pageViewDelegate == nullptr || _cachePages) {
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ for (int i = _currentPageIndex - 1; i <= _currentPageIndex + 1; i++) {
|
|
|
+ if (i >= 0 && i < _pageCount) {
|
|
|
+ PurchaseBannerCell* page = dynamic_cast<PurchaseBannerCell*>(_scrollView->getContainer()->getChildByTag(i));
|
|
|
+ if (page == nullptr) {
|
|
|
+ page = _pageViewDelegate->pageCellAtIndex(this, i);
|
|
|
+ if (_isHori) {
|
|
|
+ page->setPositionX(_viewSize.width * i);
|
|
|
+ } else {
|
|
|
+ page->setPositionY(_viewSize.height * (_pageCount - i - 1));
|
|
|
+ }
|
|
|
+ _scrollView->getContainer()->addChild(page,0,i);
|
|
|
+ page->setIdx(i);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+void PurchaseBannerView::_removeExpirePage() {
|
|
|
+ if (_cachePages) {
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ int firstLeftPageIndex = _currentPageIndex - 2;
|
|
|
+ int lastRightPageIndex = _currentPageIndex + 2;
|
|
|
+ for (int i = 0; i <= firstLeftPageIndex; i++) {
|
|
|
+ PurchaseBannerCell* page = dynamic_cast<PurchaseBannerCell*>(_scrollView->getContainer()->getChildByTag(i));
|
|
|
+ if (page != nullptr) {
|
|
|
+ _scrollView->getContainer()->removeChild(page);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ for (int i = lastRightPageIndex; i < _pageCount; i++) {
|
|
|
+ PurchaseBannerCell* page = dynamic_cast<PurchaseBannerCell*>(_scrollView->getContainer()->getChildByTag(i));
|
|
|
+ if (page != nullptr ) {
|
|
|
+ _scrollView->getContainer()->removeChild(page);
|
|
|
+ }
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+void PurchaseBannerView::_beginNewMoveToAnimation(float dt) {
|
|
|
+ _scrollView->unscheduleAllCallbacks();
|
|
|
+ _scrollView->getContainer()->stopAllActions();
|
|
|
+ if (_isHori) {
|
|
|
+ _scrollView->setContentOffset(Vec2(-_currentPageIndex * _viewSize.width,0),true);
|
|
|
+ } else {
|
|
|
+ _scrollView->setContentOffset(Vec2(0,-(_pageCount - _currentPageIndex - 1) * _viewSize.height),true);
|
|
|
+ }
|
|
|
+ this->_generatePage();
|
|
|
+ this->_removeExpirePage();
|
|
|
+ auto thisnode = this;
|
|
|
+ this->scheduleOnce([=](float dt){
|
|
|
+ thisnode->_notifyPageChanged(false);
|
|
|
+ },0.18,"notifyPageChanged");
|
|
|
+}
|
|
|
+
|
|
|
+void PurchaseBannerView::_notifyPageChanged(bool manualSet) {
|
|
|
+ if (_pageViewDelegate != nullptr) {
|
|
|
+ _pageViewDelegate->onPageChanged(_currentPageIndex, manualSet);
|
|
|
+ }
|
|
|
+ this->_updateIndSp();
|
|
|
+ this->_autoSetBounceable();
|
|
|
+}
|
|
|
+
|
|
|
+void PurchaseBannerView::_autoSetBounceable() {
|
|
|
+ if (_currentPageIndex == 0 || _currentPageIndex == _pageCount - 1) {
|
|
|
+ _scrollView->setBounceable(true);
|
|
|
+ } else {
|
|
|
+ _scrollView->setBounceable(false);
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+bool PurchaseBannerView::onTouchBegan(Touch* touch, Event* unused_event) {
|
|
|
+ if (this->isTouchedInNode(this,touch)) {
|
|
|
+ //log("PageView : onTouchBegan!");
|
|
|
+ if (this->isTouchedInNode(_scrollView,touch,true,_scrollView->getViewSize())) {
|
|
|
+ _touchedCount++;
|
|
|
+ if (_touchedCount == 1) {
|
|
|
+ _touchBeganPoint = touch->getLocation();
|
|
|
+ this->_autoSetBounceable();
|
|
|
+ if (_pageViewDelegate != nullptr) {
|
|
|
+ _pageViewDelegate->onPageTouchBegan(touch);
|
|
|
+ }
|
|
|
+ return true;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ return false;
|
|
|
+}
|
|
|
+
|
|
|
+void PurchaseBannerView::onTouchEnded(Touch* touch, Event* unused_event) {
|
|
|
+ //log("PageView - onTouchEnded");
|
|
|
+ Vec2 newPoint = touch->getLocation();
|
|
|
+ if (_scrollViewMoved) {
|
|
|
+ bool autoScroll = false;
|
|
|
+ if (_isHori) {
|
|
|
+ if (newPoint.x > _touchBeganPoint.x && _currentPageIndex > 0) {
|
|
|
+ //<-
|
|
|
+ _currentPageIndex--;
|
|
|
+ autoScroll = true;
|
|
|
+ } else if (newPoint.x < _touchBeganPoint.x && _currentPageIndex < _pageCount - 1) {
|
|
|
+ //->
|
|
|
+ _currentPageIndex++;
|
|
|
+ autoScroll = true;
|
|
|
+ }
|
|
|
+ } else {
|
|
|
+ if (newPoint.y < _touchBeganPoint.y && _currentPageIndex > 0) {
|
|
|
+ //-/|\;
|
|
|
+ _currentPageIndex--;
|
|
|
+ autoScroll = true;
|
|
|
+ } else if (newPoint.y > _touchBeganPoint.y && _currentPageIndex < _pageCount - 1) {
|
|
|
+ //-\|/
|
|
|
+ _currentPageIndex++;
|
|
|
+ autoScroll = true;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ if (autoScroll) {
|
|
|
+ _scrollView->setBounceable(false);
|
|
|
+ this->scheduleOnce(CC_SCHEDULE_SELECTOR(PurchaseBannerView::_beginNewMoveToAnimation),0);
|
|
|
+ }
|
|
|
+ _scrollViewMoved = false;
|
|
|
+ } else if (_touchedCount == 1) {
|
|
|
+ if (this->isTouchedInNode(_scrollView,touch,true,_scrollView->getViewSize())) {
|
|
|
+ PurchaseBannerCell* page = dynamic_cast<PurchaseBannerCell*>(_scrollView->getContainer()->getChildByTag(_currentPageIndex));
|
|
|
+ if (_pageViewDelegate != nullptr) {
|
|
|
+ _pageViewDelegate->pageCellTouched(touch, page);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ _touchedCount = 0;
|
|
|
+}
|
|
|
+
|
|
|
+void PurchaseBannerView::scrollViewDidScroll(cocos2d::extension::ScrollView* view) {
|
|
|
+ _scrollViewMoved = _scrollView->isTouchMoved();
|
|
|
+}
|
|
|
+
|
|
|
+bool PurchaseBannerView::isTouchedInNode(Node* node, Touch* touch, bool isAnotherSize, Vec2 anotherSize) {
|
|
|
+ Size contentSize = Size::ZERO;
|
|
|
+ if (isAnotherSize) {
|
|
|
+ contentSize = Size(anotherSize.x,anotherSize.y);
|
|
|
+ } else {
|
|
|
+ contentSize = node->getContentSize();
|
|
|
+ }
|
|
|
+ Vec2 pos = node->convertTouchToNodeSpace(touch);
|
|
|
+ if (pos.x >= 0 && pos.x <= contentSize.width) {
|
|
|
+ if (pos.y >= 0 && pos.y <= contentSize.height) {
|
|
|
+ return true;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ return false;
|
|
|
+}
|