Add padding options to ListView (#17587)

* Add options to ListView for setting padding

* Add 'setPadding' method test cases.
This commit is contained in:
shintaro.tanikawa 2017-06-15 15:56:54 +09:00 committed by minggo
parent f79a138c2b
commit f9c8bd4bc1
4 changed files with 379 additions and 9 deletions

View File

@ -39,6 +39,10 @@ _gravity(Gravity::CENTER_VERTICAL),
_magneticType(MagneticType::NONE), _magneticType(MagneticType::NONE),
_magneticAllowedOutOfBoundary(true), _magneticAllowedOutOfBoundary(true),
_itemsMargin(0.0f), _itemsMargin(0.0f),
_leftPadding(0.0f),
_topPadding(0.0f),
_rightPadding(0.0f),
_bottomPadding(0.0f),
_scrollTime(DEFAULT_TIME_IN_SEC_FOR_SCROLL_TO_ITEM), _scrollTime(DEFAULT_TIME_IN_SEC_FOR_SCROLL_TO_ITEM),
_curSelectedIndex(-1), _curSelectedIndex(-1),
_innerContainerDoLayoutDirty(true), _innerContainerDoLayoutDirty(true),
@ -113,7 +117,7 @@ void ListView::updateInnerContainerSize()
case Direction::VERTICAL: case Direction::VERTICAL:
{ {
size_t length = _items.size(); size_t length = _items.size();
float totalHeight = (length - 1) * _itemsMargin; float totalHeight = (length - 1) * _itemsMargin + (_topPadding + _bottomPadding);
for (auto& item : _items) for (auto& item : _items)
{ {
totalHeight += item->getContentSize().height; totalHeight += item->getContentSize().height;
@ -126,7 +130,7 @@ void ListView::updateInnerContainerSize()
case Direction::HORIZONTAL: case Direction::HORIZONTAL:
{ {
size_t length = _items.size(); size_t length = _items.size();
float totalWidth = (length - 1) * _itemsMargin; float totalWidth = (length - 1) * _itemsMargin + (_leftPadding + _rightPadding);
for (auto& item : _items) for (auto& item : _items)
{ {
totalWidth += item->getContentSize().width; totalWidth += item->getContentSize().width;
@ -162,11 +166,15 @@ void ListView::remedyVerticalLayoutParameter(LinearLayoutParameter* layoutParame
if (0 == itemIndex) if (0 == itemIndex)
{ {
layoutParameter->setMargin(Margin::ZERO); layoutParameter->setMargin(Margin(_leftPadding, _topPadding, _rightPadding, 0.f));
}
else if (_items.size() - 1 == itemIndex)
{
layoutParameter->setMargin(Margin(_leftPadding, _itemsMargin, _rightPadding, _bottomPadding));
} }
else else
{ {
layoutParameter->setMargin(Margin(0.0f, _itemsMargin, 0.0f, 0.0f)); layoutParameter->setMargin(Margin(_leftPadding, _itemsMargin, _rightPadding, 0.0f));
} }
} }
@ -190,11 +198,15 @@ void ListView::remedyHorizontalLayoutParameter(LinearLayoutParameter* layoutPara
} }
if (0 == itemIndex) if (0 == itemIndex)
{ {
layoutParameter->setMargin(Margin::ZERO); layoutParameter->setMargin(Margin(_leftPadding, _topPadding, 0.f, _bottomPadding));
}
else if (_items.size() == itemIndex)
{
layoutParameter->setMargin(Margin(_itemsMargin, _topPadding, _rightPadding, _bottomPadding));
} }
else else
{ {
layoutParameter->setMargin(Margin(_itemsMargin, 0.0f, 0.0f, 0.0f)); layoutParameter->setMargin(Margin(_itemsMargin, _topPadding, 0.f, _bottomPadding));
} }
} }
@ -441,6 +453,79 @@ float ListView::getItemsMargin()const
return _itemsMargin; return _itemsMargin;
} }
void ListView::setPadding(float l, float t, float r, float b)
{
if (l == _leftPadding && t == _topPadding && r == _rightPadding && b == _bottomPadding)
{
return;
}
_leftPadding = l;
_topPadding = t;
_rightPadding = r;
_bottomPadding = b;
requestDoLayout();
}
void ListView::setLeftPadding(float l)
{
if (l == _leftPadding)
{
return;
}
_leftPadding = l;
requestDoLayout();
}
void ListView::setTopPadding(float t)
{
if (t == _topPadding)
{
return;
}
_topPadding = t;
requestDoLayout();
}
void ListView::setRightPadding(float r)
{
if (r == _rightPadding)
{
return;
}
_rightPadding = r;
requestDoLayout();
}
void ListView::setBottomPadding(float b)
{
if (b == _bottomPadding)
{
return;
}
_bottomPadding = b;
requestDoLayout();
}
float ListView::getLeftPadding() const
{
return _leftPadding;
}
float ListView::getTopPadding() const
{
return _topPadding;
}
float ListView::getRightPadding() const
{
return _rightPadding;
}
float ListView::getBottomPadding() const
{
return _bottomPadding;
}
void ListView::setScrollDuration(float time) void ListView::setScrollDuration(float time)
{ {
if (time >= 0) if (time >= 0)

View File

@ -244,6 +244,63 @@ public:
*/ */
float getItemsMargin()const; float getItemsMargin()const;
/**
* Change padding with left, top, right, and bottom padding.
* @param l Left padding in float.
* @param t Top margin in float.
* @param r Right margin in float.
* @param b Bottom margin in float.
*/
void setPadding(float l, float t, float r, float b);
/**
* Change padding with left padding
* @param l Left padding in float.
*/
void setLeftPadding(float l);
/**
* Change padding with top padding
* @param t Top padding in float
*/
void setTopPadding(float t);
/**
* Change padding with right padding
* @param r Right padding in float
*/
void setRightPadding(float r);
/**
* Change padding with bottom padding
* @param b Bottom padding in float
*/
void setBottomPadding(float b);
/**
* Get the left padding in ListView
* @return Left padding in float
*/
float getLeftPadding() const;
/**
* Get the top padding in ListView
* @return Top padding in float
*/
float getTopPadding() const;
/**
* Get the right padding in ListView
* @return Right padding in float
*/
float getRightPadding() const;
/**
* Get the bottom padding in ListView
* @return Bottom padding in float
*/
float getBottomPadding() const;
/** /**
* Set the time in seconds to scroll between items. * Set the time in seconds to scroll between items.
* Subsequent calls of function 'scrollToItem', will take 'time' seconds for scrolling. * Subsequent calls of function 'scrollToItem', will take 'time' seconds for scrolling.
@ -442,6 +499,11 @@ protected:
float _itemsMargin; float _itemsMargin;
float _leftPadding;
float _topPadding;
float _rightPadding;
float _bottomPadding;
float _scrollTime; float _scrollTime;
ssize_t _curSelectedIndex; ssize_t _curSelectedIndex;

View File

@ -13,6 +13,8 @@ UIListViewTests::UIListViewTests()
ADD_TEST_CASE(UIListViewTest_ScrollToItemHorizontal); ADD_TEST_CASE(UIListViewTest_ScrollToItemHorizontal);
ADD_TEST_CASE(UIListViewTest_MagneticVertical); ADD_TEST_CASE(UIListViewTest_MagneticVertical);
ADD_TEST_CASE(UIListViewTest_MagneticHorizontal); ADD_TEST_CASE(UIListViewTest_MagneticHorizontal);
ADD_TEST_CASE(UIListViewTest_PaddingVertical);
ADD_TEST_CASE(UIListViewTest_PaddingHorizontal);
ADD_TEST_CASE(Issue12692); ADD_TEST_CASE(Issue12692);
ADD_TEST_CASE(Issue8316); ADD_TEST_CASE(Issue8316);
} }
@ -871,3 +873,187 @@ bool UIListViewTest_Magnetic::init()
} }
return true; return true;
} }
// UIListViewTest_Padding
bool UIListViewTest_Padding::init()
{
if(!UIScene::init())
{
return false;
}
Size layerSize = _uiLayer->getContentSize();
_titleLabel = Text::create("Set Padding", "fonts/Marker Felt.ttf", 32);
_titleLabel->setAnchorPoint(Vec2::ANCHOR_MIDDLE);
_titleLabel->setPosition(Vec2(layerSize / 2) + Vec2(0, _titleLabel->getContentSize().height * 3.15f));
_uiLayer->addChild(_titleLabel, 3);
// Create the list view
_listView = ListView::create();
_listView->setDirection(getListViewDirection());
_listView->setBounceEnabled(true);
_listView->setBackGroundImage("cocosui/green_edit.png");
_listView->setBackGroundImageScale9Enabled(true);
_listView->setContentSize(layerSize / 2);
_listView->setScrollBarPositionFromCorner(Vec2(7, 7));
_listView->setItemsMargin(2.0f);
_listView->setAnchorPoint(Vec2::ANCHOR_MIDDLE);
_listView->setGravity(ListView::Gravity::TOP);
_listView->setPosition(layerSize / 2);
_uiLayer->addChild(_listView);
// Guide line for center align
{
DrawNode* pNode = DrawNode::create();
Vec2 center = layerSize / 2;
if(getListViewDirection() == ScrollView::Direction::HORIZONTAL)
{
float halfY = 110;
pNode->drawLine(Vec2(center.x, center.y - halfY), Vec2(center.x, center.y + halfY), Color4F(0, 0, 0, 1));
}
else
{
float halfX = 150;
pNode->drawLine(Vec2(center.x - halfX, center.y), Vec2(center.x + halfX, center.y), Color4F(0, 0, 0, 1));
}
pNode->setLineWidth(2);
_uiLayer->addChild(pNode);
}
// Slider for setting padding
{
auto title = Text::create("Padding", "fonts/Marker Felt.ttf", 14);
title->setAnchorPoint(Vec2::ANCHOR_MIDDLE);
title->setPosition(Vec2(30, 170));
_uiLayer->addChild(title);
for (int i = 0; i < 4; ++i)
{
auto slider = Slider::create();
slider->loadBarTexture("cocosui/sliderTrack.png");
slider->loadSlidBallTextures("cocosui/sliderThumb.png", "cocosui/sliderThumb.png", "");
slider->loadProgressBarTexture("cocosui/sliderProgress.png");
slider->setScale9Enabled(true);
slider->setCapInsets(Rect(0, 0, 0, 0));
slider->setContentSize(Size(30, 10));
slider->setPosition(Vec2(60, 150 - (25 * i)));
slider->addEventListener(CC_CALLBACK_2(UIListViewTest_Padding::sliderEvent, this));
slider->setTag(i);
_uiLayer->addChild(slider);
std::string str;
if (i == 0) str = "Left";
else if (i == 1) str = "Top";
else if (i == 2) str = "Right";
else if (i == 3) str = "Bottom";
// Show title of slider
{
auto text = Text::create(str, "fonts/Marker Felt.ttf", 12);
text->setAnchorPoint(Vec2::ANCHOR_MIDDLE_LEFT);
text->setPosition(Vec2(3, 150 - (25 * i)));
_uiLayer->addChild(text);
}
// Show value of paddings
{
auto text = Text::create(str + "\nPadding=0", "fonts/Marker Felt.ttf", 12);
text->setAnchorPoint(Vec2::ANCHOR_MIDDLE_LEFT);
text->setPosition(Vec2(layerSize.width - 65, 200 - (40 * i)));
_uiLayer->addChild(text);
_paddingLabels[i] = text;
}
}
}
// Show the indexes of items on each boundary.
{
for(int i = 0; i < 5; ++i)
{
_indexLabels[i] = Text::create(" ", "fonts/Marker Felt.ttf", 12);
_indexLabels[i]->setAnchorPoint(Vec2::ANCHOR_MIDDLE);
_uiLayer->addChild(_indexLabels[i]);
}
float deltaX = 145, deltaY = 90;
_indexLabels[0]->setPosition(_uiLayer->getContentSize() / 2 + Size(-deltaX, 0)); // left
_indexLabels[1]->setPosition(_uiLayer->getContentSize() / 2 + Size(deltaX, 0)); // right
_indexLabels[2]->setPosition(_uiLayer->getContentSize() / 2 + Size(0, deltaY)); // top
_indexLabels[3]->setPosition(_uiLayer->getContentSize() / 2 + Size(0, -deltaY)); // bottom
_indexLabels[4]->setPosition(_uiLayer->getContentSize() / 2 + Size(deltaX, deltaY)); // center
// Callback
_listView->ScrollView::addEventListener([this](Ref* ref, ScrollView::EventType eventType) {
ListView* listView = dynamic_cast<ListView*>(ref);
if(listView == nullptr || eventType != ScrollView::EventType::CONTAINER_MOVED)
{
return;
}
auto left = listView->getLeftmostItemInCurrentView();
auto right = listView->getRightmostItemInCurrentView();
auto top = listView->getTopmostItemInCurrentView();
auto bottom = listView->getBottommostItemInCurrentView();
auto center = listView->getCenterItemInCurrentView();
_indexLabels[0]->setString(StringUtils::format("Left\nindex=%zd", listView->getIndex(left)));
_indexLabels[1]->setString(StringUtils::format("RIght\nindex=%zd", listView->getIndex(right)));
_indexLabels[2]->setString(StringUtils::format("Top index=%zd", listView->getIndex(top)));
_indexLabels[3]->setString(StringUtils::format("Bottom index=%zd", listView->getIndex(bottom)));
_indexLabels[4]->setString(StringUtils::format("Center\nindex=%zd", listView->getIndex(center)));
});
}
// Add list items
static const Size BUTTON_SIZE(100, 70);
for (int i = 0; i < 40; ++i)
{
auto pButton = Button::create("cocosui/button.png", "cocosui/buttonHighlighted.png");
pButton->setContentSize(BUTTON_SIZE);
pButton->setScale9Enabled(true);
pButton->setTitleText(StringUtils::format("Button-%d", i));
_listView->pushBackCustomItem(pButton);
}
return true;
}
void UIListViewTest_Padding::sliderEvent(Ref *pSender, Slider::EventType type)
{
if (type == Slider::EventType::ON_PERCENTAGE_CHANGED)
{
auto slider = dynamic_cast<Slider*>(pSender);
// left
if (slider && slider->getTag() == 0)
{
int left = slider->getPercent() / 100.f * 50.f;
CCLOG("Left Padding: %d", left);
_listView->setLeftPadding(left);
_paddingLabels[0]->setString(StringUtils::format("Left\nPadding=%d", left));
}
// top
if (slider && slider->getTag() == 1)
{
int top = slider->getPercent() / 100.f * 50.f;
CCLOG("Top Padding: %d", top);
_listView->setTopPadding(top);
_paddingLabels[1]->setString(StringUtils::format("Top\nPadding=%d", top));
}
// right
if (slider && slider->getTag() == 2)
{
int right = slider->getPercent() / 100.f * 50.f;
CCLOG("Right Padding: %d", right);
_listView->setRightPadding(right);
_paddingLabels[2]->setString(StringUtils::format("Right\nPadding=%d", right));
}
// bottom
if (slider && slider->getTag() == 3)
{
int bottom = slider->getPercent() / 100.f * 50.f;
CCLOG("Bottom Padding: %d", bottom);
_listView->setBottomPadding(bottom);
_paddingLabels[3]->setString(StringUtils::format("Bottom\nPadding=%d", bottom));
}
}
}

View File

@ -179,4 +179,41 @@ public:
} }
}; };
// Test for setting padding
class UIListViewTest_Padding : public UIScene
{
protected:
virtual bool init() override;
virtual cocos2d::ui::ScrollView::Direction getListViewDirection() const = 0;
void sliderEvent(cocos2d::Ref *pSender, cocos2d::ui::Slider::EventType type);
cocos2d::ui::ListView* _listView;
cocos2d::ui::Text* _titleLabel;
cocos2d::ui::Text* _indexLabels[5];
cocos2d::ui::Text* _paddingLabels[4];
};
class UIListViewTest_PaddingVertical : public UIListViewTest_Padding
{
public:
CREATE_FUNC(UIListViewTest_PaddingVertical);
virtual cocos2d::ui::ScrollView::Direction getListViewDirection() const
{
return cocos2d::ui::ScrollView::Direction::VERTICAL;
}
};
class UIListViewTest_PaddingHorizontal : public UIListViewTest_Padding
{
public:
CREATE_FUNC(UIListViewTest_PaddingHorizontal);
virtual cocos2d::ui::ScrollView::Direction getListViewDirection() const
{
return cocos2d::ui::ScrollView::Direction::HORIZONTAL;
}
};
#endif /* defined(__TestCpp__UIListViewTest__) */ #endif /* defined(__TestCpp__UIListViewTest__) */