对应源码位置:cocos2d-x-3.3\cocos\ui\UI*
HBox
与 VBox
这两者的实现很简单
class CC_GUI_DLL VBox : public Layout{
public:
/**
* Default constructor
*/
VBox();
/**
* Default destructor
*/
virtual ~VBox();
/**
* Allocates and initializes a VBox.
*/
static VBox* create();
static VBox* create(const Size& size);
CC_CONSTRUCTOR_ACCESS:
//initializes state of widget.
virtual bool init() override;
virtual bool initWithSize(const Size& size);
};
//具体
bool VBox::init()
{
if (Layout::init())
{
//只是将 Type设置为 VERTICAL
setLayoutType(Layout::Type::VERTICAL);
return true;
}
return false;
}
//同时设置 区域大小
bool VBox::initWithSize(const Size& size)
{
if (init())
{
setContentSize(size);
return true;
}
return false;
}
//Hbox类型 不贴代码了
Scale9Sprite
的实现
Scale9Sprite
就是 Android中的 常说的.9图片。这部分代码很多但是思想却很简单。
首先 将原始图形根据对应切割点的位置,找出对应9个位置的纹理位置的坐标以对应的矩形大小。从而根据原本的纹理以及纹理坐标和对应矩形代表的精灵位置。构造出9个Sprite
对象,然后当Scale9Sprite
对象的大小发生变化时,将对应的调整部分的sprite
进行缩放。绘制的时候绘制这9个Sprite
即可。
bool _spritesGenerated;
Rect _spriteRect;
bool _spriteFrameRotated;
Rect _capInsetsInternal;
bool _positionsAreDirty;
Sprite* _scale9Image; //the original sprite
//分割成 9部分
Sprite* _topLeft;
Sprite* _top;
Sprite* _topRight;
Sprite* _left;
Sprite* _centre;
Sprite* _right;
Sprite* _bottomLeft;
Sprite* _bottom;
Sprite* _bottomRight;
bool _scale9Enabled;
Size _topLeftSize;
Size _centerSize;
Size _bottomRightSize;
Vec2 _centerOffset;
ImageView
的实现
class CC_GUI_DLL ImageView : public Widget
{
DECLARE_CLASS_GUI_INFO
public:
static ImageView* create(const std::string& imageFileName, TextureResType texType = TextureResType::LOCAL);
void loadTexture(const std::string& fileName,TextureResType texType = TextureResType::LOCAL);
void setTextureRect(const Rect& rect);
//是否启用点9
void setScale9Enabled(bool able);
protected:
bool _scale9Enabled;
bool _prevIgnoreSize;
Rect _capInsets;
Scale9Sprite* _imageRenderer;
std::string _textureFile;
TextureResType _imageTexType;
Size _imageTextureSize;
bool _imageRendererAdaptDirty;
};
//create
ImageView* ImageView::create(const std::string &imageFileName, TextureResType texType)
{
ImageView *widget = new (std::nothrow) ImageView;
if (widget && widget->init(imageFileName, texType)) {
widget->autorelease();
return widget;
}
CC_SAFE_DELETE(widget);
return nullptr;
}
bool ImageView::init(const std::string &imageFileName, TextureResType texType)
{
bool bRet = true;
do {
if (!Widget::init()) {
bRet = false;
break;
}
//加载纹理
this->loadTexture(imageFileName, texType);
} while (0);
return bRet;
}
//加载
void ImageView::loadTexture(const std::string& fileName, TextureResType texType)
{
if (fileName.empty() || (_textureFile == fileName && _imageTexType == texType))
{
return;
}
_textureFile = fileName;
_imageTexType = texType;
switch (_imageTexType)
{
case TextureResType::LOCAL:
_imageRenderer->initWithFile(fileName);
break;
case TextureResType::PLIST:
_imageRenderer->initWithSpriteFrameName(fileName);
break;
default:
break;
}
_imageTextureSize = _imageRenderer->getContentSize();
this->updateChildrenDisplayedRGBA();
//使用 纹理大小 当无视尺寸时 用户自定义的大小不起作用 只使用纹理大小
updateContentSizeWithTextureSize(_imageTextureSize);
_imageRendererAdaptDirty = true;
}
Button
的实现
//其主要 包含三个图片 用于表示状态的切换 同时 又一个 字符串表示 显示的内容
virtual bool init(const std::string& normalImage,
const std::string& selectedImage = "",
const std::string& disableImage = "",
TextureResType texType = TextureResType::LOCAL);
protected:
virtual void initRenderer() override;
virtual void onPressStateChangedToNormal() override;
virtual void onPressStateChangedToPressed() override;
virtual void onPressStateChangedToDisabled() override;
virtual void onSizeChanged() override;
Scale9Sprite* _buttonNormalRenderer;
Scale9Sprite* _buttonClickedRenderer;
Scale9Sprite* _buttonDisableRenderer;
Label* _titleRenderer;
//处理 点击状态的回调
void Button::onPressStateChangedToNormal()
{
//设置 图片的切换
_buttonNormalRenderer->setVisible(true);
_buttonClickedRenderer->setVisible(false);
_buttonDisableRenderer->setVisible(false);
if (_pressedTextureLoaded)
{
//设置动作
if (_pressedActionEnabled)
{
_buttonNormalRenderer->stopAllActions();
_buttonClickedRenderer->stopAllActions();
Action *zoomAction = ScaleTo::create(ZOOM_ACTION_TIME_STEP, _normalTextureScaleXInSize, _normalTextureScaleYInSize);
_buttonNormalRenderer->runAction(zoomAction);
_buttonClickedRenderer->setScale(_pressedTextureScaleXInSize, _pressedTextureScaleYInSize);
_titleRenderer->stopAllActions();
if (_unifySize)
{
Action *zoomTitleAction = ScaleTo::create(ZOOM_ACTION_TIME_STEP, 1, 1);
_titleRenderer->runAction(zoomTitleAction);
}
else
{
_titleRenderer->runAction(zoomAction->clone());
}
}
}
else
{
if (_scale9Enabled)
{
_buttonNormalRenderer->setColor(Color3B::WHITE);
}
else
{
_buttonNormalRenderer->stopAllActions();
_buttonNormalRenderer->setScale(_normalTextureScaleXInSize, _normalTextureScaleYInSize);
_titleRenderer->stopAllActions();
if (_unifySize)
{
_titleRenderer->setScaleX(1.0f);
_titleRenderer->setScaleY(1.0f);
}
else
{
_titleRenderer->setScaleX(_normalTextureScaleXInSize);
_titleRenderer->setScaleY(_normalTextureScaleYInSize);
}
}
}
}
void Button::onPressStateChangedToPressed()
{
if (_pressedTextureLoaded)
{
_buttonNormalRenderer->setVisible(false);
_buttonClickedRenderer->setVisible(true);
_buttonDisableRenderer->setVisible(false);
if (_pressedActionEnabled)
{
_buttonNormalRenderer->stopAllActions();
_buttonClickedRenderer->stopAllActions();
Action *zoomAction = ScaleTo::create(ZOOM_ACTION_TIME_STEP, _pressedTextureScaleXInSize + _zoomScale, _pressedTextureScaleYInSize + _zoomScale);
_buttonClickedRenderer->runAction(zoomAction);
_buttonNormalRenderer->setScale(_pressedTextureScaleXInSize + _zoomScale, _pressedTextureScaleYInSize + _zoomScale);
_titleRenderer->stopAllActions();
//we must call zoomAction->clone here
_titleRenderer->runAction(zoomAction->clone());
if (_unifySize)
{
Action *zoomTitleAction = ScaleTo::create(ZOOM_ACTION_TIME_STEP, 1 + _zoomScale, 1 + _zoomScale);
_titleRenderer->runAction(zoomTitleAction);
}
else
{
_titleRenderer->runAction(zoomAction->clone());
}
}
}
else
{
_buttonNormalRenderer->setVisible(true);
_buttonClickedRenderer->setVisible(true);
_buttonDisableRenderer->setVisible(false);
if (_scale9Enabled)
{
_buttonNormalRenderer->setColor(Color3B::GRAY);
}
else
{
_buttonNormalRenderer->stopAllActions();
_buttonNormalRenderer->setScale(_normalTextureScaleXInSize +_zoomScale, _normalTextureScaleYInSize + _zoomScale);
_titleRenderer->stopAllActions();
if (_unifySize)
{
_titleRenderer->setScaleX(1.0f + _zoomScale);
_titleRenderer->setScaleY(1.0f + _zoomScale);
}
else
{
_titleRenderer->setScaleX(_normalTextureScaleXInSize + _zoomScale);
_titleRenderer->setScaleY(_normalTextureScaleYInSize + _zoomScale);
}
}
}
}
void Button::onPressStateChangedToDisabled()
{
_buttonNormalRenderer->setVisible(false);
_buttonClickedRenderer->setVisible(false);
_buttonDisableRenderer->setVisible(true);
_buttonNormalRenderer->setScale(_normalTextureScaleXInSize, _normalTextureScaleYInSize);
_buttonClickedRenderer->setScale(_pressedTextureScaleXInSize, _pressedTextureScaleYInSize);
}
最后
下一篇 分析 内存管理 的实现。