2014-03-11 17:13:54 +08:00
|
|
|
/****************************************************************************
|
|
|
|
Copyright (c) 2013-2014 Chukong Technologies Inc.
|
|
|
|
|
|
|
|
http://www.cocos2d-x.org
|
|
|
|
|
|
|
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
|
|
of this software and associated documentation files (the "Software"), to deal
|
|
|
|
in the Software without restriction, including without limitation the rights
|
|
|
|
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
|
|
copies of the Software, and to permit persons to whom the Software is
|
|
|
|
furnished to do so, subject to the following conditions:
|
|
|
|
|
|
|
|
The above copyright notice and this permission notice shall be included in
|
|
|
|
all copies or substantial portions of the Software.
|
|
|
|
|
|
|
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
|
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
|
|
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
|
|
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
|
|
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
|
|
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
|
|
|
THE SOFTWARE.
|
|
|
|
****************************************************************************/
|
|
|
|
|
|
|
|
#include "ui/UIWidget.h"
|
|
|
|
#include "ui/UILayout.h"
|
|
|
|
#include "ui/UIHelper.h"
|
|
|
|
|
|
|
|
NS_CC_BEGIN
|
|
|
|
|
|
|
|
namespace ui {
|
|
|
|
|
2014-05-04 11:23:20 +08:00
|
|
|
Widget* Widget::_focusedWidget = nullptr;
|
2014-05-07 18:27:05 +08:00
|
|
|
Widget* Widget::_realFocusedWidget = nullptr;
|
2014-05-04 11:23:20 +08:00
|
|
|
|
2014-03-11 17:13:54 +08:00
|
|
|
Widget::Widget():
|
|
|
|
_enabled(true),
|
|
|
|
_bright(true),
|
|
|
|
_touchEnabled(false),
|
2014-05-04 10:19:11 +08:00
|
|
|
_highlight(false),
|
2014-05-09 15:23:34 +08:00
|
|
|
_brightStyle(BrightStyle::NONE),
|
2014-05-15 01:07:09 +08:00
|
|
|
_touchStartPos(Vec2::ZERO),
|
|
|
|
_touchMovePos(Vec2::ZERO),
|
|
|
|
_touchEndPos(Vec2::ZERO),
|
2014-03-11 17:13:54 +08:00
|
|
|
_touchEventListener(nullptr),
|
|
|
|
_touchEventSelector(nullptr),
|
|
|
|
_name("default"),
|
|
|
|
_actionTag(0),
|
|
|
|
_size(Size::ZERO),
|
|
|
|
_customSize(Size::ZERO),
|
|
|
|
_ignoreSize(false),
|
|
|
|
_affectByClipping(false),
|
2014-05-09 09:37:51 +08:00
|
|
|
_sizeType(SizeType::ABSOLUTE),
|
2014-05-15 01:07:09 +08:00
|
|
|
_sizePercent(Vec2::ZERO),
|
2014-05-08 18:25:49 +08:00
|
|
|
_positionType(PositionType::ABSOLUTE),
|
2014-05-15 01:07:09 +08:00
|
|
|
_positionPercent(Vec2::ZERO),
|
2014-03-11 17:13:54 +08:00
|
|
|
_reorderWidgetChildDirty(true),
|
|
|
|
_hitted(false),
|
|
|
|
_touchListener(nullptr),
|
|
|
|
_color(Color3B::WHITE),
|
|
|
|
_opacity(255),
|
|
|
|
_flippedX(false),
|
2014-05-04 11:23:20 +08:00
|
|
|
_flippedY(false),
|
|
|
|
_focused(false),
|
2014-05-20 14:36:29 +08:00
|
|
|
_focusEnabled(true)
|
2014-03-11 17:13:54 +08:00
|
|
|
{
|
2014-05-04 11:23:20 +08:00
|
|
|
onFocusChanged = CC_CALLBACK_2(Widget::onFocusChange,this);
|
|
|
|
onNextFocusedWidget = nullptr;
|
2014-05-15 01:07:09 +08:00
|
|
|
this->setAnchorPoint(Vec2(0.5f, 0.5f));
|
2014-05-13 16:37:41 +08:00
|
|
|
this->setTouchEnabled(true);
|
2014-03-11 17:13:54 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
Widget::~Widget()
|
|
|
|
{
|
|
|
|
setTouchEnabled(false);
|
2014-05-09 11:28:36 +08:00
|
|
|
|
|
|
|
//cleanup focused widget
|
2014-05-05 11:25:30 +08:00
|
|
|
if (_focusedWidget == this) {
|
|
|
|
_focusedWidget = nullptr;
|
|
|
|
}
|
2014-05-07 18:27:05 +08:00
|
|
|
if (_realFocusedWidget == this) {
|
|
|
|
_realFocusedWidget = nullptr;
|
|
|
|
}
|
2014-03-11 17:13:54 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
Widget* Widget::create()
|
|
|
|
{
|
|
|
|
Widget* widget = new Widget();
|
|
|
|
if (widget && widget->init())
|
|
|
|
{
|
|
|
|
widget->autorelease();
|
|
|
|
return widget;
|
|
|
|
}
|
|
|
|
CC_SAFE_DELETE(widget);
|
|
|
|
return nullptr;
|
|
|
|
}
|
|
|
|
|
|
|
|
bool Widget::init()
|
|
|
|
{
|
2014-03-24 15:25:44 +08:00
|
|
|
if (ProtectedNode::init())
|
2014-03-11 17:13:54 +08:00
|
|
|
{
|
|
|
|
initRenderer();
|
|
|
|
setBright(true);
|
|
|
|
ignoreContentAdaptWithSize(true);
|
2014-05-15 01:07:09 +08:00
|
|
|
setAnchorPoint(Vec2(0.5f, 0.5f));
|
2014-03-11 17:13:54 +08:00
|
|
|
return true;
|
|
|
|
}
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
void Widget::onEnter()
|
|
|
|
{
|
|
|
|
updateSizeAndPosition();
|
2014-03-24 15:25:44 +08:00
|
|
|
ProtectedNode::onEnter();
|
2014-03-11 17:13:54 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
void Widget::onExit()
|
|
|
|
{
|
|
|
|
unscheduleUpdate();
|
2014-03-24 15:25:44 +08:00
|
|
|
ProtectedNode::onExit();
|
2014-03-11 17:13:54 +08:00
|
|
|
}
|
|
|
|
|
2014-05-15 01:07:09 +08:00
|
|
|
void Widget::visit(Renderer *renderer, const Mat4 &parentTransform, bool parentTransformUpdated)
|
2014-03-11 17:13:54 +08:00
|
|
|
{
|
2014-05-13 14:56:44 +08:00
|
|
|
if (_visible)
|
2014-03-11 17:13:54 +08:00
|
|
|
{
|
2014-04-17 14:08:25 +08:00
|
|
|
adaptRenderers();
|
2014-03-24 15:25:44 +08:00
|
|
|
ProtectedNode::visit(renderer, parentTransform, parentTransformUpdated);
|
2014-03-11 17:13:54 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
Widget* Widget::getWidgetParent()
|
|
|
|
{
|
|
|
|
return dynamic_cast<Widget*>(getParent());
|
|
|
|
}
|
|
|
|
|
2014-03-24 15:25:44 +08:00
|
|
|
void Widget::setEnabled(bool enabled)
|
2014-03-11 17:13:54 +08:00
|
|
|
{
|
2014-03-24 15:25:44 +08:00
|
|
|
_enabled = enabled;
|
2014-03-11 17:13:54 +08:00
|
|
|
}
|
|
|
|
|
2014-05-12 14:59:00 +08:00
|
|
|
Widget* Widget::getChildByName(const std::string& name)
|
2014-03-11 17:13:54 +08:00
|
|
|
{
|
2014-03-24 15:25:44 +08:00
|
|
|
for (auto& child : _children)
|
2014-03-11 17:13:54 +08:00
|
|
|
{
|
|
|
|
if (child)
|
|
|
|
{
|
2014-03-24 15:25:44 +08:00
|
|
|
Widget* widgetChild = dynamic_cast<Widget*>(child);
|
|
|
|
if (widgetChild)
|
2014-03-11 17:13:54 +08:00
|
|
|
{
|
2014-05-12 14:59:00 +08:00
|
|
|
if (widgetChild->getName() == name)
|
2014-03-24 15:25:44 +08:00
|
|
|
{
|
|
|
|
return widgetChild;
|
|
|
|
}
|
2014-03-11 17:13:54 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return nullptr;
|
|
|
|
}
|
2014-03-24 15:25:44 +08:00
|
|
|
|
2014-03-11 17:13:54 +08:00
|
|
|
void Widget::initRenderer()
|
|
|
|
{
|
|
|
|
}
|
|
|
|
|
|
|
|
void Widget::setSize(const Size &size)
|
|
|
|
{
|
|
|
|
_customSize = size;
|
|
|
|
if (_ignoreSize)
|
|
|
|
{
|
2014-04-17 14:08:25 +08:00
|
|
|
_size = getVirtualRendererSize();
|
2014-03-11 17:13:54 +08:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
_size = size;
|
|
|
|
}
|
|
|
|
if (_running)
|
|
|
|
{
|
|
|
|
Widget* widgetParent = getWidgetParent();
|
|
|
|
Size pSize;
|
|
|
|
if (widgetParent)
|
|
|
|
{
|
|
|
|
pSize = widgetParent->getSize();
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
pSize = _parent->getContentSize();
|
|
|
|
}
|
|
|
|
float spx = 0.0f;
|
|
|
|
float spy = 0.0f;
|
|
|
|
if (pSize.width > 0.0f)
|
|
|
|
{
|
|
|
|
spx = _customSize.width / pSize.width;
|
|
|
|
}
|
|
|
|
if (pSize.height > 0.0f)
|
|
|
|
{
|
|
|
|
spy = _customSize.height / pSize.height;
|
|
|
|
}
|
2014-05-15 01:07:09 +08:00
|
|
|
_sizePercent = Vec2(spx, spy);
|
2014-03-11 17:13:54 +08:00
|
|
|
}
|
|
|
|
onSizeChanged();
|
|
|
|
}
|
|
|
|
|
2014-05-15 01:07:09 +08:00
|
|
|
void Widget::setSizePercent(const Vec2 &percent)
|
2014-03-11 17:13:54 +08:00
|
|
|
{
|
|
|
|
_sizePercent = percent;
|
|
|
|
Size cSize = _customSize;
|
|
|
|
if (_running)
|
|
|
|
{
|
|
|
|
Widget* widgetParent = getWidgetParent();
|
|
|
|
if (widgetParent)
|
|
|
|
{
|
|
|
|
cSize = Size(widgetParent->getSize().width * percent.x , widgetParent->getSize().height * percent.y);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
cSize = Size(_parent->getContentSize().width * percent.x , _parent->getContentSize().height * percent.y);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if (_ignoreSize)
|
|
|
|
{
|
2014-04-17 14:08:25 +08:00
|
|
|
_size = getVirtualRendererSize();
|
2014-03-11 17:13:54 +08:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
_size = cSize;
|
|
|
|
}
|
|
|
|
_customSize = cSize;
|
|
|
|
onSizeChanged();
|
|
|
|
}
|
|
|
|
|
|
|
|
void Widget::updateSizeAndPosition()
|
2014-03-13 10:11:41 +08:00
|
|
|
{
|
|
|
|
Widget* widgetParent = getWidgetParent();
|
|
|
|
Size pSize;
|
|
|
|
if (widgetParent)
|
|
|
|
{
|
2014-05-20 10:24:22 +08:00
|
|
|
pSize = widgetParent->getLayoutSize();
|
2014-03-13 10:11:41 +08:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
pSize = _parent->getContentSize();
|
|
|
|
}
|
|
|
|
updateSizeAndPosition(pSize);
|
|
|
|
}
|
|
|
|
|
|
|
|
void Widget::updateSizeAndPosition(const cocos2d::Size &parentSize)
|
2014-03-11 17:13:54 +08:00
|
|
|
{
|
|
|
|
switch (_sizeType)
|
|
|
|
{
|
2014-05-09 09:37:51 +08:00
|
|
|
case SizeType::ABSOLUTE:
|
2014-03-11 17:13:54 +08:00
|
|
|
{
|
|
|
|
if (_ignoreSize)
|
|
|
|
{
|
2014-04-17 14:08:25 +08:00
|
|
|
_size = getVirtualRendererSize();
|
2014-03-11 17:13:54 +08:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
_size = _customSize;
|
|
|
|
}
|
2014-03-13 10:11:41 +08:00
|
|
|
float spx = 0.0f;
|
|
|
|
float spy = 0.0f;
|
|
|
|
if (parentSize.width > 0.0f)
|
2014-03-11 17:13:54 +08:00
|
|
|
{
|
2014-03-13 10:11:41 +08:00
|
|
|
spx = _customSize.width / parentSize.width;
|
2014-03-11 17:13:54 +08:00
|
|
|
}
|
2014-03-13 10:11:41 +08:00
|
|
|
if (parentSize.height > 0.0f)
|
2014-03-11 17:13:54 +08:00
|
|
|
{
|
2014-03-13 10:11:41 +08:00
|
|
|
spy = _customSize.height / parentSize.height;
|
2014-03-11 17:13:54 +08:00
|
|
|
}
|
2014-05-15 01:07:09 +08:00
|
|
|
_sizePercent = Vec2(spx, spy);
|
2014-03-11 17:13:54 +08:00
|
|
|
break;
|
|
|
|
}
|
2014-05-09 09:37:51 +08:00
|
|
|
case SizeType::PERCENT:
|
2014-03-11 17:13:54 +08:00
|
|
|
{
|
2014-03-13 10:11:41 +08:00
|
|
|
Size cSize = Size(parentSize.width * _sizePercent.x , parentSize.height * _sizePercent.y);
|
|
|
|
if (_ignoreSize)
|
2014-03-11 17:13:54 +08:00
|
|
|
{
|
2014-04-17 14:08:25 +08:00
|
|
|
_size = getVirtualRendererSize();
|
2014-03-11 17:13:54 +08:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2014-03-13 10:11:41 +08:00
|
|
|
_size = cSize;
|
2014-03-11 17:13:54 +08:00
|
|
|
}
|
2014-03-13 10:11:41 +08:00
|
|
|
_customSize = cSize;
|
2014-03-11 17:13:54 +08:00
|
|
|
break;
|
2014-03-13 10:11:41 +08:00
|
|
|
}
|
2014-03-11 17:13:54 +08:00
|
|
|
default:
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
onSizeChanged();
|
2014-05-15 01:07:09 +08:00
|
|
|
Vec2 absPos = getPosition();
|
2014-03-11 17:13:54 +08:00
|
|
|
switch (_positionType)
|
|
|
|
{
|
2014-05-08 18:25:49 +08:00
|
|
|
case PositionType::ABSOLUTE:
|
2014-03-11 17:13:54 +08:00
|
|
|
{
|
2014-03-13 10:11:41 +08:00
|
|
|
if (parentSize.width <= 0.0f || parentSize.height <= 0.0f)
|
2014-03-11 17:13:54 +08:00
|
|
|
{
|
2014-05-15 01:07:09 +08:00
|
|
|
_positionPercent = Vec2::ZERO;
|
2014-03-11 17:13:54 +08:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2014-05-15 01:07:09 +08:00
|
|
|
_positionPercent = Vec2(absPos.x / parentSize.width, absPos.y / parentSize.height);
|
2014-03-11 17:13:54 +08:00
|
|
|
}
|
|
|
|
break;
|
|
|
|
}
|
2014-05-08 18:25:49 +08:00
|
|
|
case PositionType::PERCENT:
|
2014-03-11 17:13:54 +08:00
|
|
|
{
|
2014-05-15 01:07:09 +08:00
|
|
|
absPos = Vec2(parentSize.width * _positionPercent.x, parentSize.height * _positionPercent.y);
|
2014-03-11 17:13:54 +08:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
default:
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
setPosition(absPos);
|
|
|
|
}
|
|
|
|
|
|
|
|
void Widget::setSizeType(SizeType type)
|
|
|
|
{
|
|
|
|
_sizeType = type;
|
|
|
|
}
|
|
|
|
|
2014-05-09 09:37:51 +08:00
|
|
|
Widget::SizeType Widget::getSizeType() const
|
2014-03-11 17:13:54 +08:00
|
|
|
{
|
|
|
|
return _sizeType;
|
|
|
|
}
|
|
|
|
|
|
|
|
void Widget::ignoreContentAdaptWithSize(bool ignore)
|
|
|
|
{
|
|
|
|
if (_ignoreSize == ignore)
|
|
|
|
{
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
_ignoreSize = ignore;
|
|
|
|
if (_ignoreSize)
|
|
|
|
{
|
2014-04-17 14:08:25 +08:00
|
|
|
Size s = getVirtualRendererSize();
|
2014-03-11 17:13:54 +08:00
|
|
|
_size = s;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
_size = _customSize;
|
|
|
|
}
|
|
|
|
onSizeChanged();
|
|
|
|
}
|
|
|
|
|
|
|
|
bool Widget::isIgnoreContentAdaptWithSize() const
|
|
|
|
{
|
|
|
|
return _ignoreSize;
|
|
|
|
}
|
|
|
|
|
|
|
|
const Size& Widget::getSize() const
|
|
|
|
{
|
|
|
|
return _size;
|
|
|
|
}
|
|
|
|
|
|
|
|
const Size& Widget::getCustomSize() const
|
|
|
|
{
|
|
|
|
return _customSize;
|
|
|
|
}
|
|
|
|
|
2014-05-15 01:07:09 +08:00
|
|
|
const Vec2& Widget::getSizePercent() const
|
2014-03-11 17:13:54 +08:00
|
|
|
{
|
|
|
|
return _sizePercent;
|
|
|
|
}
|
|
|
|
|
2014-05-15 01:07:09 +08:00
|
|
|
Vec2 Widget::getWorldPosition()
|
2014-03-11 17:13:54 +08:00
|
|
|
{
|
2014-05-15 01:07:09 +08:00
|
|
|
return convertToWorldSpace(Vec2(_anchorPoint.x * _contentSize.width, _anchorPoint.y * _contentSize.height));
|
2014-03-11 17:13:54 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
Node* Widget::getVirtualRenderer()
|
|
|
|
{
|
|
|
|
return this;
|
|
|
|
}
|
|
|
|
|
|
|
|
void Widget::onSizeChanged()
|
|
|
|
{
|
2014-04-17 14:08:25 +08:00
|
|
|
setContentSize(_size);
|
2014-03-11 17:13:54 +08:00
|
|
|
for (auto& child : getChildren())
|
|
|
|
{
|
2014-03-24 15:25:44 +08:00
|
|
|
Widget* widgetChild = dynamic_cast<Widget*>(child);
|
|
|
|
if (widgetChild)
|
2014-03-11 17:13:54 +08:00
|
|
|
{
|
2014-03-24 15:25:44 +08:00
|
|
|
widgetChild->updateSizeAndPosition();
|
2014-03-11 17:13:54 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2014-04-17 14:08:25 +08:00
|
|
|
const Size& Widget::getVirtualRendererSize() const
|
2014-03-11 17:13:54 +08:00
|
|
|
{
|
2014-04-17 14:08:25 +08:00
|
|
|
return _contentSize;
|
|
|
|
}
|
|
|
|
|
|
|
|
void Widget::updateContentSizeWithTextureSize(const cocos2d::Size &size)
|
|
|
|
{
|
|
|
|
if (_ignoreSize)
|
|
|
|
{
|
|
|
|
_size = size;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
_size = _customSize;
|
|
|
|
}
|
|
|
|
onSizeChanged();
|
2014-03-11 17:13:54 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
void Widget::setTouchEnabled(bool enable)
|
|
|
|
{
|
|
|
|
if (enable == _touchEnabled)
|
|
|
|
{
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
_touchEnabled = enable;
|
|
|
|
if (_touchEnabled)
|
|
|
|
{
|
|
|
|
_touchListener = EventListenerTouchOneByOne::create();
|
|
|
|
CC_SAFE_RETAIN(_touchListener);
|
|
|
|
_touchListener->setSwallowTouches(true);
|
|
|
|
_touchListener->onTouchBegan = CC_CALLBACK_2(Widget::onTouchBegan, this);
|
|
|
|
_touchListener->onTouchMoved = CC_CALLBACK_2(Widget::onTouchMoved, this);
|
|
|
|
_touchListener->onTouchEnded = CC_CALLBACK_2(Widget::onTouchEnded, this);
|
|
|
|
_touchListener->onTouchCancelled = CC_CALLBACK_2(Widget::onTouchCancelled, this);
|
|
|
|
_eventDispatcher->addEventListenerWithSceneGraphPriority(_touchListener, this);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
_eventDispatcher->removeEventListener(_touchListener);
|
|
|
|
CC_SAFE_RELEASE_NULL(_touchListener);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
bool Widget::isTouchEnabled() const
|
|
|
|
{
|
|
|
|
return _touchEnabled;
|
|
|
|
}
|
|
|
|
|
2014-05-06 12:04:52 +08:00
|
|
|
bool Widget::isHighlighted() const
|
2014-03-11 17:13:54 +08:00
|
|
|
{
|
2014-05-04 10:19:11 +08:00
|
|
|
return _highlight;
|
2014-03-11 17:13:54 +08:00
|
|
|
}
|
|
|
|
|
2014-05-06 12:04:52 +08:00
|
|
|
void Widget::setHighlighted(bool hilight)
|
2014-03-11 17:13:54 +08:00
|
|
|
{
|
2014-05-04 10:19:11 +08:00
|
|
|
if (hilight == _highlight)
|
2014-03-11 17:13:54 +08:00
|
|
|
{
|
|
|
|
return;
|
|
|
|
}
|
2014-05-04 10:19:11 +08:00
|
|
|
_highlight = hilight;
|
2014-03-11 17:13:54 +08:00
|
|
|
if (_bright)
|
|
|
|
{
|
2014-05-04 10:19:11 +08:00
|
|
|
if (_highlight)
|
2014-03-11 17:13:54 +08:00
|
|
|
{
|
2014-05-09 15:23:34 +08:00
|
|
|
setBrightStyle(BrightStyle::HIGHLIGHT);
|
2014-03-11 17:13:54 +08:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2014-05-09 15:23:34 +08:00
|
|
|
setBrightStyle(BrightStyle::NORMAL);
|
2014-03-11 17:13:54 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
onPressStateChangedToDisabled();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void Widget::setBright(bool bright)
|
|
|
|
{
|
|
|
|
_bright = bright;
|
|
|
|
if (_bright)
|
|
|
|
{
|
2014-05-09 15:23:34 +08:00
|
|
|
_brightStyle = BrightStyle::NONE;
|
|
|
|
setBrightStyle(BrightStyle::NORMAL);
|
2014-03-11 17:13:54 +08:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
onPressStateChangedToDisabled();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void Widget::setBrightStyle(BrightStyle style)
|
|
|
|
{
|
|
|
|
if (_brightStyle == style)
|
|
|
|
{
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
_brightStyle = style;
|
|
|
|
switch (_brightStyle)
|
|
|
|
{
|
2014-05-09 15:23:34 +08:00
|
|
|
case BrightStyle::NORMAL:
|
2014-03-11 17:13:54 +08:00
|
|
|
onPressStateChangedToNormal();
|
|
|
|
break;
|
2014-05-09 15:23:34 +08:00
|
|
|
case BrightStyle::HIGHLIGHT:
|
2014-03-11 17:13:54 +08:00
|
|
|
onPressStateChangedToPressed();
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void Widget::onPressStateChangedToNormal()
|
|
|
|
{
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
void Widget::onPressStateChangedToPressed()
|
|
|
|
{
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
void Widget::onPressStateChangedToDisabled()
|
|
|
|
{
|
|
|
|
|
|
|
|
}
|
|
|
|
|
2014-05-13 16:37:41 +08:00
|
|
|
|
|
|
|
Widget* Widget::getAncensterWidget(Node* node)
|
2014-03-11 17:13:54 +08:00
|
|
|
{
|
2014-05-13 18:41:38 +08:00
|
|
|
if (nullptr == node)
|
|
|
|
{
|
2014-05-13 16:37:41 +08:00
|
|
|
return nullptr;
|
|
|
|
}
|
2014-05-13 18:41:38 +08:00
|
|
|
|
2014-05-13 16:37:41 +08:00
|
|
|
Node* parent = node->getParent();
|
2014-05-13 18:41:38 +08:00
|
|
|
if (nullptr == parent)
|
|
|
|
{
|
2014-05-13 17:12:48 +08:00
|
|
|
return nullptr;
|
|
|
|
}
|
2014-05-13 16:37:41 +08:00
|
|
|
Widget* parentWidget = dynamic_cast<Widget*>(parent);
|
2014-05-13 18:41:38 +08:00
|
|
|
if (parentWidget)
|
|
|
|
{
|
2014-05-13 16:37:41 +08:00
|
|
|
return parentWidget;
|
|
|
|
}
|
2014-05-13 18:41:38 +08:00
|
|
|
else
|
|
|
|
{
|
2014-05-13 16:37:41 +08:00
|
|
|
return this->getAncensterWidget(parent->getParent());
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
bool Widget::isAncestorsVisible(Node* node)
|
|
|
|
{
|
2014-05-13 18:41:38 +08:00
|
|
|
if (nullptr == node)
|
|
|
|
{
|
2014-05-13 16:37:41 +08:00
|
|
|
return true;
|
|
|
|
}
|
|
|
|
Node* parent = node->getParent();
|
|
|
|
|
2014-05-13 18:41:38 +08:00
|
|
|
if (parent && !parent->isVisible())
|
|
|
|
{
|
2014-05-13 16:37:41 +08:00
|
|
|
return false;
|
|
|
|
}
|
|
|
|
return this->isAncestorsVisible(parent);
|
|
|
|
}
|
|
|
|
|
2014-05-14 09:23:56 +08:00
|
|
|
bool Widget::isAncestorsEnabled()
|
2014-05-13 16:37:41 +08:00
|
|
|
{
|
|
|
|
Widget* parentWidget = this->getAncensterWidget(this);
|
2014-05-13 18:41:38 +08:00
|
|
|
if (parentWidget == nullptr)
|
|
|
|
{
|
2014-05-13 16:37:41 +08:00
|
|
|
return true;
|
|
|
|
}
|
2014-05-13 18:41:38 +08:00
|
|
|
if (parentWidget && !parentWidget->isEnabled())
|
|
|
|
{
|
2014-05-13 16:37:41 +08:00
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2014-05-14 09:23:56 +08:00
|
|
|
return parentWidget->isAncestorsEnabled();
|
2014-03-11 17:13:54 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
bool Widget::onTouchBegan(Touch *touch, Event *unusedEvent)
|
|
|
|
{
|
|
|
|
_hitted = false;
|
2014-05-14 09:23:56 +08:00
|
|
|
if (isVisible() && isEnabled() && isAncestorsEnabled() && isAncestorsVisible(this) )
|
2014-03-11 17:13:54 +08:00
|
|
|
{
|
|
|
|
_touchStartPos = touch->getLocation();
|
|
|
|
if(hitTest(_touchStartPos) && clippingParentAreaContainPoint(_touchStartPos))
|
|
|
|
{
|
|
|
|
_hitted = true;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if (!_hitted)
|
|
|
|
{
|
|
|
|
return false;
|
|
|
|
}
|
2014-05-06 12:04:52 +08:00
|
|
|
setHighlighted(true);
|
2014-03-11 17:13:54 +08:00
|
|
|
Widget* widgetParent = getWidgetParent();
|
|
|
|
if (widgetParent)
|
|
|
|
{
|
|
|
|
widgetParent->checkChildInfo(0,this,_touchStartPos);
|
|
|
|
}
|
|
|
|
pushDownEvent();
|
2014-05-13 16:37:41 +08:00
|
|
|
return true;
|
2014-03-11 17:13:54 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
void Widget::onTouchMoved(Touch *touch, Event *unusedEvent)
|
|
|
|
{
|
|
|
|
_touchMovePos = touch->getLocation();
|
2014-05-06 12:04:52 +08:00
|
|
|
setHighlighted(hitTest(_touchMovePos));
|
2014-03-11 17:13:54 +08:00
|
|
|
Widget* widgetParent = getWidgetParent();
|
|
|
|
if (widgetParent)
|
|
|
|
{
|
|
|
|
widgetParent->checkChildInfo(1,this,_touchMovePos);
|
|
|
|
}
|
|
|
|
moveEvent();
|
|
|
|
}
|
|
|
|
|
|
|
|
void Widget::onTouchEnded(Touch *touch, Event *unusedEvent)
|
|
|
|
{
|
|
|
|
_touchEndPos = touch->getLocation();
|
2014-05-04 10:19:11 +08:00
|
|
|
bool highlight = _highlight;
|
2014-05-06 12:04:52 +08:00
|
|
|
setHighlighted(false);
|
2014-03-11 17:13:54 +08:00
|
|
|
Widget* widgetParent = getWidgetParent();
|
|
|
|
if (widgetParent)
|
|
|
|
{
|
|
|
|
widgetParent->checkChildInfo(2,this,_touchEndPos);
|
|
|
|
}
|
2014-05-04 10:19:11 +08:00
|
|
|
if (highlight)
|
2014-03-11 17:13:54 +08:00
|
|
|
{
|
|
|
|
releaseUpEvent();
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
cancelUpEvent();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void Widget::onTouchCancelled(Touch *touch, Event *unusedEvent)
|
|
|
|
{
|
2014-05-06 12:04:52 +08:00
|
|
|
setHighlighted(false);
|
2014-03-11 17:13:54 +08:00
|
|
|
cancelUpEvent();
|
|
|
|
}
|
|
|
|
|
|
|
|
void Widget::pushDownEvent()
|
|
|
|
{
|
2014-05-09 11:28:36 +08:00
|
|
|
if (_touchEventCallback) {
|
|
|
|
_touchEventCallback(this, TouchEventType::BEGAN);
|
|
|
|
}
|
|
|
|
|
2014-03-11 17:13:54 +08:00
|
|
|
if (_touchEventListener && _touchEventSelector)
|
|
|
|
{
|
|
|
|
(_touchEventListener->*_touchEventSelector)(this,TOUCH_EVENT_BEGAN);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void Widget::moveEvent()
|
|
|
|
{
|
2014-05-09 11:28:36 +08:00
|
|
|
if (_touchEventCallback) {
|
|
|
|
_touchEventCallback(this, TouchEventType::MOVED);
|
|
|
|
}
|
|
|
|
|
2014-03-11 17:13:54 +08:00
|
|
|
if (_touchEventListener && _touchEventSelector)
|
|
|
|
{
|
|
|
|
(_touchEventListener->*_touchEventSelector)(this,TOUCH_EVENT_MOVED);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void Widget::releaseUpEvent()
|
|
|
|
{
|
2014-05-09 11:28:36 +08:00
|
|
|
|
|
|
|
if (_touchEventCallback) {
|
|
|
|
_touchEventCallback(this, TouchEventType::ENDED);
|
|
|
|
}
|
|
|
|
|
2014-03-11 17:13:54 +08:00
|
|
|
if (_touchEventListener && _touchEventSelector)
|
|
|
|
{
|
|
|
|
(_touchEventListener->*_touchEventSelector)(this,TOUCH_EVENT_ENDED);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void Widget::cancelUpEvent()
|
|
|
|
{
|
2014-05-09 11:28:36 +08:00
|
|
|
if (_touchEventCallback)
|
|
|
|
{
|
|
|
|
_touchEventCallback(this, TouchEventType::CANCELED);
|
|
|
|
}
|
|
|
|
|
2014-03-11 17:13:54 +08:00
|
|
|
if (_touchEventListener && _touchEventSelector)
|
|
|
|
{
|
|
|
|
(_touchEventListener->*_touchEventSelector)(this,TOUCH_EVENT_CANCELED);
|
|
|
|
}
|
2014-05-09 11:28:36 +08:00
|
|
|
|
2014-03-11 17:13:54 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
void Widget::addTouchEventListener(Ref *target, SEL_TouchEvent selector)
|
|
|
|
{
|
|
|
|
_touchEventListener = target;
|
|
|
|
_touchEventSelector = selector;
|
2014-05-09 11:28:36 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
void Widget::addTouchEventListener(Widget::ccWidgetTouchCallback callback)
|
|
|
|
{
|
|
|
|
this->_touchEventCallback = callback;
|
2014-03-11 17:13:54 +08:00
|
|
|
}
|
|
|
|
|
2014-05-15 01:07:09 +08:00
|
|
|
bool Widget::hitTest(const Vec2 &pt)
|
2014-03-11 17:13:54 +08:00
|
|
|
{
|
2014-05-15 01:07:09 +08:00
|
|
|
Vec2 nsp = convertToNodeSpace(pt);
|
2014-04-17 14:08:25 +08:00
|
|
|
Rect bb;
|
|
|
|
bb.size = _contentSize;
|
|
|
|
if (bb.containsPoint(nsp))
|
2014-03-11 17:13:54 +08:00
|
|
|
{
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2014-05-15 01:07:09 +08:00
|
|
|
bool Widget::clippingParentAreaContainPoint(const Vec2 &pt)
|
2014-03-11 17:13:54 +08:00
|
|
|
{
|
|
|
|
_affectByClipping = false;
|
|
|
|
Widget* parent = getWidgetParent();
|
|
|
|
Widget* clippingParent = nullptr;
|
|
|
|
while (parent)
|
|
|
|
{
|
|
|
|
Layout* layoutParent = dynamic_cast<Layout*>(parent);
|
|
|
|
if (layoutParent)
|
|
|
|
{
|
|
|
|
if (layoutParent->isClippingEnabled())
|
|
|
|
{
|
|
|
|
_affectByClipping = true;
|
|
|
|
clippingParent = layoutParent;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
parent = parent->getWidgetParent();
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!_affectByClipping)
|
|
|
|
{
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
if (clippingParent)
|
|
|
|
{
|
|
|
|
bool bRet = false;
|
|
|
|
if (clippingParent->hitTest(pt))
|
|
|
|
{
|
|
|
|
bRet = true;
|
|
|
|
}
|
|
|
|
if (bRet)
|
|
|
|
{
|
|
|
|
return clippingParent->clippingParentAreaContainPoint(pt);
|
|
|
|
}
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
2014-05-15 01:07:09 +08:00
|
|
|
void Widget::checkChildInfo(int handleState, Widget *sender, const Vec2 &touchPoint)
|
2014-03-11 17:13:54 +08:00
|
|
|
{
|
|
|
|
Widget* widgetParent = getWidgetParent();
|
|
|
|
if (widgetParent)
|
|
|
|
{
|
|
|
|
widgetParent->checkChildInfo(handleState,sender,touchPoint);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2014-05-15 01:07:09 +08:00
|
|
|
void Widget::setPosition(const Vec2 &pos)
|
2014-03-11 17:13:54 +08:00
|
|
|
{
|
|
|
|
if (_running)
|
|
|
|
{
|
|
|
|
Widget* widgetParent = getWidgetParent();
|
|
|
|
if (widgetParent)
|
|
|
|
{
|
|
|
|
Size pSize = widgetParent->getSize();
|
|
|
|
if (pSize.width <= 0.0f || pSize.height <= 0.0f)
|
|
|
|
{
|
2014-05-15 01:07:09 +08:00
|
|
|
_positionPercent = Vec2::ZERO;
|
2014-03-11 17:13:54 +08:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2014-05-15 01:07:09 +08:00
|
|
|
_positionPercent = Vec2(pos.x / pSize.width, pos.y / pSize.height);
|
2014-03-11 17:13:54 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2014-03-24 15:25:44 +08:00
|
|
|
ProtectedNode::setPosition(pos);
|
2014-03-11 17:13:54 +08:00
|
|
|
}
|
|
|
|
|
2014-05-15 01:07:09 +08:00
|
|
|
void Widget::setPositionPercent(const Vec2 &percent)
|
2014-03-11 17:13:54 +08:00
|
|
|
{
|
|
|
|
_positionPercent = percent;
|
|
|
|
if (_running)
|
|
|
|
{
|
|
|
|
Widget* widgetParent = getWidgetParent();
|
|
|
|
if (widgetParent)
|
|
|
|
{
|
|
|
|
Size parentSize = widgetParent->getSize();
|
2014-05-15 01:07:09 +08:00
|
|
|
Vec2 absPos = Vec2(parentSize.width * _positionPercent.x, parentSize.height * _positionPercent.y);
|
2014-03-11 17:13:54 +08:00
|
|
|
setPosition(absPos);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2014-05-15 01:07:09 +08:00
|
|
|
const Vec2& Widget::getPositionPercent()
|
2014-03-11 17:13:54 +08:00
|
|
|
{
|
|
|
|
return _positionPercent;
|
|
|
|
}
|
|
|
|
|
|
|
|
void Widget::setPositionType(PositionType type)
|
|
|
|
{
|
|
|
|
_positionType = type;
|
|
|
|
}
|
|
|
|
|
2014-05-08 18:25:49 +08:00
|
|
|
Widget::PositionType Widget::getPositionType() const
|
2014-03-11 17:13:54 +08:00
|
|
|
{
|
|
|
|
return _positionType;
|
|
|
|
}
|
|
|
|
|
|
|
|
bool Widget::isBright() const
|
|
|
|
{
|
|
|
|
return _bright;
|
|
|
|
}
|
|
|
|
|
|
|
|
bool Widget::isEnabled() const
|
|
|
|
{
|
|
|
|
return _enabled;
|
|
|
|
}
|
|
|
|
|
2014-05-20 14:36:29 +08:00
|
|
|
float Widget::getLeftInParent()
|
2014-03-11 17:13:54 +08:00
|
|
|
{
|
2014-05-20 14:36:29 +08:00
|
|
|
return getPosition().x - getAnchorPoint().x * _size.width;;
|
2014-03-11 17:13:54 +08:00
|
|
|
}
|
|
|
|
|
2014-05-20 14:36:29 +08:00
|
|
|
float Widget::getBottomInParent()
|
2014-03-11 17:13:54 +08:00
|
|
|
{
|
2014-05-20 14:36:29 +08:00
|
|
|
return getPosition().y - getAnchorPoint().y * _size.height;;
|
2014-03-11 17:13:54 +08:00
|
|
|
}
|
|
|
|
|
2014-05-20 14:36:29 +08:00
|
|
|
float Widget::getRightInParent()
|
2014-03-11 17:13:54 +08:00
|
|
|
{
|
2014-05-20 14:36:29 +08:00
|
|
|
return getLeftInParent() + _size.width;
|
2014-03-11 17:13:54 +08:00
|
|
|
}
|
|
|
|
|
2014-05-20 14:36:29 +08:00
|
|
|
float Widget::getTopInParent()
|
2014-03-11 17:13:54 +08:00
|
|
|
{
|
2014-05-20 14:36:29 +08:00
|
|
|
return getBottomInParent() + _size.height;
|
2014-03-11 17:13:54 +08:00
|
|
|
}
|
|
|
|
|
2014-05-15 01:07:09 +08:00
|
|
|
const Vec2& Widget::getTouchStartPos()
|
2014-03-11 17:13:54 +08:00
|
|
|
{
|
|
|
|
return _touchStartPos;
|
|
|
|
}
|
|
|
|
|
2014-05-15 01:07:09 +08:00
|
|
|
const Vec2& Widget::getTouchMovePos()
|
2014-03-11 17:13:54 +08:00
|
|
|
{
|
|
|
|
return _touchMovePos;
|
|
|
|
}
|
|
|
|
|
2014-05-15 01:07:09 +08:00
|
|
|
const Vec2& Widget::getTouchEndPos()
|
2014-03-11 17:13:54 +08:00
|
|
|
{
|
|
|
|
return _touchEndPos;
|
|
|
|
}
|
|
|
|
|
2014-05-12 14:59:00 +08:00
|
|
|
void Widget::setName(const std::string& name)
|
2014-03-11 17:13:54 +08:00
|
|
|
{
|
|
|
|
_name = name;
|
|
|
|
}
|
|
|
|
|
2014-05-12 14:59:00 +08:00
|
|
|
const std::string& Widget::getName() const
|
2014-03-11 17:13:54 +08:00
|
|
|
{
|
2014-05-12 14:59:00 +08:00
|
|
|
return _name;
|
2014-03-11 17:13:54 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void Widget::setLayoutParameter(LayoutParameter *parameter)
|
|
|
|
{
|
|
|
|
if (!parameter)
|
|
|
|
{
|
|
|
|
return;
|
|
|
|
}
|
2014-05-09 17:38:05 +08:00
|
|
|
_layoutParameterDictionary.insert((int)parameter->getLayoutType(), parameter);
|
2014-03-11 17:13:54 +08:00
|
|
|
}
|
|
|
|
|
2014-05-19 17:43:27 +08:00
|
|
|
LayoutParameter* Widget::getLayoutParameter(LayoutParameter::Type type)
|
|
|
|
{
|
|
|
|
return dynamic_cast<LayoutParameter*>(_layoutParameterDictionary.at((int)type));
|
|
|
|
}
|
2014-03-11 17:13:54 +08:00
|
|
|
|
|
|
|
std::string Widget::getDescription() const
|
|
|
|
{
|
|
|
|
return "Widget";
|
|
|
|
}
|
|
|
|
|
|
|
|
Widget* Widget::clone()
|
|
|
|
{
|
|
|
|
Widget* clonedWidget = createCloneInstance();
|
|
|
|
clonedWidget->copyProperties(this);
|
|
|
|
clonedWidget->copyClonedWidgetChildren(this);
|
|
|
|
return clonedWidget;
|
|
|
|
}
|
|
|
|
|
|
|
|
Widget* Widget::createCloneInstance()
|
|
|
|
{
|
|
|
|
return Widget::create();
|
|
|
|
}
|
|
|
|
|
|
|
|
void Widget::copyClonedWidgetChildren(Widget* model)
|
|
|
|
{
|
|
|
|
auto& modelChildren = model->getChildren();
|
|
|
|
|
|
|
|
for (auto& subWidget : modelChildren)
|
|
|
|
{
|
2014-03-24 15:25:44 +08:00
|
|
|
Widget* child = dynamic_cast<Widget*>(subWidget);
|
|
|
|
if (child)
|
|
|
|
{
|
|
|
|
addChild(child->clone());
|
|
|
|
}
|
2014-03-11 17:13:54 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void Widget::copySpecialProperties(Widget* model)
|
|
|
|
{
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
void Widget::copyProperties(Widget *widget)
|
|
|
|
{
|
|
|
|
setEnabled(widget->isEnabled());
|
|
|
|
setVisible(widget->isVisible());
|
|
|
|
setBright(widget->isBright());
|
|
|
|
setTouchEnabled(widget->isTouchEnabled());
|
|
|
|
setLocalZOrder(widget->getLocalZOrder());
|
|
|
|
setTag(widget->getTag());
|
|
|
|
setName(widget->getName());
|
|
|
|
setActionTag(widget->getActionTag());
|
|
|
|
_ignoreSize = widget->_ignoreSize;
|
|
|
|
_size = widget->_size;
|
|
|
|
_customSize = widget->_customSize;
|
|
|
|
_sizeType = widget->getSizeType();
|
|
|
|
_sizePercent = widget->_sizePercent;
|
|
|
|
_positionType = widget->_positionType;
|
|
|
|
_positionPercent = widget->_positionPercent;
|
|
|
|
setPosition(widget->getPosition());
|
|
|
|
setAnchorPoint(widget->getAnchorPoint());
|
|
|
|
setScaleX(widget->getScaleX());
|
|
|
|
setScaleY(widget->getScaleY());
|
|
|
|
setRotation(widget->getRotation());
|
2014-03-14 15:38:43 +08:00
|
|
|
setRotationSkewX(widget->getRotationSkewX());
|
|
|
|
setRotationSkewY(widget->getRotationSkewY());
|
2014-03-11 17:13:54 +08:00
|
|
|
setFlippedX(widget->isFlippedX());
|
|
|
|
setFlippedY(widget->isFlippedY());
|
|
|
|
setColor(widget->getColor());
|
|
|
|
setOpacity(widget->getOpacity());
|
2014-05-23 15:03:46 +08:00
|
|
|
_touchEventCallback = widget->_touchEventCallback;
|
|
|
|
_touchEventListener = widget->_touchEventListener;
|
|
|
|
_touchEventSelector = widget->_touchEventSelector;
|
|
|
|
_focused = widget->_focused;
|
|
|
|
_focusEnabled = widget->_focusEnabled;
|
|
|
|
|
|
|
|
copySpecialProperties(widget);
|
|
|
|
|
2014-05-09 17:38:05 +08:00
|
|
|
//FIXME:copy focus properties, also make sure all the subclass the copy behavior is correct
|
2014-03-11 17:13:54 +08:00
|
|
|
Map<int, LayoutParameter*>& layoutParameterDic = widget->_layoutParameterDictionary;
|
|
|
|
for (auto iter = layoutParameterDic.begin(); iter != layoutParameterDic.end(); ++iter)
|
|
|
|
{
|
|
|
|
setLayoutParameter(iter->second->clone());
|
|
|
|
}
|
|
|
|
onSizeChanged();
|
|
|
|
}
|
|
|
|
|
|
|
|
void Widget::setColor(const Color3B& color)
|
|
|
|
{
|
|
|
|
_color = color;
|
|
|
|
updateTextureColor();
|
|
|
|
}
|
|
|
|
|
|
|
|
void Widget::setOpacity(GLubyte opacity)
|
|
|
|
{
|
|
|
|
_opacity = opacity;
|
|
|
|
updateTextureOpacity();
|
|
|
|
}
|
|
|
|
|
|
|
|
void Widget::setFlippedX(bool flippedX)
|
|
|
|
{
|
|
|
|
_flippedX = flippedX;
|
|
|
|
updateFlippedX();
|
|
|
|
}
|
|
|
|
|
|
|
|
void Widget::setFlippedY(bool flippedY)
|
|
|
|
{
|
|
|
|
_flippedY = flippedY;
|
|
|
|
updateFlippedY();
|
|
|
|
}
|
|
|
|
|
|
|
|
void Widget::updateColorToRenderer(Node* renderer)
|
|
|
|
{
|
|
|
|
renderer->setColor(_color);
|
|
|
|
}
|
|
|
|
|
|
|
|
void Widget::updateOpacityToRenderer(Node* renderer)
|
|
|
|
{
|
|
|
|
renderer->setOpacity(_opacity);
|
|
|
|
}
|
|
|
|
|
|
|
|
void Widget::updateRGBAToRenderer(Node* renderer)
|
|
|
|
{
|
|
|
|
renderer->setColor(_color);
|
|
|
|
renderer->setOpacity(_opacity);
|
|
|
|
}
|
|
|
|
|
|
|
|
/*temp action*/
|
|
|
|
void Widget::setActionTag(int tag)
|
|
|
|
{
|
|
|
|
_actionTag = tag;
|
|
|
|
}
|
|
|
|
|
|
|
|
int Widget::getActionTag()
|
|
|
|
{
|
|
|
|
return _actionTag;
|
|
|
|
}
|
2014-05-04 11:23:20 +08:00
|
|
|
|
|
|
|
void Widget::setFocused(bool focus)
|
|
|
|
{
|
|
|
|
_focused = focus;
|
|
|
|
|
|
|
|
//make sure there is only one focusedWidget
|
|
|
|
if (focus) {
|
2014-05-07 10:23:57 +08:00
|
|
|
_focusedWidget = this;
|
2014-05-07 18:27:05 +08:00
|
|
|
if (!dynamic_cast<Layout*>(this)) {
|
|
|
|
_realFocusedWidget = this;
|
|
|
|
}
|
2014-05-04 11:23:20 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
bool Widget::isFocused()
|
|
|
|
{
|
|
|
|
return _focused;
|
|
|
|
}
|
|
|
|
|
|
|
|
void Widget::setFocusEnabled(bool enable)
|
|
|
|
{
|
|
|
|
_focusEnabled = enable;
|
|
|
|
}
|
|
|
|
|
|
|
|
bool Widget::isFocusEnabled()
|
|
|
|
{
|
|
|
|
return _focusEnabled;
|
|
|
|
}
|
|
|
|
|
2014-05-08 18:10:21 +08:00
|
|
|
Widget* Widget::findNextFocusedWidget(FocusDirection direction, Widget* current)
|
2014-05-04 11:23:20 +08:00
|
|
|
{
|
2014-05-07 14:26:41 +08:00
|
|
|
if (nullptr == onNextFocusedWidget || nullptr == onNextFocusedWidget(direction) ) {
|
2014-05-07 14:06:44 +08:00
|
|
|
if (this->isFocused() || !current->isFocusEnabled())
|
|
|
|
{
|
2014-05-04 11:23:20 +08:00
|
|
|
Node* parent = this->getParent();
|
2014-05-08 18:10:21 +08:00
|
|
|
|
2014-05-04 11:23:20 +08:00
|
|
|
Layout* layout = dynamic_cast<Layout*>(parent);
|
2014-05-07 14:06:44 +08:00
|
|
|
if (nullptr == layout)
|
|
|
|
{
|
2014-05-04 11:23:20 +08:00
|
|
|
//the outer layout's default behaviour is : loop focus
|
2014-05-07 14:06:44 +08:00
|
|
|
if (dynamic_cast<Layout*>(current))
|
|
|
|
{
|
2014-05-07 14:26:41 +08:00
|
|
|
return current->findNextFocusedWidget(direction, current);
|
2014-05-04 11:23:20 +08:00
|
|
|
}
|
|
|
|
return current;
|
2014-05-07 14:06:44 +08:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2014-05-07 14:26:41 +08:00
|
|
|
Widget *nextWidget = layout->findNextFocusedWidget(direction, current);
|
2014-05-04 11:23:20 +08:00
|
|
|
return nextWidget;
|
|
|
|
}
|
2014-05-07 14:06:44 +08:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2014-05-04 11:23:20 +08:00
|
|
|
return current;
|
|
|
|
}
|
|
|
|
}
|
2014-05-07 14:06:44 +08:00
|
|
|
else
|
|
|
|
{
|
2014-05-07 14:26:41 +08:00
|
|
|
Widget *getFocusWidget = onNextFocusedWidget(direction);
|
2014-05-04 11:23:20 +08:00
|
|
|
this->dispatchFocusEvent(this, getFocusWidget);
|
|
|
|
return getFocusWidget;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void Widget::dispatchFocusEvent(cocos2d::ui::Widget *widgetLoseFocus, cocos2d::ui::Widget *widgetGetFocus)
|
|
|
|
{
|
2014-05-06 17:28:12 +08:00
|
|
|
//if the widgetLoseFocus doesn't get focus, it will use the previous focused widget instead
|
2014-05-07 14:06:44 +08:00
|
|
|
if (widgetLoseFocus && !widgetLoseFocus->isFocused())
|
|
|
|
{
|
2014-05-06 17:28:12 +08:00
|
|
|
widgetLoseFocus = _focusedWidget;
|
2014-05-04 11:23:20 +08:00
|
|
|
}
|
|
|
|
|
2014-05-06 17:28:12 +08:00
|
|
|
if (widgetGetFocus != widgetLoseFocus)
|
|
|
|
{
|
|
|
|
|
2014-05-07 14:06:44 +08:00
|
|
|
if (widgetGetFocus)
|
|
|
|
{
|
2014-05-06 17:28:12 +08:00
|
|
|
widgetGetFocus->onFocusChanged(widgetLoseFocus, widgetGetFocus);
|
|
|
|
}
|
|
|
|
|
2014-05-07 14:06:44 +08:00
|
|
|
if (widgetLoseFocus)
|
|
|
|
{
|
2014-05-06 17:28:12 +08:00
|
|
|
widgetLoseFocus->onFocusChanged(widgetLoseFocus, widgetGetFocus);
|
|
|
|
}
|
|
|
|
|
|
|
|
EventFocus event(widgetLoseFocus, widgetGetFocus);
|
|
|
|
auto dispatcher = cocos2d::Director::getInstance()->getEventDispatcher();
|
|
|
|
dispatcher->dispatchEvent(&event);
|
2014-05-04 11:23:20 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
2014-05-07 10:23:57 +08:00
|
|
|
void Widget::requestFocus()
|
|
|
|
{
|
2014-05-07 14:06:44 +08:00
|
|
|
if (this == _focusedWidget)
|
|
|
|
{
|
2014-05-07 10:23:57 +08:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
this->dispatchFocusEvent(_focusedWidget, this);
|
|
|
|
}
|
|
|
|
|
2014-05-04 11:23:20 +08:00
|
|
|
void Widget::onFocusChange(Widget* widgetLostFocus, Widget* widgetGetFocus)
|
|
|
|
{
|
2014-05-06 17:28:12 +08:00
|
|
|
//only change focus when there is indeed a get&lose happens
|
2014-05-07 14:06:44 +08:00
|
|
|
if (widgetLostFocus)
|
|
|
|
{
|
2014-05-04 11:23:20 +08:00
|
|
|
widgetLostFocus->setFocused(false);
|
|
|
|
}
|
|
|
|
|
2014-05-07 14:06:44 +08:00
|
|
|
if (widgetGetFocus)
|
|
|
|
{
|
2014-05-04 11:23:20 +08:00
|
|
|
widgetGetFocus->setFocused(true);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2014-05-07 18:27:05 +08:00
|
|
|
Widget* Widget::getCurrentFocusedWidget(bool isWidget)
|
2014-05-04 11:23:20 +08:00
|
|
|
{
|
2014-05-07 18:27:05 +08:00
|
|
|
if (isWidget) {
|
|
|
|
return _realFocusedWidget;
|
|
|
|
}
|
2014-05-04 11:23:20 +08:00
|
|
|
return _focusedWidget;
|
|
|
|
}
|
2014-03-11 17:13:54 +08:00
|
|
|
|
2014-05-07 18:27:05 +08:00
|
|
|
|
|
|
|
|
2014-03-11 17:13:54 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
NS_CC_END
|