mirror of https://github.com/axmolengine/axmol.git
454 lines
12 KiB
C++
454 lines
12 KiB
C++
#include "GButton.h"
|
|
#include "GLabel.h"
|
|
#include "GRoot.h"
|
|
#include "GTextField.h"
|
|
#include "PackageItem.h"
|
|
#include "UIConfig.h"
|
|
#include "utils/ByteBuffer.h"
|
|
#include "utils/ToolSet.h"
|
|
|
|
NS_FGUI_BEGIN
|
|
USING_NS_AX;
|
|
|
|
const std::string GButton::UP = "up";
|
|
const std::string GButton::DOWN = "down";
|
|
const std::string GButton::OVER = "over";
|
|
const std::string GButton::SELECTED_OVER = "selectedOver";
|
|
const std::string GButton::DISABLED = "disabled";
|
|
const std::string GButton::SELECTED_DISABLED = "selectedDisabled";
|
|
|
|
GButton::GButton() : _mode(ButtonMode::COMMON),
|
|
_titleObject(nullptr),
|
|
_iconObject(nullptr),
|
|
_buttonController(nullptr),
|
|
_relatedController(nullptr),
|
|
_selected(false),
|
|
_over(false),
|
|
_down(false),
|
|
_downEffect(0),
|
|
_downScaled(false),
|
|
_downEffectValue(0.8f),
|
|
_changeStateOnClick(true),
|
|
_sound(UIConfig::buttonSound),
|
|
_soundVolumeScale(UIConfig::buttonSoundVolumeScale)
|
|
{
|
|
}
|
|
|
|
GButton::~GButton()
|
|
{
|
|
}
|
|
|
|
void GButton::setTitle(const std::string& value)
|
|
{
|
|
_title = value;
|
|
if (_titleObject != nullptr)
|
|
_titleObject->setText((_selected && _selectedTitle.length() > 0) ? _selectedTitle : _title);
|
|
updateGear(6);
|
|
}
|
|
|
|
void GButton::setIcon(const std::string& value)
|
|
{
|
|
_icon = value;
|
|
if (_iconObject != nullptr)
|
|
_iconObject->setIcon((_selected && _selectedIcon.length() > 0) ? _selectedIcon : _icon);
|
|
updateGear(7);
|
|
}
|
|
|
|
void GButton::setSelectedTitle(const std::string& value)
|
|
{
|
|
_selectedTitle = value;
|
|
if (_titleObject != nullptr)
|
|
_titleObject->setText((_selected && _selectedTitle.length() > 0) ? _selectedTitle : _title);
|
|
}
|
|
|
|
void GButton::setSelectedIcon(const std::string& value)
|
|
{
|
|
_selectedIcon = value;
|
|
if (_iconObject != nullptr)
|
|
_iconObject->setIcon((_selected && _selectedIcon.length() > 0) ? _selectedIcon : _icon);
|
|
}
|
|
|
|
axis::Color3B GButton::getTitleColor() const
|
|
{
|
|
GTextField* tf = getTextField();
|
|
if (tf)
|
|
return tf->getColor();
|
|
else
|
|
return Color3B::BLACK;
|
|
}
|
|
|
|
void GButton::setTitleColor(const axis::Color3B& value)
|
|
{
|
|
GTextField* tf = getTextField();
|
|
if (tf)
|
|
tf->setColor(value);
|
|
}
|
|
|
|
int GButton::getTitleFontSize() const
|
|
{
|
|
GTextField* tf = getTextField();
|
|
if (tf)
|
|
return tf->getFontSize();
|
|
else
|
|
return 0;
|
|
}
|
|
|
|
void GButton::setTitleFontSize(int value)
|
|
{
|
|
GTextField* tf = getTextField();
|
|
if (tf)
|
|
tf->setFontSize(value);
|
|
}
|
|
|
|
void GButton::setSelected(bool value)
|
|
{
|
|
if (_mode == ButtonMode::COMMON)
|
|
return;
|
|
|
|
if (_selected != value)
|
|
{
|
|
_selected = value;
|
|
setCurrentState();
|
|
if (!_selectedTitle.empty() && _titleObject != nullptr)
|
|
_titleObject->setText(_selected ? _selectedTitle : _title);
|
|
if (!_selectedIcon.empty())
|
|
{
|
|
const std::string& str = _selected ? _selectedIcon : _icon;
|
|
if (_iconObject != nullptr)
|
|
_iconObject->setIcon(str);
|
|
}
|
|
if (_relatedController != nullptr && getParent() != nullptr && !getParent()->_buildingDisplayList)
|
|
{
|
|
if (_selected)
|
|
{
|
|
_relatedController->setSelectedPageId(_relatedPageId);
|
|
if (_relatedController->autoRadioGroupDepth)
|
|
getParent()->adjustRadioGroupDepth(this, _relatedController);
|
|
}
|
|
else if (_mode == ButtonMode::CHECK && _relatedController->getSelectedPageId().compare(_relatedPageId) == 0)
|
|
_relatedController->setOppositePageId(_relatedPageId);
|
|
}
|
|
}
|
|
}
|
|
|
|
void GButton::setRelatedController(GController* c)
|
|
{
|
|
_relatedController = c;
|
|
}
|
|
|
|
void GButton::setState(const std::string& value)
|
|
{
|
|
if (_buttonController != nullptr)
|
|
_buttonController->setSelectedPage(value);
|
|
|
|
if (_downEffect == 1)
|
|
{
|
|
int cnt = this->numChildren();
|
|
if (value == DOWN || value == SELECTED_OVER || value == SELECTED_DISABLED)
|
|
{
|
|
int c = _downEffectValue * 255;
|
|
Value color = Value((c << 16) + (c << 8) + c);
|
|
for (int i = 0; i < cnt; i++)
|
|
{
|
|
GObject* obj = this->getChildAt(i);
|
|
if (dynamic_cast<GTextField*>(obj) == nullptr)
|
|
obj->setProp(ObjectPropID::Color, color);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
Value color = Value(0xFFFFFF);
|
|
for (int i = 0; i < cnt; i++)
|
|
{
|
|
GObject* obj = this->getChildAt(i);
|
|
if (dynamic_cast<GTextField*>(obj) == nullptr)
|
|
obj->setProp(ObjectPropID::Color, color);
|
|
}
|
|
}
|
|
}
|
|
else if (_downEffect == 2)
|
|
{
|
|
if (value == DOWN || value == SELECTED_OVER || value == SELECTED_DISABLED)
|
|
{
|
|
if (!_downScaled)
|
|
{
|
|
_downScaled = true;
|
|
setScale(getScaleX() * _downEffectValue, getScaleY() * _downEffectValue);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
if (_downScaled)
|
|
{
|
|
_downScaled = false;
|
|
setScale(getScaleX() / _downEffectValue, getScaleY() / _downEffectValue);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
void GButton::setCurrentState()
|
|
{
|
|
if (isGrayed() && _buttonController != nullptr && _buttonController->hasPage(DISABLED))
|
|
{
|
|
if (_selected)
|
|
setState(SELECTED_DISABLED);
|
|
else
|
|
setState(DISABLED);
|
|
}
|
|
else
|
|
{
|
|
if (_selected)
|
|
setState(_over ? SELECTED_OVER : DOWN);
|
|
else
|
|
setState(_over ? OVER : UP);
|
|
}
|
|
}
|
|
|
|
GTextField* GButton::getTextField() const
|
|
{
|
|
if (dynamic_cast<GTextField*>(_titleObject))
|
|
return dynamic_cast<GTextField*>(_titleObject);
|
|
else if (dynamic_cast<GLabel*>(_titleObject))
|
|
return dynamic_cast<GLabel*>(_titleObject)->getTextField();
|
|
else if (dynamic_cast<GButton*>(_titleObject))
|
|
return dynamic_cast<GButton*>(_titleObject)->getTextField();
|
|
else
|
|
return nullptr;
|
|
}
|
|
|
|
axis::Value GButton::getProp(ObjectPropID propId)
|
|
{
|
|
switch (propId)
|
|
{
|
|
case ObjectPropID::Color:
|
|
return Value(ToolSet::colorToInt(getTitleColor()));
|
|
case ObjectPropID::OutlineColor:
|
|
{
|
|
GTextField* tf = getTextField();
|
|
if (tf != nullptr)
|
|
return Value(ToolSet::colorToInt(tf->getOutlineColor()));
|
|
else
|
|
return Value::Null;
|
|
}
|
|
case ObjectPropID::FontSize:
|
|
return Value(getTitleFontSize());
|
|
case ObjectPropID::Selected:
|
|
return Value(isSelected());
|
|
default:
|
|
return GComponent::getProp(propId);
|
|
}
|
|
}
|
|
|
|
void GButton::setProp(ObjectPropID propId, const axis::Value& value)
|
|
{
|
|
switch (propId)
|
|
{
|
|
case ObjectPropID::Color:
|
|
setTitleColor(ToolSet::intToColor(value.asUnsignedInt()));
|
|
break;
|
|
case ObjectPropID::OutlineColor:
|
|
{
|
|
GTextField* tf = getTextField();
|
|
if (tf != nullptr)
|
|
tf->setOutlineColor(ToolSet::intToColor(value.asUnsignedInt()));
|
|
break;
|
|
}
|
|
case ObjectPropID::FontSize:
|
|
setTitleFontSize(value.asInt());
|
|
break;
|
|
case ObjectPropID::Selected:
|
|
setSelected(value.asBool());
|
|
break;
|
|
default:
|
|
GComponent::setProp(propId, value);
|
|
break;
|
|
}
|
|
}
|
|
|
|
void GButton::constructExtension(ByteBuffer* buffer)
|
|
{
|
|
buffer->seek(0, 6);
|
|
|
|
_mode = (ButtonMode)buffer->readByte();
|
|
buffer->readS(_sound);
|
|
_soundVolumeScale = buffer->readFloat();
|
|
_downEffect = buffer->readByte();
|
|
_downEffectValue = buffer->readFloat();
|
|
if (_downEffect == 2)
|
|
setPivot(0.5f, 0.5f, isPivotAsAnchor());
|
|
|
|
_buttonController = getController("button");
|
|
_titleObject = getChild("title");
|
|
_iconObject = getChild("icon");
|
|
if (_titleObject != nullptr)
|
|
_title = _titleObject->getText();
|
|
if (_iconObject != nullptr)
|
|
_icon = _iconObject->getIcon();
|
|
|
|
if (_mode == ButtonMode::COMMON)
|
|
setState(UP);
|
|
|
|
addEventListener(UIEventType::RollOver, CC_CALLBACK_1(GButton::onRollOver, this));
|
|
addEventListener(UIEventType::RollOut, CC_CALLBACK_1(GButton::onRollOut, this));
|
|
addEventListener(UIEventType::TouchBegin, CC_CALLBACK_1(GButton::onTouchBegin, this));
|
|
addEventListener(UIEventType::TouchEnd, CC_CALLBACK_1(GButton::onTouchEnd, this));
|
|
addEventListener(UIEventType::Click, CC_CALLBACK_1(GButton::onClick, this));
|
|
addEventListener(UIEventType::Exit, CC_CALLBACK_1(GButton::onExit, this));
|
|
}
|
|
|
|
void GButton::setup_afterAdd(ByteBuffer* buffer, int beginPos)
|
|
{
|
|
GComponent::setup_afterAdd(buffer, beginPos);
|
|
|
|
if (!buffer->seek(beginPos, 6))
|
|
return;
|
|
|
|
if ((ObjectType)buffer->readByte() != _packageItem->objectType)
|
|
return;
|
|
|
|
const std::string* str;
|
|
|
|
if ((str = buffer->readSP()))
|
|
setTitle(*str);
|
|
if ((str = buffer->readSP()))
|
|
setSelectedTitle(*str);
|
|
if ((str = buffer->readSP()))
|
|
setIcon(*str);
|
|
if ((str = buffer->readSP()))
|
|
setSelectedIcon(*str);
|
|
if (buffer->readBool())
|
|
setTitleColor((Color3B)buffer->readColor());
|
|
int iv = buffer->readInt();
|
|
if (iv != 0)
|
|
setTitleFontSize(iv);
|
|
iv = buffer->readShort();
|
|
if (iv >= 0)
|
|
_relatedController = _parent->getControllerAt(iv);
|
|
_relatedPageId = buffer->readS();
|
|
|
|
buffer->readS(_sound);
|
|
if (buffer->readBool())
|
|
_soundVolumeScale = buffer->readFloat();
|
|
|
|
setSelected(buffer->readBool());
|
|
}
|
|
|
|
void GButton::handleControllerChanged(GController* c)
|
|
{
|
|
GObject::handleControllerChanged(c);
|
|
|
|
if (_relatedController == c)
|
|
setSelected(_relatedPageId.compare(c->getSelectedPageId()) == 0);
|
|
}
|
|
|
|
void GButton::onRollOver(EventContext* context)
|
|
{
|
|
if (_buttonController == nullptr || !_buttonController->hasPage(OVER))
|
|
return;
|
|
|
|
_over = true;
|
|
if (_down)
|
|
return;
|
|
|
|
if (isGrayed() && _buttonController->hasPage(DISABLED))
|
|
return;
|
|
|
|
setState(_selected ? SELECTED_OVER : OVER);
|
|
}
|
|
|
|
void GButton::onRollOut(EventContext* context)
|
|
{
|
|
if (_buttonController == nullptr || !_buttonController->hasPage(OVER))
|
|
return;
|
|
|
|
_over = false;
|
|
if (_down)
|
|
return;
|
|
|
|
if (isGrayed() && _buttonController->hasPage(DISABLED))
|
|
return;
|
|
|
|
setState(_selected ? DOWN : UP);
|
|
}
|
|
|
|
void GButton::onTouchBegin(EventContext* context)
|
|
{
|
|
if (context->getInput()->getButton() != EventMouse::MouseButton::BUTTON_LEFT)
|
|
return;
|
|
|
|
_down = true;
|
|
context->captureTouch();
|
|
|
|
if (_mode == ButtonMode::COMMON)
|
|
{
|
|
if (isGrayed() && _buttonController != nullptr && _buttonController->hasPage(DISABLED))
|
|
setState(SELECTED_DISABLED);
|
|
else
|
|
setState(DOWN);
|
|
}
|
|
}
|
|
|
|
void GButton::onTouchEnd(EventContext* context)
|
|
{
|
|
if (context->getInput()->getButton() != EventMouse::MouseButton::BUTTON_LEFT)
|
|
return;
|
|
|
|
if (_down)
|
|
{
|
|
_down = false;
|
|
if (_mode == ButtonMode::COMMON)
|
|
{
|
|
if (isGrayed() && _buttonController != nullptr && _buttonController->hasPage(DISABLED))
|
|
setState(DISABLED);
|
|
else if (_over)
|
|
setState(OVER);
|
|
else
|
|
setState(UP);
|
|
}
|
|
else
|
|
{
|
|
if (!_over && _buttonController != nullptr && (_buttonController->getSelectedPage() == OVER || _buttonController->getSelectedPage() == SELECTED_OVER))
|
|
{
|
|
setCurrentState();
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
void GButton::onClick(EventContext* context)
|
|
{
|
|
if (!_sound.empty())
|
|
UIRoot->playSound(_sound, _soundVolumeScale);
|
|
|
|
if (_mode == ButtonMode::CHECK)
|
|
{
|
|
if (_changeStateOnClick)
|
|
{
|
|
setSelected(!_selected);
|
|
dispatchEvent(UIEventType::Changed);
|
|
}
|
|
}
|
|
else if (_mode == ButtonMode::RADIO)
|
|
{
|
|
if (_changeStateOnClick && !_selected)
|
|
{
|
|
setSelected(true);
|
|
dispatchEvent(UIEventType::Changed);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
if (_relatedController != nullptr)
|
|
_relatedController->setSelectedPageId(_relatedPageId);
|
|
}
|
|
}
|
|
|
|
void GButton::onExit(EventContext* context)
|
|
{
|
|
if (_over)
|
|
onRollOut(context);
|
|
}
|
|
|
|
NS_FGUI_END
|