1. 程式人生 > >給cocos2dx的ui::ScrollView增加滾動條

給cocos2dx的ui::ScrollView增加滾動條

本人現在的cocos2dx的版本是3.0

cocos2dx提供了兩個scrollview,一個是ui::ScrollView,一個是extension::ScrollView,兩個都沒有滾動條! 

這篇文章就是增加ui::ScrollView的滾動條

新建檔案TScrollView.h和TScrollView.cpp

標頭檔案:

#ifndef __UTILS_TSCROLL_VIEW_H__
#define __UTILS_TSCROLL_VIEW_H__
#include "cocos2d.h"
#include "ui/CocosGUI.h"
#include "extensions/cocos-ext.h"
USING_NS_CC;
using namespace ui;
using namespace std;
using namespace extension;
class TScrollView :public ui::ScrollView
{
public:
	static TScrollView* create();
	TScrollView();
	virtual ~TScrollView();
	void setAutoHidden(bool b); // 滾動結束時滾動條是否自動隱藏
	void setIsShowBar(bool b);
	virtual void setDirection(SCROLLVIEW_DIR dir);
	virtual void setSize(const Size &size);
	void setInnerContainerSize(const Size &size);
	virtual void update(float dt) override;
protected:
	void resetBar();
	virtual bool init() override;
protected:
	bool _bar_auto_hidden;
	bool _is_show_bar;
	bool _bar_setted_opacity;
	bool _is_content_smaller; // innerContentSize是否較小(相對iewSize, 較小則不顯示滾動條)
	extension::Scale9Sprite *_barImg;
};
#endif


原始檔

#include "TScrollView.h"

enum
{
	e_scroll_bar_tag = 111
};
TScrollView::TScrollView()
: _bar_auto_hidden(true)
, _is_show_bar(true)
, _bar_setted_opacity(false)
, _is_content_smaller(false)
, _barImg(nullptr)
, ui::ScrollView()
{

}
TScrollView::~TScrollView()
{

}
TScrollView* TScrollView::create()
{
	auto widget = new TScrollView();
	if (widget && widget->init()) {
		widget->autorelease();
		return widget;
	}
	CC_SAFE_DELETE(widget);
	return nullptr;
}
bool TScrollView::init()
{
	if (ui::ScrollView::init()) {
		Size viewSize = getSize();
		Size contentSize = getInnerContainerSize();
		_barImg = extension::Scale9Sprite::create("scroll_bar.png");
		_barImg->setContentSize(Size(10, viewSize.height * (viewSize.height / contentSize.height)));	
		_barImg->setTag(e_scroll_bar_tag);
		Layout::addChild(_barImg, 2, e_scroll_bar_tag); // 必須要這樣寫,否則滾動時不正確!
		return true;
	}
	return false;
}
void TScrollView::setDirection(SCROLLVIEW_DIR dir)
{
	ui::ScrollView::setDirection(dir);
	resetBar();
}
void TScrollView::setSize(const Size &size)
{
	ui::ScrollView::setSize(size);
	resetBar();
}
void TScrollView::setInnerContainerSize(const Size &size)
{
	ui::ScrollView::setInnerContainerSize(size);
	resetBar();
}
void TScrollView::setAutoHidden(bool b)
{
	_bar_auto_hidden = b;
	if (_barImg && _bar_auto_hidden) {
		_barImg->setVisible(false);
	}
}
void TScrollView::setIsShowBar(bool b)
{
	_is_show_bar = b;
	if (_is_show_bar == false) {
		_barImg->setVisible(false);
	} else {
		resetBar();
	}
}
void TScrollView::update(float dt)
{
	ui::ScrollView::update(dt);
	if (_is_show_bar && _barImg && _is_content_smaller == false) {		
		if (getDirection() == SCROLLVIEW_DIR_VERTICAL) {
			Size viewSize = getSize();
			Size contentSize = getInnerContainerSize();			
			float y = _barImg->getContentSize().height + viewSize.height * (-_moveChildPoint.y / contentSize.height);
			_barImg->setPositionY(y);
		} else if (getDirection() == SCROLLVIEW_DIR_HORIZONTAL) {
			Size viewSize = getSize();
			Size contentSize = getInnerContainerSize();
			float x = viewSize.width * (-_moveChildPoint.x / contentSize.width);
			_barImg->setPositionX(x);
		}
		if (_bar_auto_hidden) {
			if ((_bePressed || _autoScrollAddUpTime > 0.0f) && _bar_setted_opacity == false) {
				_barImg->setVisible(true);
				_barImg->setOpacity(0);
				_barImg->runAction(FadeIn::create(0.2f));
				_bar_setted_opacity = true;
			} else if (_bar_setted_opacity && _autoScrollAddUpTime <= 0.0f && _bePressed == false) {
				_barImg->runAction(FadeOut::create(0.2f));
				_bar_setted_opacity = false;
			}
		}
	}
}
void TScrollView::resetBar()
{
	if (_barImg == nullptr) {
		return;
	}
	Size viewSize = getSize();
	Size contentSize = getInnerContainerSize();
	SCROLLVIEW_DIR dir = getDirection();
	if (dir == SCROLLVIEW_DIR_HORIZONTAL) {
		if (contentSize.width > 0) {
			_barImg->setContentSize(Size(8, viewSize.width * (viewSize.width / contentSize.width)));			
			_barImg->setPosition(Point(0, 8));
			_barImg->setAnchorPoint(Point(0, 0));
			_barImg->setRotation(90.0f);
		}
	} else if (dir == SCROLLVIEW_DIR_VERTICAL) {
		if (contentSize.height > 0) {
			_barImg->setContentSize(Size(8, viewSize.height * (viewSize.height / contentSize.height)));
			_barImg->setPosition(Point(viewSize.width, contentSize.height));
			_barImg->setAnchorPoint(Point(1, 1));			
		}
	}	
	if (_is_show_bar) {
		if (dir == SCROLLVIEW_DIR_VERTICAL) {
			_is_content_smaller = viewSize.height + 20 > contentSize.height;
			if (viewSize.height + 20 > contentSize.height || _bar_auto_hidden) {
				_barImg->setVisible(false); // contentSize較小時不顯示滾動條
			} else {
				_barImg->setVisible(true);
			}
		} else if (dir == SCROLLVIEW_DIR_HORIZONTAL) {
			_is_content_smaller = viewSize.width + 20 > contentSize.width;
			if (viewSize.width + 20 > contentSize.width || _bar_auto_hidden) {
				_barImg->setVisible(false);
			} else {
				_barImg->setVisible(true);
			}
		}
	} else {
		_barImg->setVisible(false);
	}
}