Merge pull request #14252 from neokim/change_pageview_to_derive_from_listview

Change PageView to derive from ListView
This commit is contained in:
zilongshanren 2015-11-17 12:02:10 +08:00
commit 5d8cfa889c
26 changed files with 870 additions and 1089 deletions

View File

@ -2072,6 +2072,10 @@
B5668D7E1B3838E4003CBD5E /* UIScrollViewBar.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B5668D7B1B3838E4003CBD5E /* UIScrollViewBar.cpp */; };
B5668D7F1B3838E4003CBD5E /* UIScrollViewBar.h in Headers */ = {isa = PBXBuildFile; fileRef = B5668D7C1B3838E4003CBD5E /* UIScrollViewBar.h */; };
B5668D801B3838E4003CBD5E /* UIScrollViewBar.h in Headers */ = {isa = PBXBuildFile; fileRef = B5668D7C1B3838E4003CBD5E /* UIScrollViewBar.h */; };
B5A738961BB0051F00BAAEF8 /* UIPageViewIndicator.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B5A738941BB0051F00BAAEF8 /* UIPageViewIndicator.cpp */; settings = {ASSET_TAGS = (); }; };
B5A738971BB0051F00BAAEF8 /* UIPageViewIndicator.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B5A738941BB0051F00BAAEF8 /* UIPageViewIndicator.cpp */; settings = {ASSET_TAGS = (); }; };
B5A738981BB0051F00BAAEF8 /* UIPageViewIndicator.h in Headers */ = {isa = PBXBuildFile; fileRef = B5A738951BB0051F00BAAEF8 /* UIPageViewIndicator.h */; settings = {ASSET_TAGS = (); }; };
B5A738991BB0051F00BAAEF8 /* UIPageViewIndicator.h in Headers */ = {isa = PBXBuildFile; fileRef = B5A738951BB0051F00BAAEF8 /* UIPageViewIndicator.h */; settings = {ASSET_TAGS = (); }; };
B5CE6DBE1B3BF2B1002B0419 /* UIAbstractCheckButton.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B5CE6DBC1B3BF2B1002B0419 /* UIAbstractCheckButton.cpp */; };
B5CE6DBF1B3BF2B1002B0419 /* UIAbstractCheckButton.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B5CE6DBC1B3BF2B1002B0419 /* UIAbstractCheckButton.cpp */; };
B5CE6DC01B3BF2B1002B0419 /* UIAbstractCheckButton.h in Headers */ = {isa = PBXBuildFile; fileRef = B5CE6DBD1B3BF2B1002B0419 /* UIAbstractCheckButton.h */; };
@ -4805,6 +4809,8 @@
B3AF019F1842FBA400A98B85 /* b2MotorJoint.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = b2MotorJoint.h; sourceTree = "<group>"; };
B5668D7B1B3838E4003CBD5E /* UIScrollViewBar.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = UIScrollViewBar.cpp; sourceTree = "<group>"; };
B5668D7C1B3838E4003CBD5E /* UIScrollViewBar.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = UIScrollViewBar.h; sourceTree = "<group>"; };
B5A738941BB0051F00BAAEF8 /* UIPageViewIndicator.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = UIPageViewIndicator.cpp; sourceTree = "<group>"; };
B5A738951BB0051F00BAAEF8 /* UIPageViewIndicator.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = UIPageViewIndicator.h; sourceTree = "<group>"; };
B5CE6DBC1B3BF2B1002B0419 /* UIAbstractCheckButton.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = UIAbstractCheckButton.cpp; sourceTree = "<group>"; };
B5CE6DBD1B3BF2B1002B0419 /* UIAbstractCheckButton.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = UIAbstractCheckButton.h; sourceTree = "<group>"; };
B5CE6DC61B3C05BA002B0419 /* UIRadioButton.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = UIRadioButton.cpp; sourceTree = "<group>"; };
@ -6971,6 +6977,8 @@
2905FA0118CF08D000240AA3 /* UILoadingBar.h */,
2905FA0218CF08D000240AA3 /* UIPageView.cpp */,
2905FA0318CF08D000240AA3 /* UIPageView.h */,
B5A738941BB0051F00BAAEF8 /* UIPageViewIndicator.cpp */,
B5A738951BB0051F00BAAEF8 /* UIPageViewIndicator.h */,
2905FA0418CF08D000240AA3 /* UIRichText.cpp */,
2905FA0518CF08D000240AA3 /* UIRichText.h */,
2905FA0718CF08D000240AA3 /* UIScrollView.cpp */,
@ -9481,6 +9489,7 @@
B665E3F41AA80A6600DDB1C5 /* CCPUSlaveEmitter.h in Headers */,
15AE1B6919AADA9900C27E9E /* UIDeprecated.h in Headers */,
1A570223180BCC1A0088DEC7 /* CCParticleBatchNode.h in Headers */,
B5A738981BB0051F00BAAEF8 /* UIPageViewIndicator.h in Headers */,
B6CAB53F1AF9AA1A00B9B856 /* cl_platform.h in Headers */,
15AE1A8319AAD40300C27E9E /* b2GearJoint.h in Headers */,
15AE1BD519AAE01E00C27E9E /* CCControlSaturationBrightnessPicker.h in Headers */,
@ -10984,6 +10993,7 @@
B665E2951AA80A6500DDB1C5 /* CCPUEmitter.h in Headers */,
B6CAB3BE1AF9AA1A00B9B856 /* btGeneric6DofSpringConstraint.h in Headers */,
B6CAB3521AF9AA1A00B9B856 /* gim_geometry.h in Headers */,
B5A738991BB0051F00BAAEF8 /* UIPageViewIndicator.h in Headers */,
15AE1BED19AAE01E00C27E9E /* CCControlColourPicker.h in Headers */,
15AE195019AAD35100C27E9E /* CCDatas.h in Headers */,
15AE18B319AAD33D00C27E9E /* CCBReader.h in Headers */,
@ -11169,6 +11179,7 @@
ED9C6A9418599AD8000A5232 /* CCNodeGrid.cpp in Sources */,
15AE1A2C19AAD3D500C27E9E /* b2DynamicTree.cpp in Sources */,
B665E36A1AA80A6500DDB1C5 /* CCPUOnVelocityObserver.cpp in Sources */,
B5A738961BB0051F00BAAEF8 /* UIPageViewIndicator.cpp in Sources */,
B665E3961AA80A6500DDB1C5 /* CCPUPointEmitter.cpp in Sources */,
15AE184019AAD2F700C27E9E /* CCSprite3D.cpp in Sources */,
B6CAB2E51AF9AA1A00B9B856 /* btSphereShape.cpp in Sources */,
@ -12644,6 +12655,7 @@
B665E1FB1AA80A6500DDB1C5 /* CCPUAffectorTranslator.cpp in Sources */,
B665E3931AA80A6500DDB1C5 /* CCPUPlaneColliderTranslator.cpp in Sources */,
382383F71A258FA7002C4610 /* idl_gen_fbs.cpp in Sources */,
B5A738971BB0051F00BAAEF8 /* UIPageViewIndicator.cpp in Sources */,
B665E24B1AA80A6500DDB1C5 /* CCPUColorAffector.cpp in Sources */,
B665E20F1AA80A6500DDB1C5 /* CCPUBaseForceAffector.cpp in Sources */,
15AE1B7419AADA9A00C27E9E /* UILoadingBar.cpp in Sources */,

View File

@ -652,6 +652,7 @@ xcopy /Y /Q "$(ProjectDir)..\..\external\chipmunk\prebuilt\win32\release-lib\*.*
<ClCompile Include="..\ui\UIListView.cpp" />
<ClCompile Include="..\ui\UILoadingBar.cpp" />
<ClCompile Include="..\ui\UIPageView.cpp" />
<ClCompile Include="..\ui\UIPageViewIndicator.cpp" />
<ClCompile Include="..\ui\UIRelativeBox.cpp" />
<ClCompile Include="..\ui\UIRichText.cpp" />
<ClCompile Include="..\ui\UIScale9Sprite.cpp" />

View File

@ -934,6 +934,9 @@
<ClCompile Include="..\ui\UIPageView.cpp">
<Filter>ui\UIWidgets\ScrollWidget</Filter>
</ClCompile>
<ClCompile Include="..\ui\UIPageViewIndicator.cpp">
<Filter>ui\UIWidgets\ScrollWidget</Filter>
</ClCompile>
<ClCompile Include="..\ui\UIScrollView.cpp">
<Filter>ui\UIWidgets\ScrollWidget</Filter>
</ClCompile>

View File

@ -1153,6 +1153,7 @@
<ClCompile Include="$(MSBuildThisFileDirectory)..\..\..\..\ui\UIListView.cpp" />
<ClCompile Include="$(MSBuildThisFileDirectory)..\..\..\..\ui\UILoadingBar.cpp" />
<ClCompile Include="$(MSBuildThisFileDirectory)..\..\..\..\ui\UIPageView.cpp" />
<ClCompile Include="$(MSBuildThisFileDirectory)..\..\..\..\ui\UIPageViewIndicator.cpp" />
<ClCompile Include="$(MSBuildThisFileDirectory)..\..\..\..\ui\UIRelativeBox.cpp" />
<ClCompile Include="$(MSBuildThisFileDirectory)..\..\..\..\ui\UIRichText.cpp" />
<ClCompile Include="$(MSBuildThisFileDirectory)..\..\..\..\ui\UIScale9Sprite.cpp" />

View File

@ -2325,6 +2325,9 @@
<ClCompile Include="$(MSBuildThisFileDirectory)..\..\..\..\ui\UIPageView.cpp">
<Filter>ui\UIWidgets\ScrollWidget</Filter>
</ClCompile>
<ClCompile Include="$(MSBuildThisFileDirectory)..\..\..\..\ui\UIPageViewIndicator.cpp">
<Filter>ui\UIWidgets\ScrollWidget</Filter>
</ClCompile>
<ClCompile Include="$(MSBuildThisFileDirectory)..\..\..\..\ui\UIScrollView.cpp">
<Filter>ui\UIWidgets\ScrollWidget</Filter>
</ClCompile>

View File

@ -653,6 +653,7 @@
<ClCompile Include="..\..\ui\UIListView.cpp" />
<ClCompile Include="..\..\ui\UILoadingBar.cpp" />
<ClCompile Include="..\..\ui\UIPageView.cpp" />
<ClCompile Include="..\..\ui\UIPageViewIndicator.cpp" />
<ClCompile Include="..\..\ui\UIRelativeBox.cpp" />
<ClCompile Include="..\..\ui\UIRichText.cpp" />
<ClCompile Include="..\..\ui\UIScale9Sprite.cpp" />

View File

@ -1689,6 +1689,9 @@
<ClCompile Include="..\..\ui\UIPageView.cpp">
<Filter>ui\UIWidgets\ScrollWidget</Filter>
</ClCompile>
<ClCompile Include="..\..\ui\UIPageViewIndicator.cpp">
<Filter>ui\UIWidgets\ScrollWidget</Filter>
</ClCompile>
<ClCompile Include="..\..\ui\UIScrollView.cpp">
<Filter>ui\UIWidgets\ScrollWidget</Filter>
</ClCompile>

View File

@ -30,10 +30,12 @@ THE SOFTWARE.
#include "base/CCDirector.h"
#include "base/CCAsyncTaskPool.h"
#include "base/CCEventDispatcher.h"
#include "base/base64.h"
#include "renderer/CCCustomCommand.h"
#include "renderer/CCRenderer.h"
#include "platform/CCImage.h"
#include "platform/CCFileUtils.h"
#include "2d/CCSprite.h"
NS_CC_BEGIN
@ -264,6 +266,27 @@ Rect getCascadeBoundingBox(Node *node)
return cbb;
}
Sprite* createSpriteFromBase64(const char* base64String)
{
unsigned char* decoded;
int length = base64Decode((const unsigned char*) base64String, (unsigned int) strlen(base64String), &decoded);
Image *image = new Image();
bool imageResult = image->initWithImageData(decoded, length);
CCASSERT(imageResult, "Failed to create image from base64!");
free(decoded);
Texture2D *texture = new Texture2D();
texture->initWithImage(image);
texture->setAliasTexParameters();
image->release();
Sprite* sprite = Sprite::createWithTexture(texture);
texture->release();
return sprite;
}
}
NS_CC_END

View File

@ -52,6 +52,8 @@ Examples:
int ccNextPOT(int value);
class Sprite;
namespace utils
{
/** Capture the entire screen.
@ -100,6 +102,14 @@ namespace utils
* @return Returns unionof bounding box of a node and its children.
*/
Rect CC_DLL getCascadeBoundingBox(Node *node);
/**
* Create a sprite instance from base64 encoded image.
* @return Returns an instance of sprite
*/
Sprite* createSpriteFromBase64(const char* base64String);
}
NS_CC_END

View File

@ -18,6 +18,7 @@ CocosGUI.cpp \
UIHelper.cpp \
UIListView.cpp \
UIPageView.cpp \
UIPageViewIndicator.cpp \
UIScrollView.cpp \
UIScrollViewBar.cpp \
UIButton.cpp \

View File

@ -38,6 +38,7 @@ set(COCOS_UI_SRC
ui/UIListView.cpp
ui/UILoadingBar.cpp
ui/UIPageView.cpp
ui/UIPageViewIndicator.cpp
ui/UIRelativeBox.cpp
ui/UIRichText.cpp
ui/UIScale9Sprite.cpp

View File

@ -72,7 +72,7 @@ bool ListView::init()
{
if (ScrollView::init())
{
setLayoutType(Type::VERTICAL);
setDirection(Direction::VERTICAL);
return true;
}
return false;
@ -100,6 +100,11 @@ void ListView::handleReleaseLogic(Touch *touch)
}
}
void ListView::onItemListChanged()
{
_outOfBoundaryAmountDirty = true;
}
void ListView::updateInnerContainerSize()
{
switch (_direction)
@ -263,7 +268,7 @@ void ListView::addChild(cocos2d::Node *child, int zOrder, int tag)
if (nullptr != widget)
{
_items.pushBack(widget);
_outOfBoundaryAmountDirty = true;
onItemListChanged();
}
}
@ -285,7 +290,7 @@ void ListView::addChild(Node* child, int zOrder, const std::string &name)
if (nullptr != widget)
{
_items.pushBack(widget);
_outOfBoundaryAmountDirty = true;
onItemListChanged();
}
}
@ -307,7 +312,7 @@ void ListView::removeChild(cocos2d::Node *child, bool cleaup)
}
}
_items.eraseObject(widget);
_outOfBoundaryAmountDirty = true;
onItemListChanged();
}
ScrollView::removeChild(child, cleaup);
@ -321,9 +326,9 @@ void ListView::removeAllChildren()
void ListView::removeAllChildrenWithCleanup(bool cleanup)
{
ScrollView::removeAllChildrenWithCleanup(cleanup);
_items.clear();
_curSelectedIndex = -1;
_outOfBoundaryAmountDirty = true;
_items.clear();
onItemListChanged();
}
void ListView::insertCustomItem(Widget* item, ssize_t index)
@ -336,7 +341,7 @@ void ListView::insertCustomItem(Widget* item, ssize_t index)
}
}
_items.insert(index, item);
_outOfBoundaryAmountDirty = true;
onItemListChanged();
ScrollView::addChild(item);
@ -479,8 +484,8 @@ void ListView::doLayout()
item->setLocalZOrder(i);
remedyLayoutParameter(item);
}
_innerContainer->forceDoLayout();
updateInnerContainerSize();
_innerContainer->forceDoLayout();
_innerContainerDoLayoutDirty = false;
}
@ -738,8 +743,9 @@ void ListView::jumpToPercentBothDirection(const Vec2& percent)
ScrollView::jumpToPercentBothDirection(percent);
}
static Vec2 calculateItemDestination(const Size& contentSize, Widget* item, const Vec2& positionRatioInView, const Vec2& itemAnchorPoint)
Vec2 ListView::calculateItemDestination(const Vec2& positionRatioInView, Widget* item, const Vec2& itemAnchorPoint)
{
const Size& contentSize = getContentSize();
Vec2 positionInView;
positionInView.x += contentSize.width * positionRatioInView.x;
positionInView.y += contentSize.height * positionRatioInView.y;
@ -748,7 +754,7 @@ static Vec2 calculateItemDestination(const Size& contentSize, Widget* item, cons
return -(itemPosition - positionInView);
}
void ListView::jumpToItem(int itemIndex, const Vec2& positionRatioInView, const Vec2& itemAnchorPoint)
void ListView::jumpToItem(ssize_t itemIndex, const Vec2& positionRatioInView, const Vec2& itemAnchorPoint)
{
Widget* item = getItem(itemIndex);
if (item == nullptr)
@ -757,27 +763,29 @@ void ListView::jumpToItem(int itemIndex, const Vec2& positionRatioInView, const
}
doLayout();
Vec2 destination = calculateItemDestination(getContentSize(), item, positionRatioInView, itemAnchorPoint);
destination = flattenVectorByDirection(destination);
Vec2 destination = calculateItemDestination(positionRatioInView, item, itemAnchorPoint);
if(!_bounceEnabled)
{
Vec2 delta = destination - getInnerContainerPosition();
Vec2 outOfBoundary = getHowMuchOutOfBoundary(delta);
destination += outOfBoundary;
moveChildrenToPosition(destination);
}
jumpToDestination(destination);
}
void ListView::scrollToItem(int itemIndex, const Vec2& positionRatioInView, const Vec2& itemAnchorPoint)
void ListView::scrollToItem(ssize_t itemIndex, const Vec2& positionRatioInView, const Vec2& itemAnchorPoint)
{
scrollToItem(itemIndex, positionRatioInView, itemAnchorPoint, DEFAULT_TIME_IN_SEC_FOR_SCROLL_TO_ITEM);
}
void ListView::scrollToItem(int itemIndex, const Vec2& positionRatioInView, const Vec2& itemAnchorPoint, float timeInSec)
void ListView::scrollToItem(ssize_t itemIndex, const Vec2& positionRatioInView, const Vec2& itemAnchorPoint, float timeInSec)
{
Widget* item = getItem(itemIndex);
if (item == nullptr)
{
return;
}
Vec2 destination = calculateItemDestination(getContentSize(), item, positionRatioInView, itemAnchorPoint);
Vec2 destination = calculateItemDestination(positionRatioInView, item, itemAnchorPoint);
startAutoScrollToDestination(destination, timeInSec, true);
}
@ -847,7 +855,7 @@ Vec2 ListView::getHowMuchOutOfBoundary(const Vec2& addition)
float topBoundary = _topBoundary;
float bottomBoundary = _bottomBoundary;
{
int lastItemIndex = _items.size() - 1;
ssize_t lastItemIndex = _items.size() - 1;
Size contentSize = getContentSize();
Vec2 firstItemAdjustment, lastItemAdjustment;
if(_magneticType == MagneticType::CENTER)

View File

@ -173,7 +173,6 @@ public:
*/
void removeItem(ssize_t index);
/**
* @brief Remove all items in current ListView.
*
@ -326,7 +325,7 @@ public:
* @param positionRatioInView Specifies the position with ratio in list view's content size.
* @param itemAnchorPoint Specifies an anchor point of each item for position to calculate distance.
*/
void jumpToItem(int itemIndex, const Vec2& positionRatioInView, const Vec2& itemAnchorPoint);
void jumpToItem(ssize_t itemIndex, const Vec2& positionRatioInView, const Vec2& itemAnchorPoint);
/**
* @brief Scroll to specific item
@ -334,8 +333,8 @@ public:
* @param itemAnchorPoint Specifies an anchor point of each item for position to calculate distance.
* @param timeInSec Scroll time
*/
void scrollToItem(int itemIndex, const Vec2& positionRatioInView, const Vec2& itemAnchorPoint);
void scrollToItem(int itemIndex, const Vec2& positionRatioInView, const Vec2& itemAnchorPoint, float timeInSec);
void scrollToItem(ssize_t itemIndex, const Vec2& positionRatioInView, const Vec2& itemAnchorPoint);
void scrollToItem(ssize_t itemIndex, const Vec2& positionRatioInView, const Vec2& itemAnchorPoint, float timeInSec);
/**
* @brief Query current selected widget's idnex.
@ -389,6 +388,8 @@ CC_CONSTRUCTOR_ACCESS:
protected:
virtual void handleReleaseLogic(Touch *touch) override;
virtual void onItemListChanged();
void updateInnerContainerSize();
void remedyLayoutParameter(Widget* item);
void remedyVerticalLayoutParameter(LinearLayoutParameter* layoutParameter, ssize_t itemIndex);
@ -406,6 +407,7 @@ protected:
virtual void startAttenuatingAutoScroll(const Vec2& deltaMove, const Vec2& initialVelocity) override;
void startMagneticScroll();
Vec2 calculateItemDestination(const Vec2& positionRatioInView, Widget* item, const Vec2& itemAnchorPoint);
protected:
Widget* _model;

View File

@ -23,6 +23,7 @@ THE SOFTWARE.
****************************************************************************/
#include "ui/UIPageView.h"
#include "ui/UIPageViewIndicator.h"
NS_CC_BEGIN
@ -31,25 +32,14 @@ namespace ui {
IMPLEMENT_CLASS_GUI_INFO(PageView)
PageView::PageView():
_isAutoScrolling(false),
_autoScrollDistance(0.0f),
_autoScrollSpeed(0.0f),
_autoScrollDirection(AutoScrollDirection::LEFT),
_direction(Direction::HORIZONTAL),
_curPageIdx(-1),
_touchMoveDirection(TouchDirection::LEFT),
_leftBoundaryChild(nullptr),
_rightBoundaryChild(nullptr),
_leftBoundary(0.0f),
_rightBoundary(0.0f),
_customScrollThreshold(0.0),
_usingCustomScrollThreshold(false),
_indicator(nullptr),
_indicatorPositionAsAnchorPoint(Vec2(0.5f, 0.1f)),
_currentPageIndex(-1),
_childFocusCancelOffset(5.0f),
_pageViewEventListener(nullptr),
_pageViewEventSelector(nullptr),
_eventCallback(nullptr)
{
this->setTouchEnabled(true);
}
PageView::~PageView()
@ -70,680 +60,204 @@ PageView* PageView::create()
return nullptr;
}
void PageView::onEnter()
{
#if CC_ENABLE_SCRIPT_BINDING
if (_scriptType == kScriptTypeJavascript)
{
if (ScriptEngineManager::sendNodeEventToJSExtended(this, kNodeOnEnter))
return;
}
#endif
Layout::onEnter();
scheduleUpdate();
}
bool PageView::init()
{
if (Layout::init())
if (ListView::init())
{
setClippingEnabled(true);
setDirection(Direction::HORIZONTAL);
setMagneticType(MagneticType::CENTER);
setScrollBarEnabled(false);
return true;
}
return false;
}
void PageView::addWidgetToPage(Widget *widget, ssize_t pageIdx, bool forceCreate)
{
if (!widget || pageIdx < 0)
{
return;
}
ssize_t pageCount = this->getPageCount();
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
{
Node * page = _pages.at(pageIdx);
page->addChild(widget);
}
}
Layout* PageView::createPage()
{
Layout* newPage = Layout::create();
newPage->setContentSize(getContentSize());
return newPage;
}
void PageView::addPage(Layout* page)
{
if (!page || _pages.contains(page))
{
return;
}
addChild(page);
_pages.pushBack(page);
if (_curPageIdx == -1)
{
_curPageIdx = 0;
}
_doLayoutDirty = true;
}
void PageView::insertPage(Layout* page, int idx)
{
if (idx < 0 || !page || _pages.contains(page))
{
return;
}
ssize_t pageCount = this->getPageCount();
if (idx >= pageCount)
{
addPage(page);
}
else
{
_pages.insert(idx, page);
addChild(page);
if(_curPageIdx == -1)
{
_curPageIdx = 0;
}
}
_doLayoutDirty = true;
}
void PageView::removePage(Layout* page)
{
if (!page)
{
return;
}
removeChild(page);
_pages.eraseObject(page);
auto pageCount = _pages.size();
if (_curPageIdx >= pageCount)
{
_curPageIdx = pageCount - 1;
}
_doLayoutDirty = true;
}
void PageView::removePageAtIndex(ssize_t index)
{
if (index < 0 || index >= this->getPages().size())
{
return;
}
Layout* page = _pages.at(index);
removePage(page);
}
void PageView::removeAllPages()
{
for(const auto& node : _pages)
{
removeChild(node);
}
_pages.clear();
_curPageIdx = -1;
}
void PageView::updateBoundaryPages()
{
if (_pages.size() <= 0)
{
_leftBoundaryChild = nullptr;
_rightBoundaryChild = nullptr;
return;
}
_leftBoundaryChild = _pages.at(0);
_rightBoundaryChild = _pages.at(this->getPageCount()-1);
}
ssize_t PageView::getPageCount()const
{
return _pages.size();
}
float PageView::getPositionXByIndex(ssize_t idx)const
{
return (getContentSize().width * (idx-_curPageIdx));
}
float PageView::getPositionYByIndex(ssize_t idx)const
{
return (getContentSize().height * (idx-_curPageIdx));
}
void PageView::onSizeChanged()
{
Layout::onSizeChanged();
if (_direction == Direction::HORIZONTAL)
{
_rightBoundary = getContentSize().width;
}
else
{
_rightBoundary = getContentSize().height;
}
_doLayoutDirty = true;
}
void PageView::updateAllPagesSize()
{
Size selfSize = getContentSize();
for (auto& page : _pages)
{
page->setContentSize(selfSize);
}
}
void PageView::updateAllPagesPosition()
{
ssize_t pageCount = this->getPageCount();
if (pageCount <= 0)
{
_curPageIdx = -1;
return;
}
if (_curPageIdx >= pageCount)
{
_curPageIdx = pageCount-1;
}
// If the layout is dirty, don't trigger auto scroll
_isAutoScrolling = false;
for (int i=0; i<pageCount; i++)
{
Layout* page = _pages.at(i);
Vec2 newPosition;
if (_direction == Direction::HORIZONTAL)
{
float pageWidth = getContentSize().width;
newPosition = Vec2((i-_curPageIdx) * pageWidth, 0);
}
else if(_direction == Direction::VERTICAL)
{
float pageHeight = getContentSize().height;
newPosition = Vec2(0,(i-_curPageIdx) * pageHeight * -1);
}
page->setPosition(newPosition);
}
}
void PageView::setCurPageIndex( ssize_t index )
{
if (index < 0 || index >= this->getPageCount())
{
return;
}
_curPageIdx = index;
_doLayoutDirty = true;
}
void PageView::scrollToPage(ssize_t idx)
{
if (idx < 0 || idx >= this->getPageCount())
{
return;
}
_curPageIdx = idx;
Layout* curPage = _pages.at(idx);
if (_direction == Direction::HORIZONTAL)
{
_autoScrollDistance = -(curPage->getPosition().x);
if (_autoScrollDistance > 0)
{
_autoScrollDirection = AutoScrollDirection::RIGHT;
}
else
{
_autoScrollDirection = AutoScrollDirection::LEFT;
}
}
else if(_direction == Direction::VERTICAL)
{
_autoScrollDistance = -curPage->getPosition().y;
if (_autoScrollDistance > 0)
{
_autoScrollDirection = AutoScrollDirection::DOWN;
}
else
{
_autoScrollDirection = AutoScrollDirection::UP;
}
}
_autoScrollSpeed = fabs(_autoScrollDistance)/0.2f;
_isAutoScrolling = true;
}
void PageView::setDirection(cocos2d::ui::PageView::Direction direction)
{
this->_direction = direction;
}
PageView::Direction PageView::getDirection()const
{
return this->_direction;
}
void PageView::update(float dt)
{
if (_isAutoScrolling)
{
this->autoScroll(dt);
}
}
void PageView::autoScroll(float dt)
{
float step = _autoScrollSpeed*dt;
int sign = 1;
switch (_autoScrollDirection)
{
case AutoScrollDirection::LEFT:
case AutoScrollDirection::UP:
{
if (_autoScrollDistance + step >= 0.0f)
{
step = -_autoScrollDistance;
_isAutoScrolling = false;
_autoScrollDistance = 0.0f;
}
else
{
_autoScrollDistance += step;
}
sign = -1;
break;
}
break;
case AutoScrollDirection::RIGHT:
case AutoScrollDirection::DOWN:
{
if (_autoScrollDistance - step <= 0.0f)
{
step = _autoScrollDistance;
_autoScrollDistance = 0.0f;
_isAutoScrolling = false;
}
else
{
_autoScrollDistance -= step;
}
break;
}
default:
break;
}
if (_direction == Direction::HORIZONTAL)
{
scrollPages(Vec2(step * sign, 0));
}
else
{
scrollPages(Vec2(0, step * sign));
}
if (!_isAutoScrolling)
{
pageTurningEvent();
}
}
bool PageView::onTouchBegan(Touch *touch, Event *unusedEvent)
{
bool pass = Layout::onTouchBegan(touch, unusedEvent);
return pass;
}
void PageView::onTouchMoved(Touch *touch, Event *unusedEvent)
{
Layout::onTouchMoved(touch, unusedEvent);
if (!_isInterceptTouch)
{
handleMoveLogic(touch);
}
}
void PageView::onTouchEnded(Touch *touch, Event *unusedEvent)
{
Layout::onTouchEnded(touch, unusedEvent);
if (!_isInterceptTouch)
{
handleReleaseLogic(touch);
}
_isInterceptTouch = false;
}
void PageView::onTouchCancelled(Touch *touch, Event *unusedEvent)
{
Layout::onTouchCancelled(touch, unusedEvent);
if (!_isInterceptTouch)
{
handleReleaseLogic(touch);
}
_isInterceptTouch = false;
}
void PageView::doLayout()
{
if (!_doLayoutDirty)
if(!_innerContainerDoLayoutDirty)
{
return;
}
updateAllPagesPosition();
updateAllPagesSize();
updateBoundaryPages();
_doLayoutDirty = false;
ListView::doLayout();
if(_indicator != nullptr)
{
ssize_t index = getIndex(getCenterItemInCurrentView());
_indicator->indicate(index);
}
_innerContainerDoLayoutDirty = false;
}
void PageView::movePages(Vec2 offset)
void PageView::setDirection(PageView::Direction direction)
{
for (auto& page : this->getPages())
ListView::setDirection(direction);
if(direction == Direction::HORIZONTAL)
{
Vec2 oldPosition = page->getPosition();
page->setPosition(oldPosition + offset);
_indicatorPositionAsAnchorPoint = Vec2(0.5f, 0.1f);
}
else if(direction == Direction::VERTICAL)
{
_indicatorPositionAsAnchorPoint = Vec2(0.1f, 0.5f);
}
if(_indicator != nullptr)
{
_indicator->setDirection(direction);
refreshIndicatorPosition();
}
}
bool PageView::scrollPages(Vec2 touchOffset)
void PageView::addWidgetToPage(Widget *widget, ssize_t pageIdx, bool forceCreate)
{
if (this->getPageCount() <= 0)
{
return false;
insertCustomItem(widget, pageIdx);
}
if (!_leftBoundaryChild || !_rightBoundaryChild)
void PageView::addPage(Widget* page)
{
return false;
pushBackCustomItem(page);
}
Vec2 realOffset = touchOffset;
switch (_touchMoveDirection)
void PageView::insertPage(Widget* page, int idx)
{
case TouchDirection::LEFT: // left
if (_rightBoundaryChild->getRightBoundary() + touchOffset.x <= _rightBoundary)
{
realOffset.x = _rightBoundary - _rightBoundaryChild->getRightBoundary();
realOffset.y = 0;
movePages(realOffset);
return false;
}
break;
case TouchDirection::RIGHT: // right
if (_leftBoundaryChild->getLeftBoundary() + touchOffset.x >= _leftBoundary)
{
realOffset.x = _leftBoundary - _leftBoundaryChild->getLeftBoundary();
realOffset.y = 0;
movePages(realOffset);
return false;
}
break;
case TouchDirection::UP:
{
if (_rightBoundaryChild->getBottomBoundary() + touchOffset.y >= _leftBoundary)
{
realOffset.y = _leftBoundary - _rightBoundaryChild->getBottomBoundary();
realOffset.x = 0;
movePages(realOffset);
return false;
insertCustomItem(page, idx);
}
}break;
case TouchDirection::DOWN:
void PageView::removePage(Widget* page)
{
if (_leftBoundaryChild->getTopBoundary() + touchOffset.y <= _rightBoundary)
{
realOffset.y = _rightBoundary - _leftBoundaryChild->getTopBoundary();
realOffset.x = 0;
movePages(realOffset);
return false;
}
}break;
default:
break;
removeItem(getIndex(page));
}
movePages(realOffset);
return true;
void PageView::removePageAtIndex(ssize_t index)
{
removeItem(index);
}
void PageView::handleMoveLogic(Touch *touch)
void PageView::removeAllPages()
{
Vec2 touchPoint = touch->getLocation();
Vec2 offset;
offset = touchPoint - touch->getPreviousLocation();
if (_direction == Direction::HORIZONTAL)
{
if (offset.x < 0)
{
_touchMoveDirection = TouchDirection::LEFT;
}
else if (offset.x > 0)
{
_touchMoveDirection = TouchDirection::RIGHT;
}
offset.y = 0;
}
else
{
offset.x = 0;
if(offset.y > 0)
{
_touchMoveDirection = TouchDirection::UP;
}
else if(offset.y < 0)
{
_touchMoveDirection = TouchDirection::DOWN;
}
removeAllItems();
}
scrollPages(offset);
void PageView::setCurPageIndex( ssize_t index )
{
setCurrentPageIndex(index);
}
void PageView::setCurrentPageIndex(ssize_t index)
{
jumpToItem(index, Vec2::ANCHOR_MIDDLE, Vec2::ANCHOR_MIDDLE);
}
void PageView::scrollToPage(ssize_t idx)
{
scrollToItem(idx);
}
void PageView::scrollToItem(ssize_t itemIndex)
{
ListView::scrollToItem(itemIndex, Vec2::ANCHOR_MIDDLE, Vec2::ANCHOR_MIDDLE);
}
void PageView::setCustomScrollThreshold(float threshold)
{
CCASSERT(threshold > 0, "Invalid threshold!");
_customScrollThreshold = threshold;
this->setUsingCustomScrollThreshold(true);
CCLOG("PageView::setCustomScrollThreshold() has no effect!");
}
float PageView::getCustomScrollThreshold()const
{
return _customScrollThreshold;
return 0;
}
void PageView::setUsingCustomScrollThreshold(bool flag)
{
_usingCustomScrollThreshold = flag;
CCLOG("PageView::setUsingCustomScrollThreshold() has no effect!");
}
bool PageView::isUsingCustomScrollThreshold()const
{
return _usingCustomScrollThreshold;
return false;
}
void PageView::moveInnerContainer(const Vec2& deltaMove, bool canStartBounceBack)
{
ListView::moveInnerContainer(deltaMove, canStartBounceBack);
_currentPageIndex = getIndex(getCenterItemInCurrentView());
if(_indicator != nullptr)
{
_indicator->indicate(_currentPageIndex);
}
}
void PageView::onItemListChanged()
{
ListView::onItemListChanged();
if(_indicator != nullptr)
{
_indicator->reset(_items.size());
}
}
void PageView::onSizeChanged()
{
ListView::onSizeChanged();
refreshIndicatorPosition();
}
void PageView::refreshIndicatorPosition()
{
if(_indicator != nullptr)
{
const Size& contentSize = getContentSize();
float posX = contentSize.width * _indicatorPositionAsAnchorPoint.x;
float posY = contentSize.height * _indicatorPositionAsAnchorPoint.y;
_indicator->setPosition(Vec2(posX, posY));
}
}
void PageView::handleReleaseLogic(Touch *touch)
{
if (this->getPageCount() <= 0)
// Use `ScrollView` method in order to avoid `startMagneticScroll()` by `ListView`.
ScrollView::handleReleaseLogic(touch);
if(_items.empty())
{
return;
}
Widget* curPage = dynamic_cast<Widget*>(this->getPages().at(_curPageIdx));
if (curPage)
{
Vec2 curPagePos = curPage->getPosition();
ssize_t pageCount = this->getPageCount();
auto contentSize = getContentSize();
Vec2 touchMoveVelocity = flattenVectorByDirection(calculateTouchMoveVelocity());
float moveBoundray = 0.0f;
float scrollDistance;
if (_direction == Direction::HORIZONTAL)
static const float INERTIA_THRESHOLD = 500;
if(touchMoveVelocity.length() < INERTIA_THRESHOLD)
{
curPagePos.y = 0;
moveBoundray = curPagePos.x;
scrollDistance = contentSize.width / 2.0;
}
else if(_direction == Direction::VERTICAL)
{
curPagePos.x = 0;
moveBoundray = curPagePos.y;
scrollDistance = contentSize.height / 2.0;
}
if (!_usingCustomScrollThreshold)
{
_customScrollThreshold = scrollDistance;
}
float boundary = _customScrollThreshold;
if (_direction == Direction::HORIZONTAL)
{
if (moveBoundray <= -boundary)
{
if (_curPageIdx >= pageCount-1)
{
scrollPages(curPagePos);
startMagneticScroll();
}
else
{
scrollToPage(_curPageIdx+1);
}
}
else if (moveBoundray >= boundary)
{
if (_curPageIdx <= 0)
{
scrollPages(curPagePos);
}
else
{
scrollToPage(_curPageIdx-1);
}
}
else
{
scrollToPage(_curPageIdx);
}
}
else if(_direction == Direction::VERTICAL)
{
if (moveBoundray >= boundary)
{
if (_curPageIdx >= pageCount-1)
{
scrollPages(curPagePos);
}
else
{
scrollToPage(_curPageIdx+1);
}
}
else if (moveBoundray <= -boundary)
{
if (_curPageIdx <= 0)
{
scrollPages(curPagePos);
}
else
{
scrollToPage(_curPageIdx-1);
}
}
else
{
scrollToPage(_curPageIdx);
}
}
}
}
// Handle paging by inertia force.
Widget* currentPage = getItem(_currentPageIndex);
Vec2 destination = calculateItemDestination(Vec2::ANCHOR_MIDDLE, currentPage, Vec2::ANCHOR_MIDDLE);
Vec2 deltaToCurrentpage = destination - getInnerContainerPosition();
deltaToCurrentpage = flattenVectorByDirection(deltaToCurrentpage);
void PageView::interceptTouchEvent(TouchEventType event, Widget *sender, Touch *touch)
// If the direction of displacement to current page and the direction of touch are same, just start magnetic scroll to the current page.
// Otherwise, move to the next page of touch direction.
if(touchMoveVelocity.x * deltaToCurrentpage.x > 0 || touchMoveVelocity.y * deltaToCurrentpage.y > 0)
{
if (!_touchEnabled)
{
Layout::interceptTouchEvent(event, sender, touch);
return;
startMagneticScroll();
}
Vec2 touchPoint = touch->getLocation();
switch (event)
else
{
case TouchEventType::BEGAN:
if(touchMoveVelocity.x < 0 || touchMoveVelocity.y > 0)
{
_touchBeganPosition = touch->getLocation();
_isInterceptTouch = true;
++_currentPageIndex;
}
break;
case TouchEventType::MOVED:
else
{
float offset = 0;
if (_direction == Direction::HORIZONTAL)
{
offset = fabs(sender->getTouchBeganPosition().x - touchPoint.x);
--_currentPageIndex;
}
else if(_direction == Direction::VERTICAL)
{
offset = fabs(sender->getTouchBeganPosition().y - touchPoint.y);
_currentPageIndex = MIN(_currentPageIndex, _items.size());
_currentPageIndex = MAX(_currentPageIndex, 0);
scrollToItem(_currentPageIndex);
}
_touchMovePosition = touch->getLocation();
if (offset > _childFocusCancelOffset)
{
sender->setHighlighted(false);
handleMoveLogic(touch);
}
}
break;
case TouchEventType::CANCELED:
case TouchEventType::ENDED:
{
_touchEndPosition = touch->getLocation();
handleReleaseLogic(touch);
if (sender->isSwallowTouches())
{
_isInterceptTouch = false;
}
}
break;
}
}
@ -778,12 +292,22 @@ void PageView::addEventListener(const ccPageViewCallback& callback)
ssize_t PageView::getCurPageIndex() const
{
return _curPageIdx;
Widget* widget = ListView::getCenterItemInCurrentView();
return getIndex(widget);
}
Vector<Layout*>& PageView::getPages()
{
return _pages;
CCASSERT(false, "This method is obsolete!");
// Temporary code to keep backward compatibility.
static Vector<Layout*> pages;
pages.clear();
for(Widget* widget : getItems())
{
pages.pushBack(dynamic_cast<Layout*>(widget));
}
return pages;
}
Layout* PageView::getPage(ssize_t index)
@ -792,7 +316,15 @@ Layout* PageView::getPage(ssize_t index)
{
return nullptr;
}
return _pages.at(index);
// Temporary code to keep backward compatibility.
static Vector<Layout*> pages;
pages.clear();
for(Widget* widget : getItems())
{
pages.pushBack(dynamic_cast<Layout*>(widget));
}
return pages.at(index);
}
std::string PageView::getDescription() const
@ -805,31 +337,97 @@ Widget* PageView::createCloneInstance()
return PageView::create();
}
void PageView::copyClonedWidgetChildren(Widget* model)
{
auto modelPages = static_cast<PageView*>(model)->getPages();
for (auto& page : modelPages)
{
addPage(static_cast<Layout*>(page->clone()));
}
}
void PageView::copySpecialProperties(Widget *widget)
{
PageView* pageView = dynamic_cast<PageView*>(widget);
if (pageView)
{
Layout::copySpecialProperties(widget);
ListView::copySpecialProperties(widget);
_eventCallback = pageView->_eventCallback;
_ccEventCallback = pageView->_ccEventCallback;
_pageViewEventListener = pageView->_pageViewEventListener;
_pageViewEventSelector = pageView->_pageViewEventSelector;
_usingCustomScrollThreshold = pageView->_usingCustomScrollThreshold;
_customScrollThreshold = pageView->_customScrollThreshold;
_direction = pageView->_direction;
}
}
void PageView::setIndicatorEnabled(bool enabled)
{
if(enabled == (_indicator != nullptr))
{
return;
}
if(!enabled)
{
removeProtectedChild(_indicator);
_indicator = nullptr;
}
else
{
_indicator = PageViewIndicator::create();
_indicator->setDirection(getDirection());
addProtectedChild(_indicator, 10000);
setIndicatorSelectedIndexColor(Color3B(100, 100, 255));
refreshIndicatorPosition();
}
}
void PageView::setIndicatorPositionAsAnchorPoint(const Vec2& positionAsAnchorPoint)
{
_indicatorPositionAsAnchorPoint = positionAsAnchorPoint;
refreshIndicatorPosition();
}
const Vec2& PageView::getIndicatorPositionAsAnchorPoint() const
{
return _indicatorPositionAsAnchorPoint;
}
void PageView::setIndicatorPosition(const Vec2& position)
{
if(_indicator != nullptr)
{
const Size& contentSize = getContentSize();
_indicatorPositionAsAnchorPoint.x = position.x / contentSize.width;
_indicatorPositionAsAnchorPoint.y = position.y / contentSize.height;
_indicator->setPosition(position);
}
}
const Vec2& PageView::getIndicatorPosition() const
{
CCASSERT(_indicator != nullptr, "");
return _indicator->getPosition();
}
void PageView::setIndicatorSpaceBetweenIndexNodes(float spaceBetweenIndexNodes)
{
if(_indicator != nullptr)
{
_indicator->setSpaceBetweenIndexNodes(spaceBetweenIndexNodes);
}
}
float PageView::getIndicatorSpaceBetweenIndexNodes() const
{
CCASSERT(_indicator != nullptr, "");
return _indicator->getSpaceBetweenIndexNodes();
}
void PageView::setIndicatorSelectedIndexColor(const Color3B& color)
{
if(_indicator != nullptr)
{
_indicator->setSelectedIndexColor(color);
}
}
const Color3B& PageView::getIndicatorSelectedIndexColor() const
{
CCASSERT(_indicator != nullptr, "");
return _indicator->getSelectedIndexColor();
}
}
NS_CC_END

View File

@ -25,7 +25,7 @@ THE SOFTWARE.
#ifndef __UIPAGEVIEW_H__
#define __UIPAGEVIEW_H__
#include "ui/UILayout.h"
#include "ui/UIListView.h"
#include "ui/GUIExport.h"
/**
@ -36,6 +36,8 @@ NS_CC_BEGIN
namespace ui {
class PageViewIndicator;
/**
*PageView page turn event type.
*@deprecated Use `PageView::EventType` instead.
@ -56,7 +58,7 @@ typedef void (Ref::*SEL_PageViewEvent)(Ref*, PageViewEventType);
*@brief Layout manager that allows the user to flip left & right and up & down through pages of data.
*
*/
class CC_GUI_DLL PageView : public Layout
class CC_GUI_DLL PageView : public ListView
{
DECLARE_CLASS_GUI_INFO
@ -81,12 +83,6 @@ public:
DOWN
};
enum class Direction
{
HORIZONTAL,
VERTICAL
};
/**
* PageView page turn event callback.
*/
@ -112,21 +108,30 @@ public:
*/
static PageView* create();
/**
* Changes direction
* Direction Direction::VERTICAL means vertical scroll, Direction::HORIZONTAL means horizontal scroll.
* @param direction Set the page view's scroll direction.
*/
virtual void setDirection(Direction direction) override;
/**
* Add a widget as a page of PageView in a given index.
*
* @param widget Widget to be added to pageview.
* @param pageIdx A given index.
* @param forceCreate If `forceCreate` is true and `widget` isn't exists, pageview would create a default page and add it.
*
* Since v3.9, this is deprecated. Use `insertPage(Widget* page, int idx)` instead.
*/
void addWidgetToPage(Widget* widget, ssize_t pageIdx, bool forceCreate);
CC_DEPRECATED_ATTRIBUTE void addWidgetToPage(Widget* widget, ssize_t pageIdx, bool forceCreate);
/**
* Insert a page into the end of PageView.
*
* @param page Page to be inserted.
*/
void addPage(Layout* page);
void addPage(Widget* page);
/**
* Insert a page into PageView at a given index.
@ -134,14 +139,14 @@ public:
* @param page Page to be inserted.
* @param idx A given index.
*/
void insertPage(Layout* page, int idx);
void insertPage(Widget* page, int idx);
/**
* Remove a page of PageView.
*
* @param page Page to be removed.
*/
void removePage(Layout* page);
void removePage(Widget* page);
/**
* Remove a page at a given index of PageView.
@ -150,24 +155,6 @@ public:
*/
void removePageAtIndex(ssize_t index);
/**
* Changes scroll direction of PageView
*
* @see `Direction`
* @param direction Scroll direction enum.
* @since v3.8
*/
void setDirection(Direction direction);
/**
* Query scroll direction of PageView.
*
* @see `Direction`
* @since v3.8
* @return PageView scroll direction.
*/
Direction getDirection()const;
/**
* @brief Remove all pages of the PageView.
*/
@ -180,12 +167,36 @@ public:
*/
void scrollToPage(ssize_t idx);
/**
* Scroll to a page with a given index.
*
* @param idx A given index in the PageView. Index start from 0 to pageCount -1.
*/
void scrollToItem(ssize_t itemIndex);
/**
* Gets current displayed page index.
* @return current page index.
*
* Since v3.9, this is deprecated. Use `getCurrentPageIndex()` instead.
*/
CC_DEPRECATED_ATTRIBUTE ssize_t getCurPageIndex() const;
/**
* Gets current displayed page index.
* @return current page index.
*/
ssize_t getCurPageIndex() const;
ssize_t getCurrentPageIndex() const { return _currentPageIndex; }
/**
* Jump to a page with a given index without scrolling.
* This is the different between scrollToPage.
*
* @param index A given index in PageView. Index start from 0 to pageCount -1.
*
* Since v3.9, this is deprecated. Use `setCurrentPageIndex()` instead.
*/
CC_DEPRECATED_ATTRIBUTE void setCurPageIndex(ssize_t index);
/**
* Jump to a page with a given index without scrolling.
@ -193,22 +204,25 @@ public:
*
* @param index A given index in PageView. Index start from 0 to pageCount -1.
*/
void setCurPageIndex(ssize_t index);
void setCurrentPageIndex(ssize_t index);
/**
* @brief Get all the pages in the PageView.
* @return A vector of Layout pointers.
*
* Since v3.9, this is obsolete. Use `Vector<Widget*>& ListView::getItems()` instead.
*/
Vector<Layout*>& getPages();
CC_DEPRECATED_ATTRIBUTE Vector<Layout*>& getPages();
/**
* @brief Get a page at a given index
*
* @param index A given index.
* @return A layout pointer in PageView container.
*
* Since v3.9, this is obsolete. Use `Widget* ListView::getItem(index)` instead.
*/
Layout* getPage(ssize_t index);
CC_DEPRECATED_ATTRIBUTE Layout* getPage(ssize_t index);
/**
* Add a page turn callback to PageView, then when one page is turning, the callback will be called.
@ -218,7 +232,6 @@ public:
*/
CC_DEPRECATED_ATTRIBUTE void addEventListenerPageView(Ref *target, SEL_PageViewEvent selector);
/**
* @brief Add a page turn callback to PageView, then when one page is turning, the callback will be called.
*
@ -227,100 +240,131 @@ public:
void addEventListener(const ccPageViewCallback& callback);
//override methods
virtual bool onTouchBegan(Touch *touch, Event *unusedEvent) override;
virtual void onTouchMoved(Touch *touch, Event *unusedEvent) override;
virtual void onTouchEnded(Touch *touch, Event *unusedEvent) override;
virtual void onTouchCancelled(Touch *touch, Event *unusedEvent) override;
virtual void update(float dt) override;
virtual void setLayoutType(Type type) override{};
virtual Type getLayoutType() const override{return Type::ABSOLUTE;};
virtual std::string getDescription() const override;
/**
* @lua NA
* @brief Toggle page indicator enabled.
*
* @param enabled True if enable page indicator, false otherwise.
*/
virtual void onEnter() override;
void setIndicatorEnabled(bool enabled);
/**
* @brief Query page indicator state.
*
* @return True if page indicator is enabled, false otherwise.
*/
bool getIndicatorEnabled() const { return _indicator != nullptr; }
/**
* @brief Set the page indicator's position using anchor point.
*
* @param positionAsAnchorPoint The position as anchor point.
*/
void setIndicatorPositionAsAnchorPoint(const Vec2& positionAsAnchorPoint);
/**
* @brief Get the page indicator's position as anchor point.
*
* @return positionAsAnchorPoint
*/
const Vec2& getIndicatorPositionAsAnchorPoint() const;
/**
* @brief Set the page indicator's position in page view.
*
* @param position The position in page view
*/
void setIndicatorPosition(const Vec2& position);
/**
* @brief Get the page indicator's position.
*
* @return positionAsAnchorPoint
*/
const Vec2& getIndicatorPosition() const;
/**
* @brief Set space between page indicator's index nodes.
*
* @param spaceBetweenIndexNodes Space between nodes in pixel.
*/
void setIndicatorSpaceBetweenIndexNodes(float spaceBetweenIndexNodes);
/**
* @brief Get the space between page indicator's index nodes.
*
* @return spaceBetweenIndexNodes
*/
float getIndicatorSpaceBetweenIndexNodes() const;
/**
* @brief Set color of page indicator's selected index.
*
* @param spaceBetweenIndexNodes Space between nodes in pixel.
*/
void setIndicatorSelectedIndexColor(const Color3B& color);
/**
* @brief Get the color of page indicator's selected index.
*
* @return color
*/
const Color3B& getIndicatorSelectedIndexColor() const;
/**
*@brief If you don't specify the value, the pageView will turn page when scrolling at the half width of a page.
*@param threshold A threshold in float.
*@deprecated Since v3.9, this method has no effect.
*/
void setCustomScrollThreshold(float threshold);
CC_DEPRECATED_ATTRIBUTE void setCustomScrollThreshold(float threshold);
/**
*@brief Query the custom scroll threshold of the PageView.
*@return Custom scroll threshold in float.
*@deprecated Since v3.9, this method always returns 0.
*/
float getCustomScrollThreshold()const;
CC_DEPRECATED_ATTRIBUTE float getCustomScrollThreshold()const;
/**
*@brief Set using user defined scroll page threshold or not.
* If you set it to false, then the default scroll threshold is pageView.width / 2
*@param flag True if using custom scroll threshold, false otherwise.
*@deprecated Since v3.9, this method has no effect.
*/
void setUsingCustomScrollThreshold(bool flag);
CC_DEPRECATED_ATTRIBUTE void setUsingCustomScrollThreshold(bool flag);
/**
*@brief Query whether use user defined scroll page threshold or not.
*@return True if using custom scroll threshold, false otherwise.
*@deprecated Since v3.9, this method always returns false.
*/
bool isUsingCustomScrollThreshold()const;
CC_DEPRECATED_ATTRIBUTE bool isUsingCustomScrollThreshold()const;
CC_CONSTRUCTOR_ACCESS:
virtual bool init() override;
protected:
Layout* createPage();
float getPositionXByIndex(ssize_t idx)const;
float getPositionYByIndex(ssize_t idx)const;
ssize_t getPageCount()const;
void updateBoundaryPages();
virtual bool scrollPages(Vec2 touchOffset);
void movePages(Vec2 offset);
void pageTurningEvent();
void updateAllPagesSize();
void updateAllPagesPosition();
void autoScroll(float dt);
virtual void handleMoveLogic(Touch *touch) ;
virtual void handleReleaseLogic(Touch *touch) ;
virtual void interceptTouchEvent(TouchEventType event, Widget* sender,Touch *touch) override;
virtual void onSizeChanged() override;
virtual Widget* createCloneInstance() override;
virtual void copySpecialProperties(Widget* model) override;
virtual void copyClonedWidgetChildren(Widget* model) override;
//override methods
virtual void doLayout() override;
protected:
enum class AutoScrollDirection
{
LEFT,
RIGHT,
UP,
DOWN
};
bool _isAutoScrolling;
float _autoScrollDistance;
float _autoScrollSpeed;
AutoScrollDirection _autoScrollDirection;
Direction _direction;
void pageTurningEvent();
ssize_t _curPageIdx;
Vector<Layout*> _pages;
virtual void moveInnerContainer(const Vec2& deltaMove, bool canStartBounceBack) override;
virtual void onItemListChanged() override;
virtual void onSizeChanged() override;
virtual void handleReleaseLogic(Touch *touch) override;
TouchDirection _touchMoveDirection;
virtual Widget* createCloneInstance() override;
virtual void copySpecialProperties(Widget* model) override;
Widget* _leftBoundaryChild;
Widget* _rightBoundaryChild;
void refreshIndicatorPosition();
float _leftBoundary;
float _rightBoundary;
float _customScrollThreshold;
bool _usingCustomScrollThreshold;
protected:
PageViewIndicator* _indicator;
Vec2 _indicatorPositionAsAnchorPoint;
ssize_t _currentPageIndex;
float _childFocusCancelOffset;

View File

@ -0,0 +1,170 @@
/****************************************************************************
Copyright (c) 2015 Neo Kim (neo.kim@neofect.com)
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 "UIPageViewIndicator.h"
#include "2d/CCSprite.h"
#include "base/ccUtils.h"
static const char* CIRCLE_IMAGE = "iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAQAAADZc7J/AAAA8ElEQVRIx62VyRGCQBBF+6gWRCEmYDIQkhiBCgHhSclC8YqWzOV5oVzKAYZp3r1/9fpbxAIBMTsKrjx5cqVgR0wgLhCRUWOjJiPqD56xoaGPhpRZV/iSEy6crHmw5oIrF9b/lVeMofrJgjlnxlIy/wik+JB+mme8BExbBhm+5CJC2LE2LtSEQoyGWDioBA5CoRIohJtK4CYDxzNEM4GAugR1E9VjVC+SZpXvhCJCrjomESLvc17pDGX7bWmlh6UtpjPVCWy9zaJ0TD7qfm3pwERMz2trRVZk3K3BD/L34AY+dEDCniMVBkPFkT2J/b2/AIV+dRpFLOYoAAAAAElFTkSuQmCC";
NS_CC_BEGIN
static const float SPACE_BETWEEN_INDEX_NODES_DEFAULT = 23;
namespace ui {
PageViewIndicator* PageViewIndicator::create()
{
PageViewIndicator* node = new (std::nothrow) PageViewIndicator();
if (node && node->init())
{
node->autorelease();
return node;
}
CC_SAFE_DELETE(node);
return nullptr;
}
PageViewIndicator::PageViewIndicator()
: _direction(PageView::Direction::HORIZONTAL)
, _currentIndexNode(nullptr)
, _spaceBetweenIndexNodes(SPACE_BETWEEN_INDEX_NODES_DEFAULT)
{
}
PageViewIndicator::~PageViewIndicator()
{
}
bool PageViewIndicator::init()
{
_currentIndexNode = (Node*) utils::createSpriteFromBase64(CIRCLE_IMAGE);
_currentIndexNode->setVisible(false);
addProtectedChild(_currentIndexNode, 1);
return true;
}
void PageViewIndicator::setDirection(PageView::Direction direction)
{
_direction = direction;
rearrange();
}
void PageViewIndicator::reset(ssize_t numberOfTotalPages)
{
while(_indexNodes.size() < numberOfTotalPages)
{
increaseNumberOfPages();
}
while(_indexNodes.size() > numberOfTotalPages)
{
decreaseNumberOfPages();
}
rearrange();
_currentIndexNode->setVisible(!_indexNodes.empty());
}
void PageViewIndicator::indicate(ssize_t index)
{
if (index < 0 || index >= _indexNodes.size())
{
return;
}
_currentIndexNode->setPosition(_indexNodes.at(index)->getPosition());
}
void PageViewIndicator::rearrange()
{
if(_indexNodes.empty())
{
return;
}
bool horizontal = (_direction == PageView::Direction::HORIZONTAL);
// Calculate total size
Size indexNodeSize = _indexNodes.at(0)->getContentSize();
float sizeValue = (horizontal ? indexNodeSize.width : indexNodeSize.height);
ssize_t numberOfItems = _indexNodes.size();
float totalSizeValue = sizeValue * numberOfItems + _spaceBetweenIndexNodes * (numberOfItems - 1);
float posValue = -(totalSizeValue / 2) + (sizeValue / 2);
for(auto indexNode : _indexNodes) {
Vec2 position;
if(horizontal)
{
position = Vec2(posValue, indexNodeSize.height / 2.0f);
}
else
{
position = Vec2(indexNodeSize.width / 2.0f, -posValue);
}
indexNode->setPosition(position);
posValue += sizeValue + _spaceBetweenIndexNodes;
}
}
void PageViewIndicator::setSpaceBetweenIndexNodes(float spaceBetweenIndexNodes)
{
if(_spaceBetweenIndexNodes == spaceBetweenIndexNodes)
{
return;
}
_spaceBetweenIndexNodes = spaceBetweenIndexNodes;
rearrange();
}
void PageViewIndicator::increaseNumberOfPages()
{
Sprite* indexNode = utils::createSpriteFromBase64(CIRCLE_IMAGE);
// indexNode->setOpacity(255 * 0.3f);
addProtectedChild(indexNode);
_indexNodes.pushBack(indexNode);
}
void PageViewIndicator::decreaseNumberOfPages()
{
if(_indexNodes.empty())
{
return;
}
removeProtectedChild(*_indexNodes.begin());
_indexNodes.erase(_indexNodes.begin());
}
void PageViewIndicator::clear()
{
for(auto indexNode : _indexNodes)
{
removeProtectedChild(indexNode);
}
_indexNodes.clear();
_currentIndexNode->setVisible(false);
}
}
NS_CC_END

View File

@ -0,0 +1,78 @@
/****************************************************************************
Copyright (c) 2015 Neo Kim (neo.kim@neofect.com)
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.
****************************************************************************/
#ifndef __UIPAGEVIEWINDICATOR_H__
#define __UIPAGEVIEWINDICATOR_H__
#include "UIPageView.h"
NS_CC_BEGIN
/**
* @addtogroup ui
* @{
*/
namespace ui {
class PageViewIndicator : public ProtectedNode
{
public:
/**
* Create a page view indicator with its parent page view.
* @return A page view indicator instance.
*/
static PageViewIndicator* create();
PageViewIndicator();
virtual ~PageViewIndicator();
void setDirection(PageView::Direction direction);
void reset(ssize_t numberOfTotalPages);
void indicate(ssize_t index);
void clear();
void setSpaceBetweenIndexNodes(float spaceBetweenIndexNodes);
float getSpaceBetweenIndexNodes() const { return _spaceBetweenIndexNodes; }
void setSelectedIndexColor(const Color3B& color) { _currentIndexNode->setColor(color); }
const Color3B& getSelectedIndexColor() const { return _currentIndexNode->getColor(); }
protected:
bool init() override;
void increaseNumberOfPages();
void decreaseNumberOfPages();
void rearrange();
PageView::Direction _direction;
Vector<Node*> _indexNodes;
Node* _currentIndexNode;
float _spaceBetweenIndexNodes;
};
}
// end of ui group
/// @}
NS_CC_END
#endif /* defined(__UIPAGEVIEWINDICATOR_H__) */

View File

@ -176,23 +176,6 @@ void ScrollView::setInnerContainerSize(const Size &size)
}
_innerContainer->setContentSize(Size(innerSizeWidth, innerSizeHeight));
// move children appropriately
{
Size newInnerSize = _innerContainer->getContentSize();
float offsetY = originalInnerSize.height - newInnerSize.height;
float offsetX = 0;
if (_innerContainer->getRightBoundary() <= _contentSize.width)
{
offsetX = originalInnerSize.width - newInnerSize.width;
}
if(offsetX != 0 || offsetY != 0)
{
Vec2 position = _innerContainer->getPosition() + Vec2(offsetX, offsetY);
setInnerContainerPosition(position);
}
}
// Calculate and set the position of the inner container.
Vec2 pos = _innerContainer->getPosition();
if (_innerContainer->getLeftBoundary() > 0.0f)
@ -319,18 +302,19 @@ Node* ScrollView::getChildByName(const std::string& name)const
return _innerContainer->getChildByName(name);
}
void ScrollView::moveChildren(float offsetX, float offsetY)
void ScrollView::moveInnerContainer(const Vec2& deltaMove, bool canStartBounceBack)
{
Vec2 position = _innerContainer->getPosition() + Vec2(offsetX, offsetY);
moveChildrenToPosition(position);
}
Vec2 adjustedMove = flattenVectorByDirection(deltaMove);
void ScrollView::moveChildrenToPosition(const Vec2& position)
{
setInnerContainerPosition(position);
setInnerContainerPosition(getInnerContainerPosition() + adjustedMove);
Vec2 outOfBoundary = getHowMuchOutOfBoundary(Vec2::ZERO);
Vec2 outOfBoundary = getHowMuchOutOfBoundary();
updateScrollBar(outOfBoundary);
if(_bounceEnabled && canStartBounceBack)
{
startBounceBackIfNeeded();
}
}
void ScrollView::updateScrollBar(const Vec2& outOfBoundary)
@ -352,7 +336,7 @@ Vec2 ScrollView::calculateTouchMoveVelocity() const
{
totalTime += timeDelta;
}
if(totalTime == 0 || totalTime >= 0.1f)
if(totalTime == 0 || totalTime >= 0.5f)
{
return Vec2::ZERO;
}
@ -554,101 +538,78 @@ void ScrollView::processAutoScrolling(float deltaTime)
}
}
moveChildrenToPosition(newPosition);
// Finish auto scroll if it ended
if(reachedEnd)
{
_autoScrolling = false;
startBounceBackIfNeeded();
}
moveInnerContainer(newPosition - getInnerContainerPosition(), reachedEnd);
}
void ScrollView::jumpToDestination(const Vec2 &des)
{
float finalOffsetX = des.x;
float finalOffsetY = des.y;
if (des.y <= 0 && _direction != Direction::HORIZONTAL)
{
finalOffsetY = MAX(des.y, _contentSize.height - _innerContainer->getContentSize().height);
}
if (des.x <= 0 && _direction != Direction::VERTICAL)
{
finalOffsetX = MAX(des.x, _contentSize.width - _innerContainer->getContentSize().width);
}
moveChildrenToPosition(Vec2(finalOffsetX, finalOffsetY));
_autoScrolling = false;
moveInnerContainer(des - getInnerContainerPosition(), true);
}
bool ScrollView::scrollChildren(float touchOffsetX, float touchOffsetY)
void ScrollView::scrollChildren(const Vec2& deltaMove)
{
touchOffsetX = (_direction == Direction::VERTICAL ? 0 : touchOffsetX);
touchOffsetY = (_direction == Direction::HORIZONTAL ? 0 : touchOffsetY);
Vec2 realMove = deltaMove;
if(_bounceEnabled)
{
// If the position of the inner container is out of the boundary, the offsets should be divided by two.
Vec2 outOfBoundary = getHowMuchOutOfBoundary();
touchOffsetX *= (outOfBoundary.x == 0 ? 1 : 0.5f);
touchOffsetY *= (outOfBoundary.y == 0 ? 1 : 0.5f);
realMove.x *= (outOfBoundary.x == 0 ? 1 : 0.5f);
realMove.y *= (outOfBoundary.y == 0 ? 1 : 0.5f);
}
float realOffsetX = touchOffsetX;
float realOffsetY = touchOffsetY;
if(!_bounceEnabled)
{
Vec2 outOfBoundary = getHowMuchOutOfBoundary(Vec2(realOffsetX, realOffsetY));
realOffsetX += outOfBoundary.x;
realOffsetY += outOfBoundary.y;
Vec2 outOfBoundary = getHowMuchOutOfBoundary(realMove);
realMove += outOfBoundary;
}
bool scrolledToLeft = false;
bool scrolledToRight = false;
bool scrolledToTop = false;
bool scrolledToBottom = false;
if (realOffsetY > 0.0f) // up
if (realMove.y > 0.0f) // up
{
float icBottomPos = _innerContainer->getBottomBoundary();
if (icBottomPos + realOffsetY >= _bottomBoundary)
if (icBottomPos + realMove.y >= _bottomBoundary)
{
scrolledToBottom = true;
}
}
else if (realOffsetY < 0.0f) // down
else if (realMove.y < 0.0f) // down
{
float icTopPos = _innerContainer->getTopBoundary();
if (icTopPos + realOffsetY <= _topBoundary)
if (icTopPos + realMove.y <= _topBoundary)
{
scrolledToTop = true;
}
}
if (realOffsetX < 0.0f) // left
if (realMove.x < 0.0f) // left
{
float icRightPos = _innerContainer->getRightBoundary();
if (icRightPos + realOffsetX <= _rightBoundary)
if (icRightPos + realMove.x <= _rightBoundary)
{
if(!_bounceEnabled)
{
realOffsetX = _rightBoundary - icRightPos;
}
scrolledToRight = true;
}
}
else if (realOffsetX > 0.0f) // right
else if (realMove.x > 0.0f) // right
{
float icLeftPos = _innerContainer->getLeftBoundary();
if (icLeftPos + realOffsetX >= _leftBoundary)
if (icLeftPos + realMove.x >= _leftBoundary)
{
if(!_bounceEnabled)
{
realOffsetX = _leftBoundary - icLeftPos;
}
scrolledToLeft = true;
}
}
moveChildren(realOffsetX, realOffsetY);
moveInnerContainer(realMove, false);
if(realOffsetX != 0 || realOffsetY != 0)
if(realMove.x != 0 || realMove.y != 0)
{
processScrollingEvent();
}
@ -668,10 +629,6 @@ bool ScrollView::scrollChildren(float touchOffsetX, float touchOffsetY)
{
processScrollEvent(MoveDirection::RIGHT, false);
}
bool scrollEnabledUpDown = (!scrolledToBottom && !scrolledToTop);
bool scrollEnabledLeftRight = (!scrolledToLeft && !scrolledToRight);
return scrollEnabledUpDown || scrollEnabledLeftRight;
}
void ScrollView::scrollToBottom(float timeInSec, bool attenuated)
@ -905,7 +862,7 @@ void ScrollView::handleMoveLogic(Touch *touch)
}
Vec3 delta3 = currPt - prevPt;
Vec2 delta(delta3.x, delta3.y);
scrollChildren(delta.x, delta.y);
scrollChildren(delta);
// Gather touch move information for speed calculation
gatherTouchMove(delta);

View File

@ -570,8 +570,7 @@ protected:
bool isOutOfBoundary(MoveDirection dir);
bool isOutOfBoundary();
void moveChildren(float offsetX, float offsetY);
void moveChildrenToPosition(const Vec2& position);
virtual void moveInnerContainer(const Vec2& deltaMove, bool canStartBounceBack);
bool calculateCurrAndPrevTouchPoints(Touch* touch, Vec3* currPt, Vec3* prevPt);
void gatherTouchMove(const Vec2& delta);
@ -589,7 +588,7 @@ protected:
void jumpToDestination(const Vec2& des);
virtual bool scrollChildren(float touchOffsetX, float touchOffsetY);
virtual void scrollChildren(const Vec2& deltaMove);
virtual void handlePressLogic(Touch *touch);
virtual void handleMoveLogic(Touch *touch);

View File

@ -25,7 +25,7 @@ THE SOFTWARE.
#include "UIScrollViewBar.h"
#include "CCImage.h"
#include "2d/CCSprite.h"
#include "base/base64.h"
#include "base/ccUtils.h"
NS_CC_BEGIN
@ -39,27 +39,6 @@ static const float DEFAULT_MARGIN = 20;
static const float DEFAULT_AUTO_HIDE_TIME = 0.2f;
static const float DEFAULT_SCROLLBAR_OPACITY = 0.4f;
static Sprite* createSpriteFromBase64(const char* base64String)
{
unsigned char* decoded;
int length = base64Decode((const unsigned char*) base64String, (unsigned int) strlen(base64String), &decoded);
Image *image = new Image();
bool imageResult = image->initWithImageData(decoded, length);
CCASSERT(imageResult, "Failed to create image from base64!");
free(decoded);
Texture2D *texture = new Texture2D();
texture->initWithImage(image);
texture->setAliasTexParameters();
image->release();
Sprite* sprite = Sprite::createWithTexture(texture);
texture->release();
return sprite;
}
ScrollViewBar::ScrollViewBar(ScrollView* parent, ScrollView::Direction direction):
_parent(parent),
_direction(direction),
@ -103,7 +82,7 @@ bool ScrollViewBar::init()
return false;
}
_upperHalfCircle = createSpriteFromBase64(HALF_CIRCLE_IMAGE);
_upperHalfCircle = utils::createSpriteFromBase64(HALF_CIRCLE_IMAGE);
_upperHalfCircle->setAnchorPoint(Vec2::ANCHOR_MIDDLE_BOTTOM);
addProtectedChild(_upperHalfCircle);
@ -112,7 +91,7 @@ bool ScrollViewBar::init()
_lowerHalfCircle->setAnchorPoint(Vec2::ANCHOR_MIDDLE_BOTTOM);
addProtectedChild(_lowerHalfCircle);
_body = createSpriteFromBase64(BODY_IMAGE_1_PIXEL_HEIGHT);
_body = utils::createSpriteFromBase64(BODY_IMAGE_1_PIXEL_HEIGHT);
_body->setAnchorPoint(Vec2::ANCHOR_MIDDLE_BOTTOM);
addProtectedChild(_body);

View File

@ -59,8 +59,8 @@ public:
virtual ~ScrollViewBar();
/**
* Create a ScrollView with its parent ScrollView and direction.
* @return A ScrollViewBar instance.
* Create a scroll bar with its parent scroll view and direction.
* @return A scroll bar instance.
*/
static ScrollViewBar* create(ScrollView* parent, ScrollView::Direction direction);

View File

@ -62,6 +62,7 @@
<ClCompile Include="..\UIListView.cpp" />
<ClCompile Include="..\UILoadingBar.cpp" />
<ClCompile Include="..\UIPageView.cpp" />
<ClCompile Include="..\UIPageViewIndicator.cpp" />
<ClCompile Include="..\UIRelativeBox.cpp" />
<ClCompile Include="..\UIRichText.cpp" />
<ClCompile Include="..\UIScale9Sprite.cpp" />

View File

@ -131,6 +131,9 @@
<ClCompile Include="..\UIPageView.cpp">
<Filter>UIWidgets\ScrollWidget</Filter>
</ClCompile>
<ClCompile Include="..\UIPageViewIndicator.cpp">
<Filter>UIWidgets\ScrollWidget</Filter>
</ClCompile>
<ClCompile Include="..\UIButton.cpp">
<Filter>UIWidgets</Filter>
</ClCompile>

View File

@ -1256,6 +1256,8 @@
"cocos/ui/UILoadingBar.h",
"cocos/ui/UIPageView.cpp",
"cocos/ui/UIPageView.h",
"cocos/ui/UIPageViewIndicator.cpp",
"cocos/ui/UIPageViewIndicator.h",
"cocos/ui/UIRadioButton.cpp",
"cocos/ui/UIRadioButton.h",
"cocos/ui/UIRelativeBox.cpp",

View File

@ -8,7 +8,6 @@ UIPageViewTests::UIPageViewTests()
{
ADD_TEST_CASE(UIPageViewTest);
ADD_TEST_CASE(UIPageViewButtonTest);
ADD_TEST_CASE(UIPageViewCustomScrollThreshold);
ADD_TEST_CASE(UIPageViewTouchPropagationTest);
ADD_TEST_CASE(UIPageViewDynamicAddAndRemoveTest);
ADD_TEST_CASE(UIPageViewJumpToPageTest);
@ -52,25 +51,24 @@ bool UIPageViewTest::init()
Layout* background = dynamic_cast<Layout*>(root->getChildByName("background_Panel"));
// Create the page view
Size size(240, 130);
PageView* pageView = PageView::create();
pageView->setContentSize(Size(240.0f, 130.0f));
pageView->setDirection(PageView::Direction::HORIZONTAL);
pageView->setContentSize(size);
Size backgroundSize = background->getContentSize();
pageView->setPosition(Vec2((widgetSize.width - backgroundSize.width) / 2.0f +
(backgroundSize.width - pageView->getContentSize().width) / 2.0f,
(widgetSize.height - backgroundSize.height) / 2.0f +
(backgroundSize.height - pageView->getContentSize().height) / 2.0f));
pageView->removeAllPages();
pageView->setPosition((widgetSize - pageView->getContentSize()) / 2.0f);
pageView->removeAllItems();
pageView->setIndicatorEnabled(true);
int pageCount = 4;
for (int i = 0; i < pageCount; ++i)
{
Layout* layout = Layout::create();
layout->setContentSize(Size(240.0f, 130.0f));
layout->setContentSize(size);
ImageView* imageView = ImageView::create("cocosui/scrollviewbg.png");
imageView->setScale9Enabled(true);
imageView->setContentSize(Size(240, 130));
imageView->setContentSize(size);
imageView->setPosition(Vec2(layout->getContentSize().width / 2.0f, layout->getContentSize().height / 2.0f));
layout->addChild(imageView);
@ -79,12 +77,11 @@ bool UIPageViewTest::init()
label->setPosition(Vec2(layout->getContentSize().width / 2.0f, layout->getContentSize().height / 2.0f));
layout->addChild(label);
pageView->insertPage(layout,i);
pageView->insertCustomItem(layout, i);
}
pageView->removePageAtIndex(0);
pageView->scrollToPage(pageCount-2);
pageView->removeItem(0);
pageView->scrollToItem(pageCount - 2);
pageView->addEventListener(CC_CALLBACK_2(UIPageViewTest::pageViewEvent, this));
_uiLayer->addChild(pageView);
@ -102,7 +99,7 @@ void UIPageViewTest::pageViewEvent(Ref *pSender, PageView::EventType type)
{
PageView* pageView = dynamic_cast<PageView*>(pSender);
_displayValueLabel->setString(StringUtils::format("page = %ld", pageView->getCurPageIndex() + 1));
_displayValueLabel->setString(StringUtils::format("page = %ld", pageView->getCurrentPageIndex() + 1));
}
break;
@ -156,7 +153,7 @@ bool UIPageViewButtonTest::init()
(widgetSize.height - backgroundSize.height) / 2.0f +
(backgroundSize.height - pageView->getContentSize().height) / 2.0f));
pageView->removeAllPages();
pageView->removeAllItems();
int pageCount = 4;
for (int i = 0; i < pageCount; ++i)
@ -184,10 +181,10 @@ bool UIPageViewButtonTest::init()
}
pageView->insertPage(outerBox,i);
pageView->insertCustomItem(outerBox, i);
}
pageView->removePageAtIndex(0);
pageView->removeItem(0);
pageView->addEventListener(CC_CALLBACK_2(UIPageViewButtonTest::pageViewEvent, this));
@ -212,7 +209,7 @@ void UIPageViewButtonTest::pageViewEvent(Ref *pSender, PageView::EventType type)
{
PageView* pageView = dynamic_cast<PageView*>(pSender);
_displayValueLabel->setString(StringUtils::format("page = %ld", pageView->getCurPageIndex() + 1));
_displayValueLabel->setString(StringUtils::format("page = %ld", pageView->getCurrentPageIndex() + 1));
}
break;
@ -222,105 +219,6 @@ void UIPageViewButtonTest::pageViewEvent(Ref *pSender, PageView::EventType type)
}
// UIPageViewCustomScrollThreshold
UIPageViewCustomScrollThreshold::UIPageViewCustomScrollThreshold()
: _displayValueLabel(nullptr)
{
}
UIPageViewCustomScrollThreshold::~UIPageViewCustomScrollThreshold()
{
}
bool UIPageViewCustomScrollThreshold::init()
{
if (UIScene::init())
{
Size widgetSize = _widget->getContentSize();
// Add a label in which the dragpanel events will be displayed
_displayValueLabel = Text::create("Scroll Threshold", "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.5));
_uiLayer->addChild(_displayValueLabel);
// Add the black background
Text* alert = Text::create("PageView", "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 = dynamic_cast<Layout*>(root->getChildByName("background_Panel"));
// Create the page view
PageView* pageView = PageView::create();
pageView->setContentSize(Size(240.0f, 100.0f));
Size backgroundSize = background->getContentSize();
pageView->setPosition(Vec2((widgetSize.width - backgroundSize.width) / 2.0f +
(backgroundSize.width - pageView->getContentSize().width) / 2.0f,
(widgetSize.height - backgroundSize.height) / 2.0f +
(backgroundSize.height - pageView->getContentSize().height) / 2.0f + 20));
int pageCount = 4;
for (int i = 0; i < pageCount; ++i)
{
Layout* layout = Layout::create();
layout->setContentSize(Size(240.0f, 130.0f));
ImageView* imageView = ImageView::create("cocosui/scrollviewbg.png");
imageView->setScale9Enabled(true);
imageView->setContentSize(Size(240, 130));
imageView->setPosition(Vec2(layout->getContentSize().width / 2.0f, layout->getContentSize().height / 2.0f));
layout->addChild(imageView);
Text* label = Text::create(StringUtils::format("page %d",(i+1)), "fonts/Marker Felt.ttf", 30);
label->setColor(Color3B(192, 192, 192));
label->setPosition(Vec2(layout->getContentSize().width / 2.0f, layout->getContentSize().height / 2.0f));
layout->addChild(label);
pageView->insertPage(layout,i);
}
_uiLayer->addChild(pageView);
pageView->setName("pageView");
Slider* slider = Slider::create();
slider->loadBarTexture("cocosui/sliderTrack.png");
slider->loadSlidBallTextures("cocosui/sliderThumb.png", "cocosui/sliderThumb.png", "");
slider->loadProgressBarTexture("cocosui/sliderProgress.png");
slider->setPosition(Vec2(widgetSize.width / 2.0f , widgetSize.height / 2.0f - 40));
slider->addEventListener(CC_CALLBACK_2(UIPageViewCustomScrollThreshold::sliderEvent, this));
slider->setPercent(50);
_uiLayer->addChild(slider);
return true;
}
return false;
}
void UIPageViewCustomScrollThreshold::sliderEvent(Ref *pSender, Slider::EventType type)
{
if (type == Slider::EventType::ON_PERCENTAGE_CHANGED)
{
Slider* slider = dynamic_cast<Slider*>(pSender);
int percent = slider->getPercent();
PageView* pageView = (PageView*)_uiLayer->getChildByName("pageView");
if (percent == 0) {
percent = 1;
}
pageView->setCustomScrollThreshold(percent * 0.01 * pageView->getContentSize().width);
_displayValueLabel->setString(StringUtils::format("Scroll Threshold: %f", pageView->getCustomScrollThreshold()));
}
}
// UIPageViewTouchPropagationTest
UIPageViewTouchPropagationTest::UIPageViewTouchPropagationTest()
: _displayValueLabel(nullptr)
@ -391,7 +289,7 @@ bool UIPageViewTouchPropagationTest::init()
}
pageView->insertPage(outerBox,i);
pageView->insertCustomItem(outerBox, i);
}
pageView->addEventListener(CC_CALLBACK_2(UIPageViewTouchPropagationTest::pageViewEvent, this));
@ -508,7 +406,7 @@ void UIPageViewTouchPropagationTest::pageViewEvent(Ref *pSender, PageView::Event
{
PageView* pageView = dynamic_cast<PageView*>(pSender);
_displayValueLabel->setString(StringUtils::format("page = %ld", pageView->getCurPageIndex() + 1));
_displayValueLabel->setString(StringUtils::format("page = %ld", pageView->getCurrentPageIndex() + 1));
}
break;
@ -554,12 +452,15 @@ bool UIPageViewDynamicAddAndRemoveTest::init()
// Create the page view
PageView* pageView = PageView::create();
pageView->setDirection(ui::PageView::Direction::VERTICAL);
pageView->setContentSize(Size(240.0f, 130.0f));
pageView->setAnchorPoint(Vec2(0.5,0.5));
Size backgroundSize = background->getContentSize();
pageView->setPosition(Vec2(widgetSize.width / 2.0f ,widgetSize.height / 2.0f));
pageView->setBackGroundColor(Color3B::GREEN);
pageView->setBackGroundColorType(Layout::BackGroundColorType::SOLID);
pageView->setIndicatorEnabled(true);
pageView->setIndicatorSpaceBetweenIndexNodes(10);
int pageCount = 4;
for (int i = 0; i < pageCount; ++i)
@ -588,7 +489,7 @@ bool UIPageViewDynamicAddAndRemoveTest::init()
}
pageView->insertPage(outerBox,i);
pageView->insertCustomItem(outerBox, i);
}
pageView->addEventListener(CC_CALLBACK_2(UIPageViewDynamicAddAndRemoveTest::pageViewEvent, this));
@ -624,9 +525,9 @@ bool UIPageViewDynamicAddAndRemoveTest::init()
outerBox->addChild(innerBox);
}
pageView->addPage(outerBox);
_displayValueLabel->setString(StringUtils::format("page count = %ld", pageView->getPages().size()));
CCLOG("current page index = %zd", pageView->getCurPageIndex());
pageView->pushBackCustomItem(outerBox);
_displayValueLabel->setString(StringUtils::format("page count = %ld", pageView->getItems().size()));
CCLOG("current page index = %zd", pageView->getCurrentPageIndex());
});
_uiLayer->addChild(button);
@ -638,16 +539,16 @@ bool UIPageViewDynamicAddAndRemoveTest::init()
button2->setTitleColor(Color3B::RED);
button2->addClickEventListener([=](Ref* sender)
{
if (pageView->getPages().size() > 0)
if (pageView->getItems().size() > 0)
{
pageView->removePageAtIndex(pageView->getPages().size()-1);
pageView->removeItem(pageView->getItems().size()-1);
}
else
{
CCLOG("There is no page to remove!");
}
_displayValueLabel->setString(StringUtils::format("page count = %ld", pageView->getPages().size()));
CCLOG("current page index = %zd", pageView->getCurPageIndex());
_displayValueLabel->setString(StringUtils::format("page count = %ld", pageView->getItems().size()));
CCLOG("current page index = %zd", pageView->getCurrentPageIndex());
});
_uiLayer->addChild(button2);
@ -660,9 +561,9 @@ bool UIPageViewDynamicAddAndRemoveTest::init()
button3->setTitleColor(Color3B::RED);
button3->addClickEventListener([=](Ref* sender)
{
pageView->removeAllPages();
_displayValueLabel->setString(StringUtils::format("page count = %ld", pageView->getPages().size()));
CCLOG("current page index = %zd", pageView->getCurPageIndex());
pageView->removeAllItems();
_displayValueLabel->setString(StringUtils::format("page count = %ld", pageView->getItems().size()));
CCLOG("current page index = %zd", pageView->getCurrentPageIndex());
});
_uiLayer->addChild(button3);
@ -671,8 +572,8 @@ bool UIPageViewDynamicAddAndRemoveTest::init()
button4->setTitleText("Scroll to Page4");
button4->setNormalizedPosition(Vec2(0.85,0.5));
button4->addClickEventListener([=](Ref* sender){
pageView->scrollToPage(3);
CCLOG("current page index = %zd", pageView->getCurPageIndex());
pageView->scrollToItem(3);
CCLOG("current page index = %zd", pageView->getCurrentPageIndex());
});
_uiLayer->addChild(button4);
@ -690,7 +591,7 @@ void UIPageViewDynamicAddAndRemoveTest::pageViewEvent(Ref *pSender, PageView::Ev
{
PageView* pageView = dynamic_cast<PageView*>(pSender);
_displayValueLabel->setString(StringUtils::format("page = %ld", pageView->getCurPageIndex() + 1));
_displayValueLabel->setString(StringUtils::format("page = %ld", pageView->getCurrentPageIndex() + 1));
}
break;
@ -718,7 +619,7 @@ bool UIPageViewJumpToPageTest::init()
Size widgetSize = _widget->getContentSize();
// Add a label in which the dragpanel events will be displayed
_displayValueLabel = Text::create("setCurPageIndex API Test", "fonts/Marker Felt.ttf", 32);
_displayValueLabel = Text::create("setCurrentPageIndex API Test", "fonts/Marker Felt.ttf", 32);
_displayValueLabel->setAnchorPoint(Vec2(0.5f, -1.0f));
_displayValueLabel->setPosition(Vec2(widgetSize.width / 2.0f,
widgetSize.height / 2.0f +
@ -743,8 +644,8 @@ bool UIPageViewJumpToPageTest::init()
(backgroundSize.width - pageView->getContentSize().width) / 2.0f,
(widgetSize.height - backgroundSize.height) / 2.0f +
(backgroundSize.height - pageView->getContentSize().height) / 2.0f));
pageView->removeAllPages();
pageView->setIndicatorEnabled(true);
pageView->removeAllItems();
int pageCount = 4;
for (int i = 0; i < pageCount; ++i)
@ -763,10 +664,10 @@ bool UIPageViewJumpToPageTest::init()
label->setPosition(Vec2(layout->getContentSize().width / 2.0f, layout->getContentSize().height / 2.0f));
layout->addChild(label);
pageView->insertPage(layout,i);
pageView->insertCustomItem(layout, i);
}
pageView->setCurPageIndex(1);
pageView->setCurrentPageIndex(1);
//add buttons to jump to specific page
auto button1 = ui::Button::create();
@ -775,7 +676,7 @@ bool UIPageViewJumpToPageTest::init()
CCLOG("button1 content Size = %f, %f", button1->getContentSize().width,
button1->getContentSize().height);
button1->addClickEventListener([=](Ref*){
pageView->setCurPageIndex(0);
pageView->setCurrentPageIndex(0);
});
_uiLayer->addChild(button1);
@ -785,7 +686,7 @@ bool UIPageViewJumpToPageTest::init()
CCLOG("button2 content Size = %f, %f", button2->getContentSize().width,
button2->getContentSize().height);
button2->addClickEventListener([=](Ref*){
pageView->setCurPageIndex(1);
pageView->setCurrentPageIndex(1);
});
_uiLayer->addChild(button2);
@ -793,7 +694,7 @@ bool UIPageViewJumpToPageTest::init()
button3->setTitleText("Jump to Page3");
button3->setNormalizedPosition(Vec2(0.9, 0.75));
button3->addClickEventListener([=](Ref*){
pageView->setCurPageIndex(2);
pageView->setCurrentPageIndex(2);
});
_uiLayer->addChild(button3);
@ -801,7 +702,7 @@ bool UIPageViewJumpToPageTest::init()
button4->setTitleText("Jump to Page4");
button4->setNormalizedPosition(Vec2(0.9, 0.65));
button4->addClickEventListener([=](Ref*){
pageView->setCurPageIndex(3);
pageView->setCurrentPageIndex(3);
});
_uiLayer->addChild(button4);
_uiLayer->addChild(pageView);
@ -848,15 +749,12 @@ bool UIPageViewVerticalTest::init()
// Create the page view
PageView* pageView = PageView::create();
pageView->setIndicatorEnabled(true);
pageView->setDirection(ui::PageView::Direction::VERTICAL);
pageView->setContentSize(Size(240.0f, 130.0f));
Size backgroundSize = background->getContentSize();
pageView->setPosition(Vec2((widgetSize.width - backgroundSize.width) / 2.0f +
(backgroundSize.width - pageView->getContentSize().width) / 2.0f,
(widgetSize.height - backgroundSize.height) / 2.0f +
(backgroundSize.height - pageView->getContentSize().height) / 2.0f));
pageView->removeAllPages();
pageView->setPosition((widgetSize - pageView->getContentSize()) / 2.0f);
pageView->removeAllItems();
int pageCount = 4;
for (int i = 0; i < pageCount; ++i)
@ -875,7 +773,7 @@ bool UIPageViewVerticalTest::init()
label->setPosition(Vec2(layout->getContentSize().width / 2.0f, layout->getContentSize().height / 2.0f));
layout->addChild(label);
pageView->insertPage(layout,i);
pageView->insertCustomItem(layout, i);
}
pageView->addEventListener(CC_CALLBACK_2(UIPageViewVerticalTest::pageViewEvent, this));
@ -895,7 +793,7 @@ void UIPageViewVerticalTest::pageViewEvent(Ref *pSender, PageView::EventType typ
{
PageView* pageView = dynamic_cast<PageView*>(pSender);
_displayValueLabel->setString(StringUtils::format("page = %ld", pageView->getCurPageIndex() + 1));
_displayValueLabel->setString(StringUtils::format("page = %ld", pageView->getCurrentPageIndex() + 1));
}
break;
@ -949,7 +847,7 @@ bool UIPageViewDisableTouchTest::init()
(backgroundSize.height - pageView->getContentSize().height) / 2.0f));
pageView->setDirection(ui::PageView::Direction::VERTICAL);
pageView->setTouchEnabled(false);
pageView->removeAllPages();
pageView->removeAllItems();
int pageCount = 4;
for (int i = 0; i < pageCount; ++i)
@ -968,7 +866,7 @@ bool UIPageViewDisableTouchTest::init()
label->setPosition(Vec2(layout->getContentSize().width / 2.0f, layout->getContentSize().height / 2.0f));
layout->addChild(label);
pageView->insertPage(layout,i);
pageView->insertCustomItem(layout, i);
}
_uiLayer->addChild(pageView);

View File

@ -61,23 +61,6 @@ protected:
cocos2d::ui::Text* _displayValueLabel;
};
class UIPageViewCustomScrollThreshold : public UIScene
{
public:
CREATE_FUNC(UIPageViewCustomScrollThreshold);
UIPageViewCustomScrollThreshold();
~UIPageViewCustomScrollThreshold();
virtual bool init() override;
void sliderEvent(cocos2d::Ref* sender, cocos2d::ui::Slider::EventType type);
void pageViewEvent(cocos2d::Ref* sender, cocos2d::ui::PageView::EventType type);
protected:
cocos2d::ui::Text* _displayValueLabel;
};
class UIPageViewTouchPropagationTest : public UIScene
{
public: