PurchaseBannerView.cpp 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359
  1. //
  2. // PurchaseBannerView.cpp
  3. // merge6
  4. //
  5. // Created by Black Homles on 2024/9/23.
  6. //
  7. #include "PurchaseBannerView.hpp"
  8. PurchaseBannerView* PurchaseBannerView::create(Size& viewSize, sDotCfg& dotCfg, bool cachePages,bool isHor) {
  9. PurchaseBannerView* ret = new PurchaseBannerView();
  10. ret->init(viewSize, dotCfg, cachePages, isHor);
  11. ret->autorelease();
  12. return ret;
  13. }
  14. void PurchaseBannerView::setDelegate(PurchaseBannerViewDelegate* delegate) {
  15. _pageViewDelegate = delegate;
  16. }
  17. void PurchaseBannerView::init(Size& viewSize, sDotCfg& dotCfg, bool cachePages, bool isHor) {
  18. Layer::init();
  19. _dotCfg = dotCfg;
  20. _viewSize = viewSize;
  21. _cachePages = cachePages;
  22. _isHori = isHor;
  23. _currentPageIndex = 0;
  24. _pageCount = 0;
  25. this->setContentSize(_viewSize);
  26. //get scrollview
  27. _scrollView = cocos2d::extension::ScrollView::create();
  28. _scrollView->setViewSize(_viewSize);
  29. if (isHor) {
  30. _scrollView->setDirection(cocos2d::extension::ScrollView::Direction::HORIZONTAL);
  31. } else {
  32. _scrollView->setDirection(cocos2d::extension::ScrollView::Direction::VERTICAL);
  33. }
  34. _scrollView->setBounceable(false);
  35. _scrollView->setDelegate(this);
  36. this->addChild(_scrollView);
  37. auto listener = EventListenerTouchOneByOne::create();
  38. listener->setSwallowTouches(true);
  39. listener->onTouchBegan = CC_CALLBACK_2(PurchaseBannerView::onTouchBegan,this);
  40. listener->onTouchMoved = CC_CALLBACK_2(PurchaseBannerView::onTouchMoved,this);
  41. listener->onTouchEnded = CC_CALLBACK_2(PurchaseBannerView::onTouchEnded,this);
  42. listener->onTouchCancelled = CC_CALLBACK_2(PurchaseBannerView::onTouchCancelled,this);
  43. Director::getInstance()->getEventDispatcher()->addEventListenerWithSceneGraphPriority(listener,this);
  44. }
  45. void PurchaseBannerView::_initDotInd() {
  46. if (!_initedDot) {
  47. _initedDot = true;
  48. if (_dotCfg.sepWidth != 0) {
  49. int sepWidth = _dotCfg.sepWidth;
  50. int yStart = _dotCfg.yStart;
  51. auto tmpSp = Sprite::createWithSpriteFrameName(_dotCfg.normalSp);
  52. int contentWidth = tmpSp->getContentSize().width;
  53. int xStart = (_viewSize.width - _pageCount * contentWidth - (_pageCount - 1) * sepWidth) / 2;
  54. for (int i = 0; i < _pageCount; i++) {
  55. tmpSp = Sprite::createWithSpriteFrameName(_dotCfg.normalSp);
  56. tmpSp->setPosition(Vec2(xStart + i * (contentWidth + sepWidth), yStart));
  57. this->addChild(tmpSp, 1);
  58. _dotSpArr.push_back(tmpSp);
  59. }
  60. _updateIndSp();
  61. }
  62. }
  63. }
  64. void PurchaseBannerView::_initDotAdded() {
  65. if (_dotSpArr.size() < _pageCount && _dotCfg.sepWidth != 0) {
  66. int sepWidth = _dotCfg.sepWidth;
  67. int yStart = _dotCfg.yStart;
  68. auto tmpSp = Sprite::createWithSpriteFrameName(_dotCfg.normalSp);
  69. int contentWidth = tmpSp->getContentSize().width;
  70. int xStart = (_viewSize.width - _pageCount * contentWidth - (_pageCount - 1) * sepWidth) / 2;
  71. for (int i = (int)_dotSpArr.size(); i < _pageCount; i++) {
  72. tmpSp = Sprite::createWithSpriteFrameName(_dotCfg.normalSp);
  73. tmpSp->setPosition(Vec2(xStart + i * (contentWidth + sepWidth), yStart));
  74. this->addChild(tmpSp, 1);
  75. _dotSpArr.push_back(tmpSp);
  76. }
  77. for (int i = 0; i < _dotSpArr.size(); i++) {
  78. tmpSp = _dotSpArr[i];
  79. tmpSp->setPosition(Vec2(xStart + i * (contentWidth + sepWidth), yStart));
  80. }
  81. _updateIndSp();
  82. }
  83. }
  84. void PurchaseBannerView::_updateIndSp() {
  85. if (_dotSpArr.size() > 0) {
  86. for (int i = 0; i < _pageCount; i++) {
  87. string spname = i == _currentPageIndex ? _dotCfg.highSp : _dotCfg.normalSp;
  88. _dotSpArr[i]->setSpriteFrame(spname);
  89. }
  90. }
  91. }
  92. void PurchaseBannerView::_resizeView() {
  93. if (_scrollView == nullptr) {
  94. return;
  95. }
  96. if (_isHori) {
  97. _scrollView->setContentSize(Size(_viewSize.width * _pageCount, _viewSize.height));
  98. _scrollView->setContentOffset(Vec2(-_currentPageIndex * _viewSize.width, 0));
  99. } else {
  100. _scrollView->setContentSize(Size(_viewSize.width, _viewSize.height * _pageCount));
  101. _scrollView->getContainer()->setPositionY(-_viewSize.height * (_pageCount - 1));
  102. _scrollView->setContentOffset(Vec2(0, -(_pageCount - 1 - _currentPageIndex) * _viewSize.height));
  103. }
  104. }
  105. void PurchaseBannerView::onEnter() {
  106. Layer::onEnter();
  107. _touchedCount = 0;
  108. _scrollView->setTouchEnabled(true);
  109. _scrollView->setSwallowTouches(false);
  110. }
  111. void PurchaseBannerView::onExit() {
  112. Layer::onExit();
  113. //log("PageView ~ onExit");
  114. }
  115. void PurchaseBannerView::addBanner(PurchaseBannerCell* tmpNode) {
  116. if (tmpNode == nullptr) {
  117. return;
  118. }
  119. _pageCount++;
  120. _currentPageIndex = 0;
  121. this->_resizeView();
  122. int addInIdx = _pageCount - 1;
  123. if (_isHori) {
  124. tmpNode->setPositionX(_viewSize.width * addInIdx);
  125. } else {
  126. tmpNode->setPositionY(_viewSize.height * (_pageCount - addInIdx - 1));
  127. }
  128. tmpNode->setAnchorPoint(Vec2(0,0));
  129. _scrollView->getContainer()->addChild(tmpNode,0,addInIdx);
  130. tmpNode->setIdx(addInIdx);
  131. this->_initDotAdded();
  132. }
  133. void PurchaseBannerView::reloadData(int pageCount, int defaultIndex) {
  134. _scrollView->getContainer()->removeAllChildren();
  135. _currentPageIndex = defaultIndex;
  136. _pageCount = pageCount;
  137. this->_resizeView();
  138. this->_generatePage();
  139. if (_pageViewDelegate != nullptr) {
  140. _pageViewDelegate->onPageChanged(_currentPageIndex, defaultIndex > 0);
  141. }
  142. this->_initDotInd();
  143. }
  144. void PurchaseBannerView::setCurrentPageIndex(int index) {
  145. if (index != _currentPageIndex && index >= 0 && index < _pageCount) {
  146. _currentPageIndex = index;
  147. this->_generatePage();
  148. this->_removeExpirePage();
  149. _scrollView->setContentOffset(Vec2(-_currentPageIndex * _viewSize.width, 0));
  150. this->_notifyPageChanged(true);
  151. }
  152. }
  153. PurchaseBannerCell* PurchaseBannerView::getCurrentPage() {
  154. return dynamic_cast<PurchaseBannerCell*>(_scrollView->getContainer()->getChildByTag(_currentPageIndex));
  155. }
  156. int PurchaseBannerView::getCurrentPageIdx() {
  157. return _currentPageIndex;
  158. }
  159. void PurchaseBannerView::moveToPrePage() {
  160. if (_currentPageIndex > 0) {
  161. --_currentPageIndex;
  162. this->_beginNewMoveToAnimation(0);
  163. }
  164. }
  165. void PurchaseBannerView::moveToNextPage() {
  166. if (_currentPageIndex < _pageCount - 1) {
  167. ++_currentPageIndex;
  168. this->_beginNewMoveToAnimation(0);
  169. }
  170. }
  171. void PurchaseBannerView::moveReferToPageIndex(int delta) {
  172. if (delta > 0 && _currentPageIndex + delta < _pageCount - 1) {
  173. _currentPageIndex += delta;
  174. this->_beginNewMoveToAnimation(0);
  175. } else if (delta < 0 && delta + _currentPageIndex >= 0) {
  176. _currentPageIndex += delta;
  177. this->_beginNewMoveToAnimation(0);
  178. }
  179. }
  180. void PurchaseBannerView::moveToFirstPage() {
  181. _currentPageIndex = 0;
  182. this->_beginNewMoveToAnimation(0);
  183. }
  184. int PurchaseBannerView::getPageCount() {
  185. return _pageCount;
  186. }
  187. void PurchaseBannerView::_generatePage() {
  188. if (_pageViewDelegate == nullptr || _cachePages) {
  189. return;
  190. }
  191. for (int i = _currentPageIndex - 1; i <= _currentPageIndex + 1; i++) {
  192. if (i >= 0 && i < _pageCount) {
  193. PurchaseBannerCell* page = dynamic_cast<PurchaseBannerCell*>(_scrollView->getContainer()->getChildByTag(i));
  194. if (page == nullptr) {
  195. page = _pageViewDelegate->pageCellAtIndex(this, i);
  196. if (_isHori) {
  197. page->setPositionX(_viewSize.width * i);
  198. } else {
  199. page->setPositionY(_viewSize.height * (_pageCount - i - 1));
  200. }
  201. _scrollView->getContainer()->addChild(page,0,i);
  202. page->setIdx(i);
  203. }
  204. }
  205. }
  206. }
  207. void PurchaseBannerView::_removeExpirePage() {
  208. if (_cachePages) {
  209. return;
  210. }
  211. int firstLeftPageIndex = _currentPageIndex - 2;
  212. int lastRightPageIndex = _currentPageIndex + 2;
  213. for (int i = 0; i <= firstLeftPageIndex; i++) {
  214. PurchaseBannerCell* page = dynamic_cast<PurchaseBannerCell*>(_scrollView->getContainer()->getChildByTag(i));
  215. if (page != nullptr) {
  216. _scrollView->getContainer()->removeChild(page);
  217. }
  218. }
  219. for (int i = lastRightPageIndex; i < _pageCount; i++) {
  220. PurchaseBannerCell* page = dynamic_cast<PurchaseBannerCell*>(_scrollView->getContainer()->getChildByTag(i));
  221. if (page != nullptr ) {
  222. _scrollView->getContainer()->removeChild(page);
  223. }
  224. }
  225. }
  226. void PurchaseBannerView::_beginNewMoveToAnimation(float dt) {
  227. _scrollView->unscheduleAllCallbacks();
  228. _scrollView->getContainer()->stopAllActions();
  229. if (_isHori) {
  230. _scrollView->setContentOffset(Vec2(-_currentPageIndex * _viewSize.width,0),true);
  231. } else {
  232. _scrollView->setContentOffset(Vec2(0,-(_pageCount - _currentPageIndex - 1) * _viewSize.height),true);
  233. }
  234. this->_generatePage();
  235. this->_removeExpirePage();
  236. auto thisnode = this;
  237. this->scheduleOnce([=](float dt){
  238. thisnode->_notifyPageChanged(false);
  239. },0.18,"notifyPageChanged");
  240. }
  241. void PurchaseBannerView::_notifyPageChanged(bool manualSet) {
  242. if (_pageViewDelegate != nullptr) {
  243. _pageViewDelegate->onPageChanged(_currentPageIndex, manualSet);
  244. }
  245. this->_updateIndSp();
  246. this->_autoSetBounceable();
  247. }
  248. void PurchaseBannerView::_autoSetBounceable() {
  249. if (_currentPageIndex == 0 || _currentPageIndex == _pageCount - 1) {
  250. _scrollView->setBounceable(true);
  251. } else {
  252. _scrollView->setBounceable(false);
  253. }
  254. }
  255. bool PurchaseBannerView::onTouchBegan(Touch* touch, Event* unused_event) {
  256. if (this->isTouchedInNode(this,touch)) {
  257. //log("PageView : onTouchBegan!");
  258. if (this->isTouchedInNode(_scrollView,touch,true,_scrollView->getViewSize())) {
  259. _touchedCount++;
  260. if (_touchedCount == 1) {
  261. _touchBeganPoint = touch->getLocation();
  262. this->_autoSetBounceable();
  263. if (_pageViewDelegate != nullptr) {
  264. _pageViewDelegate->onPageTouchBegan(touch);
  265. }
  266. return true;
  267. }
  268. }
  269. }
  270. return false;
  271. }
  272. void PurchaseBannerView::onTouchEnded(Touch* touch, Event* unused_event) {
  273. //log("PageView - onTouchEnded");
  274. Vec2 newPoint = touch->getLocation();
  275. if (_scrollViewMoved) {
  276. bool autoScroll = false;
  277. if (_isHori) {
  278. if (newPoint.x > _touchBeganPoint.x && _currentPageIndex > 0) {
  279. //<-
  280. _currentPageIndex--;
  281. autoScroll = true;
  282. } else if (newPoint.x < _touchBeganPoint.x && _currentPageIndex < _pageCount - 1) {
  283. //->
  284. _currentPageIndex++;
  285. autoScroll = true;
  286. }
  287. } else {
  288. if (newPoint.y < _touchBeganPoint.y && _currentPageIndex > 0) {
  289. //-/|\;
  290. _currentPageIndex--;
  291. autoScroll = true;
  292. } else if (newPoint.y > _touchBeganPoint.y && _currentPageIndex < _pageCount - 1) {
  293. //-\|/
  294. _currentPageIndex++;
  295. autoScroll = true;
  296. }
  297. }
  298. if (autoScroll) {
  299. _scrollView->setBounceable(false);
  300. this->scheduleOnce(CC_SCHEDULE_SELECTOR(PurchaseBannerView::_beginNewMoveToAnimation),0);
  301. }
  302. _scrollViewMoved = false;
  303. } else if (_touchedCount == 1) {
  304. if (this->isTouchedInNode(_scrollView,touch,true,_scrollView->getViewSize())) {
  305. PurchaseBannerCell* page = dynamic_cast<PurchaseBannerCell*>(_scrollView->getContainer()->getChildByTag(_currentPageIndex));
  306. if (_pageViewDelegate != nullptr) {
  307. _pageViewDelegate->pageCellTouched(touch, page);
  308. }
  309. }
  310. }
  311. _touchedCount = 0;
  312. }
  313. void PurchaseBannerView::scrollViewDidScroll(cocos2d::extension::ScrollView* view) {
  314. _scrollViewMoved = _scrollView->isTouchMoved();
  315. }
  316. bool PurchaseBannerView::isTouchedInNode(Node* node, Touch* touch, bool isAnotherSize, Vec2 anotherSize) {
  317. Size contentSize = Size::ZERO;
  318. if (isAnotherSize) {
  319. contentSize = Size(anotherSize.x,anotherSize.y);
  320. } else {
  321. contentSize = node->getContentSize();
  322. }
  323. Vec2 pos = node->convertTouchToNodeSpace(touch);
  324. if (pos.x >= 0 && pos.x <= contentSize.width) {
  325. if (pos.y >= 0 && pos.y <= contentSize.height) {
  326. return true;
  327. }
  328. }
  329. return false;
  330. }