2014-03-11 17:13:54 +08:00
|
|
|
/****************************************************************************
|
|
|
|
Copyright (c) 2013-2014 Chukong Technologies Inc.
|
|
|
|
|
|
|
|
http://www.cocos2d-x.org
|
|
|
|
|
|
|
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
|
|
of this software and associated documentation files (the "Software"), to deal
|
|
|
|
in the Software without restriction, including without limitation the rights
|
|
|
|
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
|
|
copies of the Software, and to permit persons to whom the Software is
|
|
|
|
furnished to do so, subject to the following conditions:
|
|
|
|
|
|
|
|
The above copyright notice and this permission notice shall be included in
|
|
|
|
all copies or substantial portions of the Software.
|
|
|
|
|
|
|
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
|
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
|
|
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
|
|
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
|
|
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
|
|
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
|
|
|
THE SOFTWARE.
|
|
|
|
****************************************************************************/
|
|
|
|
|
|
|
|
#include "ui/UIPageView.h"
|
|
|
|
|
|
|
|
NS_CC_BEGIN
|
|
|
|
|
|
|
|
namespace ui {
|
|
|
|
|
|
|
|
IMPLEMENT_CLASS_GUI_INFO(PageView)
|
|
|
|
|
|
|
|
PageView::PageView():
|
2014-10-30 22:25:46 +08:00
|
|
|
_isAutoScrolling(false),
|
|
|
|
_autoScrollDistance(0.0f),
|
|
|
|
_autoScrollSpeed(0.0f),
|
|
|
|
_autoScrollDirection(AutoScrollDirection::LEFT),
|
2015-08-01 18:18:46 +08:00
|
|
|
_direction(Direction::HORIZONTAL),
|
2015-07-17 10:39:01 +08:00
|
|
|
_curPageIdx(-1),
|
2014-05-22 09:56:42 +08:00
|
|
|
_touchMoveDirection(TouchDirection::LEFT),
|
|
|
|
_leftBoundaryChild(nullptr),
|
|
|
|
_rightBoundaryChild(nullptr),
|
2014-03-11 17:13:54 +08:00
|
|
|
_leftBoundary(0.0f),
|
|
|
|
_rightBoundary(0.0f),
|
2014-10-30 22:25:46 +08:00
|
|
|
_customScrollThreshold(0.0),
|
|
|
|
_usingCustomScrollThreshold(false),
|
2014-03-11 17:13:54 +08:00
|
|
|
_childFocusCancelOffset(5.0f),
|
|
|
|
_pageViewEventListener(nullptr),
|
2014-05-12 10:31:52 +08:00
|
|
|
_pageViewEventSelector(nullptr),
|
2014-10-30 22:25:46 +08:00
|
|
|
_eventCallback(nullptr)
|
2014-03-11 17:13:54 +08:00
|
|
|
{
|
2014-06-24 15:51:14 +08:00
|
|
|
this->setTouchEnabled(true);
|
2014-03-11 17:13:54 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
PageView::~PageView()
|
|
|
|
{
|
|
|
|
_pageViewEventListener = nullptr;
|
|
|
|
_pageViewEventSelector = nullptr;
|
|
|
|
}
|
|
|
|
|
|
|
|
PageView* PageView::create()
|
|
|
|
{
|
2014-08-28 07:31:57 +08:00
|
|
|
PageView* widget = new (std::nothrow) PageView();
|
2014-03-11 17:13:54 +08:00
|
|
|
if (widget && widget->init())
|
|
|
|
{
|
|
|
|
widget->autorelease();
|
|
|
|
return widget;
|
|
|
|
}
|
|
|
|
CC_SAFE_DELETE(widget);
|
|
|
|
return nullptr;
|
|
|
|
}
|
|
|
|
|
|
|
|
void PageView::onEnter()
|
|
|
|
{
|
2014-06-13 17:59:23 +08:00
|
|
|
#if CC_ENABLE_SCRIPT_BINDING
|
|
|
|
if (_scriptType == kScriptTypeJavascript)
|
|
|
|
{
|
2014-06-18 11:51:52 +08:00
|
|
|
if (ScriptEngineManager::sendNodeEventToJSExtended(this, kNodeOnEnter))
|
2014-06-13 17:59:23 +08:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
2014-03-11 17:13:54 +08:00
|
|
|
Layout::onEnter();
|
|
|
|
scheduleUpdate();
|
|
|
|
}
|
|
|
|
|
|
|
|
bool PageView::init()
|
|
|
|
{
|
|
|
|
if (Layout::init())
|
|
|
|
{
|
|
|
|
setClippingEnabled(true);
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
void PageView::addWidgetToPage(Widget *widget, ssize_t pageIdx, bool forceCreate)
|
|
|
|
{
|
2014-05-22 13:51:44 +08:00
|
|
|
if (!widget || pageIdx < 0)
|
2014-03-11 17:13:54 +08:00
|
|
|
{
|
|
|
|
return;
|
|
|
|
}
|
2014-05-22 13:51:44 +08:00
|
|
|
|
2014-05-21 18:30:25 +08:00
|
|
|
ssize_t pageCount = this->getPageCount();
|
2014-03-11 17:13:54 +08:00
|
|
|
if (pageIdx < 0 || pageIdx >= pageCount)
|
|
|
|
{
|
|
|
|
if (forceCreate)
|
|
|
|
{
|
|
|
|
if (pageIdx > pageCount)
|
|
|
|
{
|
|
|
|
CCLOG("pageIdx is %d, it will be added as page id [%d]",static_cast<int>(pageIdx),static_cast<int>(pageCount));
|
|
|
|
}
|
|
|
|
Layout* newPage = createPage();
|
|
|
|
newPage->addChild(widget);
|
|
|
|
addPage(newPage);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2014-05-22 11:43:02 +08:00
|
|
|
Node * page = _pages.at(pageIdx);
|
2014-03-11 17:13:54 +08:00
|
|
|
page->addChild(widget);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
Layout* PageView::createPage()
|
|
|
|
{
|
|
|
|
Layout* newPage = Layout::create();
|
2014-06-20 14:03:33 +08:00
|
|
|
newPage->setContentSize(getContentSize());
|
2014-03-11 17:13:54 +08:00
|
|
|
return newPage;
|
|
|
|
}
|
|
|
|
|
|
|
|
void PageView::addPage(Layout* page)
|
|
|
|
{
|
2014-05-22 13:51:44 +08:00
|
|
|
if (!page || _pages.contains(page))
|
2014-03-11 17:13:54 +08:00
|
|
|
{
|
|
|
|
return;
|
|
|
|
}
|
2014-05-22 13:51:44 +08:00
|
|
|
|
2014-05-21 16:07:33 +08:00
|
|
|
|
2014-07-05 12:53:56 +08:00
|
|
|
addChild(page);
|
2014-05-22 11:43:02 +08:00
|
|
|
_pages.pushBack(page);
|
2015-07-17 10:39:01 +08:00
|
|
|
if (_curPageIdx == -1)
|
|
|
|
{
|
|
|
|
_curPageIdx = 0;
|
|
|
|
}
|
2014-05-22 13:51:44 +08:00
|
|
|
_doLayoutDirty = true;
|
2014-03-11 17:13:54 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
void PageView::insertPage(Layout* page, int idx)
|
|
|
|
{
|
2014-05-22 13:51:44 +08:00
|
|
|
if (idx < 0 || !page || _pages.contains(page))
|
2014-03-11 17:13:54 +08:00
|
|
|
{
|
|
|
|
return;
|
|
|
|
}
|
2014-05-22 13:51:44 +08:00
|
|
|
|
2014-03-11 17:13:54 +08:00
|
|
|
|
2014-05-22 11:43:02 +08:00
|
|
|
ssize_t pageCount = this->getPageCount();
|
2014-03-11 17:13:54 +08:00
|
|
|
if (idx >= pageCount)
|
|
|
|
{
|
|
|
|
addPage(page);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2014-05-22 11:43:02 +08:00
|
|
|
_pages.insert(idx, page);
|
2014-07-05 12:53:56 +08:00
|
|
|
addChild(page);
|
2015-07-17 10:39:01 +08:00
|
|
|
if(_curPageIdx == -1)
|
|
|
|
{
|
|
|
|
_curPageIdx = 0;
|
|
|
|
}
|
2014-03-11 17:13:54 +08:00
|
|
|
}
|
2014-05-22 13:51:44 +08:00
|
|
|
|
|
|
|
_doLayoutDirty = true;
|
2014-03-11 17:13:54 +08:00
|
|
|
}
|
|
|
|
|
2015-07-16 16:50:47 +08:00
|
|
|
|
2014-03-11 17:13:54 +08:00
|
|
|
void PageView::removePage(Layout* page)
|
|
|
|
{
|
|
|
|
if (!page)
|
|
|
|
{
|
|
|
|
return;
|
|
|
|
}
|
2014-07-05 12:53:56 +08:00
|
|
|
removeChild(page);
|
2014-05-22 11:43:02 +08:00
|
|
|
_pages.eraseObject(page);
|
2015-07-17 10:39:01 +08:00
|
|
|
auto pageCount = _pages.size();
|
2015-07-16 16:50:47 +08:00
|
|
|
if (_curPageIdx >= pageCount)
|
|
|
|
{
|
|
|
|
_curPageIdx = pageCount - 1;
|
|
|
|
}
|
|
|
|
|
2014-05-22 13:51:44 +08:00
|
|
|
_doLayoutDirty = true;
|
2014-03-11 17:13:54 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
void PageView::removePageAtIndex(ssize_t index)
|
|
|
|
{
|
2014-05-21 18:30:25 +08:00
|
|
|
if (index < 0 || index >= this->getPages().size())
|
2014-03-11 17:13:54 +08:00
|
|
|
{
|
|
|
|
return;
|
|
|
|
}
|
2014-05-22 11:43:02 +08:00
|
|
|
Layout* page = _pages.at(index);
|
2014-03-11 17:13:54 +08:00
|
|
|
removePage(page);
|
|
|
|
}
|
|
|
|
|
|
|
|
void PageView::removeAllPages()
|
|
|
|
{
|
2014-05-27 11:20:04 +08:00
|
|
|
for(const auto& node : _pages)
|
2014-05-21 18:30:25 +08:00
|
|
|
{
|
2014-07-05 12:53:56 +08:00
|
|
|
removeChild(node);
|
2014-05-21 18:30:25 +08:00
|
|
|
}
|
2014-05-22 11:43:02 +08:00
|
|
|
_pages.clear();
|
2015-07-17 10:39:01 +08:00
|
|
|
_curPageIdx = -1;
|
2014-03-11 17:13:54 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
void PageView::updateBoundaryPages()
|
|
|
|
{
|
2014-05-22 11:43:02 +08:00
|
|
|
if (_pages.size() <= 0)
|
2014-03-11 17:13:54 +08:00
|
|
|
{
|
2014-05-22 09:56:42 +08:00
|
|
|
_leftBoundaryChild = nullptr;
|
|
|
|
_rightBoundaryChild = nullptr;
|
2014-03-11 17:13:54 +08:00
|
|
|
return;
|
|
|
|
}
|
2014-05-22 11:43:02 +08:00
|
|
|
_leftBoundaryChild = _pages.at(0);
|
|
|
|
_rightBoundaryChild = _pages.at(this->getPageCount()-1);
|
2014-05-21 18:30:25 +08:00
|
|
|
}
|
|
|
|
|
2014-05-27 10:44:31 +08:00
|
|
|
ssize_t PageView::getPageCount()const
|
2014-05-21 18:30:25 +08:00
|
|
|
{
|
2014-05-22 11:43:02 +08:00
|
|
|
return _pages.size();
|
2014-03-11 17:13:54 +08:00
|
|
|
}
|
|
|
|
|
2014-05-27 10:44:31 +08:00
|
|
|
float PageView::getPositionXByIndex(ssize_t idx)const
|
2014-03-11 17:13:54 +08:00
|
|
|
{
|
2014-06-20 11:18:53 +08:00
|
|
|
return (getContentSize().width * (idx-_curPageIdx));
|
2014-03-11 17:13:54 +08:00
|
|
|
}
|
2015-08-01 18:18:46 +08:00
|
|
|
|
|
|
|
float PageView::getPositionYByIndex(ssize_t idx)const
|
|
|
|
{
|
|
|
|
return (getContentSize().height * (idx-_curPageIdx));
|
|
|
|
}
|
2014-03-11 17:13:54 +08:00
|
|
|
|
|
|
|
void PageView::onSizeChanged()
|
|
|
|
{
|
|
|
|
Layout::onSizeChanged();
|
2015-08-01 18:18:46 +08:00
|
|
|
if (_direction == Direction::HORIZONTAL)
|
|
|
|
{
|
|
|
|
_rightBoundary = getContentSize().width;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
_rightBoundary = getContentSize().height;
|
|
|
|
}
|
2014-05-22 11:43:02 +08:00
|
|
|
|
2014-05-22 13:51:44 +08:00
|
|
|
_doLayoutDirty = true;
|
2014-03-11 17:13:54 +08:00
|
|
|
}
|
|
|
|
|
2014-05-22 11:43:02 +08:00
|
|
|
void PageView::updateAllPagesSize()
|
2014-03-11 17:13:54 +08:00
|
|
|
{
|
2014-06-20 11:18:53 +08:00
|
|
|
Size selfSize = getContentSize();
|
2014-05-22 11:43:02 +08:00
|
|
|
for (auto& page : _pages)
|
2014-03-11 17:13:54 +08:00
|
|
|
{
|
2014-06-20 14:03:33 +08:00
|
|
|
page->setContentSize(selfSize);
|
2014-03-11 17:13:54 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2014-05-22 11:43:02 +08:00
|
|
|
void PageView::updateAllPagesPosition()
|
2014-03-11 17:13:54 +08:00
|
|
|
{
|
2014-05-21 18:30:25 +08:00
|
|
|
ssize_t pageCount = this->getPageCount();
|
2014-05-22 13:51:44 +08:00
|
|
|
|
2014-03-11 17:13:54 +08:00
|
|
|
if (pageCount <= 0)
|
|
|
|
{
|
2015-07-17 10:39:01 +08:00
|
|
|
_curPageIdx = -1;
|
2014-03-11 17:13:54 +08:00
|
|
|
return;
|
|
|
|
}
|
2014-05-22 13:51:44 +08:00
|
|
|
|
2014-03-11 17:13:54 +08:00
|
|
|
if (_curPageIdx >= pageCount)
|
|
|
|
{
|
|
|
|
_curPageIdx = pageCount-1;
|
|
|
|
}
|
2015-07-16 16:50:47 +08:00
|
|
|
// If the layout is dirty, don't trigger auto scroll
|
|
|
|
_isAutoScrolling = false;
|
|
|
|
|
2015-08-01 23:33:25 +08:00
|
|
|
for (int i=0; i<pageCount; i++)
|
2014-03-11 17:13:54 +08:00
|
|
|
{
|
2015-08-01 23:33:25 +08:00
|
|
|
Layout* page = _pages.at(i);
|
|
|
|
Vec2 newPosition;
|
|
|
|
|
|
|
|
if (_direction == Direction::HORIZONTAL)
|
2015-08-01 18:18:46 +08:00
|
|
|
{
|
2015-08-01 23:33:25 +08:00
|
|
|
float pageWidth = getContentSize().width;
|
|
|
|
newPosition = Vec2((i-_curPageIdx) * pageWidth, 0);
|
2015-08-01 18:18:46 +08:00
|
|
|
}
|
2015-08-01 23:33:25 +08:00
|
|
|
else if(_direction == Direction::VERTICAL)
|
2015-08-01 18:18:46 +08:00
|
|
|
{
|
2015-08-01 23:33:25 +08:00
|
|
|
float pageHeight = getContentSize().height;
|
2015-08-03 11:38:23 +08:00
|
|
|
newPosition = Vec2(0,(i-_curPageIdx) * pageHeight * -1);
|
2015-08-01 23:33:25 +08:00
|
|
|
|
2015-08-01 18:18:46 +08:00
|
|
|
}
|
2015-08-01 23:33:25 +08:00
|
|
|
page->setPosition(newPosition);
|
2014-03-11 17:13:54 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2015-07-15 17:02:02 +08:00
|
|
|
void PageView::setCurPageIndex( ssize_t index )
|
|
|
|
{
|
|
|
|
if (index < 0 || index >= this->getPageCount())
|
|
|
|
{
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
_curPageIdx = index;
|
|
|
|
_doLayoutDirty = true;
|
|
|
|
}
|
2014-03-11 17:13:54 +08:00
|
|
|
|
|
|
|
void PageView::scrollToPage(ssize_t idx)
|
|
|
|
{
|
2014-05-21 18:30:25 +08:00
|
|
|
if (idx < 0 || idx >= this->getPageCount())
|
2014-03-11 17:13:54 +08:00
|
|
|
{
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
_curPageIdx = idx;
|
2014-05-22 11:43:02 +08:00
|
|
|
Layout* curPage = _pages.at(idx);
|
2015-08-01 18:18:46 +08:00
|
|
|
if (_direction == Direction::HORIZONTAL)
|
|
|
|
{
|
|
|
|
_autoScrollDistance = -(curPage->getPosition().x);
|
|
|
|
if (_autoScrollDistance > 0)
|
|
|
|
{
|
|
|
|
_autoScrollDirection = AutoScrollDirection::RIGHT;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
_autoScrollDirection = AutoScrollDirection::LEFT;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else if(_direction == Direction::VERTICAL)
|
|
|
|
{
|
2015-08-03 11:38:23 +08:00
|
|
|
_autoScrollDistance = -curPage->getPosition().y;
|
2015-08-01 18:18:46 +08:00
|
|
|
if (_autoScrollDistance > 0)
|
|
|
|
{
|
2015-08-03 11:38:23 +08:00
|
|
|
_autoScrollDirection = AutoScrollDirection::DOWN;
|
2015-08-01 18:18:46 +08:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2015-08-03 11:38:23 +08:00
|
|
|
_autoScrollDirection = AutoScrollDirection::UP;
|
2015-08-01 18:18:46 +08:00
|
|
|
}
|
|
|
|
}
|
2014-03-11 17:13:54 +08:00
|
|
|
_autoScrollSpeed = fabs(_autoScrollDistance)/0.2f;
|
|
|
|
_isAutoScrolling = true;
|
|
|
|
}
|
2015-08-01 18:18:46 +08:00
|
|
|
|
|
|
|
void PageView::setDirection(cocos2d::ui::PageView::Direction direction)
|
|
|
|
{
|
|
|
|
this->_direction = direction;
|
|
|
|
}
|
|
|
|
|
|
|
|
PageView::Direction PageView::getDirection()const
|
|
|
|
{
|
|
|
|
return this->_direction;
|
|
|
|
}
|
2014-03-11 17:13:54 +08:00
|
|
|
|
|
|
|
void PageView::update(float dt)
|
|
|
|
{
|
|
|
|
if (_isAutoScrolling)
|
|
|
|
{
|
2014-05-22 14:09:01 +08:00
|
|
|
this->autoScroll(dt);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void PageView::autoScroll(float dt)
|
|
|
|
{
|
2015-08-01 18:18:46 +08:00
|
|
|
float step = _autoScrollSpeed*dt;
|
|
|
|
int sign = 1;
|
2014-05-22 14:09:01 +08:00
|
|
|
switch (_autoScrollDirection)
|
2014-03-11 17:13:54 +08:00
|
|
|
{
|
2014-05-22 14:09:01 +08:00
|
|
|
case AutoScrollDirection::LEFT:
|
2015-08-03 11:38:23 +08:00
|
|
|
case AutoScrollDirection::UP:
|
2014-03-11 17:13:54 +08:00
|
|
|
{
|
|
|
|
if (_autoScrollDistance + step >= 0.0f)
|
|
|
|
{
|
|
|
|
step = -_autoScrollDistance;
|
|
|
|
_isAutoScrolling = false;
|
2015-08-01 18:18:46 +08:00
|
|
|
_autoScrollDistance = 0.0f;
|
2014-03-11 17:13:54 +08:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
_autoScrollDistance += step;
|
|
|
|
}
|
2015-08-01 18:18:46 +08:00
|
|
|
sign = -1;
|
2014-03-11 17:13:54 +08:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
break;
|
2014-05-22 14:09:01 +08:00
|
|
|
case AutoScrollDirection::RIGHT:
|
2015-08-03 11:38:23 +08:00
|
|
|
case AutoScrollDirection::DOWN:
|
2014-03-11 17:13:54 +08:00
|
|
|
{
|
|
|
|
if (_autoScrollDistance - step <= 0.0f)
|
|
|
|
{
|
|
|
|
step = _autoScrollDistance;
|
|
|
|
_autoScrollDistance = 0.0f;
|
|
|
|
_isAutoScrolling = false;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
_autoScrollDistance -= step;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
default:
|
|
|
|
break;
|
|
|
|
}
|
2015-08-01 18:18:46 +08:00
|
|
|
|
|
|
|
if (_direction == Direction::HORIZONTAL)
|
|
|
|
{
|
|
|
|
scrollPages(Vec2(step * sign, 0));
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
scrollPages(Vec2(0, step * sign));
|
|
|
|
}
|
2014-05-22 14:09:01 +08:00
|
|
|
|
2015-08-01 18:18:46 +08:00
|
|
|
if (!_isAutoScrolling)
|
|
|
|
{
|
|
|
|
pageTurningEvent();
|
|
|
|
}
|
2014-03-11 17:13:54 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
bool PageView::onTouchBegan(Touch *touch, Event *unusedEvent)
|
|
|
|
{
|
|
|
|
bool pass = Layout::onTouchBegan(touch, unusedEvent);
|
|
|
|
return pass;
|
|
|
|
}
|
|
|
|
|
|
|
|
void PageView::onTouchMoved(Touch *touch, Event *unusedEvent)
|
|
|
|
{
|
2014-08-15 15:28:28 +08:00
|
|
|
Layout::onTouchMoved(touch, unusedEvent);
|
|
|
|
if (!_isInterceptTouch)
|
2014-03-11 17:13:54 +08:00
|
|
|
{
|
2014-08-15 15:28:28 +08:00
|
|
|
handleMoveLogic(touch);
|
2014-03-11 17:13:54 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void PageView::onTouchEnded(Touch *touch, Event *unusedEvent)
|
|
|
|
{
|
|
|
|
Layout::onTouchEnded(touch, unusedEvent);
|
2014-08-15 15:28:28 +08:00
|
|
|
if (!_isInterceptTouch)
|
|
|
|
{
|
|
|
|
handleReleaseLogic(touch);
|
|
|
|
}
|
|
|
|
_isInterceptTouch = false;
|
2014-03-11 17:13:54 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
void PageView::onTouchCancelled(Touch *touch, Event *unusedEvent)
|
|
|
|
{
|
|
|
|
Layout::onTouchCancelled(touch, unusedEvent);
|
2014-08-15 15:28:28 +08:00
|
|
|
if (!_isInterceptTouch)
|
|
|
|
{
|
|
|
|
handleReleaseLogic(touch);
|
|
|
|
}
|
|
|
|
_isInterceptTouch = false;
|
2014-03-11 17:13:54 +08:00
|
|
|
}
|
|
|
|
|
2014-05-22 13:51:44 +08:00
|
|
|
void PageView::doLayout()
|
|
|
|
{
|
|
|
|
if (!_doLayoutDirty)
|
|
|
|
{
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
updateAllPagesPosition();
|
|
|
|
updateAllPagesSize();
|
|
|
|
updateBoundaryPages();
|
|
|
|
|
|
|
|
|
|
|
|
_doLayoutDirty = false;
|
|
|
|
}
|
|
|
|
|
2015-08-01 18:18:46 +08:00
|
|
|
void PageView::movePages(Vec2 offset)
|
2014-03-11 17:13:54 +08:00
|
|
|
{
|
2014-05-21 18:30:25 +08:00
|
|
|
for (auto& page : this->getPages())
|
2014-03-11 17:13:54 +08:00
|
|
|
{
|
2015-08-01 18:18:46 +08:00
|
|
|
Vec2 oldPosition = page->getPosition();
|
|
|
|
page->setPosition(oldPosition + offset);
|
2014-03-11 17:13:54 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2015-08-01 18:18:46 +08:00
|
|
|
bool PageView::scrollPages(Vec2 touchOffset)
|
2014-03-11 17:13:54 +08:00
|
|
|
{
|
2014-05-21 18:30:25 +08:00
|
|
|
if (this->getPageCount() <= 0)
|
2014-03-11 17:13:54 +08:00
|
|
|
{
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2014-05-22 09:56:42 +08:00
|
|
|
if (!_leftBoundaryChild || !_rightBoundaryChild)
|
2014-03-11 17:13:54 +08:00
|
|
|
{
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2015-08-01 18:18:46 +08:00
|
|
|
Vec2 realOffset = touchOffset;
|
2014-03-11 17:13:54 +08:00
|
|
|
|
2014-05-22 09:56:42 +08:00
|
|
|
switch (_touchMoveDirection)
|
2014-03-11 17:13:54 +08:00
|
|
|
{
|
2014-05-12 10:31:52 +08:00
|
|
|
case TouchDirection::LEFT: // left
|
2015-08-01 18:18:46 +08:00
|
|
|
if (_rightBoundaryChild->getRightBoundary() + touchOffset.x <= _rightBoundary)
|
2014-03-11 17:13:54 +08:00
|
|
|
{
|
2015-08-01 18:18:46 +08:00
|
|
|
realOffset.x = _rightBoundary - _rightBoundaryChild->getRightBoundary();
|
|
|
|
realOffset.y = 0;
|
2014-03-11 17:13:54 +08:00
|
|
|
movePages(realOffset);
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
|
2014-05-12 10:31:52 +08:00
|
|
|
case TouchDirection::RIGHT: // right
|
2015-08-01 18:18:46 +08:00
|
|
|
if (_leftBoundaryChild->getLeftBoundary() + touchOffset.x >= _leftBoundary)
|
2014-03-11 17:13:54 +08:00
|
|
|
{
|
2015-08-01 18:18:46 +08:00
|
|
|
realOffset.x = _leftBoundary - _leftBoundaryChild->getLeftBoundary();
|
|
|
|
realOffset.y = 0;
|
2014-03-11 17:13:54 +08:00
|
|
|
movePages(realOffset);
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
break;
|
2015-08-01 18:18:46 +08:00
|
|
|
case TouchDirection::UP:
|
|
|
|
{
|
2015-08-03 11:38:23 +08:00
|
|
|
if (_rightBoundaryChild->getBottomBoundary() + touchOffset.y >= _leftBoundary)
|
2015-08-01 18:18:46 +08:00
|
|
|
{
|
2015-08-03 11:38:23 +08:00
|
|
|
realOffset.y = _leftBoundary - _rightBoundaryChild->getBottomBoundary();
|
2015-08-01 18:18:46 +08:00
|
|
|
realOffset.x = 0;
|
|
|
|
movePages(realOffset);
|
|
|
|
return false;
|
|
|
|
}
|
2015-08-03 11:38:23 +08:00
|
|
|
|
2015-08-01 18:18:46 +08:00
|
|
|
}break;
|
|
|
|
case TouchDirection::DOWN:
|
|
|
|
{
|
2015-08-03 11:38:23 +08:00
|
|
|
if (_leftBoundaryChild->getTopBoundary() + touchOffset.y <= _rightBoundary)
|
2015-08-01 18:18:46 +08:00
|
|
|
{
|
2015-08-03 11:38:23 +08:00
|
|
|
realOffset.y = _rightBoundary - _leftBoundaryChild->getTopBoundary();
|
2015-08-01 18:18:46 +08:00
|
|
|
realOffset.x = 0;
|
|
|
|
movePages(realOffset);
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
}break;
|
2014-03-11 17:13:54 +08:00
|
|
|
default:
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
movePages(realOffset);
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2014-06-06 16:48:49 +08:00
|
|
|
void PageView::handleMoveLogic(Touch *touch)
|
2014-03-11 17:13:54 +08:00
|
|
|
{
|
2014-06-06 16:48:49 +08:00
|
|
|
Vec2 touchPoint = touch->getLocation();
|
|
|
|
|
2015-08-01 18:18:46 +08:00
|
|
|
Vec2 offset;
|
|
|
|
offset = touchPoint - touch->getPreviousLocation();
|
|
|
|
|
|
|
|
if (_direction == Direction::HORIZONTAL)
|
2014-03-11 17:13:54 +08:00
|
|
|
{
|
2015-08-01 18:18:46 +08:00
|
|
|
if (offset.x < 0)
|
|
|
|
{
|
|
|
|
_touchMoveDirection = TouchDirection::LEFT;
|
|
|
|
}
|
|
|
|
else if (offset.x > 0)
|
|
|
|
{
|
|
|
|
_touchMoveDirection = TouchDirection::RIGHT;
|
|
|
|
}
|
|
|
|
offset.y = 0;
|
2014-03-11 17:13:54 +08:00
|
|
|
}
|
2015-08-01 18:18:46 +08:00
|
|
|
else
|
2014-03-11 17:13:54 +08:00
|
|
|
{
|
2015-08-01 18:18:46 +08:00
|
|
|
offset.x = 0;
|
2015-08-03 11:38:23 +08:00
|
|
|
if(offset.y > 0)
|
2015-08-01 18:18:46 +08:00
|
|
|
{
|
2015-08-03 11:38:23 +08:00
|
|
|
_touchMoveDirection = TouchDirection::UP;
|
2015-08-01 18:18:46 +08:00
|
|
|
}
|
2015-08-03 11:38:23 +08:00
|
|
|
else if(offset.y < 0)
|
2015-08-01 18:18:46 +08:00
|
|
|
{
|
2015-08-03 11:38:23 +08:00
|
|
|
_touchMoveDirection = TouchDirection::DOWN;
|
2015-08-01 18:18:46 +08:00
|
|
|
}
|
2014-03-11 17:13:54 +08:00
|
|
|
}
|
2015-08-01 18:18:46 +08:00
|
|
|
|
2014-03-11 17:13:54 +08:00
|
|
|
scrollPages(offset);
|
|
|
|
}
|
2014-08-14 11:14:24 +08:00
|
|
|
|
|
|
|
void PageView::setCustomScrollThreshold(float threshold)
|
|
|
|
{
|
|
|
|
CCASSERT(threshold > 0, "Invalid threshold!");
|
|
|
|
_customScrollThreshold = threshold;
|
|
|
|
this->setUsingCustomScrollThreshold(true);
|
|
|
|
}
|
|
|
|
|
|
|
|
float PageView::getCustomScrollThreshold()const
|
|
|
|
{
|
|
|
|
return _customScrollThreshold;
|
|
|
|
}
|
|
|
|
|
|
|
|
void PageView::setUsingCustomScrollThreshold(bool flag)
|
|
|
|
{
|
2014-08-14 14:36:30 +08:00
|
|
|
_usingCustomScrollThreshold = flag;
|
2014-08-14 11:14:24 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
bool PageView::isUsingCustomScrollThreshold()const
|
|
|
|
{
|
2014-08-14 14:36:30 +08:00
|
|
|
return _usingCustomScrollThreshold;
|
2014-08-14 11:14:24 +08:00
|
|
|
}
|
2014-03-11 17:13:54 +08:00
|
|
|
|
2014-06-06 16:48:49 +08:00
|
|
|
void PageView::handleReleaseLogic(Touch *touch)
|
2014-03-11 17:13:54 +08:00
|
|
|
{
|
2014-05-22 11:43:02 +08:00
|
|
|
if (this->getPageCount() <= 0)
|
2014-03-11 17:13:54 +08:00
|
|
|
{
|
|
|
|
return;
|
|
|
|
}
|
2014-05-21 18:30:25 +08:00
|
|
|
Widget* curPage = dynamic_cast<Widget*>(this->getPages().at(_curPageIdx));
|
2014-03-11 17:13:54 +08:00
|
|
|
if (curPage)
|
|
|
|
{
|
2014-05-15 01:07:09 +08:00
|
|
|
Vec2 curPagePos = curPage->getPosition();
|
2014-05-22 11:43:02 +08:00
|
|
|
ssize_t pageCount = this->getPageCount();
|
2015-08-01 18:18:46 +08:00
|
|
|
|
|
|
|
auto contentSize = getContentSize();
|
2015-08-01 23:33:25 +08:00
|
|
|
|
2015-08-01 18:18:46 +08:00
|
|
|
float moveBoundray = 0.0f;
|
2015-08-01 23:33:25 +08:00
|
|
|
float scrollDistance;
|
2015-08-01 18:18:46 +08:00
|
|
|
if (_direction == Direction::HORIZONTAL)
|
|
|
|
{
|
|
|
|
curPagePos.y = 0;
|
|
|
|
moveBoundray = curPagePos.x;
|
2015-08-01 23:33:25 +08:00
|
|
|
scrollDistance = contentSize.width / 2.0;
|
2015-08-01 18:18:46 +08:00
|
|
|
}
|
2015-08-01 23:33:25 +08:00
|
|
|
else if(_direction == Direction::VERTICAL)
|
2015-08-01 18:18:46 +08:00
|
|
|
{
|
|
|
|
curPagePos.x = 0;
|
|
|
|
moveBoundray = curPagePos.y;
|
2015-08-01 23:33:25 +08:00
|
|
|
scrollDistance = contentSize.height / 2.0;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!_usingCustomScrollThreshold)
|
|
|
|
{
|
|
|
|
_customScrollThreshold = scrollDistance;
|
2015-08-01 18:18:46 +08:00
|
|
|
}
|
2015-08-01 23:33:25 +08:00
|
|
|
float boundary = _customScrollThreshold;
|
2015-08-01 18:18:46 +08:00
|
|
|
|
2015-08-03 11:38:23 +08:00
|
|
|
if (_direction == Direction::HORIZONTAL)
|
2014-03-11 17:13:54 +08:00
|
|
|
{
|
2015-08-03 11:38:23 +08:00
|
|
|
if (moveBoundray <= -boundary)
|
2014-03-11 17:13:54 +08:00
|
|
|
{
|
2015-08-03 11:38:23 +08:00
|
|
|
if (_curPageIdx >= pageCount-1)
|
|
|
|
{
|
|
|
|
scrollPages(curPagePos);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
scrollToPage(_curPageIdx+1);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else if (moveBoundray >= boundary)
|
|
|
|
{
|
|
|
|
if (_curPageIdx <= 0)
|
|
|
|
{
|
|
|
|
scrollPages(curPagePos);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
scrollToPage(_curPageIdx-1);
|
|
|
|
}
|
2014-03-11 17:13:54 +08:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2015-08-03 11:38:23 +08:00
|
|
|
scrollToPage(_curPageIdx);
|
2014-03-11 17:13:54 +08:00
|
|
|
}
|
|
|
|
}
|
2015-08-03 11:38:23 +08:00
|
|
|
else if(_direction == Direction::VERTICAL)
|
2014-03-11 17:13:54 +08:00
|
|
|
{
|
2015-08-03 11:38:23 +08:00
|
|
|
if (moveBoundray >= boundary)
|
|
|
|
{
|
|
|
|
if (_curPageIdx >= pageCount-1)
|
|
|
|
{
|
|
|
|
scrollPages(curPagePos);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
scrollToPage(_curPageIdx+1);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else if (moveBoundray <= -boundary)
|
2014-03-11 17:13:54 +08:00
|
|
|
{
|
2015-08-03 11:38:23 +08:00
|
|
|
if (_curPageIdx <= 0)
|
|
|
|
{
|
|
|
|
scrollPages(curPagePos);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
scrollToPage(_curPageIdx-1);
|
|
|
|
}
|
2014-03-11 17:13:54 +08:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2015-08-03 11:38:23 +08:00
|
|
|
scrollToPage(_curPageIdx);
|
2014-03-11 17:13:54 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2014-06-06 16:48:49 +08:00
|
|
|
void PageView::interceptTouchEvent(TouchEventType event, Widget *sender, Touch *touch)
|
2014-03-11 17:13:54 +08:00
|
|
|
{
|
2015-08-06 22:50:53 +08:00
|
|
|
if (!_touchEnabled)
|
|
|
|
{
|
|
|
|
Layout::interceptTouchEvent(event, sender, touch);
|
|
|
|
return;
|
|
|
|
}
|
2014-06-06 16:48:49 +08:00
|
|
|
Vec2 touchPoint = touch->getLocation();
|
|
|
|
|
2014-05-22 15:23:13 +08:00
|
|
|
switch (event)
|
2014-03-11 17:13:54 +08:00
|
|
|
{
|
2014-05-22 15:23:13 +08:00
|
|
|
case TouchEventType::BEGAN:
|
2014-08-15 15:28:28 +08:00
|
|
|
{
|
2014-08-19 15:14:07 +08:00
|
|
|
_touchBeganPosition = touch->getLocation();
|
2014-08-15 15:28:28 +08:00
|
|
|
_isInterceptTouch = true;
|
|
|
|
}
|
2015-08-01 18:18:46 +08:00
|
|
|
break;
|
2014-05-22 15:23:13 +08:00
|
|
|
case TouchEventType::MOVED:
|
2014-03-11 17:13:54 +08:00
|
|
|
{
|
|
|
|
float offset = 0;
|
2015-08-01 18:18:46 +08:00
|
|
|
if (_direction == Direction::HORIZONTAL)
|
|
|
|
{
|
|
|
|
offset = fabs(sender->getTouchBeganPosition().x - touchPoint.x);
|
|
|
|
}
|
|
|
|
else if(_direction == Direction::VERTICAL)
|
|
|
|
{
|
|
|
|
offset = fabs(sender->getTouchBeganPosition().y - touchPoint.y);
|
|
|
|
}
|
2014-08-19 15:14:07 +08:00
|
|
|
_touchMovePosition = touch->getLocation();
|
2014-03-11 17:13:54 +08:00
|
|
|
if (offset > _childFocusCancelOffset)
|
|
|
|
{
|
2014-05-06 12:04:52 +08:00
|
|
|
sender->setHighlighted(false);
|
2014-06-06 16:48:49 +08:00
|
|
|
handleMoveLogic(touch);
|
2014-03-11 17:13:54 +08:00
|
|
|
}
|
|
|
|
}
|
2015-08-01 18:18:46 +08:00
|
|
|
break;
|
2014-05-22 15:23:13 +08:00
|
|
|
case TouchEventType::CANCELED:
|
|
|
|
case TouchEventType::ENDED:
|
2014-08-15 15:28:28 +08:00
|
|
|
{
|
2014-08-19 15:14:07 +08:00
|
|
|
_touchEndPosition = touch->getLocation();
|
2014-06-06 16:48:49 +08:00
|
|
|
handleReleaseLogic(touch);
|
2014-08-15 15:28:28 +08:00
|
|
|
if (sender->isSwallowTouches())
|
|
|
|
{
|
|
|
|
_isInterceptTouch = false;
|
|
|
|
}
|
|
|
|
}
|
2014-03-11 17:13:54 +08:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void PageView::pageTurningEvent()
|
|
|
|
{
|
2014-08-01 20:58:42 +08:00
|
|
|
this->retain();
|
2014-03-11 17:13:54 +08:00
|
|
|
if (_pageViewEventListener && _pageViewEventSelector)
|
|
|
|
{
|
|
|
|
(_pageViewEventListener->*_pageViewEventSelector)(this, PAGEVIEW_EVENT_TURNING);
|
|
|
|
}
|
2014-12-16 16:44:04 +08:00
|
|
|
if (_eventCallback)
|
|
|
|
{
|
2014-05-12 10:31:52 +08:00
|
|
|
_eventCallback(this,EventType::TURNING);
|
|
|
|
}
|
2014-11-27 16:49:19 +08:00
|
|
|
if (_ccEventCallback)
|
|
|
|
{
|
|
|
|
_ccEventCallback(this, static_cast<int>(EventType::TURNING));
|
|
|
|
}
|
2014-08-01 20:58:42 +08:00
|
|
|
this->release();
|
2014-03-11 17:13:54 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
void PageView::addEventListenerPageView(Ref *target, SEL_PageViewEvent selector)
|
|
|
|
{
|
|
|
|
_pageViewEventListener = target;
|
|
|
|
_pageViewEventSelector = selector;
|
|
|
|
}
|
2014-05-12 10:31:52 +08:00
|
|
|
|
2014-05-14 16:14:28 +08:00
|
|
|
void PageView::addEventListener(const ccPageViewCallback& callback)
|
2014-05-12 10:31:52 +08:00
|
|
|
{
|
|
|
|
_eventCallback = callback;
|
|
|
|
}
|
2014-03-11 17:13:54 +08:00
|
|
|
|
|
|
|
ssize_t PageView::getCurPageIndex() const
|
|
|
|
{
|
|
|
|
return _curPageIdx;
|
|
|
|
}
|
|
|
|
|
2014-05-22 11:43:02 +08:00
|
|
|
Vector<Layout*>& PageView::getPages()
|
2014-03-11 17:13:54 +08:00
|
|
|
{
|
2014-05-22 11:43:02 +08:00
|
|
|
return _pages;
|
2014-03-11 17:13:54 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
Layout* PageView::getPage(ssize_t index)
|
|
|
|
{
|
2014-05-21 18:30:25 +08:00
|
|
|
if (index < 0 || index >= this->getPages().size())
|
2014-03-11 17:13:54 +08:00
|
|
|
{
|
|
|
|
return nullptr;
|
|
|
|
}
|
2014-05-22 13:51:44 +08:00
|
|
|
return _pages.at(index);
|
2014-03-11 17:13:54 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
std::string PageView::getDescription() const
|
|
|
|
{
|
|
|
|
return "PageView";
|
|
|
|
}
|
|
|
|
|
|
|
|
Widget* PageView::createCloneInstance()
|
|
|
|
{
|
|
|
|
return PageView::create();
|
|
|
|
}
|
|
|
|
|
|
|
|
void PageView::copyClonedWidgetChildren(Widget* model)
|
|
|
|
{
|
2014-05-21 16:07:33 +08:00
|
|
|
auto modelPages = static_cast<PageView*>(model)->getPages();
|
2014-03-11 17:13:54 +08:00
|
|
|
for (auto& page : modelPages)
|
|
|
|
{
|
2014-05-22 14:09:01 +08:00
|
|
|
addPage(static_cast<Layout*>(page->clone()));
|
2014-03-11 17:13:54 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void PageView::copySpecialProperties(Widget *widget)
|
|
|
|
{
|
|
|
|
PageView* pageView = dynamic_cast<PageView*>(widget);
|
|
|
|
if (pageView)
|
|
|
|
{
|
|
|
|
Layout::copySpecialProperties(widget);
|
2014-05-23 15:03:46 +08:00
|
|
|
_eventCallback = pageView->_eventCallback;
|
2014-11-27 16:49:19 +08:00
|
|
|
_ccEventCallback = pageView->_ccEventCallback;
|
2014-05-23 15:03:46 +08:00
|
|
|
_pageViewEventListener = pageView->_pageViewEventListener;
|
|
|
|
_pageViewEventSelector = pageView->_pageViewEventSelector;
|
2014-08-14 16:56:15 +08:00
|
|
|
_usingCustomScrollThreshold = pageView->_usingCustomScrollThreshold;
|
|
|
|
_customScrollThreshold = pageView->_customScrollThreshold;
|
2015-08-01 18:18:46 +08:00
|
|
|
_direction = pageView->_direction;
|
2014-03-11 17:13:54 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
NS_CC_END
|