Add extension fairygui support

This commit is contained in:
halx99 2020-08-04 12:31:33 +08:00
parent 2b24a1cb6f
commit 8531a1914d
153 changed files with 29642 additions and 0 deletions

View File

@ -13,6 +13,8 @@ option(BUILD_EXTENSION_DRAGONBONES "Build extension DragonBones" OFF)
option(BUILD_EXTENSION_COCOSTUDIO "Build extension cocostudio" ON)
option(BUILD_EXTENSION_FAIRYGUI "Build extension FairyGUI" ON)
function(setup_cocos_extension_config target_name)
if(ANDROID)
target_link_libraries(${target_name} INTERFACE cocos2d)
@ -59,4 +61,8 @@ if(BUILD_EXTENSION_COCOSTUDIO)
add_subdirectory(cocostudio)
endif()
if(BUILD_EXTENSION_FAIRYGUI)
add_subdirectory(fairygui)
endif()
message(STATUS "CC_EXTENSION_LIBS:${CC_EXTENSION_LIBS}")

View File

@ -0,0 +1,10 @@
set(target_name fairygui)
FILE(GLOB_RECURSE FAIRYGUI_SOURCES *.h;*.cpp)
add_library(${target_name} STATIC ${FAIRYGUI_SOURCES})
target_include_directories(${target_name} PUBLIC ${CMAKE_CURRENT_SOURCE_DIR})
setup_cocos_extension_config(${target_name})

View File

@ -0,0 +1,204 @@
#include "Controller.h"
#include "GComponent.h"
#include "controller_action/ControllerAction.h"
#include "utils/ByteBuffer.h"
#include "utils/ToolSet.h"
NS_FGUI_BEGIN
USING_NS_CC;
GController::GController() : changing(false),
autoRadioGroupDepth(false),
_parent(nullptr),
_selectedIndex(-1),
_previousIndex(-1)
{
}
GController::~GController()
{
for (auto& it : _actions)
delete it;
}
void GController::setSelectedIndex(int value, bool triggerEvent)
{
if (_selectedIndex != value)
{
CCASSERT(value < (int)_pageIds.size(), "Invalid selected index");
changing = true;
_previousIndex = _selectedIndex;
_selectedIndex = value;
_parent->applyController(this);
if (triggerEvent)
dispatchEvent(UIEventType::Changed);
changing = false;
}
}
const std::string& GController::getSelectedPage() const
{
if (_selectedIndex == -1)
return STD_STRING_EMPTY;
else
return _pageNames[_selectedIndex];
}
void GController::setSelectedPage(const std::string& value, bool triggerEvent)
{
int i = ToolSet::findInStringArray(_pageNames, value);
if (i == -1)
i = 0;
setSelectedIndex(i, triggerEvent);
}
const std::string& GController::getSelectedPageId() const
{
if (_selectedIndex == -1)
return STD_STRING_EMPTY;
else
return _pageIds[_selectedIndex];
}
void GController::setSelectedPageId(const std::string& value, bool triggerEvent)
{
int i = ToolSet::findInStringArray(_pageIds, value);
if (i != -1)
setSelectedIndex(i, triggerEvent);
}
const std::string& GController::getPreviousPage() const
{
if (_previousIndex == -1)
return STD_STRING_EMPTY;
else
return _pageNames[_previousIndex];
}
const std::string& GController::getPreviousPageId() const
{
if (_previousIndex == -1)
return STD_STRING_EMPTY;
else
return _pageIds[_previousIndex];
}
int GController::getPageCount() const
{
return (int)_pageIds.size();
}
bool GController::hasPage(const std::string& aName) const
{
return ToolSet::findInStringArray(_pageNames, aName) != -1;
}
int GController::getPageIndexById(const std::string& value) const
{
return ToolSet::findInStringArray(_pageIds, value);
}
const std::string& GController::getPageNameById(const std::string& value) const
{
int i = ToolSet::findInStringArray(_pageIds, value);
if (i != -1)
return _pageNames[i];
else
return STD_STRING_EMPTY;
}
const std::string& GController::getPageId(int index) const
{
return _pageIds[index];
}
void GController::setOppositePageId(const std::string& value)
{
int i = ToolSet::findInStringArray(_pageIds, value);
if (i > 0)
setSelectedIndex(0);
else if (_pageIds.size() > 1)
setSelectedIndex(1);
}
void GController::runActions()
{
if (_actions.empty())
return;
for (auto& it : _actions)
it->run(this, getPreviousPageId(), getSelectedPageId());
}
void GController::setup(ByteBuffer* buffer)
{
int beginPos = buffer->getPos();
buffer->seek(beginPos, 0);
name = buffer->readS();
autoRadioGroupDepth = buffer->readBool();
buffer->seek(beginPos, 1);
int cnt = buffer->readShort();
_pageIds.resize(cnt);
_pageNames.resize(cnt);
for (int i = 0; i < cnt; i++)
{
_pageIds[i].assign(buffer->readS());
_pageNames[i].assign(buffer->readS());
}
int homePageIndex = 0;
if (buffer->version >= 2)
{
int homePageType = buffer->readByte();
switch (homePageType)
{
case 1:
homePageIndex = buffer->readShort();
break;
case 2:
homePageIndex = ToolSet::findInStringArray(_pageNames, UIPackage::getBranch());
if (homePageIndex == -1)
homePageIndex = 0;
break;
case 3:
homePageIndex = ToolSet::findInStringArray(_pageNames, UIPackage::getVar(buffer->readS()));
if (homePageIndex == -1)
homePageIndex = 0;
break;
}
}
buffer->seek(beginPos, 2);
cnt = buffer->readShort();
if (cnt > 0)
{
for (int i = 0; i < cnt; i++)
{
int nextPos = buffer->readShort();
nextPos += buffer->getPos();
ControllerAction* action = ControllerAction::createAction(buffer->readByte());
action->setup(buffer);
_actions.push_back(action);
buffer->setPos(nextPos);
}
}
if (_parent != nullptr && _pageIds.size() > 0)
_selectedIndex = homePageIndex;
else
_selectedIndex = -1;
}
NS_FGUI_END

View File

@ -0,0 +1,61 @@
#ifndef __GCONTROLLER_H__
#define __GCONTROLLER_H__
#include "FairyGUIMacros.h"
#include "cocos2d.h"
#include "event/UIEventDispatcher.h"
NS_FGUI_BEGIN
class GComponent;
class ControllerAction;
class ByteBuffer;
class GController : public UIEventDispatcher
{
public:
GController();
virtual ~GController();
GComponent* getParent() const { return _parent; }
void setParent(GComponent* value) { _parent = value; }
int getSelectedIndex() const { return _selectedIndex; }
void setSelectedIndex(int value, bool triggerEvent = true);
const std::string& getSelectedPage() const;
void setSelectedPage(const std::string& value, bool triggerEvent = true);
const std::string& getSelectedPageId() const;
void setSelectedPageId(const std::string& value, bool triggerEvent = true);
int getPrevisousIndex() const { return _previousIndex; }
const std::string& getPreviousPage() const;
const std::string& getPreviousPageId() const;
int getPageCount() const;
bool hasPage(const std::string& aName) const;
int getPageIndexById(const std::string& value) const;
const std::string& getPageNameById(const std::string& value) const;
const std::string& getPageId(int index) const;
void setOppositePageId(const std::string& value);
void runActions();
void setup(ByteBuffer* buffer);
std::string name;
bool changing;
bool autoRadioGroupDepth;
private:
GComponent* _parent;
int _selectedIndex;
int _previousIndex;
std::vector<std::string> _pageIds;
std::vector<std::string> _pageNames;
std::vector<ControllerAction*> _actions;
};
NS_FGUI_END
#endif

View File

@ -0,0 +1,85 @@
#include "DragDropManager.h"
#include "UIObjectFactory.h"
#include "GRoot.h"
NS_FGUI_BEGIN
USING_NS_CC;
DragDropManager* DragDropManager::_inst = nullptr;
DragDropManager::DragDropManager() :
_agent(nullptr)
{
_agent = (GLoader*)UIObjectFactory::newObject(ObjectType::LOADER);
_agent->retain();
_agent->setTouchable(false);
_agent->setDraggable(true);
_agent->setSize(100, 100);
_agent->setPivot(0.5f, 0.5f, true);
_agent->setAlign(TextHAlignment::CENTER);
_agent->setVerticalAlign(TextVAlignment::CENTER);
_agent->setSortingOrder(INT_MAX);
_agent->addEventListener(UIEventType::DragEnd, CC_CALLBACK_1(DragDropManager::onDragEnd, this));
}
DragDropManager::~DragDropManager()
{
CC_SAFE_RELEASE(_agent);
}
DragDropManager* DragDropManager::getInstance()
{
if (_inst == nullptr)
_inst = new DragDropManager();
return _inst;
}
void DragDropManager::startDrag(const std::string & icon, const Value& sourceData, int touchPointID)
{
if (_agent->getParent() != nullptr)
return;
_sourceData = sourceData;
_agent->setURL(icon);
UIRoot->addChild(_agent);
Vec2 pt = UIRoot->globalToLocal(UIRoot->getTouchPosition(touchPointID));
_agent->setPosition(pt.x, pt.y);
_agent->startDrag(touchPointID);
}
void DragDropManager::cancel()
{
if (_agent->getParent() != nullptr)
{
_agent->stopDrag();
UIRoot->removeChild(_agent);
_sourceData = Value::Null;
}
}
void DragDropManager::onDragEnd(EventContext * context)
{
if (_agent->getParent() == nullptr) //cancelled
return;
UIRoot->removeChild(_agent);
GObject* obj = UIRoot->getTouchTarget();
while (obj != nullptr)
{
if (dynamic_cast<GComponent*>(obj))
{
if (obj->hasEventListener(UIEventType::Drop))
{
//obj->requestFocus();
obj->dispatchEvent(UIEventType::Drop, nullptr, _sourceData);
return;
}
}
obj = obj->getParent();
}
}
NS_FGUI_END

View File

@ -0,0 +1,34 @@
#ifndef __DRAGDROPMANAGER_H__
#define __DRAGDROPMANAGER_H__
#include "FairyGUIMacros.h"
#include "cocos2d.h"
#include "GLoader.h"
NS_FGUI_BEGIN
class DragDropManager
{
public:
DragDropManager();
~DragDropManager();
static DragDropManager* getInstance();
GLoader* getAgent() const { return _agent; }
bool isDragging() const { return _agent->getParent() != nullptr; }
void startDrag(const std::string& icon, const cocos2d::Value& sourceData = cocos2d::Value::Null, int touchPointID = -1);
void cancel();
private:
void onDragEnd(EventContext* context);
static DragDropManager* _inst;
GLoader* _agent;
cocos2d::Value _sourceData;
};
NS_FGUI_END
#endif

View File

@ -0,0 +1,32 @@
#ifndef __FAIRYGUI_H__
#define __FAIRYGUI_H__
#include "UIConfig.h"
#include "UIPackage.h"
#include "GImage.h"
#include "GMovieClip.h"
#include "GTextField.h"
#include "GRichTextField.h"
#include "GTextInput.h"
#include "GGraph.h"
#include "GLoader.h"
#include "GGroup.h"
#include "GComponent.h"
#include "GLabel.h"
#include "GButton.h"
#include "GComboBox.h"
#include "GProgressBar.h"
#include "GSlider.h"
#include "GScrollBar.h"
#include "GList.h"
#include "GTree.h"
#include "GRoot.h"
#include "Window.h"
#include "PopupMenu.h"
#include "UIObjectFactory.h"
#include "GObjectPool.h"
#include "DragDropManager.h"
#include "tween/GTween.h"
#include "FairyGUIMacros.h"
#endif

View File

@ -0,0 +1,36 @@
#ifndef __FAIRYGUIMACROS_H__
#define __FAIRYGUIMACROS_H__
#include "cocos2d.h"
#define NS_FGUI_BEGIN namespace fairygui {
#define NS_FGUI_END }
#define USING_NS_FGUI using namespace fairygui
#define CALL_LATER_FUNC(__TYPE__,__FUNC__) \
void __selector_##__FUNC__(float dt) \
{\
cocos2d::Director::getInstance()->getScheduler()->unschedule(CC_SCHEDULE_SELECTOR(__TYPE__::__selector_##__FUNC__), this);\
__FUNC__(); \
}\
void __FUNC__()
#define CALL_LATER(__TYPE__,__FUNC__,...) \
if (!cocos2d::Director::getInstance()->getScheduler()->isScheduled(CC_SCHEDULE_SELECTOR(__TYPE__::__selector_##__FUNC__), this))\
cocos2d::Director::getInstance()->getScheduler()->schedule(CC_SCHEDULE_SELECTOR(__TYPE__::__selector_##__FUNC__), this, (__VA_ARGS__+0), false)
#define CALL_LATER_CANCEL(__TYPE__,__FUNC__) \
cocos2d::Director::getInstance()->getScheduler()->unschedule(CC_SCHEDULE_SELECTOR(__TYPE__::__selector_##__FUNC__), this)
#define CALL_PER_FRAME(__TYPE__,__FUNC__) \
if (!cocos2d::Director::getInstance()->getScheduler()->isScheduled(CC_SCHEDULE_SELECTOR(__TYPE__::__FUNC__), this))\
cocos2d::Director::getInstance()->getScheduler()->schedule(CC_SCHEDULE_SELECTOR(__TYPE__::__FUNC__), this, 0, false)
#define CALL_PER_FRAME_CANCEL(__TYPE__,__FUNC__) \
cocos2d::Director::getInstance()->getScheduler()->unschedule(CC_SCHEDULE_SELECTOR(__TYPE__::__FUNC__), this)
#define UIRoot GRoot::getInstance()
#include "FieldTypes.h"
#endif

View File

@ -0,0 +1,201 @@
#ifndef __FIELDTYPES_H__
#define __FIELDTYPES_H__
#include "FairyGUIMacros.h"
NS_FGUI_BEGIN
enum class PackageItemType
{
IMAGE,
MOVIECLIP,
SOUND,
COMPONENT,
ATLAS,
FONT,
SWF,
MISC,
UNKNOWN,
SPINE,
DRAGONBONES
};
enum class ObjectType
{
IMAGE,
MOVIECLIP,
SWF,
GRAPH,
LOADER,
GROUP,
TEXT,
RICHTEXT,
INPUTTEXT,
COMPONENT,
LIST,
LABEL,
BUTTON,
COMBOBOX,
PROGRESSBAR,
SLIDER,
SCROLLBAR,
TREE,
LOADER3D
};
enum class ButtonMode
{
COMMON,
CHECK,
RADIO
};
enum class ChildrenRenderOrder
{
ASCENT,
DESCENT,
ARCH,
};
enum class OverflowType
{
VISIBLE,
HIDDEN,
SCROLL
};
enum class ScrollType
{
HORIZONTAL,
VERTICAL,
BOTH
};
enum ScrollBarDisplayType
{
DEFAULT,
VISIBLE,
AUTO,
HIDDEN
};
enum class LoaderFillType
{
NONE,
SCALE,
SCALE_MATCH_HEIGHT,
SCALE_MATCH_WIDTH,
SCALE_FREE,
SCALE_NO_BORDER
};
enum class ProgressTitleType
{
PERCENT,
VALUE_MAX,
VALUE,
MAX
};
enum class ListLayoutType
{
SINGLE_COLUMN,
SINGLE_ROW,
FLOW_HORIZONTAL,
FLOW_VERTICAL,
PAGINATION
};
enum class ListSelectionMode
{
SINGLE,
MULTIPLE,
MULTIPLE_SINGLECLICK,
NONE
};
enum class GroupLayoutType
{
NONE,
HORIZONTAL,
VERTICAL
};
enum class PopupDirection
{
AUTO,
UP,
DOWN
};
enum class AutoSizeType
{
NONE,
BOTH,
HEIGHT,
SHRINK
};
enum class FlipType
{
NONE,
HORIZONTAL,
VERTICAL,
BOTH
};
enum class TransitionActionType
{
XY,
Size,
Scale,
Pivot,
Alpha,
Rotation,
Color,
Animation,
Visible,
Sound,
Transition,
Shake,
ColorFilter,
Skew,
Text,
Icon,
Unknown
};
enum class FillMethod
{
None,
Horizontal,
Vertical,
Radial90,
Radial180,
Radial360,
};
enum class FillOrigin
{
Top,
Bottom,
Left,
Right
};
enum class ObjectPropID {
Text,
Icon,
Color,
OutlineColor,
Playing,
Frame,
DeltaTime,
TimeScale,
FontSize,
Selected
};
NS_FGUI_END
#endif

View File

@ -0,0 +1,453 @@
#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_CC;
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);
}
cocos2d::Color3B GButton::getTitleColor() const
{
GTextField* tf = getTextField();
if (tf)
return tf->getColor();
else
return Color3B::BLACK;
}
void GButton::setTitleColor(const cocos2d::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;
}
cocos2d::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 cocos2d::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

View File

@ -0,0 +1,101 @@
#ifndef __GBUTTON_H
#define __GBUTTON_H
#include "cocos2d.h"
#include "FairyGUIMacros.h"
#include "GComponent.h"
NS_FGUI_BEGIN
class GTextField;
class GButton : public GComponent
{
public:
static const std::string UP;
static const std::string DOWN;
static const std::string OVER;
static const std::string SELECTED_OVER;
static const std::string DISABLED;
static const std::string SELECTED_DISABLED;
GButton();
virtual ~GButton();
CREATE_FUNC(GButton);
const std::string& getTitle() { return _title; }
void setTitle(const std::string& value);
virtual const std::string& getText() const override { return _title; }
virtual void setText(const std::string& value) override { setTitle(value); }
virtual const std::string& getIcon() const override { return _icon; }
virtual void setIcon(const std::string& value) override;
const std::string& getSelectedTitle() const { return _selectedTitle; }
void setSelectedTitle(const std::string& value);
const std::string& getSelectedIcon() const { return _selectedIcon; }
void setSelectedIcon(const std::string& value);
cocos2d::Color3B getTitleColor() const;
void setTitleColor(const cocos2d::Color3B& value);
int getTitleFontSize() const;
void setTitleFontSize(int value);
bool isSelected() const { return _selected; }
void setSelected(bool value);
GController* getRelatedController() const { return _relatedController; }
void setRelatedController(GController* c);
bool isChangeStateOnClick() { return _changeStateOnClick; }
void setChangeStateOnClick(bool value) { _changeStateOnClick = value; }
GTextField* getTextField() const;
virtual cocos2d::Value getProp(ObjectPropID propId) override;
virtual void setProp(ObjectPropID propId, const cocos2d::Value& value) override;
protected:
virtual void constructExtension(ByteBuffer* buffer) override;
virtual void setup_afterAdd(ByteBuffer* buffer, int beginPos) override;
virtual void handleControllerChanged(GController* c) override;
void setState(const std::string& value);
void setCurrentState();
private:
void onRollOver(EventContext* context);
void onRollOut(EventContext* context);
void onTouchBegin(EventContext* context);
void onTouchEnd(EventContext* context);
void onClick(EventContext* context);
void onExit(EventContext* context);
ButtonMode _mode;
GObject* _titleObject;
GObject* _iconObject;
GController* _buttonController;
GController* _relatedController;
std::string _relatedPageId;
std::string _title;
std::string _selectedTitle;
std::string _icon;
std::string _selectedIcon;
std::string _sound;
float _soundVolumeScale;
bool _selected;
bool _over;
bool _down;
int _downEffect;
bool _downScaled;
float _downEffectValue;
bool _changeStateOnClick;
};
NS_FGUI_END
#endif

View File

@ -0,0 +1,452 @@
#include "GComboBox.h"
#include "GRoot.h"
#include "PackageItem.h"
#include "UIConfig.h"
#include "utils/ByteBuffer.h"
#include "utils/ToolSet.h"
NS_FGUI_BEGIN
USING_NS_CC;
GComboBox::GComboBox()
: _dropdown(nullptr),
_titleObject(nullptr),
_iconObject(nullptr),
_list(nullptr),
_selectionController(nullptr),
_itemsUpdated(true),
_selectedIndex(-1),
popupDirection(PopupDirection::AUTO)
{
visibleItemCount = UIConfig::defaultComboBoxVisibleItemCount;
}
GComboBox::~GComboBox()
{
CC_SAFE_RELEASE(_dropdown);
}
const std::string& GComboBox::getTitle() const
{
if (_titleObject != nullptr)
return _titleObject->getText();
else
return STD_STRING_EMPTY;
}
void GComboBox::setTitle(const std::string& value)
{
if (_titleObject != nullptr)
_titleObject->setText(value);
updateGear(6);
}
const cocos2d::Color3B GComboBox::getTitleColor() const
{
GTextField* tf = getTextField();
if (tf)
return tf->getColor();
else
return Color3B::BLACK;
}
void GComboBox::setTitleColor(const cocos2d::Color3B& value)
{
GTextField* tf = getTextField();
if (tf)
tf->setColor(value);
}
int GComboBox::getTitleFontSize() const
{
GTextField* tf = getTextField();
if (tf)
return tf->getFontSize();
else
return 0;
}
void GComboBox::setTitleFontSize(int value)
{
GTextField* tf = getTextField();
if (tf)
tf->setFontSize(value);
}
const std::string& GComboBox::getIcon() const
{
if (_iconObject != nullptr)
return _iconObject->getIcon();
else
return STD_STRING_EMPTY;
}
void GComboBox::setIcon(const std::string& value)
{
if (_iconObject != nullptr)
_iconObject->setIcon(value);
updateGear(7);
}
const std::string& GComboBox::getValue() const
{
if (_selectedIndex >= 0 && _selectedIndex < (int)_values.size())
return _values[_selectedIndex];
else
return STD_STRING_EMPTY;
}
void GComboBox::setValue(const std::string& value)
{
setSelectedIndex(ToolSet::findInStringArray(_values, value));
}
void GComboBox::setSelectedIndex(int value)
{
if (_selectedIndex == value)
return;
_selectedIndex = value;
if (_selectedIndex >= 0 && _selectedIndex < (int)_items.size())
{
setText(_items[_selectedIndex]);
if (!_icons.empty() && _selectedIndex != -1 && _selectedIndex < (int)_icons.size())
setIcon(_icons[_selectedIndex]);
}
else
{
setTitle(STD_STRING_EMPTY);
if (!_icons.empty())
setIcon(STD_STRING_EMPTY);
}
updateSelectionController();
}
void GComboBox::refresh()
{
if (!_items.empty())
{
if (_selectedIndex >= (int)_items.size())
_selectedIndex = (int)_items.size() - 1;
else if (_selectedIndex == -1)
_selectedIndex = 0;
setTitle(_items[_selectedIndex]);
}
else
{
setTitle(STD_STRING_EMPTY);
_selectedIndex = -1;
}
if (!_icons.empty())
{
if (_selectedIndex != -1 && _selectedIndex < (int)_icons.size())
setIcon(_icons[_selectedIndex]);
else
setIcon(STD_STRING_EMPTY);
}
_itemsUpdated = true;
}
void GComboBox::setState(const std::string& value)
{
if (_buttonController != nullptr)
_buttonController->setSelectedPage(value);
}
void GComboBox::setCurrentState()
{
if (isGrayed() && _buttonController != nullptr && _buttonController->hasPage(GButton::DISABLED))
setState(GButton::DISABLED);
else if (_dropdown != nullptr && _dropdown->getParent() != nullptr)
setState(GButton::DOWN);
else
setState(_over ? GButton::OVER : GButton::UP);
}
void GComboBox::updateSelectionController()
{
if (_selectionController != nullptr && !_selectionController->changing && _selectedIndex < _selectionController->getPageCount())
{
GController* c = _selectionController;
_selectionController = nullptr;
c->setSelectedIndex(_selectedIndex);
_selectionController = c;
}
}
void GComboBox::updateDropdownList()
{
if (_itemsUpdated)
{
_itemsUpdated = false;
renderDropdownList();
_list->resizeToFit(visibleItemCount);
}
}
void GComboBox::showDropdown()
{
updateDropdownList();
if (_list->getSelectionMode() == ListSelectionMode::SINGLE)
_list->setSelectedIndex(-1);
_dropdown->setWidth(_size.width);
_list->ensureBoundsCorrect();
UIRoot->togglePopup(_dropdown, this, popupDirection);
if (_dropdown->getParent() != nullptr)
setState(GButton::DOWN);
}
void GComboBox::renderDropdownList()
{
_list->removeChildrenToPool();
size_t cnt = _items.size();
for (size_t i = 0; i < cnt; i++)
{
GObject* item = _list->addItemFromPool();
item->setText(_items[i]);
item->setIcon((!_icons.empty() && i < _icons.size()) ? _icons[i] : STD_STRING_EMPTY);
item->name = i < _values.size() ? _values[i] : STD_STRING_EMPTY;
}
}
void GComboBox::handleControllerChanged(GController* c)
{
GComponent::handleControllerChanged(c);
if (_selectionController == c)
setSelectedIndex(c->getSelectedIndex());
}
void GComboBox::handleGrayedChanged()
{
if (_buttonController != nullptr && _buttonController->hasPage(GButton::DISABLED))
{
if (isGrayed())
setState(GButton::DISABLED);
else
setState(GButton::UP);
}
else
GComponent::handleGrayedChanged();
}
GTextField* GComboBox::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;
}
cocos2d::Value GComboBox::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());
default:
return GComponent::getProp(propId);
}
}
void GComboBox::setProp(ObjectPropID propId, const cocos2d::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;
default:
GComponent::setProp(propId, value);
break;
}
}
void GComboBox::constructExtension(ByteBuffer* buffer)
{
buffer->seek(0, 6);
_buttonController = getController("button");
_titleObject = getChild("title");
_iconObject = getChild("icon");
const std::string& dropdown = buffer->readS();
if (!dropdown.empty())
{
_dropdown = dynamic_cast<GComponent*>(UIPackage::createObjectFromURL(dropdown));
CCASSERT(_dropdown != nullptr, "FairyGUI: should be a component.");
_dropdown->retain();
_list = dynamic_cast<GList*>(_dropdown->getChild("list"));
CCASSERT(_list != nullptr, "FairyGUI: should container a list component named list.");
_list->addEventListener(UIEventType::ClickItem, CC_CALLBACK_1(GComboBox::onClickItem, this));
_list->addRelation(_dropdown, RelationType::Width);
_list->removeRelation(_dropdown, RelationType::Height);
_dropdown->addRelation(_list, RelationType::Height);
_dropdown->removeRelation(_list, RelationType::Width);
_dropdown->addEventListener(UIEventType::Exit, CC_CALLBACK_1(GComboBox::onPopupWinClosed, this));
}
addEventListener(UIEventType::RollOver, CC_CALLBACK_1(GComboBox::onRollover, this));
addEventListener(UIEventType::RollOut, CC_CALLBACK_1(GComboBox::onRollout, this));
addEventListener(UIEventType::TouchBegin, CC_CALLBACK_1(GComboBox::onTouchBegin, this));
addEventListener(UIEventType::TouchEnd, CC_CALLBACK_1(GComboBox::onTouchEnd, this));
}
void GComboBox::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;
bool hasIcon = false;
int itemCount = buffer->readShort();
for (int i = 0; i < itemCount; i++)
{
int nextPos = buffer->readShort();
nextPos += buffer->getPos();
_items.push_back(buffer->readS());
_values.push_back(buffer->readS());
if ((str = buffer->readSP()))
{
if (!hasIcon)
{
for (int i = 0; i < (int)_items.size() - 1; i++)
_icons.push_back(STD_STRING_EMPTY);
}
_icons.push_back(*str);
}
buffer->setPos(nextPos);
}
if ((str = buffer->readSP()))
{
setTitle(*str);
_selectedIndex = ToolSet::findInStringArray(_items, *str);
}
else if (!_items.empty())
{
_selectedIndex = 0;
setTitle(_items[0]);
}
else
_selectedIndex = -1;
if ((str = buffer->readSP()))
setIcon(*str);
if (buffer->readBool())
setTitleColor((Color3B)buffer->readColor());
int iv = buffer->readInt();
if (iv > 0)
visibleItemCount = iv;
popupDirection = (PopupDirection)buffer->readByte();
iv = buffer->readShort();
if (iv >= 0)
_selectionController = _parent->getControllerAt(iv);
}
void GComboBox::onClickItem(EventContext* context)
{
if (dynamic_cast<GRoot*>(_dropdown->getParent()))
((GRoot*)_dropdown->getParent())->hidePopup(_dropdown);
_selectedIndex = INT_MIN;
setSelectedIndex(_list->getChildIndex((GObject*)context->getData()));
dispatchEvent(UIEventType::Changed);
}
void GComboBox::onRollover(EventContext* context)
{
_over = true;
if (_down || (_dropdown != nullptr && _dropdown->getParent() != nullptr))
return;
setCurrentState();
}
void GComboBox::onRollout(EventContext* context)
{
_over = false;
if (_down || (_dropdown != nullptr && _dropdown->getParent() != nullptr))
return;
setCurrentState();
}
void GComboBox::onTouchBegin(EventContext* context)
{
if (context->getInput()->getButton() != EventMouse::MouseButton::BUTTON_LEFT)
return;
if (dynamic_cast<GTextInput*>(context->getInput()->getTarget()))
return;
_down = true;
if (_dropdown != nullptr)
showDropdown();
context->captureTouch();
}
void GComboBox::onTouchEnd(EventContext* context)
{
if (context->getInput()->getButton() != EventMouse::MouseButton::BUTTON_LEFT)
return;
if (_down)
{
_down = false;
if (_dropdown != nullptr && _dropdown->getParent() != nullptr)
setCurrentState();
}
}
void GComboBox::onPopupWinClosed(EventContext* context)
{
setCurrentState();
}
NS_FGUI_END

View File

@ -0,0 +1,102 @@
#ifndef __GCOMBOBOX_H__
#define __GCOMBOBOX_H__
#include "cocos2d.h"
#include "FairyGUIMacros.h"
#include "GComponent.h"
#include "GList.h"
NS_FGUI_BEGIN
class GTextField;
class GComboBox : public GComponent
{
public:
GComboBox();
virtual ~GComboBox();
CREATE_FUNC(GComboBox);
const std::string& getTitle() const;
void setTitle(const std::string& value);
virtual const std::string& getText() const override { return getTitle(); }
virtual void setText(const std::string& value) override { setTitle(value); }
const cocos2d::Color3B getTitleColor() const;
void setTitleColor(const cocos2d::Color3B& value);
int getTitleFontSize() const;
void setTitleFontSize(int value);
virtual const std::string& getIcon() const override;
virtual void setIcon(const std::string& value) override;
const std::string& getValue() const;
void setValue(const std::string& value);
int getSelectedIndex() const { return _selectedIndex; }
void setSelectedIndex(int value);
GController* getSelectionController() const { return _selectionController; }
void setSelectionController(GController* value) { _selectionController = value; }
std::vector<std::string>& getItems() { return _items; }
std::vector<std::string>& getIcons() { return _icons; }
std::vector<std::string>& getValues() { return _values; }
GObject* getDropdown() const { return _dropdown; }
void refresh();
int visibleItemCount;
PopupDirection popupDirection;
GTextField* getTextField() const;
virtual cocos2d::Value getProp(ObjectPropID propId) override;
virtual void setProp(ObjectPropID propId, const cocos2d::Value& value) override;
protected:
virtual void constructExtension(ByteBuffer* buffer) override;
virtual void setup_afterAdd(ByteBuffer* buffer, int beginPos) override;
virtual void handleControllerChanged(GController* c) override;
virtual void handleGrayedChanged() override;
void setState(const std::string& value);
void setCurrentState();
void updateSelectionController();
void updateDropdownList();
void showDropdown();
void renderDropdownList();
GComponent* _dropdown;
GObject* _titleObject;
GObject* _iconObject;
GList* _list;
GController* _selectionController;
std::vector<std::string> _items;
std::vector<std::string> _icons;
std::vector<std::string> _values;
private:
void onClickItem(EventContext* context);
void onRollover(EventContext* context);
void onRollout(EventContext* context);
void onTouchBegin(EventContext* context);
void onTouchEnd(EventContext* context);
void onPopupWinClosed(EventContext* context);
bool _itemsUpdated;
int _selectedIndex;
GController* _buttonController;
bool _down;
bool _over;
};
NS_FGUI_END
#endif

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,150 @@
#ifndef __GCOMPONENT_H__
#define __GCOMPONENT_H__
#include "FairyGUIMacros.h"
#include "GObject.h"
#include "Margin.h"
#include "ScrollPane.h"
#include "Transition.h"
#include "cocos2d.h"
#include "display/FUIContainer.h"
#include "event/HitTest.h"
NS_FGUI_BEGIN
class GComponent : public GObject
{
public:
GComponent();
virtual ~GComponent();
CREATE_FUNC(GComponent);
GObject* addChild(GObject* child);
virtual GObject* addChildAt(GObject* child, int index);
void removeChild(GObject* child);
virtual void removeChildAt(int index);
void removeChildren() { removeChildren(0, -1); }
void removeChildren(int beginIndex, int endIndex);
GObject* getChildAt(int index) const;
GObject* getChild(const std::string& name) const;
GObject* getChildByPath(const std::string& path) const;
GObject* getChildInGroup(const GGroup* group, const std::string& name) const;
GObject* getChildById(const std::string& id) const;
const cocos2d::Vector<GObject*>& getChildren() const { return _children; }
int getChildIndex(const GObject* child) const;
void setChildIndex(GObject* child, int index);
int setChildIndexBefore(GObject* child, int index);
void swapChildren(GObject* child1, GObject* child2);
void swapChildrenAt(int index1, int index2);
int numChildren() const;
bool isAncestorOf(const GObject* obj) const;
virtual bool isChildInView(GObject* child);
virtual int getFirstChildInView();
void addController(GController* c);
GController* getControllerAt(int index) const;
GController* getController(const std::string& name) const;
const cocos2d::Vector<GController*>& getControllers() const { return _controllers; }
void removeController(GController* c);
void applyController(GController* c);
void applyAllControllers();
Transition* getTransition(const std::string& name) const;
Transition* getTransitionAt(int index) const;
const cocos2d::Vector<Transition*>& getTransitions() const { return _transitions; }
bool getOpaque() const { return _opaque; }
void setOpaque(bool value);
const Margin& getMargin() { return _margin; }
void setMargin(const Margin& value);
ChildrenRenderOrder getChildrenRenderOrder() const { return _childrenRenderOrder; }
void setChildrenRenderOrder(ChildrenRenderOrder value);
int getApexIndex() const { return _apexIndex; }
void setApexIndex(int value);
cocos2d::Node* getMask() const;
void setMask(cocos2d::Node* value, bool inverted = false);
IHitTest* getHitArea() const { return _hitArea; }
void setHitArea(IHitTest* value);
ScrollPane* getScrollPane() const { return _scrollPane; }
float getViewWidth() const;
void setViewWidth(float value);
float getViewHeight() const;
void setViewHeight(float value);
void setBoundsChangedFlag();
void ensureBoundsCorrect();
virtual GObject* hitTest(const cocos2d::Vec2& worldPoint, const cocos2d::Camera* camera) override;
virtual cocos2d::Vec2 getSnappingPosition(const cocos2d::Vec2& pt);
//internal use
void childSortingOrderChanged(GObject* child, int oldValue, int newValue);
void childStateChanged(GObject* child);
void adjustRadioGroupDepth(GObject* obj, GController* c);
virtual void constructFromResource() override;
void constructFromResource(std::vector<GObject*>* objectPool, int poolIndex);
bool _buildingDisplayList;
protected:
virtual void constructExtension(ByteBuffer* buffer);
virtual void onConstruct();
virtual void setup_afterAdd(ByteBuffer* buffer, int beginPos) override;
virtual void handleInit() override;
virtual void handleSizeChanged() override;
virtual void handleGrayedChanged() override;
virtual void handleControllerChanged(GController* c) override;
virtual void onEnter() override;
virtual void onExit() override;
virtual void updateBounds();
void setBounds(float ax, float ay, float aw, float ah);
void setupOverflow(OverflowType overflow);
void setupScroll(ByteBuffer* buffer);
cocos2d::Vector<GObject*> _children;
cocos2d::Vector<GController*> _controllers;
cocos2d::Vector<Transition*> _transitions;
FUIInnerContainer* _container;
ScrollPane* _scrollPane;
Margin _margin;
cocos2d::Vec2 _alignOffset;
ChildrenRenderOrder _childrenRenderOrder;
int _apexIndex;
bool _boundsChanged;
bool _trackBounds;
GObject* _maskOwner;
IHitTest* _hitArea;
private:
int getInsertPosForSortingChild(GObject* target);
int moveChild(GObject* child, int oldIndex, int index);
CALL_LATER_FUNC(GComponent, doUpdateBounds);
CALL_LATER_FUNC(GComponent, buildNativeDisplayList);
bool _opaque;
int _sortingChildCount;
GController* _applyingController;
friend class ScrollPane;
};
NS_FGUI_END
#endif

View File

@ -0,0 +1,290 @@
#include "GGraph.h"
#include "utils/ByteBuffer.h"
#include "utils/ToolSet.h"
NS_FGUI_BEGIN
USING_NS_CC;
static void drawVertRect(cocos2d::DrawNode* shape, float x, float y, float width, float height, const cocos2d::Color4F& color)
{
float mx = x + width;
float my = y + height;
shape->drawTriangle(Vec2(x, y), Vec2(mx, y), Vec2(x, my), color);
shape->drawTriangle(Vec2(mx, y), Vec2(mx, my), Vec2(x, my), color);
}
GGraph::GGraph() : _shape(nullptr),
_type(0),
_lineSize(1),
_lineColor(Color4F::BLACK),
_fillColor(Color4F::WHITE),
_cornerRadius(nullptr),
_polygonPoints(nullptr),
_distances(nullptr)
{
_touchDisabled = true;
}
GGraph::~GGraph()
{
CC_SAFE_DELETE(_cornerRadius);
CC_SAFE_DELETE(_polygonPoints);
CC_SAFE_DELETE(_distances);
}
void GGraph::handleInit()
{
_shape = DrawNode::create();
_shape->retain();
_displayObject = _shape;
}
void GGraph::drawRect(float aWidth, float aHeight, int lineSize, const cocos2d::Color4F& lineColor, const cocos2d::Color4F& fillColor)
{
_type = 0; //avoid updateshape call in handleSizeChange
setSize(aWidth, aHeight);
_type = 1;
_lineSize = lineSize;
_lineColor = lineColor;
_fillColor = fillColor;
updateShape();
}
void GGraph::drawEllipse(float aWidth, float aHeight, int lineSize, const cocos2d::Color4F& lineColor, const cocos2d::Color4F& fillColor)
{
_type = 0; //avoid updateshape call in handleSizeChange
setSize(aWidth, aHeight);
_type = 2;
_lineSize = lineSize;
_lineColor = lineColor;
_fillColor = fillColor;
updateShape();
}
void GGraph::drawPolygon(int lineSize, const cocos2d::Color4F& lineColor, const cocos2d::Color4F& fillColor, const cocos2d::Vec2* points, int count)
{
_type = 3;
_lineSize = lineSize;
_lineColor = lineColor;
_fillColor = fillColor;
if (_polygonPoints == nullptr)
_polygonPoints = new std::vector<Vec2>();
else
_polygonPoints->clear();
float h = getHeight();
_polygonPointOffset = h;
for (int i = 0; i < count; i++)
{
Vec2 pt = *(points + i);
pt.y = h - pt.y;
_polygonPoints->push_back(*(points + i));
}
updateShape();
}
void GGraph::drawRegularPolygon(int lineSize, const cocos2d::Color4F& lineColor, const cocos2d::Color4F& fillColor,
int sides, float startAngle, const float* distances, int count)
{
_type = 4;
_lineSize = lineSize;
_lineColor = lineColor;
_fillColor = fillColor;
_sides = sides;
_startAngle = startAngle;
if (distances != nullptr)
{
if (_distances == nullptr)
_distances = new std::vector<float>();
else
_distances->clear();
for (int i = 0; i < count; i++)
_distances->push_back(*(distances + i));
}
else if (_distances != nullptr)
_distances->clear();
}
void GGraph::updateShape()
{
_shape->clear();
if (_type == 0)
{
_touchDisabled = false;
return;
}
switch (_type)
{
case 1:
{
if (_lineSize > 0)
{
float wl = _size.width - _lineSize;
float hl = _size.height - _lineSize;
drawVertRect(_shape, 0, 0, wl, _lineSize, _lineColor);
drawVertRect(_shape, wl, 0, _lineSize, hl, _lineColor);
drawVertRect(_shape, _lineSize, hl, wl, _lineSize, _lineColor);
drawVertRect(_shape, 0, _lineSize, _lineSize, hl, _lineColor);
drawVertRect(_shape, _lineSize, _lineSize, _size.width - _lineSize * 2, _size.height - _lineSize * 2, _fillColor);
}
else
drawVertRect(_shape, 0, 0, _size.width, _size.height, _fillColor);
break;
}
case 2:
{
if (_lineSize > 0)
{
_shape->setLineWidth(_lineSize);
_shape->drawCircle(Vec2(_size.width / 2, _size.height / 2), _size.width / 2, 0, 360, false, 1, _size.height / _size.width, _lineColor);
}
_shape->drawSolidCircle(Vec2(_size.width / 2, _size.height / 2), _size.width / 2, 0, 360, 1, _size.height / _size.width, _fillColor);
break;
}
case 3:
{
_shape->drawPolygon(_polygonPoints->data(), (int)_polygonPoints->size(), _fillColor, _lineSize * 0.5f, _lineColor);
break;
}
case 4:
{
float h = getHeight();
_polygonPointOffset = h;
if (_polygonPoints == nullptr)
_polygonPoints = new std::vector<Vec2>();
else
_polygonPoints->clear();
float radius = MIN(getWidth(), getHeight()) * 0.5f;
float angle = MATH_DEG_TO_RAD(_startAngle);
float deltaAngle = 2 * M_PI / _sides;
float dist;
for (int i = 0; i < _sides; i++)
{
if (_distances != nullptr && i < (int)_distances->size())
dist = (*_distances)[i];
else
dist = 1;
float xv = radius + radius * dist * cos(angle);
float yv = h - (radius + radius * dist * sin(angle));
_polygonPoints->push_back(Vec2(xv, yv));
angle += deltaAngle;
}
_shape->drawPolygon(_polygonPoints->data(), (int)_polygonPoints->size(), _fillColor, _lineSize * 0.5f, _lineColor);
break;
}
}
}
cocos2d::Color3B GGraph::getColor() const
{
return (Color3B)_fillColor;
}
void GGraph::setColor(const cocos2d::Color3B& value)
{
_fillColor = Color4F(value, _fillColor.a);
updateShape();
}
cocos2d::Value GGraph::getProp(ObjectPropID propId)
{
switch (propId)
{
case ObjectPropID::Color:
return Value(ToolSet::colorToInt(getColor()));
default:
return GObject::getProp(propId);
}
}
void GGraph::setProp(ObjectPropID propId, const cocos2d::Value& value)
{
switch (propId)
{
case ObjectPropID::Color:
setColor(ToolSet::intToColor(value.asUnsignedInt()));
break;
default:
GObject::setProp(propId, value);
break;
}
}
void GGraph::handleSizeChanged()
{
GObject::handleSizeChanged();
if (_type == 3 || _type == 4)
{
float h = getHeight();
int count = (int)_polygonPoints->size();
for (int i = 0; i < count; i++)
{
Vec2 pt = (*_polygonPoints)[i];
pt.y = h - (_polygonPointOffset - pt.y);
(*_polygonPoints)[i] = pt;
}
_polygonPointOffset = h;
}
updateShape();
}
void GGraph::setup_beforeAdd(ByteBuffer* buffer, int beginPos)
{
GObject::setup_beforeAdd(buffer, beginPos);
buffer->seek(beginPos, 5);
_type = buffer->readByte();
if (_type != 0)
{
_lineSize = buffer->readInt();
_lineColor = (Color4F)buffer->readColor();
_fillColor = (Color4F)buffer->readColor();
if (buffer->readBool())
{
_cornerRadius = new float[4];
for (int i = 0; i < 4; i++)
_cornerRadius[i] = buffer->readFloat();
}
if (_type == 3)
{
int cnt = buffer->readShort() / 2;
_polygonPoints = new std::vector<Vec2>(cnt);
float h = getHeight();
_polygonPointOffset = h;
for (int i = 0; i < cnt; i++)
{
float f1 = buffer->readFloat();
float f2 = h - buffer->readFloat();
(*_polygonPoints)[i] = Vec2(f1, f2);
}
}
else if (_type == 4)
{
_sides = buffer->readShort();
_startAngle = buffer->readFloat();
int cnt = buffer->readShort();
if (cnt > 0)
{
_distances = new std::vector<float>(cnt);
for (int i = 0; i < cnt; i++)
(*_distances)[i] = buffer->readFloat();
}
}
updateShape();
}
}
NS_FGUI_END

View File

@ -0,0 +1,54 @@
#ifndef __GGRAPH_H__
#define __GGRAPH_H__
#include "FairyGUIMacros.h"
#include "GObject.h"
#include "cocos2d.h"
NS_FGUI_BEGIN
class GGraph : public GObject
{
public:
GGraph();
virtual ~GGraph();
CREATE_FUNC(GGraph);
void drawRect(float aWidth, float aHeight, int lineSize, const cocos2d::Color4F& lineColor, const cocos2d::Color4F& fillColor);
void drawEllipse(float aWidth, float aHeight, int lineSize, const cocos2d::Color4F& lineColor, const cocos2d::Color4F& fillColor);
void drawPolygon(int lineSize, const cocos2d::Color4F& lineColor, const cocos2d::Color4F& fillColor, const cocos2d::Vec2* points, int count);
void drawRegularPolygon(int lineSize, const cocos2d::Color4F& lineColor, const cocos2d::Color4F& fillColor, int sides, float startAngle = 0, const float* distances = nullptr, int distanceCount = 0);
bool isEmpty() const { return _type == 0; }
cocos2d::Color3B getColor() const;
void setColor(const cocos2d::Color3B& value);
virtual cocos2d::Value getProp(ObjectPropID propId) override;
virtual void setProp(ObjectPropID propId, const cocos2d::Value& value) override;
protected:
virtual void handleInit() override;
virtual void setup_beforeAdd(ByteBuffer* buffer, int beginPos) override;
virtual void handleSizeChanged() override;
private:
void updateShape();
int _type;
cocos2d::Color4F _lineColor;
cocos2d::Color4F _fillColor;
int _lineSize;
float* _cornerRadius;
std::vector<cocos2d::Vec2>* _polygonPoints;
float _polygonPointOffset;
int _sides;
float _startAngle;
std::vector<float>* _distances;
cocos2d::DrawNode* _shape;
};
NS_FGUI_END
#endif

View File

@ -0,0 +1,467 @@
#include "GGroup.h"
#include "GComponent.h"
#include "utils/ByteBuffer.h"
NS_FGUI_BEGIN
USING_NS_CC;
GGroup::GGroup() : _layout(GroupLayoutType::NONE),
_lineGap(0),
_columnGap(0),
_excludeInvisibles(false),
_autoSizeDisabled(false),
_mainGridIndex(-1),
_mainGridMinSize(10),
_mainChildIndex(-1),
_totalSize(0),
_numChildren(0),
_percentReady(false),
_boundsChanged(false),
_updating(false)
{
_touchDisabled = true;
}
GGroup::~GGroup()
{
CALL_LATER_CANCEL(GGroup, ensureBoundsCorrect);
}
void GGroup::setLayout(GroupLayoutType value)
{
if (_layout != value)
{
_layout = value;
setBoundsChangedFlag(true);
}
}
void GGroup::setColumnGap(int value)
{
if (_columnGap != value)
{
_columnGap = value;
setBoundsChangedFlag();
}
}
void GGroup::setLineGap(int value)
{
if (_lineGap != value)
{
_lineGap = value;
setBoundsChangedFlag();
}
}
void GGroup::setExcludeInvisibles(bool value)
{
if (_excludeInvisibles != value)
{
_excludeInvisibles = value;
setBoundsChangedFlag();
}
}
void GGroup::setAutoSizeDisabled(bool value)
{
if (_autoSizeDisabled != value)
{
_autoSizeDisabled = value;
setBoundsChangedFlag();
}
}
void GGroup::setMainGridIndex(int value)
{
if (_mainGridIndex != value)
{
_mainGridIndex = value;
setBoundsChangedFlag();
}
}
void GGroup::setMainGridMinSize(int value)
{
if (_mainGridMinSize != value)
{
_mainGridMinSize = value;
setBoundsChangedFlag();
}
}
void GGroup::setBoundsChangedFlag(bool positionChangedOnly)
{
if (_updating == 0 && _parent != nullptr)
{
if (!positionChangedOnly)
_percentReady = false;
if (!_boundsChanged)
{
_boundsChanged = true;
if (_layout != GroupLayoutType::NONE)
CALL_LATER(GGroup, ensureBoundsCorrect);
}
}
}
void GGroup::ensureBoundsCorrect()
{
if (_parent == nullptr || !_boundsChanged)
return;
CALL_LATER_CANCEL(GGroup, ensureBoundsCorrect);
_boundsChanged = false;
if (_autoSizeDisabled)
resizeChildren(0, 0);
else
{
handleLayout();
updateBounds();
}
}
void GGroup::updateBounds()
{
int cnt = _parent->numChildren();
int i;
GObject* child;
float ax = FLT_MAX, ay = FLT_MAX;
float ar = FLT_MIN, ab = FLT_MIN;
float tmp;
bool empty = true;
for (i = 0; i < cnt; i++)
{
child = _parent->getChildAt(i);
if (child->_group != this || (_excludeInvisibles && !child->internalVisible3()))
continue;
tmp = child->getX();
if (tmp < ax)
ax = tmp;
tmp = child->getY();
if (tmp < ay)
ay = tmp;
tmp = child->getX() + child->getWidth();
if (tmp > ar)
ar = tmp;
tmp = child->getY() + child->getHeight();
if (tmp > ab)
ab = tmp;
empty = false;
}
float w;
float h;
if (!empty)
{
_updating |= 1;
setPosition(ax, ay);
_updating &= 2;
w = ar - ax;
h = ab - ay;
}
else
w = h = 0;
if ((_updating & 2) == 0)
{
_updating |= 2;
setSize(w, h);
_updating &= 1;
}
else
{
_updating &= 1;
resizeChildren(getWidth() - w, getHeight() - h);
}
}
void GGroup::handleLayout()
{
_updating |= 1;
if (_layout == GroupLayoutType::HORIZONTAL)
{
float curX = getX();
int cnt = _parent->numChildren();
for (int i = 0; i < cnt; i++)
{
GObject* child = _parent->getChildAt(i);
if (child->_group != this)
continue;
if (_excludeInvisibles && !child->internalVisible3())
continue;
child->setXMin(curX);
if (child->getWidth() != 0)
curX += child->getWidth() + _columnGap;
}
}
else if (_layout == GroupLayoutType::VERTICAL)
{
float curY = getY();
int cnt = _parent->numChildren();
for (int i = 0; i < cnt; i++)
{
GObject* child = _parent->getChildAt(i);
if (child->_group != this)
continue;
if (_excludeInvisibles && !child->internalVisible3())
continue;
child->setYMin(curY);
if (child->getHeight() != 0)
curY += child->getHeight() + _lineGap;
}
}
_updating &= 2;
}
void GGroup::moveChildren(float dx, float dy)
{
if ((_updating & 1) != 0 || _parent == nullptr)
return;
_updating |= 1;
int cnt = _parent->numChildren();
int i;
GObject* child;
for (i = 0; i < cnt; i++)
{
child = _parent->getChildAt(i);
if (child->_group == this)
{
child->setPosition(child->getX() + dx, child->getY() + dy);
}
}
_updating &= 2;
}
void GGroup::resizeChildren(float dw, float dh)
{
if (_layout == GroupLayoutType::NONE || (_updating & 2) != 0 || _parent == nullptr)
return;
_updating |= 2;
if (_boundsChanged)
{
_boundsChanged = false;
if (!_autoSizeDisabled)
{
updateBounds();
return;
}
}
int cnt = _parent->numChildren();
if (!_percentReady)
{
_percentReady = true;
_numChildren = 0;
_totalSize = 0;
_mainChildIndex = -1;
int j = 0;
for (int i = 0; i < cnt; i++)
{
GObject* child = _parent->getChildAt(i);
if (child->_group != this)
continue;
if (!_excludeInvisibles || child->internalVisible3())
{
if (j == _mainGridIndex)
_mainChildIndex = i;
_numChildren++;
if (_layout == GroupLayoutType::HORIZONTAL)
_totalSize += child->getWidth();
else
_totalSize += child->getHeight();
}
j++;
}
if (_mainChildIndex != -1)
{
if (_layout == GroupLayoutType::HORIZONTAL)
{
GObject* child = _parent->getChildAt(_mainChildIndex);
_totalSize += _mainGridMinSize - child->getWidth();
child->_sizePercentInGroup = _mainGridMinSize / _totalSize;
}
else
{
GObject* child = _parent->getChildAt(_mainChildIndex);
_totalSize += _mainGridMinSize - child->getHeight();
child->_sizePercentInGroup = _mainGridMinSize / _totalSize;
}
}
for (int i = 0; i < cnt; i++)
{
GObject* child = _parent->getChildAt(i);
if (child->_group != this)
continue;
if (i == _mainChildIndex)
continue;
if (_totalSize > 0)
child->_sizePercentInGroup = (_layout == GroupLayoutType::HORIZONTAL ? child->getWidth() : child->getHeight()) / _totalSize;
else
child->_sizePercentInGroup = 0;
}
}
float remainSize = 0;
float remainPercent = 1;
bool priorHandled = false;
if (_layout == GroupLayoutType::HORIZONTAL)
{
remainSize = getWidth() - (_numChildren - 1) * _columnGap;
if (_mainChildIndex != -1 && remainSize >= _totalSize)
{
GObject* child = _parent->getChildAt(_mainChildIndex);
child->setSize(remainSize - (_totalSize - _mainGridMinSize), child->_rawSize.height + dh, true);
remainSize -= child->getWidth();
remainPercent -= child->_sizePercentInGroup;
priorHandled = true;
}
float curX = getX();
for (int i = 0; i < cnt; i++)
{
GObject* child = _parent->getChildAt(i);
if (child->_group != this)
continue;
if (_excludeInvisibles && !child->internalVisible3())
{
child->setSize(child->_rawSize.width, child->_rawSize.height + dh, true);
continue;
}
if (!priorHandled || i != _mainChildIndex)
{
child->setSize(round(child->_sizePercentInGroup / remainPercent * remainSize), child->_rawSize.height + dh, true);
remainPercent -= child->_sizePercentInGroup;
remainSize -= child->getWidth();
}
child->setXMin(curX);
if (child->getWidth() != 0)
curX += child->getWidth() + _columnGap;
}
}
else
{
remainSize = getHeight() - (_numChildren - 1) * _lineGap;
if (_mainChildIndex != -1 && remainSize >= _totalSize)
{
GObject* child = _parent->getChildAt(_mainChildIndex);
child->setSize(child->_rawSize.width + dw, remainSize - (_totalSize - _mainGridMinSize), true);
remainSize -= child->getHeight();
remainPercent -= child->_sizePercentInGroup;
priorHandled = true;
}
float curY = getY();
for (int i = 0; i < cnt; i++)
{
GObject* child = _parent->getChildAt(i);
if (child->_group != this)
continue;
if (_excludeInvisibles && !child->internalVisible3())
{
child->setSize(child->_rawSize.width + dw, child->_rawSize.height, true);
continue;
}
if (!priorHandled || i != _mainChildIndex)
{
child->setSize(child->_rawSize.width + dw, round(child->_sizePercentInGroup / remainPercent * remainSize), true);
remainPercent -= child->_sizePercentInGroup;
remainSize -= child->getHeight();
}
child->setYMin(curY);
if (child->getHeight() != 0)
curY += child->getHeight() + _lineGap;
}
}
_updating &= 1;
}
void GGroup::handleAlphaChanged()
{
GObject::handleAlphaChanged();
if (_underConstruct)
return;
int cnt = _parent->numChildren();
for (int i = 0; i < cnt; i++)
{
GObject* child = _parent->getChildAt(i);
if (child->_group == this)
child->setAlpha(_alpha);
}
}
void GGroup::handleVisibleChanged()
{
if (!_parent)
return;
int cnt = _parent->numChildren();
for (int i = 0; i < cnt; i++)
{
GObject* child = _parent->getChildAt(i);
if (child->_group == this)
child->handleVisibleChanged();
}
}
void GGroup::setup_beforeAdd(ByteBuffer* buffer, int beginPos)
{
GObject::setup_beforeAdd(buffer, beginPos);
buffer->seek(beginPos, 5);
_layout = (GroupLayoutType)buffer->readByte();
_lineGap = buffer->readInt();
_columnGap = buffer->readInt();
if (buffer->version >= 2)
{
_excludeInvisibles = buffer->readBool();
_autoSizeDisabled = buffer->readBool();
_mainChildIndex = buffer->readShort();
}
}
void GGroup::setup_afterAdd(ByteBuffer* buffer, int beginPos)
{
GObject::setup_afterAdd(buffer, beginPos);
if (!_visible)
handleVisibleChanged();
}
NS_FGUI_END

View File

@ -0,0 +1,74 @@
#ifndef __GGROUP_H__
#define __GGROUP_H__
#include "cocos2d.h"
#include "FairyGUIMacros.h"
#include "GObject.h"
NS_FGUI_BEGIN
class GGroup : public GObject
{
public:
GGroup();
virtual ~GGroup();
CREATE_FUNC(GGroup);
GroupLayoutType getLayout() { return _layout; }
void setLayout(GroupLayoutType value);
int getColumnGap() { return _columnGap; }
void setColumnGap(int value);
int getLineGap() { return _lineGap; }
void setLineGap(int value);
bool isExcludeInvisibles() { return _excludeInvisibles; }
void setExcludeInvisibles(bool value);
bool isAutoSizeDisabled() { return _autoSizeDisabled; }
void setAutoSizeDisabled(bool value);
int getMainGridIndex() { return _mainGridIndex; }
void setMainGridIndex(int value);
int getMainGridMinSize() { return _mainGridMinSize; }
void setMainGridMinSize(int value);
void setBoundsChangedFlag(bool positionChangedOnly = false);
void moveChildren(float dx, float dy);
void resizeChildren(float dw, float dh);
int _updating;
protected:
virtual void setup_beforeAdd(ByteBuffer* buffer, int beginPos) override;
virtual void setup_afterAdd(ByteBuffer* buffer, int beginPos) override;
virtual void handleAlphaChanged() override;
virtual void handleVisibleChanged() override;
private:
void updateBounds();
void handleLayout();
CALL_LATER_FUNC(GGroup, ensureBoundsCorrect);
GroupLayoutType _layout;
int _lineGap;
int _columnGap;
bool _excludeInvisibles;
bool _autoSizeDisabled;
int _mainGridIndex;
int _mainGridMinSize;
bool _percentReady;
bool _boundsChanged;
int _mainChildIndex;
float _totalSize;
int _numChildren;
};
NS_FGUI_END
#endif

View File

@ -0,0 +1,164 @@
#include "GImage.h"
#include "PackageItem.h"
#include "display/FUISprite.h"
#include "utils/ByteBuffer.h"
#include "utils/ToolSet.h"
NS_FGUI_BEGIN
USING_NS_CC;
GImage::GImage() : _content(nullptr)
{
_touchDisabled = true;
}
GImage::~GImage()
{
}
void GImage::handleInit()
{
_content = FUISprite::create();
_content->retain();
_displayObject = _content;
}
FlipType GImage::getFlip() const
{
if (_content->isFlippedX() && _content->isFlippedY())
return FlipType::BOTH;
else if (_content->isFlippedX())
return FlipType::HORIZONTAL;
else if (_content->isFlippedY())
return FlipType::VERTICAL;
else
return FlipType::NONE;
}
void GImage::setFlip(FlipType value)
{
_content->setFlippedX(value == FlipType::HORIZONTAL || value == FlipType::BOTH);
_content->setFlippedY(value == FlipType::VERTICAL || value == FlipType::BOTH);
}
void GImage::handleGrayedChanged()
{
GObject::handleGrayedChanged();
((FUISprite*)_content)->setGrayed(_finalGrayed);
}
cocos2d::Color3B GImage::getColor() const
{
return _content->getColor();
}
void GImage::setColor(const cocos2d::Color3B& value)
{
_content->setColor(value);
}
FillMethod GImage::getFillMethod() const
{
return _content->getFillMethod();
}
void GImage::setFillMethod(FillMethod value)
{
_content->setFillMethod(value);
}
FillOrigin GImage::getFillOrigin() const
{
return _content->getFillOrigin();
}
void GImage::setFillOrigin(FillOrigin value)
{
_content->setFillOrigin(value);
}
bool GImage::isFillClockwise() const
{
return _content->isFillClockwise();
}
void GImage::setFillClockwise(bool value)
{
_content->setFillClockwise(value);
}
float GImage::getFillAmount() const
{
return _content->getFillAmount();
}
void GImage::setFillAmount(float value)
{
_content->setFillAmount(value);
}
cocos2d::Value GImage::getProp(ObjectPropID propId)
{
switch (propId)
{
case ObjectPropID::Color:
return Value(ToolSet::colorToInt(getColor()));
default:
return GObject::getProp(propId);
}
}
void GImage::setProp(ObjectPropID propId, const cocos2d::Value& value)
{
switch (propId)
{
case ObjectPropID::Color:
setColor(ToolSet::intToColor(value.asUnsignedInt()));
break;
default:
GObject::setProp(propId, value);
break;
}
}
void GImage::constructFromResource()
{
PackageItem* contentItem = _packageItem->getBranch();
sourceSize.width = contentItem->width;
sourceSize.height = contentItem->height;
initSize = sourceSize;
contentItem = contentItem->getHighResolution();
contentItem->load();
_content->setSpriteFrame(contentItem->spriteFrame);
if (contentItem->scale9Grid)
((FUISprite*)_content)->setScale9Grid(contentItem->scale9Grid);
else if (contentItem->scaleByTile)
((FUISprite*)_content)->setScaleByTile(true);
setSize(sourceSize.width, sourceSize.height);
}
void GImage::setup_beforeAdd(ByteBuffer* buffer, int beginPos)
{
GObject::setup_beforeAdd(buffer, beginPos);
buffer->seek(beginPos, 5);
if (buffer->readBool())
setColor((Color3B)buffer->readColor());
setFlip((FlipType)buffer->readByte());
int fillMethod = buffer->readByte();
if (fillMethod != 0)
{
_content->setFillMethod((FillMethod)fillMethod);
_content->setFillOrigin((FillOrigin)buffer->readByte());
_content->setFillClockwise(buffer->readBool());
_content->setFillAmount(buffer->readFloat());
}
}
NS_FGUI_END

View File

@ -0,0 +1,55 @@
#ifndef __GIMAGE_H__
#define __GIMAGE_H__
#include "FairyGUIMacros.h"
#include "GObject.h"
#include "cocos2d.h"
#include "ui/UIScale9Sprite.h"
NS_FGUI_BEGIN
class FUISprite;
class GImage : public GObject
{
public:
GImage();
virtual ~GImage();
CREATE_FUNC(GImage);
FlipType getFlip() const;
void setFlip(FlipType value);
cocos2d::Color3B getColor() const;
void setColor(const cocos2d::Color3B& value);
FillMethod getFillMethod() const;
void setFillMethod(FillMethod value);
FillOrigin getFillOrigin() const;
void setFillOrigin(FillOrigin value);
bool isFillClockwise() const;
void setFillClockwise(bool value);
float getFillAmount() const;
void setFillAmount(float value);
virtual void constructFromResource() override;
virtual cocos2d::Value getProp(ObjectPropID propId) override;
virtual void setProp(ObjectPropID propId, const cocos2d::Value& value) override;
protected:
virtual void handleInit() override;
virtual void handleGrayedChanged() override;
virtual void setup_beforeAdd(ByteBuffer* buffer, int beginPos) override;
private:
FUISprite* _content;
};
NS_FGUI_END
#endif

View File

@ -0,0 +1,190 @@
#include "GLabel.h"
#include "GButton.h"
#include "GTextField.h"
#include "GTextInput.h"
#include "PackageItem.h"
#include "utils/ByteBuffer.h"
#include "utils/ToolSet.h"
NS_FGUI_BEGIN
USING_NS_CC;
GLabel::GLabel() :
_titleObject(nullptr),
_iconObject(nullptr)
{
}
GLabel::~GLabel()
{
}
const std::string& GLabel::getText() const
{
if (_titleObject != nullptr)
return _titleObject->getText();
else
return STD_STRING_EMPTY;
}
void GLabel::setText(const std::string & value)
{
if (_titleObject != nullptr)
_titleObject->setText(value);
updateGear(6);
}
const std::string& GLabel::getIcon() const
{
if (_iconObject != nullptr)
return _iconObject->getIcon();
else
return STD_STRING_EMPTY;
}
void GLabel::setIcon(const std::string & value)
{
if (_iconObject != nullptr)
_iconObject->setIcon(value);
updateGear(7);
}
cocos2d::Color3B GLabel::getTitleColor() const
{
GTextField* tf = getTextField();
if (tf)
return tf->getColor();
else
return Color3B::BLACK;
}
void GLabel::setTitleColor(const cocos2d::Color3B & value)
{
GTextField* tf = getTextField();
if (tf)
tf->setColor(value);
}
int GLabel::getTitleFontSize() const
{
GTextField* tf = getTextField();
if (tf)
return tf->getFontSize();
else
return 0;
}
void GLabel::setTitleFontSize(int value)
{
GTextField* tf = getTextField();
if (tf)
tf->setFontSize(value);
}
GTextField * GLabel::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;
}
cocos2d::Value GLabel::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());
default:
return GComponent::getProp(propId);
}
}
void GLabel::setProp(ObjectPropID propId, const cocos2d::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;
default:
GComponent::setProp(propId, value);
break;
}
}
void GLabel::constructExtension(ByteBuffer* buffer)
{
_titleObject = getChild("title");
_iconObject = getChild("icon");
}
void GLabel::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()))
setIcon(*str);
if (buffer->readBool())
setTitleColor((Color3B)buffer->readColor());
int iv = buffer->readInt();
if (iv != 0)
setTitleFontSize(iv);
if (buffer->readBool())
{
GTextInput* input = dynamic_cast<GTextInput*>(getTextField());
if (input)
{
if ((str = buffer->readSP()))
input->setPrompt(*str);
if ((str = buffer->readSP()))
input->setRestrict(*str);
iv = buffer->readInt();
if (iv != 0)
input->setMaxLength(iv);
iv = buffer->readInt();
if (iv != 0)
input->setKeyboardType(iv);
if (buffer->readBool())
input->setPassword(true);
}
else
buffer->skip(13);
}
}
NS_FGUI_END

View File

@ -0,0 +1,51 @@
#ifndef __GLABEL_H__
#define __GLABEL_H__
#include "cocos2d.h"
#include "FairyGUIMacros.h"
#include "GComponent.h"
NS_FGUI_BEGIN
class GTextField;
class GLabel : public GComponent
{
public:
GLabel();
virtual ~GLabel();
CREATE_FUNC(GLabel);
const std::string& getTitle() { return getText(); }
void setTitle(const std::string& value) { setText(value); };
virtual const std::string& getText() const override;
virtual void setText(const std::string& value) override;
virtual const std::string& getIcon() const override;
virtual void setIcon(const std::string& value) override;
cocos2d::Color3B getTitleColor() const;
void setTitleColor(const cocos2d::Color3B& value);
int getTitleFontSize() const;
void setTitleFontSize(int value);
GTextField* getTextField() const;
virtual cocos2d::Value getProp(ObjectPropID propId) override;
virtual void setProp(ObjectPropID propId, const cocos2d::Value& value) override;
protected:
virtual void constructExtension(ByteBuffer* buffer) override;
virtual void setup_afterAdd(ByteBuffer* buffer, int beginPos) override;
private:
GObject* _titleObject;
GObject* _iconObject;
};
NS_FGUI_END
#endif

File diff suppressed because it is too large Load Diff

190
extensions/fairygui/GList.h Normal file
View File

@ -0,0 +1,190 @@
#ifndef __GLIST_H__
#define __GLIST_H__
#include "FairyGUIMacros.h"
#include "GComponent.h"
#include "GObjectPool.h"
#include "cocos2d.h"
NS_FGUI_BEGIN
class GList : public GComponent
{
public:
typedef std::function<void(int, GObject*)> ListItemRenderer;
typedef std::function<std::string(int)> ListItemProvider;
GList();
virtual ~GList();
CREATE_FUNC(GList);
const std::string& getDefaultItem() const { return _defaultItem; }
void setDefaultItem(const std::string& value) { _defaultItem = value; }
ListLayoutType getLayout() const { return _layout; }
void setLayout(ListLayoutType value);
int getLineCount() const { return _lineCount; }
void setLineCount(int value);
int getColumnCount() { return _columnCount; }
void setColumnCount(int value);
int getColumnGap() const { return _columnGap; }
void setColumnGap(int value);
int getLineGap() const { return _lineGap; }
void setLineGap(int value);
cocos2d::TextHAlignment getAlign() const { return _align; }
void setAlign(cocos2d::TextHAlignment value);
cocos2d::TextVAlignment getVerticalAlign() const { return _verticalAlign; }
void setVerticalAlign(cocos2d::TextVAlignment value);
bool getAutoResizeItem() const { return _autoResizeItem; }
void setAutoResizeItem(bool value);
ListSelectionMode getSelectionMode() const { return _selectionMode; }
void setSelectionMode(ListSelectionMode value) { _selectionMode = value; }
GObjectPool* getItemPool() const { return _pool; }
GObject* getFromPool() { return getFromPool(cocos2d::STD_STRING_EMPTY); }
GObject* getFromPool(const std::string& url);
void returnToPool(GObject* obj);
GObject* addItemFromPool() { return addItemFromPool(cocos2d::STD_STRING_EMPTY); }
GObject* addItemFromPool(const std::string& url);
GObject* addChildAt(GObject* child, int index) override;
void removeChildAt(int index) override;
void removeChildToPoolAt(int index);
void removeChildToPool(GObject* child);
void removeChildrenToPool();
void removeChildrenToPool(int beginIndex, int endIndex);
int getSelectedIndex() const;
void setSelectedIndex(int value);
void getSelection(std::vector<int>& result) const;
void addSelection(int index, bool scrollItToView);
void removeSelection(int index);
void clearSelection();
void selectAll();
void selectReverse();
void handleArrowKey(int dir);
void resizeToFit(int itemCount) { resizeToFit(itemCount, 0); }
void resizeToFit(int itemCount, int minSize);
virtual int getFirstChildInView() override;
void scrollToView(int index, bool ani = false, bool setFirst = false);
GController* getSelectionController() const { return _selectionController; }
void setSelectionController(GController* value);
void setVirtual();
void setVirtualAndLoop();
bool isVirtual() { return _virtual; }
void refreshVirtualList();
int getNumItems();
void setNumItems(int value);
int childIndexToItemIndex(int index);
int itemIndexToChildIndex(int index);
virtual cocos2d::Vec2 getSnappingPosition(const cocos2d::Vec2& pt) override;
ListItemRenderer itemRenderer;
ListItemProvider itemProvider;
bool scrollItemToViewOnClick;
bool foldInvisibleItems;
protected:
virtual void handleControllerChanged(GController* c) override;
virtual void handleSizeChanged() override;
virtual void updateBounds() override;
virtual void setup_beforeAdd(ByteBuffer* buffer, int beginPos) override;
virtual void setup_afterAdd(ByteBuffer* buffer, int beginPos) override;
virtual void dispatchItemEvent(GObject* item, EventContext* context);
virtual void readItems(ByteBuffer* buffer);
virtual void setupItem(ByteBuffer* buffer, GObject* obj);
private:
void clearSelectionExcept(GObject* g);
void setSelectionOnEvent(GObject* item, InputEvent* evt);
void onItemTouchBegin(EventContext* context);
void onClickItem(EventContext* context);
void updateSelectionController(int index);
void setVirtual(bool loop);
void checkVirtualList();
void setVirtualListChangedFlag(bool layoutChanged);
CALL_LATER_FUNC(GList, doRefreshVirtualList);
void onScroll(EventContext* context);
int getIndexOnPos1(float& pos, bool forceUpdate);
int getIndexOnPos2(float& pos, bool forceUpdate);
int getIndexOnPos3(float& pos, bool forceUpdate);
void handleScroll(bool forceUpdate);
bool handleScroll1(bool forceUpdate);
bool handleScroll2(bool forceUpdate);
void handleScroll3(bool forceUpdate);
void handleArchOrder1();
void handleArchOrder2();
void handleAlign(float contentWidth, float contentHeight);
ListLayoutType _layout;
int _lineCount;
int _columnCount;
int _lineGap;
int _columnGap;
cocos2d::TextHAlignment _align;
cocos2d::TextVAlignment _verticalAlign;
bool _autoResizeItem;
ListSelectionMode _selectionMode;
std::string _defaultItem;
GController* _selectionController;
GObjectPool* _pool;
bool _selectionHandled;
int _lastSelectedIndex;
//Virtual List support
bool _virtual;
bool _loop;
int _numItems;
int _realNumItems;
int _firstIndex; //the top left index
int _curLineItemCount; //item count in one line
int _curLineItemCount2; //item count in vertical direction,only pagination layout
cocos2d::Vec2 _itemSize;
int _virtualListChanged; //1-content changed, 2-size changed
bool _eventLocked;
uint32_t _itemInfoVer;
struct ItemInfo
{
cocos2d::Vec2 size;
GObject* obj;
uint32_t updateFlag;
bool selected;
ItemInfo();
};
std::vector<ItemInfo> _virtualItems;
};
NS_FGUI_END
#endif

View File

@ -0,0 +1,603 @@
#include "GLoader.h"
#include "GComponent.h"
#include "GMovieClip.h"
#include "UIPackage.h"
#include "display/FUISprite.h"
#include "utils/ByteBuffer.h"
#include "utils/ToolSet.h"
NS_FGUI_BEGIN
USING_NS_CC;
GLoader::GLoader()
: _autoSize(false),
_align(TextHAlignment::LEFT),
_verticalAlign(TextVAlignment::TOP),
_fill(LoaderFillType::NONE),
_shrinkOnly(false),
_updatingLayout(false),
_contentItem(nullptr),
_contentStatus(0),
_content(nullptr),
_content2(nullptr),
_playAction(nullptr),
_playing(true),
_frame(0)
{
}
GLoader::~GLoader()
{
CC_SAFE_RELEASE(_playAction);
CC_SAFE_RELEASE(_content);
CC_SAFE_RELEASE(_content2);
}
void GLoader::handleInit()
{
_content = FUISprite::create();
_content->retain();
_content->setAnchorPoint(Vec2::ZERO);
_content->setCascadeOpacityEnabled(true);
FUIContainer* c = FUIContainer::create();
c->retain();
c->gOwner = this;
_displayObject = c;
_displayObject->addChild(_content);
}
void GLoader::setURL(const std::string& value)
{
if (_url.compare(value) == 0)
return;
_url = value;
loadContent();
updateGear(7);
}
void GLoader::setAlign(cocos2d::TextHAlignment value)
{
if (_align != value)
{
_align = value;
updateLayout();
}
}
void GLoader::setVerticalAlign(cocos2d::TextVAlignment value)
{
if (_verticalAlign != value)
{
_verticalAlign = value;
updateLayout();
}
}
void GLoader::setAutoSize(bool value)
{
if (_autoSize != value)
{
_autoSize = value;
updateLayout();
}
}
void GLoader::setFill(LoaderFillType value)
{
if (_fill != value)
{
_fill = value;
updateLayout();
}
}
void GLoader::setShrinkOnly(bool value)
{
if (_shrinkOnly != value)
{
_shrinkOnly = value;
updateLayout();
}
}
const cocos2d::Size & GLoader::getContentSize()
{
return _content->getContentSize();
}
cocos2d::Color3B GLoader::getColor() const
{
return _content->getColor();
}
void GLoader::setColor(const cocos2d::Color3B& value)
{
_content->setColor(value);
}
void GLoader::setPlaying(bool value)
{
if (_playing != value)
{
_playing = value;
if (_playAction)
{
if (_playing)
_content->runAction(_playAction);
else
_content->stopAction(_playAction);
}
updateGear(5);
}
}
int GLoader::getFrame() const
{
return _frame;
}
void GLoader::setFrame(int value)
{
if (_frame != value)
{
_frame = value;
if (_playAction)
_playAction->setFrame(value);
updateGear(5);
}
}
FillMethod GLoader::getFillMethod() const
{
return _content->getFillMethod();
}
void GLoader::setFillMethod(FillMethod value)
{
_content->setFillMethod(value);
}
FillOrigin GLoader::getFillOrigin() const
{
return _content->getFillOrigin();
}
void GLoader::setFillOrigin(FillOrigin value)
{
_content->setFillOrigin(value);
}
bool GLoader::isFillClockwise() const
{
return _content->isFillClockwise();
}
void GLoader::setFillClockwise(bool value)
{
_content->setFillClockwise(value);
}
float GLoader::getFillAmount() const
{
return _content->getFillAmount();
}
void GLoader::setFillAmount(float value)
{
_content->setFillAmount(value);
}
void GLoader::loadContent()
{
clearContent();
if (_url.length() == 0)
return;
if (_url.compare(0, 5, "ui://") == 0)
loadFromPackage();
else
{
_contentStatus = 3;
loadExternal();
}
}
void GLoader::loadFromPackage()
{
_contentItem = UIPackage::getItemByURL(_url);
if (_contentItem != nullptr)
{
_contentItem = _contentItem->getBranch();
sourceSize.width = _contentItem->width;
sourceSize.height = _contentItem->height;
_contentItem = _contentItem->getHighResolution();
_contentItem->load();
if (_contentItem->type == PackageItemType::IMAGE)
{
_contentStatus = 1;
_content->initWithSpriteFrame(_contentItem->spriteFrame);
if (_contentItem->scale9Grid)
((FUISprite*)_content)->setScale9Grid(_contentItem->scale9Grid);
updateLayout();
}
else if (_contentItem->type == PackageItemType::MOVIECLIP)
{
_contentStatus = 2;
if (_playAction == nullptr)
{
_playAction = ActionMovieClip::create(_contentItem->animation, _contentItem->repeatDelay);
_playAction->retain();
}
else
_playAction->setAnimation(_contentItem->animation, _contentItem->repeatDelay);
if (_playing)
_content->runAction(_playAction);
else
_playAction->setFrame(_frame);
updateLayout();
}
else if (_contentItem->type == PackageItemType::COMPONENT)
{
GObject* obj = UIPackage::createObjectFromURL(_url);
if (obj == nullptr)
setErrorState();
else if (dynamic_cast<GComponent*>(obj) == nullptr)
{
setErrorState();
}
else
{
_content2 = obj->as<GComponent>();
_content2->retain();
_content2->addEventListener(UIEventType::SizeChange, [this](EventContext*) {
if (!_updatingLayout)
updateLayout();
});
_displayObject->addChild(_content2->displayObject());
updateLayout();
}
}
else
{
if (_autoSize)
setSize(_contentItem->width, _contentItem->height);
setErrorState();
}
}
else
setErrorState();
}
void GLoader::loadExternal()
{
auto tex = Director::getInstance()->getTextureCache()->addImage(_url);
if (tex)
{
auto sf = SpriteFrame::createWithTexture(tex, Rect(Vec2::ZERO, tex->getContentSize()));
onExternalLoadSuccess(sf);
}
else
onExternalLoadFailed();
}
void GLoader::freeExternal(cocos2d::SpriteFrame* spriteFrame)
{
}
void GLoader::onExternalLoadSuccess(cocos2d::SpriteFrame* spriteFrame)
{
_contentStatus = 4;
_content->setSpriteFrame(spriteFrame);
sourceSize = spriteFrame->getRectInPixels().size;
updateLayout();
}
void GLoader::onExternalLoadFailed()
{
setErrorState();
}
void GLoader::clearContent()
{
clearErrorState();
if (_contentStatus == 4)
freeExternal(_content->getSpriteFrame());
if (_contentStatus == 2)
{
_playAction->setAnimation(nullptr);
_content->stopAction(_playAction);
}
if (_content2 != nullptr)
{
_displayObject->removeChild(_content2->displayObject());
CC_SAFE_RELEASE(_content2);
}
((FUISprite*)_content)->clearContent();
_contentItem = nullptr;
_contentStatus = 0;
}
void GLoader::updateLayout()
{
if (_content2 == nullptr && _contentStatus == 0)
{
if (_autoSize)
{
_updatingLayout = true;
setSize(50, 30);
_updatingLayout = false;
}
return;
}
Size contentSize = sourceSize;
if (_autoSize)
{
_updatingLayout = true;
if (contentSize.width == 0)
contentSize.width = 50;
if (contentSize.height == 0)
contentSize.height = 30;
setSize(contentSize.width, contentSize.height);
_updatingLayout = false;
if (_size.equals(contentSize))
{
if (_content2 != nullptr)
{
_content2->setScale(1, 1);
_content2->setPosition(0, -_size.height);
}
else
{
_content->setScale(1, 1);
_content->setAnchorPoint(Vec2::ZERO);
_content->setPosition(0, 0);
}
return;
}
}
float sx = 1, sy = 1;
if (_fill != LoaderFillType::NONE)
{
sx = _size.width / sourceSize.width;
sy = _size.height / sourceSize.height;
if (sx != 1 || sy != 1)
{
if (_fill == LoaderFillType::SCALE_MATCH_HEIGHT)
sx = sy;
else if (_fill == LoaderFillType::SCALE_MATCH_WIDTH)
sy = sx;
else if (_fill == LoaderFillType::SCALE)
{
if (sx > sy)
sx = sy;
else
sy = sx;
}
else if (_fill == LoaderFillType::SCALE_NO_BORDER)
{
if (sx > sy)
sy = sx;
else
sx = sy;
}
if (_shrinkOnly)
{
if (sx > 1)
sx = 1;
if (sy > 1)
sy = 1;
}
contentSize.width = floor(sourceSize.width * sx);
contentSize.height = floor(sourceSize.height * sy);
}
}
if (_content2 != nullptr)
{
_content2->setScale(sx, sy);
}
else
{
if (_contentItem != nullptr)
{
if (_contentItem->scale9Grid)
{
_content->setScale(1, 1);
_content->setContentSize(contentSize);
}
else if (_contentItem->scaleByTile)
{
_content->setScale(1, 1);
_content->setContentSize(sourceSize);
_content->setTextureRect(Rect(Vec2::ZERO, contentSize));
}
else
{
_content->setContentSize(sourceSize);
_content->setScale(sx, sy);
}
}
else
{
_content->setContentSize(sourceSize);
_content->setScale(sx, sy);
}
_content->setAnchorPoint(Vec2::ZERO);
}
float nx;
float ny;
if (_align == TextHAlignment::CENTER)
nx = floor((_size.width - contentSize.width) / 2);
else if (_align == TextHAlignment::RIGHT)
nx = floor(_size.width - contentSize.width);
else
nx = 0;
if (_content2 != nullptr)
{
if (_verticalAlign == TextVAlignment::CENTER)
ny = floor(-contentSize.height - (_size.height - contentSize.height) / 2);
else if (_verticalAlign == TextVAlignment::BOTTOM)
ny = -contentSize.height;
else
ny = -_size.height;
_content2->setPosition(nx, ny);
}
else
{
if (_verticalAlign == TextVAlignment::CENTER)
ny = floor((_size.height - contentSize.height) / 2);
else if (_verticalAlign == TextVAlignment::BOTTOM)
ny = 0;
else
ny = _size.height - contentSize.height;
_content->setPosition(nx, ny);
}
}
void GLoader::setErrorState()
{
}
void GLoader::clearErrorState()
{
}
void GLoader::handleSizeChanged()
{
GObject::handleSizeChanged();
if (!_updatingLayout)
updateLayout();
}
void GLoader::handleGrayedChanged()
{
GObject::handleGrayedChanged();
((FUISprite*)_content)->setGrayed(_finalGrayed);
if (_content2 != nullptr)
_content2->setGrayed(_finalGrayed);
}
cocos2d::Value GLoader::getProp(ObjectPropID propId)
{
switch (propId)
{
case ObjectPropID::Color:
return Value(ToolSet::colorToInt(getColor()));
case ObjectPropID::Playing:
return Value(isPlaying());
case ObjectPropID::Frame:
return Value(getFrame());
case ObjectPropID::TimeScale:
if (_playAction)
return Value(_playAction->getTimeScale());
else
return Value(1);
default:
return GObject::getProp(propId);
}
}
void GLoader::setProp(ObjectPropID propId, const cocos2d::Value& value)
{
switch (propId)
{
case ObjectPropID::Color:
setColor(ToolSet::intToColor(value.asUnsignedInt()));
break;
case ObjectPropID::Playing:
setPlaying(value.asBool());
break;
case ObjectPropID::Frame:
setFrame(value.asInt());
break;
case ObjectPropID::TimeScale:
if (_playAction)
_playAction->setTimeScale(value.asFloat());
break;
case ObjectPropID::DeltaTime:
if (_playAction)
_playAction->advance(value.asFloat());
break;
default:
GObject::setProp(propId, value);
break;
}
}
void GLoader::setup_beforeAdd(ByteBuffer* buffer, int beginPos)
{
GObject::setup_beforeAdd(buffer, beginPos);
buffer->seek(beginPos, 5);
_url = buffer->readS();
_align = (TextHAlignment)buffer->readByte();
_verticalAlign = (TextVAlignment)buffer->readByte();
_fill = (LoaderFillType)buffer->readByte();
_shrinkOnly = buffer->readBool();
_autoSize = buffer->readBool();
buffer->readBool(); //_showErrorSign
_playing = buffer->readBool();
_frame = buffer->readInt();
if (buffer->readBool())
setColor((Color3B)buffer->readColor());
int fillMethod = buffer->readByte();
if (fillMethod != 0)
{
_content->setFillMethod((FillMethod)fillMethod);
_content->setFillOrigin((FillOrigin)buffer->readByte());
_content->setFillClockwise(buffer->readBool());
_content->setFillAmount(buffer->readFloat());
}
if (_url.length() > 0)
loadContent();
}
GObject* GLoader::hitTest(const Vec2& worldPoint, const Camera* camera)
{
if (!_touchable || !_displayObject->isVisible() || !_displayObject->getParent())
return nullptr;
if (_content2 != nullptr)
{
GObject* obj = _content2->hitTest(worldPoint, camera);
if (obj != nullptr)
return obj;
}
Rect rect;
rect.size = _size;
//if (isScreenPointInRect(worldPoint, camera, _displayObject->getWorldToNodeTransform(), rect, nullptr))
if (rect.containsPoint(_displayObject->convertToNodeSpace(worldPoint)))
return this;
else
return nullptr;
}
NS_FGUI_END

View File

@ -0,0 +1,110 @@
#ifndef __GLOADER_H__
#define __GLOADER_H__
#include "cocos2d.h"
#include "FairyGUIMacros.h"
#include "GObject.h"
NS_FGUI_BEGIN
class GComponent;
class ActionMovieClip;
class FUISprite;
class GLoader : public GObject
{
public:
GLoader();
virtual ~GLoader();
CREATE_FUNC(GLoader);
const std::string& getURL() const { return _url; }
void setURL(const std::string& value);
virtual const std::string& getIcon() const override { return _url; }
virtual void setIcon(const std::string& value) override { setURL(value); }
cocos2d::TextHAlignment getAlign() const { return _align; }
void setAlign(cocos2d::TextHAlignment value);
cocos2d::TextVAlignment getVerticalAlign() const { return _verticalAlign; }
void setVerticalAlign(cocos2d::TextVAlignment value);
bool getAutoSize() const { return _autoSize; }
void setAutoSize(bool value);
LoaderFillType getFill() const { return _fill; }
void setFill(LoaderFillType value);
bool isShrinkOnly() const { return _shrinkOnly; }
void setShrinkOnly(bool value);
const cocos2d::Size& getContentSize();
cocos2d::Color3B getColor() const;
void setColor(const cocos2d::Color3B& value);
bool isPlaying() const { return _playing; }
void setPlaying(bool value);
int getFrame() const;
void setFrame(int value);
FillMethod getFillMethod() const;
void setFillMethod(FillMethod value);
FillOrigin getFillOrigin() const;
void setFillOrigin(FillOrigin value);
bool isFillClockwise() const;
void setFillClockwise(bool value);
float getFillAmount() const;
void setFillAmount(float value);
GComponent* getComponent() const { return _content2; }
virtual cocos2d::Value getProp(ObjectPropID propId) override;
virtual void setProp(ObjectPropID propId, const cocos2d::Value& value) override;
protected:
virtual void handleInit() override;
virtual void handleSizeChanged() override;
virtual void handleGrayedChanged() override;
virtual void setup_beforeAdd(ByteBuffer* buffer, int beginPos) override;
virtual GObject* hitTest(const cocos2d::Vec2 & worldPoint, const cocos2d::Camera * camera) override;
virtual void loadExternal();
virtual void freeExternal(cocos2d::SpriteFrame* spriteFrame);
void onExternalLoadSuccess(cocos2d::SpriteFrame* spriteFrame);
void onExternalLoadFailed();
private:
void loadContent();
void loadFromPackage();
void clearContent();
void updateLayout();
void setErrorState();
void clearErrorState();
std::string _url;
cocos2d::TextHAlignment _align;
cocos2d::TextVAlignment _verticalAlign;
bool _autoSize;
LoaderFillType _fill;
bool _shrinkOnly;
bool _updatingLayout;
PackageItem* _contentItem;
int _contentStatus;
bool _playing;
int _frame;
FUISprite* _content;
GComponent* _content2;
ActionMovieClip* _playAction;
};
NS_FGUI_END
#endif

View File

@ -0,0 +1,470 @@
#include "GLoader3D.h"
#include "GComponent.h"
#include "GMovieClip.h"
#include "UIPackage.h"
#include "display/FUISprite.h"
#include "utils/ByteBuffer.h"
#include "utils/ToolSet.h"
#include "spine/spine-cocos2dx.h"
NS_FGUI_BEGIN
USING_NS_CC;
GLoader3D::GLoader3D()
: _autoSize(false),
_align(TextHAlignment::LEFT),
_verticalAlign(TextVAlignment::TOP),
_fill(LoaderFillType::NONE),
_shrinkOnly(false),
_updatingLayout(false),
_contentItem(nullptr),
_content(nullptr),
_container(nullptr),
_playing(true),
_frame(0),
_loop(false),
_color(255, 255, 255)
{
}
GLoader3D::~GLoader3D()
{
CC_SAFE_RELEASE(_content);
CC_SAFE_RELEASE(_container);
}
void GLoader3D::handleInit()
{
FUIContainer* c = FUIContainer::create();
c->retain();
c->gOwner = this;
_displayObject = c;
_container = FUIContainer::create();
_container->retain();
_container->setAnchorPoint(Vec2(0, 1));
_displayObject->addChild(_container);
}
void GLoader3D::setURL(const std::string& value)
{
if (_url.compare(value) == 0)
return;
_url = value;
loadContent();
updateGear(7);
}
void GLoader3D::setAlign(cocos2d::TextHAlignment value)
{
if (_align != value)
{
_align = value;
updateLayout();
}
}
void GLoader3D::setVerticalAlign(cocos2d::TextVAlignment value)
{
if (_verticalAlign != value)
{
_verticalAlign = value;
updateLayout();
}
}
void GLoader3D::setAutoSize(bool value)
{
if (_autoSize != value)
{
_autoSize = value;
updateLayout();
}
}
void GLoader3D::setFill(LoaderFillType value)
{
if (_fill != value)
{
_fill = value;
updateLayout();
}
}
void GLoader3D::setShrinkOnly(bool value)
{
if (_shrinkOnly != value)
{
_shrinkOnly = value;
updateLayout();
}
}
cocos2d::Color3B GLoader3D::getColor() const
{
return _color;
}
void GLoader3D::setColor(const cocos2d::Color3B& value)
{
_color = value;
if (_content != nullptr)
_content->setColor(_color);
}
void GLoader3D::setPlaying(bool value)
{
if (_playing != value)
{
_playing = value;
updateGear(5);
}
}
int GLoader3D::getFrame() const
{
return _frame;
}
void GLoader3D::setFrame(int value)
{
if (_frame != value)
{
_frame = value;
updateGear(5);
}
}
void GLoader3D::setAnimationName(const std::string& value)
{
_animationName = value;
onChange();
}
void GLoader3D::setSkinName(const std::string& value)
{
_skinName = value;
onChange();
}
void GLoader3D::setLoop(bool value)
{
_loop = value;
onChange();
}
void GLoader3D::setContent(cocos2d::Node* value)
{
setURL(STD_STRING_EMPTY);
_content = value;
if (_content != nullptr)
{
_content->retain();
_container->addChild(value);
}
}
void GLoader3D::loadContent()
{
clearContent();
if (_url.length() == 0)
return;
if (_url.compare(0, 5, "ui://") == 0)
loadFromPackage();
else
loadExternal();
}
void GLoader3D::loadFromPackage()
{
_contentItem = UIPackage::getItemByURL(_url);
if (_contentItem != nullptr)
{
_contentItem = _contentItem->getBranch();
sourceSize.width = _contentItem->width;
sourceSize.height = _contentItem->height;
_contentItem = _contentItem->getHighResolution();
_contentItem->load();
if (_contentItem->type == PackageItemType::SPINE)
{
size_t pos = _contentItem->file.find_last_of('.');
std::string atlasFile = _contentItem->file.substr(0, pos + 1).append("atlas");
if (!ToolSet::isFileExist(atlasFile))
atlasFile = _contentItem->file.substr(0, pos + 1).append("atlas.txt");
spine::SkeletonAnimation* skeletonAni;
if (FileUtils::getInstance()->getFileExtension(_contentItem->file) == ".skel")
skeletonAni = spine::SkeletonAnimation::createWithBinaryFile(_contentItem->file, atlasFile);
else
skeletonAni = spine::SkeletonAnimation::createWithJsonFile(_contentItem->file, atlasFile);
skeletonAni->setPosition(_contentItem->skeletonAnchor->x, -_contentItem->skeletonAnchor->y);
skeletonAni->retain();
_content = skeletonAni;
_container->addChild(_content);
onChangeSpine();
}
else
{
if (_autoSize)
setSize(_contentItem->width, _contentItem->height);
setErrorState();
}
}
else
setErrorState();
}
void GLoader3D::onChange()
{
onChangeSpine();
}
void GLoader3D::onChangeSpine()
{
spine::SkeletonAnimation* skeletonAni = dynamic_cast<spine::SkeletonAnimation*>(_content);
if (skeletonAni == nullptr)
return;
spine::AnimationState* state = skeletonAni->getState();
spine::Animation* aniToUse = !_animationName.empty() ? skeletonAni->findAnimation(_animationName) : nullptr;
if (aniToUse != nullptr)
{
spine::TrackEntry* entry = state->getCurrent(0);
if (entry == nullptr || strcmp(entry->getAnimation()->getName().buffer(), _animationName.c_str()) != 0
|| entry->isComplete() && !entry->getLoop())
entry = state->setAnimation(0, aniToUse, _loop);
else
entry->setLoop(_loop);
if (_playing)
entry->setTimeScale(1);
else
{
entry->setTimeScale(0);
entry->setTrackTime(MathUtil::lerp(0, entry->getAnimationEnd() - entry->getAnimationStart(), _frame / 100.0f));
}
}
else
state->clearTrack(0);
skeletonAni->setSkin(_skinName);
}
void GLoader3D::loadExternal()
{
}
void GLoader3D::freeExternal(cocos2d::SpriteFrame* spriteFrame)
{
}
void GLoader3D::onExternalLoadSuccess(cocos2d::SpriteFrame* spriteFrame)
{
}
void GLoader3D::onExternalLoadFailed()
{
setErrorState();
}
void GLoader3D::clearContent()
{
clearErrorState();
_contentItem = nullptr;
}
void GLoader3D::updateLayout()
{
Size contentSize = sourceSize;
if (_autoSize)
{
_updatingLayout = true;
if (contentSize.width == 0)
contentSize.width = 50;
if (contentSize.height == 0)
contentSize.height = 30;
setSize(contentSize.width, contentSize.height);
_updatingLayout = false;
if (_size.equals(contentSize))
{
_container->setScale(1, 1);
_container->setAnchorPoint(Vec2::ZERO);
_container->setPosition(0, 0);
return;
}
}
float sx = 1, sy = 1;
if (_fill != LoaderFillType::NONE)
{
sx = _size.width / sourceSize.width;
sy = _size.height / sourceSize.height;
if (sx != 1 || sy != 1)
{
if (_fill == LoaderFillType::SCALE_MATCH_HEIGHT)
sx = sy;
else if (_fill == LoaderFillType::SCALE_MATCH_WIDTH)
sy = sx;
else if (_fill == LoaderFillType::SCALE)
{
if (sx > sy)
sx = sy;
else
sy = sx;
}
else if (_fill == LoaderFillType::SCALE_NO_BORDER)
{
if (sx > sy)
sy = sx;
else
sx = sy;
}
if (_shrinkOnly)
{
if (sx > 1)
sx = 1;
if (sy > 1)
sy = 1;
}
contentSize.width = floor(sourceSize.width * sx);
contentSize.height = floor(sourceSize.height * sy);
}
}
_container->setScale(sx, sy);
_container->setAnchorPoint(Vec2::ZERO);
float nx;
float ny;
if (_align == TextHAlignment::CENTER)
nx = floor((_size.width - contentSize.width) / 2);
else if (_align == TextHAlignment::RIGHT)
nx = floor(_size.width - contentSize.width);
else
nx = 0;
if (_verticalAlign == TextVAlignment::CENTER)
ny = floor((_size.height - contentSize.height) / 2);
else if (_verticalAlign == TextVAlignment::BOTTOM)
ny = 0;
else
ny = _size.height - contentSize.height;
_container->setPosition(nx, ny);
}
void GLoader3D::setErrorState()
{
}
void GLoader3D::clearErrorState()
{
}
void GLoader3D::handleSizeChanged()
{
GObject::handleSizeChanged();
if (!_updatingLayout)
updateLayout();
}
void GLoader3D::handleGrayedChanged()
{
GObject::handleGrayedChanged();
}
cocos2d::Value GLoader3D::getProp(ObjectPropID propId)
{
switch (propId)
{
case ObjectPropID::Color:
return Value(ToolSet::colorToInt(getColor()));
case ObjectPropID::Playing:
return Value(isPlaying());
case ObjectPropID::Frame:
return Value(getFrame());
case ObjectPropID::TimeScale:
return Value(1);
default:
return GObject::getProp(propId);
}
}
void GLoader3D::setProp(ObjectPropID propId, const cocos2d::Value& value)
{
switch (propId)
{
case ObjectPropID::Color:
setColor(ToolSet::intToColor(value.asUnsignedInt()));
break;
case ObjectPropID::Playing:
setPlaying(value.asBool());
break;
case ObjectPropID::Frame:
setFrame(value.asInt());
break;
case ObjectPropID::TimeScale:
break;
case ObjectPropID::DeltaTime:
break;
default:
GObject::setProp(propId, value);
break;
}
}
void GLoader3D::setup_beforeAdd(ByteBuffer* buffer, int beginPos)
{
GObject::setup_beforeAdd(buffer, beginPos);
buffer->seek(beginPos, 5);
_url = buffer->readS();
_align = (TextHAlignment)buffer->readByte();
_verticalAlign = (TextVAlignment)buffer->readByte();
_fill = (LoaderFillType)buffer->readByte();
_shrinkOnly = buffer->readBool();
_autoSize = buffer->readBool();
_animationName = buffer->readS();
_skinName = buffer->readS();
_playing = buffer->readBool();
_frame = buffer->readInt();
_loop = buffer->readBool();
if (buffer->readBool())
setColor((Color3B)buffer->readColor());
if (_url.length() > 0)
loadContent();
}
GObject* GLoader3D::hitTest(const Vec2& worldPoint, const Camera* camera)
{
if (!_touchable || !_displayObject->isVisible() || !_displayObject->getParent())
return nullptr;
Rect rect;
rect.size = _size;
//if (isScreenPointInRect(worldPoint, camera, _displayObject->getWorldToNodeTransform(), rect, nullptr))
if (rect.containsPoint(_displayObject->convertToNodeSpace(worldPoint)))
return this;
else
return nullptr;
}
NS_FGUI_END

View File

@ -0,0 +1,110 @@
#ifndef __GLOADER3D_H__
#define __GLOADER3D_H__
#include "cocos2d.h"
#include "FairyGUIMacros.h"
#include "GObject.h"
NS_FGUI_BEGIN
class GComponent;
class FUIContainer;
class GLoader3D : public GObject
{
public:
GLoader3D();
virtual ~GLoader3D();
CREATE_FUNC(GLoader3D);
const std::string& getURL() const { return _url; }
void setURL(const std::string& value);
virtual const std::string& getIcon() const override { return _url; }
virtual void setIcon(const std::string& value) override { setURL(value); }
cocos2d::TextHAlignment getAlign() const { return _align; }
void setAlign(cocos2d::TextHAlignment value);
cocos2d::TextVAlignment getVerticalAlign() const { return _verticalAlign; }
void setVerticalAlign(cocos2d::TextVAlignment value);
bool getAutoSize() const { return _autoSize; }
void setAutoSize(bool value);
LoaderFillType getFill() const { return _fill; }
void setFill(LoaderFillType value);
bool isShrinkOnly() const { return _shrinkOnly; }
void setShrinkOnly(bool value);
const cocos2d::Node* getContent() { return _content; }
void setContent(cocos2d::Node* value);
cocos2d::Color3B getColor() const;
void setColor(const cocos2d::Color3B& value);
bool isPlaying() const { return _playing; }
void setPlaying(bool value);
int getFrame() const;
void setFrame(int value);
const std::string& getAnimationName() const { return _animationName; }
void setAnimationName(const std::string& value);
const std::string& getSkinName() const { return _skinName; }
void setSkinName(const std::string& value);
bool getLoop() const { return _loop; }
void setLoop(bool value);
virtual cocos2d::Value getProp(ObjectPropID propId) override;
virtual void setProp(ObjectPropID propId, const cocos2d::Value& value) override;
protected:
virtual void handleInit() override;
virtual void handleSizeChanged() override;
virtual void handleGrayedChanged() override;
virtual void setup_beforeAdd(ByteBuffer* buffer, int beginPos) override;
virtual GObject* hitTest(const cocos2d::Vec2 & worldPoint, const cocos2d::Camera * camera) override;
virtual void loadExternal();
virtual void freeExternal(cocos2d::SpriteFrame* spriteFrame);
void onExternalLoadSuccess(cocos2d::SpriteFrame* spriteFrame);
void onExternalLoadFailed();
void onChange();
void onChangeSpine();
private:
void loadContent();
void loadFromPackage();
void clearContent();
void updateLayout();
void setErrorState();
void clearErrorState();
std::string _url;
cocos2d::TextHAlignment _align;
cocos2d::TextVAlignment _verticalAlign;
bool _autoSize;
LoaderFillType _fill;
bool _shrinkOnly;
bool _updatingLayout;
PackageItem* _contentItem;
bool _playing;
int _frame;
bool _loop;
std::string _animationName;
std::string _skinName;
cocos2d::Color3B _color;
FUIContainer* _container;
cocos2d::Node* _content;
};
NS_FGUI_END
#endif

View File

@ -0,0 +1,483 @@
#include "GMovieClip.h"
#include "PackageItem.h"
#include "display/FUISprite.h"
#include "utils/ByteBuffer.h"
#include "utils/ToolSet.h"
NS_FGUI_BEGIN
USING_NS_CC;
GMovieClip::GMovieClip()
: _playAction(nullptr),
_content(nullptr),
_playing(true)
{
_sizeImplType = 1;
_touchDisabled = true;
}
GMovieClip::~GMovieClip()
{
CC_SAFE_RELEASE(_playAction);
}
void GMovieClip::handleInit()
{
_content = FUISprite::create();
_content->retain();
_playAction = ActionMovieClip::create(nullptr);
_playAction->retain();
_displayObject = _content;
}
void GMovieClip::setPlaySettings(int start, int end, int times, int endAt, std::function<void()> completeCallback)
{
_playAction->setPlaySettings(start, end, times, endAt, completeCallback);
}
void GMovieClip::setPlaying(bool value)
{
if (_playing != value)
{
_playing = value;
if (_playing)
_content->runAction(_playAction);
else
_content->stopAction(_playAction);
}
}
int GMovieClip::getFrame() const
{
return _playAction->getFrame();
}
void GMovieClip::setFrame(int value)
{
_playAction->setFrame(value);
}
float GMovieClip::getTimeScale() const
{
return _playAction->getTimeScale();
}
void GMovieClip::setTimeScale(float value)
{
_playAction->setTimeScale(value);
}
void GMovieClip::advance(float time)
{
_playAction->advance(time);
}
FlipType GMovieClip::getFlip() const
{
if (_content->isFlippedX() && _content->isFlippedY())
return FlipType::BOTH;
else if (_content->isFlippedX())
return FlipType::HORIZONTAL;
else if (_content->isFlippedY())
return FlipType::VERTICAL;
else
return FlipType::NONE;
}
void GMovieClip::setFlip(FlipType value)
{
_content->setFlippedX(value == FlipType::HORIZONTAL || value == FlipType::BOTH);
_content->setFlippedY(value == FlipType::VERTICAL || value == FlipType::BOTH);
}
void GMovieClip::setColor(const cocos2d::Color3B& value)
{
_content->setColor(value);
}
void GMovieClip::handleGrayedChanged()
{
GObject::handleGrayedChanged();
((FUISprite*)_content)->setGrayed(_finalGrayed);
}
cocos2d::Value GMovieClip::getProp(ObjectPropID propId)
{
switch (propId)
{
case ObjectPropID::Color:
return Value(ToolSet::colorToInt(getColor()));
case ObjectPropID::Playing:
return Value(isPlaying());
case ObjectPropID::Frame:
return Value(getFrame());
case ObjectPropID::TimeScale:
return Value(_playAction->getTimeScale());
default:
return GObject::getProp(propId);
}
}
void GMovieClip::setProp(ObjectPropID propId, const cocos2d::Value& value)
{
switch (propId)
{
case ObjectPropID::Color:
setColor(ToolSet::intToColor(value.asUnsignedInt()));
break;
case ObjectPropID::Playing:
setPlaying(value.asBool());
break;
case ObjectPropID::Frame:
setFrame(value.asInt());
break;
case ObjectPropID::TimeScale:
_playAction->setTimeScale(value.asFloat());
break;
case ObjectPropID::DeltaTime:
_playAction->advance(value.asFloat());
break;
default:
GObject::setProp(propId, value);
break;
}
}
void GMovieClip::constructFromResource()
{
PackageItem* contentItem = _packageItem->getBranch();
sourceSize.width = contentItem->width;
sourceSize.height = contentItem->height;
initSize = sourceSize;
contentItem = contentItem->getHighResolution();
contentItem->load();
_playAction->setAnimation(contentItem->animation, contentItem->repeatDelay, contentItem->swing);
_content->runAction(_playAction);
setSize(sourceSize.width, sourceSize.height);
}
void GMovieClip::setup_beforeAdd(ByteBuffer* buffer, int beginPos)
{
GObject::setup_beforeAdd(buffer, beginPos);
buffer->seek(beginPos, 5);
if (buffer->readBool())
setColor((Color3B)buffer->readColor());
setFlip((FlipType)buffer->readByte());
setFrame(buffer->readInt());
setPlaying(buffer->readBool());
}
ActionMovieClip::ActionMovieClip() : _animation(nullptr),
_frame(0),
_frameElapsed(0),
_repeatedCount(0),
_repeatDelay(0),
_start(0),
_end(0),
_times(0),
_endAt(0),
_status(0),
_displayFrame(-1),
_swing(false),
_reversed(false),
_timeScale(1)
{
}
ActionMovieClip::~ActionMovieClip()
{
CC_SAFE_RELEASE(_animation);
}
ActionMovieClip* ActionMovieClip::create(cocos2d::Animation* animation, float repeatDelay, bool swing)
{
ActionMovieClip* action = new (std::nothrow) ActionMovieClip();
if (action)
{
action->setAnimation(animation, repeatDelay, swing);
action->autorelease();
return action;
}
delete action;
return nullptr;
}
bool ActionMovieClip::isDone() const
{
return false;
}
void ActionMovieClip::step(float dt)
{
if (_animation == nullptr)
return;
auto frames = _animation->getFrames();
int frameCount = (int)frames.size();
if (frameCount == 0)
return;
if (frameCount == 0 || _status == 3)
return;
if (_timeScale != 1)
dt *= _timeScale;
_frameElapsed += dt;
float tt = (frames.at(_frame)->getDelayUnits() + ((_frame == 0 && _repeatedCount > 0) ? _repeatDelay : 0)) * _animation->getDelayPerUnit();
if (_frame == 0 && _repeatedCount > 0)
tt += _repeatDelay;
if (_frameElapsed < tt)
return;
_frameElapsed -= tt;
if (_frameElapsed > _animation->getDelayPerUnit())
_frameElapsed = _animation->getDelayPerUnit();
if (_swing)
{
if (_reversed)
{
_frame--;
if (_frame <= 0)
{
_frame = 0;
_repeatedCount++;
_reversed = !_reversed;
}
}
else
{
_frame++;
if (_frame > frameCount - 1)
{
_frame = MAX(0, frameCount - 2);
_repeatedCount++;
_reversed = !_reversed;
}
}
}
else
{
_frame++;
if (_frame > frameCount - 1)
{
_frame = 0;
_repeatedCount++;
}
}
if (_status == 1) //new loop
{
_frame = _start;
_frameElapsed = 0;
_status = 0;
}
else if (_status == 2) //ending
{
_frame = _endAt;
_frameElapsed = 0;
_status = 3; //ended
if (_completeCallback)
_completeCallback();
}
else
{
if (_frame == _end)
{
if (_times > 0)
{
_times--;
if (_times == 0)
_status = 2; //ending
else
_status = 1; //new loop
}
else if (_start != 0)
_status = 1; //new loop
}
}
drawFrame();
}
void ActionMovieClip::startWithTarget(Node* target)
{
Action::startWithTarget(target);
drawFrame();
}
ActionMovieClip* ActionMovieClip::reverse() const
{
CC_ASSERT(0);
return nullptr;
}
ActionMovieClip* ActionMovieClip::clone() const
{
return ActionMovieClip::create(_animation->clone(), _repeatDelay, _swing);
}
void ActionMovieClip::setFrame(int value)
{
if (_animation == nullptr)
return;
auto frames = _animation->getFrames();
int frameCount = (int)frames.size();
if (value >= frameCount)
value = frameCount - 1;
_frame = value;
_frameElapsed = 0;
_displayFrame = -1;
drawFrame();
}
void ActionMovieClip::advance(float time)
{
if (_animation == nullptr)
return;
auto frames = _animation->getFrames();
int frameCount = (int)frames.size();
if (frameCount == 0)
return;
int beginFrame = _frame;
bool beginReversed = _reversed;
float backupTime = time;
while (true)
{
float tt = (frames.at(_frame)->getDelayUnits() + ((_frame == 0 && _repeatedCount > 0) ? _repeatDelay : 0)) * _animation->getDelayPerUnit();
if (_frame == 0 && _repeatedCount > 0)
tt += _repeatDelay;
if (time < tt)
{
_frameElapsed = 0;
break;
}
time -= tt;
if (_swing)
{
if (_reversed)
{
_frame--;
if (_frame <= 0)
{
_frame = 0;
_repeatedCount++;
_reversed = !_reversed;
}
}
else
{
_frame++;
if (_frame > frameCount - 1)
{
_frame = MAX(0, frameCount - 2);
_repeatedCount++;
_reversed = !_reversed;
}
}
}
else
{
_frame++;
if (_frame > frameCount - 1)
{
_frame = 0;
_repeatedCount++;
}
}
if (_frame == beginFrame && _reversed == beginReversed)
{
float roundTime = backupTime - time;
time -= (int)floor(time / roundTime) * roundTime;
}
}
}
void ActionMovieClip::setPlaySettings(int start, int end, int times, int endAt, std::function<void()> completeCallback)
{
auto frames = _animation->getFrames();
int frameCount = (int)frames.size();
_start = start;
_end = end;
if (_end == -1 || _end > frameCount - 1)
_end = frameCount - 1;
_times = times;
_endAt = endAt;
if (_endAt == -1)
_endAt = _end;
_status = 0;
_completeCallback = completeCallback;
setFrame(start);
}
void ActionMovieClip::setAnimation(cocos2d::Animation* animation, float repeatDelay, bool swing)
{
if (_animation != animation)
{
CC_SAFE_RETAIN(animation);
CC_SAFE_RELEASE(_animation);
_animation = animation;
}
if (_animation == nullptr)
return;
_repeatDelay = repeatDelay;
_swing = swing;
_completeCallback = nullptr;
auto frames = _animation->getFrames();
int frameCount = (int)frames.size();
if (_end == -1 || _end > frameCount - 1)
_end = frameCount - 1;
if (_endAt == -1 || _endAt > frameCount - 1)
_endAt = frameCount - 1;
if (_frame < 0 || _frame > frameCount - 1)
_frame = frameCount - 1;
_displayFrame = -1;
_frameElapsed = 0;
_repeatedCount = 0;
_reversed = false;
}
void ActionMovieClip::drawFrame()
{
if (_target == nullptr || _animation == nullptr)
return;
auto frames = _animation->getFrames();
int frameCount = (int)frames.size();
if (_frame == _displayFrame || frameCount == 0)
return;
_displayFrame = _frame;
AnimationFrame* frame = frames.at(_frame);
//auto blend = static_cast<Sprite*>(_target)->getBlendFunc();
static_cast<Sprite*>(_target)->setSpriteFrame(frame->getSpriteFrame());
//static_cast<Sprite*>(_target)->setBlendFunc(blend);
}
NS_FGUI_END

View File

@ -0,0 +1,106 @@
#ifndef __GMOVIECLIP_H__
#define __GMOVIECLIP_H__
#include "cocos2d.h"
#include "FairyGUIMacros.h"
#include "GObject.h"
NS_FGUI_BEGIN
class ActionMovieClip;
class GMovieClip : public GObject
{
public:
GMovieClip();
virtual ~GMovieClip();
CREATE_FUNC(GMovieClip);
bool isPlaying() const { return _playing; }
void setPlaying(bool value);
int getFrame() const;
void setFrame(int value);
float getTimeScale() const;
void setTimeScale(float value);
void advance(float time);
FlipType getFlip() const;
void setFlip(FlipType value);
cocos2d::Color3B getColor() const { return _content->getColor(); }
void setColor(const cocos2d::Color3B& value);
//from start to end(-1 means ending) repeat times(0 means infinite loop) when all is over, stopping at endAt(-1 means same value of end)
void setPlaySettings(int start = 0, int end = -1, int times = 0, int endAt = -1, std::function<void()> completeCallback = nullptr);
virtual void constructFromResource() override;
virtual cocos2d::Value getProp(ObjectPropID propId) override;
virtual void setProp(ObjectPropID propId, const cocos2d::Value& value) override;
protected:
virtual void handleInit() override;
virtual void setup_beforeAdd(ByteBuffer* buffer, int beginPos) override;
virtual void handleGrayedChanged() override;
private:
cocos2d::Sprite* _content;
ActionMovieClip* _playAction;
bool _playing;
};
class ActionMovieClip : public cocos2d::Action
{
public:
static ActionMovieClip* create(cocos2d::Animation *animation, float repeatDelay = 0, bool swing =false);
ActionMovieClip();
~ActionMovieClip();
virtual bool isDone() const override;
virtual void step(float dt) override;
virtual void startWithTarget(cocos2d::Node *target) override;
virtual ActionMovieClip* reverse() const override;
virtual ActionMovieClip* clone() const override;
int getFrame() { return _frame; }
void setFrame(int value);
float getTimeScale() const { return _timeScale; }
void setTimeScale(float value) { _timeScale = value; }
void advance(float time);
void setPlaySettings(int start, int end, int times, int endAt, std::function<void()> completeCallback = nullptr);
void setAnimation(cocos2d::Animation *animation, float repeatDelay = 0, bool swing = false);
private:
void drawFrame();
cocos2d::Animation* _animation;
int _frame;
float _frameElapsed;
int _repeatedCount;
bool _reversed;
float _timeScale;
float _repeatDelay;
bool _swing;
std::function<void()> _completeCallback;
int _displayFrame;
int _start;
int _end;
int _times;
int _endAt;
int _status; //0-none, 1-next loop, 2-ending, 3-ended
CC_DISALLOW_COPY_AND_ASSIGN(ActionMovieClip);
};
NS_FGUI_END
#endif

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,265 @@
#ifndef __GOBJECT_H__
#define __GOBJECT_H__
#include "Controller.h"
#include "FairyGUIMacros.h"
#include "Relations.h"
#include "cocos2d.h"
#include "event/UIEventDispatcher.h"
#include "gears/GearBase.h"
NS_FGUI_BEGIN
class GComponent;
class GGroup;
class ByteBuffer;
class GRoot;
class PackageItem;
class GTreeNode;
class GObject : public UIEventDispatcher
{
public:
static GObject* getDraggingObject() { return _draggingObject; }
GObject();
virtual ~GObject();
CREATE_FUNC(GObject);
float getX() const { return _position.x; };
void setX(float value);
float getY() const { return _position.y; };
void setY(float value);
const cocos2d::Vec2& getPosition() const { return _position; }
void setPosition(float xv, float yv);
float getXMin() const;
void setXMin(float value);
float getYMin() const;
void setYMin(float value);
bool isPixelSnapping() const { return _pixelSnapping; }
void setPixelSnapping(bool value);
float getWidth() const { return _size.width; }
void setWidth(float value) { setSize(value, _rawSize.height); }
float getHeight() const { return _size.height; }
void setHeight(float value) { setSize(_rawSize.width, value); }
const cocos2d::Size& getSize() const { return _size; }
void setSize(float wv, float hv, bool ignorePivot = false);
void center(bool restraint = false);
void makeFullScreen();
const cocos2d::Vec2& getPivot() const { return _pivot; }
void setPivot(float xv, float yv, bool asAnchor = false);
bool isPivotAsAnchor() const { return _pivotAsAnchor; }
float getScaleX() const { return _scale.x; }
void setScaleX(float value) { setScale(value, _scale.y); }
float getScaleY() const { return _scale.y; }
void setScaleY(float value) { setScale(_scale.x, value); }
const cocos2d::Vec2& getScale() const { return _scale; }
void setScale(float xv, float yv);
float getSkewX() const { return _displayObject->getSkewX(); }
void setSkewX(float value);
float getSkewY() const { return _displayObject->getSkewY(); }
void setSkewY(float value);
float getRotation() const { return _rotation; }
void setRotation(float value);
float getAlpha() const { return _alpha; }
void setAlpha(float value);
bool isGrayed() const { return _grayed; }
void setGrayed(bool value);
bool isVisible() const { return _visible; }
void setVisible(bool value);
bool isTouchable() const { return _touchable; }
void setTouchable(bool value);
int getSortingOrder() const { return _sortingOrder; }
void setSortingOrder(int value);
GGroup* getGroup() const { return _group; }
void setGroup(GGroup* value);
virtual const std::string& getText() const;
virtual void setText(const std::string& text);
virtual const std::string& getIcon() const;
virtual void setIcon(const std::string& text);
const std::string& getTooltips() const { return _tooltips; }
void setTooltips(const std::string& value);
void* getData() const { return _data; };
void setData(void* value) { _data = value; }
const cocos2d::Value& getCustomData() const { return _customData; }
void setCustomData(const cocos2d::Value& value) { _customData = value; }
bool isDraggable() const { return _draggable; }
void setDraggable(bool value);
cocos2d::Rect* getDragBounds() const { return _dragBounds; }
void setDragBounds(const cocos2d::Rect& value);
void startDrag(int touchId = -1);
void stopDrag();
std::string getResourceURL() const;
PackageItem* getPackageItem() const { return _packageItem; }
cocos2d::Vec2 globalToLocal(const cocos2d::Vec2& pt);
cocos2d::Rect globalToLocal(const cocos2d::Rect& rect);
cocos2d::Vec2 localToGlobal(const cocos2d::Vec2& pt);
cocos2d::Rect localToGlobal(const cocos2d::Rect& rect);
cocos2d::Rect transformRect(const cocos2d::Rect& rect, GObject* targetSpace);
Relations* relations() { return _relations; }
void addRelation(GObject* target, RelationType relationType, bool usePercent = false);
void removeRelation(GObject* target, RelationType relationType);
GearBase* getGear(int index);
bool checkGearController(int index, GController* c);
uint32_t addDisplayLock();
void releaseDisplayLock(uint32_t token);
GComponent* getParent() const { return _parent; }
GObject* findParent() const;
cocos2d::Node* displayObject() const { return _displayObject; }
GRoot* getRoot() const;
bool onStage() const;
void removeFromParent();
void addClickListener(const EventCallback& callback) { addEventListener(UIEventType::Click, callback); }
void addClickListener(const EventCallback& callback, const EventTag& tag) { addEventListener(UIEventType::Click, callback, tag); }
void removeClickListener(const EventTag& tag) { removeEventListener(UIEventType::Click, tag); }
virtual cocos2d::Value getProp(ObjectPropID propId);
virtual void setProp(ObjectPropID propId, const cocos2d::Value& value);
virtual void constructFromResource();
virtual GObject* hitTest(const cocos2d::Vec2& worldPoint, const cocos2d::Camera* camera);
template <typename T>
T* as();
GTreeNode* treeNode() const { return _treeNode; }
std::string id;
std::string name;
cocos2d::Size sourceSize;
cocos2d::Size initSize;
cocos2d::Size minSize;
cocos2d::Size maxSize;
//internal use
bool _underConstruct;
bool _gearLocked;
bool _alignToBL;
protected:
GComponent* _parent;
cocos2d::Node* _displayObject;
PackageItem* _packageItem;
int _sizeImplType;
bool _touchDisabled;
virtual void handleInit();
virtual void handleSizeChanged();
virtual void handleScaleChanged();
virtual void handleGrayedChanged();
virtual void handlePositionChanged();
virtual void handleControllerChanged(GController* c);
virtual void handleAlphaChanged();
virtual void handleVisibleChanged();
virtual void onEnter();
virtual void onExit();
virtual void setup_beforeAdd(ByteBuffer* buffer, int beginPos);
virtual void setup_afterAdd(ByteBuffer* buffer, int beginPos);
bool init();
void updateGear(int index);
void checkGearDisplay();
void setSizeDirectly(float wv, float hv);
cocos2d::Vec2 _position;
cocos2d::Size _size;
cocos2d::Size _rawSize;
cocos2d::Vec2 _pivot;
cocos2d::Vec2 _scale;
bool _pivotAsAnchor;
float _alpha;
float _rotation;
bool _visible;
bool _touchable;
bool _grayed;
bool _finalGrayed;
private:
bool internalVisible() const;
bool internalVisible2() const;
bool internalVisible3() const;
void updateGearFromRelations(int index, float dx, float dy);
void transformRectPoint(const cocos2d::Vec2& pt, float rect[], GObject* targetSpace);
void initDrag();
void dragBegin(int touchId);
void dragEnd();
void onTouchBegin(EventContext* context);
void onTouchMove(EventContext* context);
void onTouchEnd(EventContext* context);
void onRollOver(EventContext* context);
void onRollOut(EventContext* context);
bool _internalVisible;
bool _handlingController;
bool _draggable;
int _sortingOrder;
bool _focusable;
std::string _tooltips;
bool _pixelSnapping;
GGroup* _group;
float _sizePercentInGroup;
Relations* _relations;
GearBase* _gears[10];
void* _data;
cocos2d::Value _customData;
cocos2d::Vec2 _dragTouchStartPos;
cocos2d::Rect* _dragBounds;
bool _dragTesting;
GTreeNode* _treeNode;
uint64_t _uid;
size_t _weakPtrRef;
static GObject* _draggingObject;
friend class GComponent;
friend class GGroup;
friend class RelationItem;
friend class UIObjectFactory;
friend class WeakPtr;
friend class UIPackage;
friend class GTree;
};
template <typename T>
inline T* GObject::as()
{
return dynamic_cast<T*>(this);
}
NS_FGUI_END
#endif

View File

@ -0,0 +1,41 @@
#include "GObjectPool.h"
#include "GObject.h"
#include "UIPackage.h"
NS_FGUI_BEGIN
USING_NS_CC;
GObjectPool::GObjectPool()
{
}
GObjectPool::~GObjectPool()
{
}
GObject* GObjectPool::getObject(const std::string & url)
{
std::string url2 = UIPackage::normalizeURL(url);
if (url2.length() == 0)
return nullptr;
GObject* ret;
Vector<GObject*>& arr = _pool[url2];
if (!arr.empty())
{
ret = arr.back();
ret->retain();
arr.popBack();
ret->autorelease();
}
else
ret = UIPackage::createObjectFromURL(url2);
return ret;
}
void GObjectPool::returnObject(GObject* obj)
{
_pool[obj->getResourceURL()].pushBack(obj);
}
NS_FGUI_END

View File

@ -0,0 +1,26 @@
#ifndef __GOBJECTPOOL_H__
#define __GOBJECTPOOL_H__
#include "FairyGUIMacros.h"
#include "cocos2d.h"
NS_FGUI_BEGIN
class GObject;
class GObjectPool
{
public:
GObjectPool();
~GObjectPool();
GObject* getObject(const std::string& url);
void returnObject(GObject* obj);
private:
std::unordered_map<std::string, cocos2d::Vector<GObject*>> _pool;
};
NS_FGUI_END
#endif

View File

@ -0,0 +1,234 @@
#include "GProgressBar.h"
#include "GImage.h"
#include "GLoader.h"
#include "PackageItem.h"
#include "tween/GTween.h"
#include "utils/ByteBuffer.h"
NS_FGUI_BEGIN
USING_NS_CC;
GProgressBar::GProgressBar()
: _min(0),
_max(100),
_value(0),
_titleType(ProgressTitleType::PERCENT),
_titleObject(nullptr),
_barObjectH(nullptr),
_barObjectV(nullptr),
_barMaxWidth(0),
_barMaxHeight(0),
_barMaxWidthDelta(0),
_barMaxHeightDelta(0),
_barStartX(0),
_barStartY(0)
{
}
GProgressBar::~GProgressBar()
{
}
void GProgressBar::setTitleType(ProgressTitleType value)
{
if (_titleType != value)
{
_titleType = value;
update(_value);
}
}
void GProgressBar::setMin(double value)
{
if (_min != value)
{
_min = value;
update(_value);
}
}
void GProgressBar::setMax(double value)
{
if (_max != value)
{
_max = value;
update(_value);
}
}
void GProgressBar::setValue(double value)
{
if (_value != value)
{
GTween::kill(this, TweenPropType::Progress, false);
_value = value;
update(_value);
}
}
void GProgressBar::tweenValue(double value, float duration)
{
double oldValule;
GTweener* twener = GTween::getTween(this, TweenPropType::Progress);
if (twener != nullptr)
{
oldValule = twener->value.d;
twener->kill(false);
}
else
oldValule = _value;
_value = value;
GTween::toDouble(oldValule, _value, duration)
->setEase(EaseType::Linear)
->setTarget(this, TweenPropType::Progress);
}
void GProgressBar::update(double newValue)
{
float percent;
if (_max == _min)
percent = 0;
else
percent = clampf((newValue - _min) / (_max - _min), 0, 1);
if (_titleObject != nullptr)
{
std::ostringstream oss;
switch (_titleType)
{
case ProgressTitleType::PERCENT:
oss << floor(percent * 100) << "%";
break;
case ProgressTitleType::VALUE_MAX:
oss << floor(newValue) << "/" << floor(_max);
break;
case ProgressTitleType::VALUE:
oss << floor(newValue);
break;
case ProgressTitleType::MAX:
oss << floor(_max);
break;
}
_titleObject->setText(oss.str());
}
float fullWidth = this->getWidth() - _barMaxWidthDelta;
float fullHeight = this->getHeight() - _barMaxHeightDelta;
if (!_reverse)
{
if (_barObjectH != nullptr)
{
if (!setFillAmount(_barObjectH, percent))
_barObjectH->setWidth(round(fullWidth * percent));
}
if (_barObjectV != nullptr)
{
if (!setFillAmount(_barObjectV, percent))
_barObjectV->setHeight(round(fullHeight * percent));
}
}
else
{
if (_barObjectH != nullptr)
{
if (!setFillAmount(_barObjectH, 1 - percent))
{
_barObjectH->setWidth(round(fullWidth * percent));
_barObjectH->setX(_barStartX + (fullWidth - _barObjectH->getWidth()));
}
}
if (_barObjectV != nullptr)
{
if (!setFillAmount(_barObjectV, 1 - percent))
{
_barObjectV->setHeight(round(fullHeight * percent));
_barObjectV->setY(_barStartY + (fullHeight - _barObjectV->getHeight()));
}
}
}
}
bool GProgressBar::setFillAmount(GObject* bar, float amount)
{
GImage* image = nullptr;
GLoader* loader = nullptr;
if ((image = dynamic_cast<GImage*>(bar)) != nullptr && image->getFillMethod() != FillMethod::None)
image->setFillAmount(amount);
else if ((loader = dynamic_cast<GLoader*>(bar)) != nullptr && loader->getFillMethod() != FillMethod::None)
loader->setFillAmount(amount);
else
return false;
return true;
}
void GProgressBar::handleSizeChanged()
{
GComponent::handleSizeChanged();
if (_barObjectH != nullptr)
_barMaxWidth = getWidth() - _barMaxWidthDelta;
if (_barObjectV != nullptr)
_barMaxHeight = getHeight() - _barMaxHeightDelta;
if (!_underConstruct)
update(_value);
}
void GProgressBar::constructExtension(ByteBuffer* buffer)
{
buffer->seek(0, 6);
_titleType = (ProgressTitleType)buffer->readByte();
_reverse = buffer->readBool();
_titleObject = getChild("title");
_barObjectH = getChild("bar");
_barObjectV = getChild("bar_v");
if (_barObjectH != nullptr)
{
_barMaxWidth = _barObjectH->getWidth();
_barMaxWidthDelta = getWidth() - _barMaxWidth;
_barStartX = _barObjectH->getX();
}
if (_barObjectV != nullptr)
{
_barMaxHeight = _barObjectV->getHeight();
_barMaxHeightDelta = getHeight() - _barMaxHeight;
_barStartY = _barObjectV->getY();
}
}
void GProgressBar::setup_afterAdd(ByteBuffer* buffer, int beginPos)
{
GComponent::setup_afterAdd(buffer, beginPos);
if (!buffer->seek(beginPos, 6))
{
update(_value);
return;
}
if ((ObjectType)buffer->readByte() != _packageItem->objectType)
{
update(_value);
return;
}
_value = buffer->readInt();
_max = buffer->readInt();
if (buffer->version >= 2)
_min = buffer->readInt();
update(_value);
}
NS_FGUI_END

View File

@ -0,0 +1,60 @@
#ifndef __GPROGRESSBAR_H__
#define __GPROGRESSBAR_H__
#include "FairyGUIMacros.h"
#include "GComponent.h"
#include "cocos2d.h"
NS_FGUI_BEGIN
class GProgressBar : public GComponent
{
public:
GProgressBar();
virtual ~GProgressBar();
CREATE_FUNC(GProgressBar);
ProgressTitleType getTitleType() const { return _titleType; }
void setTitleType(ProgressTitleType value);
double getMin() const { return _min; }
void setMin(double value);
double getMax() const { return _max; }
void setMax(double value);
double getValue() const { return _value; }
void setValue(double value);
void tweenValue(double value, float duration);
void update(double newValue);
protected:
virtual void handleSizeChanged() override;
virtual void constructExtension(ByteBuffer* buffer) override;
virtual void setup_afterAdd(ByteBuffer* buffer, int beginPos) override;
bool setFillAmount(GObject* bar, float amount);
private:
double _min;
double _max;
double _value;
ProgressTitleType _titleType;
bool _reverse;
GObject* _titleObject;
GObject* _barObjectH;
GObject* _barObjectV;
float _barMaxWidth;
float _barMaxHeight;
float _barMaxWidthDelta;
float _barMaxHeightDelta;
float _barStartX;
float _barStartY;
};
NS_FGUI_END
#endif

View File

@ -0,0 +1,114 @@
#include "GRichTextField.h"
#include "utils/UBBParser.h"
#include "utils/ByteBuffer.h"
NS_FGUI_BEGIN
USING_NS_CC;
GRichTextField::GRichTextField() :
_richText(nullptr),
_updatingSize(false)
{
}
GRichTextField::~GRichTextField()
{
}
void GRichTextField::handleInit()
{
_richText = FUIRichText::create();
_richText->retain();
_richText->setCascadeOpacityEnabled(true);
_displayObject = _richText;
}
void GRichTextField::applyTextFormat()
{
_richText->applyTextFormat();
updateGear(4);
if (!_underConstruct)
updateSize();
}
void GRichTextField::setAutoSize(AutoSizeType value)
{
_autoSize = value;
switch (value)
{
case AutoSizeType::NONE:
_richText->setOverflow(Label::Overflow::CLAMP);
break;
case AutoSizeType::BOTH:
_richText->setOverflow(Label::Overflow::NONE);
break;
case AutoSizeType::HEIGHT:
_richText->setOverflow(Label::Overflow::RESIZE_HEIGHT);
break;
case AutoSizeType::SHRINK:
_richText->setOverflow(Label::Overflow::SHRINK);
break;
}
_richText->setDimensions(_size.width, _size.height);
if (!_underConstruct)
updateSize();
}
void GRichTextField::setSingleLine(bool value)
{
}
void GRichTextField::setTextFieldText()
{
if (_ubbEnabled)
{
std::string parsedText = UBBParser::getInstance()->parse(_text.c_str());
if (_templateVars != nullptr)
parsedText = parseTemplate(parsedText.c_str());
_richText->setText(parsedText);
}
else
{
if (_templateVars != nullptr)
_richText->setText(parseTemplate(_text.c_str()));
else
_richText->setText(_text);
}
}
void GRichTextField::updateSize()
{
if (_updatingSize)
return;
_updatingSize = true;
Size sz = _richText->getContentSize();
if (_autoSize == AutoSizeType::BOTH)
setSize(sz.width, sz.height);
else if (_autoSize == AutoSizeType::HEIGHT)
setHeight(sz.height);
_updatingSize = false;
}
void GRichTextField::handleSizeChanged()
{
if (_updatingSize)
return;
if (_autoSize != AutoSizeType::BOTH)
{
_richText->setDimensions(_size.width, _size.height);
if (_autoSize == AutoSizeType::HEIGHT)
{
if (!_text.empty())
setSizeDirectly(_size.width, _richText->getContentSize().height);
}
}
}
NS_FGUI_END

View File

@ -0,0 +1,41 @@
#ifndef __GRICHTEXTFIELD_H__
#define __GRICHTEXTFIELD_H__
#include "cocos2d.h"
#include "FairyGUIMacros.h"
#include "GTextField.h"
#include "display/FUIRichText.h"
NS_FGUI_BEGIN
class GRichTextField : public GTextField
{
public:
GRichTextField();
virtual ~GRichTextField();
CREATE_FUNC(GRichTextField);
virtual void setAutoSize(AutoSizeType value) override;
virtual bool isSingleLine() const override { return false; }
virtual void setSingleLine(bool value) override;
virtual TextFormat* getTextFormat() const override { return _richText->getTextFormat(); }
virtual void applyTextFormat() override;
protected:
virtual void handleInit() override;
virtual void handleSizeChanged() override;
virtual void setTextFieldText() override;
virtual void updateSize() override;
private:
FUIRichText* _richText;
bool _updatingSize;
};
NS_FGUI_END
#endif

View File

@ -0,0 +1,569 @@
#include "GRoot.h"
#include "AudioEngine.h"
#include "UIConfig.h"
#include "UIPackage.h"
NS_FGUI_BEGIN
USING_NS_CC;
#if COCOS2D_VERSION < 0x00040000
using namespace cocos2d::experimental;
#endif
GRoot* GRoot::_inst = nullptr;
bool GRoot::_soundEnabled = true;
float GRoot::_soundVolumeScale = 1.0f;
int GRoot::contentScaleLevel = 0;
GRoot* GRoot::create(Scene* scene, int zOrder)
{
GRoot* pRet = new (std::nothrow) GRoot();
if (pRet && pRet->initWithScene(scene, zOrder))
{
pRet->autorelease();
return pRet;
}
else
{
delete pRet;
pRet = nullptr;
return nullptr;
}
}
GRoot::GRoot() : _windowSizeListener(nullptr),
_inputProcessor(nullptr),
_modalLayer(nullptr),
_modalWaitPane(nullptr),
_tooltipWin(nullptr),
_defaultTooltipWin(nullptr)
{
}
GRoot::~GRoot()
{
delete _inputProcessor;
CC_SAFE_RELEASE(_modalWaitPane);
CC_SAFE_RELEASE(_defaultTooltipWin);
CC_SAFE_RELEASE(_modalLayer);
CALL_LATER_CANCEL(GRoot, doShowTooltipsWin);
if (_windowSizeListener)
Director::getInstance()->getEventDispatcher()->removeEventListener(_windowSizeListener);
}
void GRoot::showWindow(Window* win)
{
addChild(win);
adjustModalLayer();
}
void GRoot::hideWindow(Window* win)
{
win->hide();
}
void GRoot::hideWindowImmediately(Window* win)
{
if (win->getParent() == this)
removeChild(win);
adjustModalLayer();
}
void GRoot::bringToFront(Window* win)
{
int cnt = numChildren();
int i;
if (_modalLayer->getParent() != nullptr && !win->isModal())
i = getChildIndex(_modalLayer) - 1;
else
i = cnt - 1;
for (; i >= 0; i--)
{
GObject* g = getChildAt(i);
if (g == win)
return;
if (dynamic_cast<Window*>(g))
break;
}
if (i >= 0)
setChildIndex(win, i);
}
void GRoot::closeAllExceptModals()
{
Vector<GObject*> map(_children);
for (const auto& child : map)
{
if (dynamic_cast<Window*>(child) && !((Window*)child)->isModal())
hideWindowImmediately((Window*)child);
}
}
void GRoot::closeAllWindows()
{
Vector<GObject*> map(_children);
for (const auto& child : map)
{
if (dynamic_cast<Window*>(child))
hideWindowImmediately((Window*)child);
}
}
Window* GRoot::getTopWindow()
{
int cnt = numChildren();
for (int i = cnt - 1; i >= 0; i--)
{
GObject* child = getChildAt(i);
if (dynamic_cast<Window*>(child))
{
return (Window*)child;
}
}
return nullptr;
}
GGraph* GRoot::getModalLayer()
{
if (_modalLayer == nullptr)
createModalLayer();
return _modalLayer;
}
void GRoot::createModalLayer()
{
_modalLayer = GGraph::create();
_modalLayer->retain();
_modalLayer->drawRect(getWidth(), getHeight(), 0, Color4F::WHITE, UIConfig::modalLayerColor);
_modalLayer->addRelation(this, RelationType::Size);
}
void GRoot::adjustModalLayer()
{
if (_modalLayer == nullptr)
createModalLayer();
int cnt = numChildren();
if (_modalWaitPane != nullptr && _modalWaitPane->getParent() != nullptr)
setChildIndex(_modalWaitPane, cnt - 1);
for (int i = cnt - 1; i >= 0; i--)
{
GObject* child = getChildAt(i);
if (dynamic_cast<Window*>(child) && ((Window*)child)->isModal())
{
if (_modalLayer->getParent() == nullptr)
addChildAt(_modalLayer, i);
else
setChildIndexBefore(_modalLayer, i);
return;
}
}
if (_modalLayer->getParent() != nullptr)
removeChild(_modalLayer);
}
bool GRoot::hasModalWindow()
{
return _modalLayer != nullptr && _modalLayer->getParent() != nullptr;
}
void GRoot::showModalWait()
{
getModalWaitingPane();
if (_modalWaitPane)
addChild(_modalWaitPane);
}
void GRoot::closeModalWait()
{
if (_modalWaitPane != nullptr && _modalWaitPane->getParent() != nullptr)
removeChild(_modalWaitPane);
}
GObject* GRoot::getModalWaitingPane()
{
if (!UIConfig::globalModalWaiting.empty())
{
if (_modalWaitPane == nullptr)
{
_modalWaitPane = UIPackage::createObjectFromURL(UIConfig::globalModalWaiting);
_modalWaitPane->setSortingOrder(INT_MAX);
_modalWaitPane->retain();
}
_modalWaitPane->setSize(getWidth(), getHeight());
_modalWaitPane->addRelation(this, RelationType::Size);
return _modalWaitPane;
}
else
return nullptr;
}
bool GRoot::isModalWaiting()
{
return (_modalWaitPane != nullptr) && _modalWaitPane->onStage();
}
cocos2d::Vec2 GRoot::getTouchPosition(int touchId)
{
return _inputProcessor->getTouchPosition(touchId);
}
GObject* GRoot::getTouchTarget()
{
return _inputProcessor->getRecentInput()->getTarget();
}
cocos2d::Vec2 GRoot::worldToRoot(const cocos2d::Vec2 &pt)
{
cocos2d::Vec2 pos = _displayObject->convertToNodeSpace(pt);
pos.y = getHeight() - pos.y;
return pos;
}
cocos2d::Vec2 GRoot::rootToWorld(const cocos2d::Vec2 &pt)
{
cocos2d::Vec2 pos = pt;
pos.y = getHeight() - pos.y;
pos = _displayObject->convertToWorldSpace(pos);
return pos;
}
void GRoot::showPopup(GObject* popup)
{
showPopup(popup, nullptr, PopupDirection::AUTO);
}
void GRoot::showPopup(GObject* popup, GObject* target, PopupDirection dir)
{
if (!_popupStack.empty())
hidePopup(popup);
_popupStack.push_back(WeakPtr(popup));
if (target != nullptr)
{
GObject* p = target;
while (p != nullptr)
{
if (p->getParent() == this)
{
if (popup->getSortingOrder() < p->getSortingOrder())
{
popup->setSortingOrder(p->getSortingOrder());
}
break;
}
p = p->getParent();
}
}
addChild(popup);
adjustModalLayer();
if (dynamic_cast<Window*>(popup) && target == nullptr && dir == PopupDirection::AUTO)
return;
Vec2 pos = getPoupPosition(popup, target, dir);
popup->setPosition(pos.x, pos.y);
}
void GRoot::togglePopup(GObject* popup)
{
togglePopup(popup, nullptr, PopupDirection::AUTO);
}
void GRoot::togglePopup(GObject* popup, GObject* target, PopupDirection dir)
{
if (std::find(_justClosedPopups.cbegin(), _justClosedPopups.cend(), popup) != _justClosedPopups.cend())
return;
showPopup(popup, target, dir);
}
void GRoot::hidePopup()
{
hidePopup(nullptr);
}
void GRoot::hidePopup(GObject* popup)
{
if (popup != nullptr)
{
auto it = std::find(_popupStack.cbegin(), _popupStack.cend(), popup);
if (it != _popupStack.cend())
{
int k = (int)(it - _popupStack.cbegin());
for (int i = (int)_popupStack.size() - 1; i >= k; i--)
{
closePopup(_popupStack.back().ptr());
_popupStack.pop_back();
}
}
}
else
{
for (const auto& it : _popupStack)
closePopup(it.ptr());
_popupStack.clear();
}
}
void GRoot::closePopup(GObject* target)
{
if (target && target->getParent() != nullptr)
{
if (dynamic_cast<Window*>(target))
((Window*)target)->hide();
else
removeChild(target);
}
}
void GRoot::checkPopups()
{
_justClosedPopups.clear();
if (!_popupStack.empty())
{
GObject* mc = _inputProcessor->getRecentInput()->getTarget();
bool handled = false;
while (mc != this && mc != nullptr)
{
auto it = std::find(_popupStack.cbegin(), _popupStack.cend(), mc);
if (it != _popupStack.cend())
{
int k = (int)(it - _popupStack.cbegin());
for (int i = (int)_popupStack.size() - 1; i > k; i--)
{
closePopup(_popupStack.back().ptr());
_popupStack.pop_back();
}
handled = true;
break;
}
mc = mc->findParent();
}
if (!handled)
{
for (int i = (int)_popupStack.size() - 1; i >= 0; i--)
{
GObject* popup = _popupStack[i].ptr();
if (popup)
{
_justClosedPopups.push_back(WeakPtr(popup));
closePopup(popup);
}
}
_popupStack.clear();
}
}
}
bool GRoot::hasAnyPopup()
{
return !_popupStack.empty();
}
cocos2d::Vec2 GRoot::getPoupPosition(GObject* popup, GObject* target, PopupDirection dir)
{
Vec2 pos;
Vec2 size;
if (target != nullptr)
{
pos = target->localToGlobal(Vec2::ZERO);
pos = this->globalToLocal(pos);
size = target->localToGlobal(target->getSize());
size = this->globalToLocal(size);
size -= pos;
}
else
{
pos = globalToLocal(_inputProcessor->getRecentInput()->getPosition());
}
float xx, yy;
xx = pos.x;
if (xx + popup->getWidth() > getWidth())
xx = xx + size.x - popup->getWidth();
yy = pos.y + size.y;
if ((dir == PopupDirection::AUTO && yy + popup->getHeight() > getHeight()) || dir == PopupDirection::UP)
{
yy = pos.y - popup->getHeight() - 1;
if (yy < 0)
{
yy = 0;
xx += size.x / 2;
}
}
return Vec2(round(xx), round(yy));
}
void GRoot::showTooltips(const std::string& msg)
{
if (_defaultTooltipWin == nullptr)
{
const std::string& resourceURL = UIConfig::tooltipsWin;
if (resourceURL.empty())
{
CCLOGWARN("FairyGUI: UIConfig.tooltipsWin not defined");
return;
}
_defaultTooltipWin = UIPackage::createObjectFromURL(resourceURL);
_defaultTooltipWin->setTouchable(false);
_defaultTooltipWin->retain();
}
_defaultTooltipWin->setText(msg);
showTooltipsWin(_defaultTooltipWin);
}
void GRoot::showTooltipsWin(GObject* tooltipWin)
{
hideTooltips();
_tooltipWin = tooltipWin;
CALL_LATER(GRoot, doShowTooltipsWin, 0.1f);
}
void GRoot::doShowTooltipsWin()
{
if (_tooltipWin == nullptr)
return;
Vec2 pt = _inputProcessor->getRecentInput()->getPosition();
float xx = pt.x + 10;
float yy = pt.y + 20;
pt = globalToLocal(Vec2(xx, yy));
xx = pt.x;
yy = pt.y;
if (xx + _tooltipWin->getWidth() > getWidth())
xx = xx - _tooltipWin->getWidth();
if (yy + _tooltipWin->getHeight() > getHeight())
{
yy = yy - _tooltipWin->getHeight() - 1;
if (yy < 0)
yy = 0;
}
_tooltipWin->setPosition(round(xx), round(yy));
addChild(_tooltipWin);
}
void GRoot::hideTooltips()
{
if (_tooltipWin != nullptr)
{
if (_tooltipWin->getParent() != nullptr)
removeChild(_tooltipWin);
_tooltipWin = nullptr;
}
}
void GRoot::playSound(const std::string& url, float volumnScale)
{
if (!_soundEnabled)
return;
PackageItem* pi = UIPackage::getItemByURL(url);
if (pi)
AudioEngine::play2d(pi->file, false, _soundVolumeScale * volumnScale);
}
void GRoot::setSoundEnabled(bool value)
{
_soundEnabled = value;
}
void GRoot::setSoundVolumeScale(float value)
{
_soundVolumeScale = value;
}
void GRoot::onTouchEvent(int eventType)
{
if (eventType == UIEventType::TouchBegin)
{
if (_tooltipWin != nullptr)
hideTooltips();
checkPopups();
}
}
void GRoot::handlePositionChanged()
{
_displayObject->setPosition(0, _size.height);
}
void GRoot::onEnter()
{
GComponent::onEnter();
_inst = this;
}
void GRoot::onExit()
{
GComponent::onExit();
if (_inst == this)
_inst = nullptr;
}
bool GRoot::initWithScene(cocos2d::Scene* scene, int zOrder)
{
if (!GComponent::init())
return false;
if (_inst == nullptr)
_inst = this;
_inputProcessor = new InputProcessor(this);
_inputProcessor->setCaptureCallback(CC_CALLBACK_1(GRoot::onTouchEvent, this));
#ifdef CC_PLATFORM_PC
_windowSizeListener = Director::getInstance()->getEventDispatcher()->addCustomEventListener(GLViewImpl::EVENT_WINDOW_RESIZED, CC_CALLBACK_0(GRoot::onWindowSizeChanged, this));
#endif
onWindowSizeChanged();
scene->addChild(_displayObject, zOrder);
return true;
}
void GRoot::onWindowSizeChanged()
{
const cocos2d::Size& rs = Director::getInstance()->getOpenGLView()->getDesignResolutionSize();
setSize(rs.width, rs.height);
updateContentScaleLevel();
}
void GRoot::updateContentScaleLevel()
{
float ss = Director::getInstance()->getContentScaleFactor();
if (ss >= 3.5f)
contentScaleLevel = 3; //x4
else if (ss >= 2.5f)
contentScaleLevel = 2; //x3
else if (ss >= 1.5f)
contentScaleLevel = 1; //x2
else
contentScaleLevel = 0;
}
NS_FGUI_END

102
extensions/fairygui/GRoot.h Normal file
View File

@ -0,0 +1,102 @@
#ifndef __GROOT_H__
#define __GROOT_H__
#include "FairyGUIMacros.h"
#include "GComponent.h"
#include "GGraph.h"
#include "Window.h"
#include "cocos2d.h"
#include "event/InputProcessor.h"
NS_FGUI_BEGIN
class WeakPtr;
class GRoot : public GComponent
{
public:
GRoot();
virtual ~GRoot();
static GRoot* create(cocos2d::Scene* scene, int zOrder = 1000);
static GRoot* getInstance() { return _inst; }
void showWindow(Window* win);
void hideWindow(Window* win);
void hideWindowImmediately(Window* win);
void bringToFront(Window* win);
void showModalWait();
void closeModalWait();
void closeAllExceptModals();
void closeAllWindows();
Window* getTopWindow();
GObject* getModalWaitingPane();
GGraph* getModalLayer();
bool hasModalWindow();
bool isModalWaiting();
InputProcessor* getInputProcessor() const { return _inputProcessor; }
cocos2d::Vec2 getTouchPosition(int touchId);
GObject* getTouchTarget();
cocos2d::Vec2 worldToRoot(const cocos2d::Vec2 &pt);
cocos2d::Vec2 rootToWorld(const cocos2d::Vec2 &pt);
void showPopup(GObject* popup);
void showPopup(GObject* popup, GObject* target, PopupDirection dir);
void togglePopup(GObject* popup);
void togglePopup(GObject* popup, GObject* target, PopupDirection dir);
void hidePopup();
void hidePopup(GObject* popup);
bool hasAnyPopup();
cocos2d::Vec2 getPoupPosition(GObject* popup, GObject* target, PopupDirection dir);
void showTooltips(const std::string& msg);
void showTooltipsWin(GObject* tooltipWin);
void hideTooltips();
void playSound(const std::string& url, float volumeScale = 1);
bool isSoundEnabled() const { return _soundEnabled; }
void setSoundEnabled(bool value);
float getSoundVolumeScale() const { return _soundVolumeScale; }
void setSoundVolumeScale(float value);
static int contentScaleLevel;
protected:
virtual void handlePositionChanged() override;
virtual void onEnter() override;
virtual void onExit() override;
private:
bool initWithScene(cocos2d::Scene* scene, int zOrder);
void onWindowSizeChanged();
void createModalLayer();
void adjustModalLayer();
void closePopup(GObject* target);
void checkPopups();
void onTouchEvent(int eventType);
void updateContentScaleLevel();
CALL_LATER_FUNC(GRoot, doShowTooltipsWin);
cocos2d::EventListener* _windowSizeListener;
InputProcessor* _inputProcessor;
GGraph* _modalLayer;
GObject* _modalWaitPane;
std::vector<WeakPtr> _popupStack;
std::vector<WeakPtr> _justClosedPopups;
GObject* _tooltipWin;
GObject* _defaultTooltipWin;
static bool _soundEnabled;
static float _soundVolumeScale;
static GRoot* _inst;
};
NS_FGUI_END
#endif

View File

@ -0,0 +1,179 @@
#include "GScrollBar.h"
#include "PackageItem.h"
#include "ScrollPane.h"
#include "utils/ByteBuffer.h"
NS_FGUI_BEGIN
USING_NS_CC;
GScrollBar::GScrollBar()
: _grip(nullptr),
_arrowButton1(nullptr),
_arrowButton2(nullptr),
_bar(nullptr),
_target(nullptr),
_vertical(false),
_scrollPerc(0),
_fixedGripSize(false),
_gripDragging(false)
{
}
GScrollBar::~GScrollBar()
{
}
void GScrollBar::setScrollPane(ScrollPane* target, bool vertical)
{
_target = target;
_vertical = vertical;
}
void GScrollBar::setDisplayPerc(float value)
{
if (_vertical)
{
if (!_fixedGripSize)
_grip->setHeight(floor(value * _bar->getHeight()));
_grip->setY(round(_bar->getY() + (_bar->getHeight() - _grip->getHeight()) * _scrollPerc));
}
else
{
if (!_fixedGripSize)
_grip->setWidth(floor(value * _bar->getWidth()));
_grip->setX(round(_bar->getX() + (_bar->getWidth() - _grip->getWidth()) * _scrollPerc));
}
_grip->setVisible(value != 0 && value != 1);
}
void GScrollBar::setScrollPerc(float value)
{
_scrollPerc = value;
if (_vertical)
_grip->setY(round(_bar->getY() + (_bar->getHeight() - _grip->getHeight()) * _scrollPerc));
else
_grip->setX(round(_bar->getX() + (_bar->getWidth() - _grip->getWidth()) * _scrollPerc));
}
float GScrollBar::getMinSize()
{
if (_vertical)
return (_arrowButton1 != nullptr ? _arrowButton1->getHeight() : 0) + (_arrowButton2 != nullptr ? _arrowButton2->getHeight() : 0);
else
return (_arrowButton1 != nullptr ? _arrowButton1->getWidth() : 0) + (_arrowButton2 != nullptr ? _arrowButton2->getWidth() : 0);
}
void GScrollBar::constructExtension(ByteBuffer* buffer)
{
buffer->seek(0, 6);
_fixedGripSize = buffer->readBool();
_grip = getChild("grip");
CCASSERT(_grip != nullptr, "FairyGUI: should define grip");
_bar = getChild("bar");
CCASSERT(_bar != nullptr, "FairyGUI: should define bar");
_arrowButton1 = getChild("arrow1");
_arrowButton2 = getChild("arrow2");
_grip->addEventListener(UIEventType::TouchBegin, CC_CALLBACK_1(GScrollBar::onGripTouchBegin, this));
_grip->addEventListener(UIEventType::TouchMove, CC_CALLBACK_1(GScrollBar::onGripTouchMove, this));
_grip->addEventListener(UIEventType::TouchEnd, CC_CALLBACK_1(GScrollBar::onGripTouchEnd, this));
this->addEventListener(UIEventType::TouchBegin, CC_CALLBACK_1(GScrollBar::onTouchBegin, this));
if (_arrowButton1 != nullptr)
_arrowButton1->addEventListener(UIEventType::TouchBegin, CC_CALLBACK_1(GScrollBar::onArrowButton1Click, this));
if (_arrowButton2 != nullptr)
_arrowButton2->addEventListener(UIEventType::TouchBegin, CC_CALLBACK_1(GScrollBar::onArrowButton2Click, this));
}
void GScrollBar::onTouchBegin(EventContext* context)
{
context->stopPropagation();
InputEvent* evt = context->getInput();
Vec2 pt = _grip->globalToLocal(evt->getPosition());
if (_vertical)
{
if (pt.y < 0)
_target->scrollUp(4, false);
else
_target->scrollDown(4, false);
}
else
{
if (pt.x < 0)
_target->scrollLeft(4, false);
else
_target->scrollRight(4, false);
}
}
void GScrollBar::onGripTouchBegin(EventContext* context)
{
if (_bar == nullptr)
return;
context->stopPropagation();
context->captureTouch();
_gripDragging = true;
_target->updateScrollBarVisible();
_dragOffset = globalToLocal(context->getInput()->getPosition()) - _grip->getPosition();
}
void GScrollBar::onGripTouchMove(EventContext* context)
{
Vec2 pt = globalToLocal(context->getInput()->getPosition());
if (_vertical)
{
float curY = pt.y - _dragOffset.y;
float diff = _bar->getHeight() - _grip->getHeight();
if (diff == 0)
_target->setPercY(0);
else
_target->setPercY((curY - _bar->getY()) / diff);
}
else
{
float curX = pt.x - _dragOffset.x;
float diff = _bar->getWidth() - _grip->getWidth();
if (diff == 0)
_target->setPercX(0);
else
_target->setPercX((curX - _bar->getX()) / diff);
}
}
void GScrollBar::onGripTouchEnd(EventContext* context)
{
_gripDragging = false;
_target->updateScrollBarVisible();
}
void GScrollBar::onArrowButton1Click(EventContext* context)
{
context->stopPropagation();
if (_vertical)
_target->scrollUp();
else
_target->scrollLeft();
}
void GScrollBar::onArrowButton2Click(EventContext* context)
{
context->stopPropagation();
if (_vertical)
_target->scrollDown();
else
_target->scrollRight();
}
NS_FGUI_END

View File

@ -0,0 +1,51 @@
#ifndef __GSCROLLBAR_H__
#define __GSCROLLBAR_H__
#include "FairyGUIMacros.h"
#include "GComponent.h"
#include "cocos2d.h"
NS_FGUI_BEGIN
class GScrollBar : public GComponent
{
public:
GScrollBar();
virtual ~GScrollBar();
CREATE_FUNC(GScrollBar);
void setScrollPane(ScrollPane* target, bool vertical);
void setDisplayPerc(float value);
void setScrollPerc(float value);
float getMinSize();
bool _gripDragging;
protected:
virtual void constructExtension(ByteBuffer* buffer) override;
private:
void onTouchBegin(EventContext* context);
void onGripTouchBegin(EventContext* context);
void onGripTouchMove(EventContext* context);
void onGripTouchEnd(EventContext* context);
void onArrowButton1Click(EventContext* context);
void onArrowButton2Click(EventContext* context);
GObject* _grip;
GObject* _arrowButton1;
GObject* _arrowButton2;
GObject* _bar;
ScrollPane* _target;
bool _vertical;
float _scrollPerc;
bool _fixedGripSize;
cocos2d::Vec2 _dragOffset;
};
NS_FGUI_END
#endif

View File

@ -0,0 +1,290 @@
#include "GSlider.h"
#include "PackageItem.h"
#include "utils/ByteBuffer.h"
NS_FGUI_BEGIN
USING_NS_CC;
GSlider::GSlider()
: changeOnClick(false),
canDrag(false),
_min(0),
_max(100),
_value(0),
_titleType(ProgressTitleType::PERCENT),
_titleObject(nullptr),
_barObjectH(nullptr),
_barObjectV(nullptr),
_barMaxWidth(0),
_barMaxHeight(0),
_barMaxWidthDelta(0),
_barMaxHeightDelta(0),
_gripObject(nullptr),
_clickPercent(0),
_barStartX(0),
_barStartY(0),
_wholeNumbers(false)
{
}
GSlider::~GSlider()
{
}
void GSlider::setTitleType(ProgressTitleType value)
{
if (_titleType != value)
{
_titleType = value;
update();
}
}
void GSlider::setMin(double value)
{
if (_min != value)
{
_min = value;
update();
}
}
void GSlider::setMax(double value)
{
if (_max != value)
{
_max = value;
update();
}
}
void GSlider::setValue(double value)
{
if (_value != value)
{
_value = value;
update();
}
}
void GSlider::setWholeNumbers(bool value)
{
if (_wholeNumbers != value)
{
_wholeNumbers = value;
update();
}
}
void GSlider::update()
{
float percent = MIN(_value / _max, 1);
updateWithPercent(percent, false);
}
void GSlider::updateWithPercent(float percent, bool manual)
{
percent = clampf(percent, 0, 1);
if (manual)
{
double newValue = _min + (_max - _min) * percent;
if (newValue < _min)
newValue = _min;
if (newValue > _max)
newValue = _max;
if (_wholeNumbers)
{
newValue = round(newValue);
percent = clampf((newValue - _min) / (_max - _min), 0, 1);
}
if (newValue != _value)
{
_value = newValue;
if (dispatchEvent(UIEventType::Changed))
return;
}
}
if (_titleObject != nullptr)
{
std::ostringstream oss;
switch (_titleType)
{
case ProgressTitleType::PERCENT:
oss << floor(percent * 100) << "%";
break;
case ProgressTitleType::VALUE_MAX:
oss << floor(_value) << "/" << floor(_max);
break;
case ProgressTitleType::VALUE:
oss << _value;
break;
case ProgressTitleType::MAX:
oss << _max;
break;
}
_titleObject->setText(oss.str());
}
float fullWidth = this->getWidth() - _barMaxWidthDelta;
float fullHeight = this->getHeight() - _barMaxHeightDelta;
if (!_reverse)
{
if (_barObjectH != nullptr)
_barObjectH->setWidth(round(fullWidth * percent));
if (_barObjectV != nullptr)
_barObjectV->setHeight(round(fullHeight * percent));
}
else
{
if (_barObjectH != nullptr)
{
_barObjectH->setWidth(round(fullWidth * percent));
_barObjectH->setX(_barStartX + (fullWidth - _barObjectH->getWidth()));
}
if (_barObjectV != nullptr)
{
_barObjectV->setHeight(round(fullHeight * percent));
_barObjectV->setY(_barStartY + (fullHeight - _barObjectV->getHeight()));
}
}
}
void GSlider::handleSizeChanged()
{
GComponent::handleSizeChanged();
if (_barObjectH != nullptr)
_barMaxWidth = getWidth() - _barMaxWidthDelta;
if (_barObjectV != nullptr)
_barMaxHeight = getHeight() - _barMaxHeightDelta;
if (!_underConstruct)
update();
}
void GSlider::constructExtension(ByteBuffer* buffer)
{
_titleType = (ProgressTitleType)buffer->readByte();
_reverse = buffer->readBool();
if (buffer->version >= 2)
{
_wholeNumbers = buffer->readBool();
changeOnClick = buffer->readBool();
}
_titleObject = getChild("title");
_barObjectH = getChild("bar");
_barObjectV = getChild("bar_v");
_gripObject = getChild("grip");
if (_barObjectH != nullptr)
{
_barMaxWidth = _barObjectH->getWidth();
_barMaxWidthDelta = getWidth() - _barMaxWidth;
_barStartX = _barObjectH->getX();
}
if (_barObjectV != nullptr)
{
_barMaxHeight = _barObjectV->getHeight();
_barMaxHeightDelta = getHeight() - _barMaxHeight;
_barStartY = _barObjectV->getY();
}
if (_gripObject != nullptr)
{
_gripObject->addEventListener(UIEventType::TouchBegin, CC_CALLBACK_1(GSlider::onGripTouchBegin, this));
_gripObject->addEventListener(UIEventType::TouchMove, CC_CALLBACK_1(GSlider::onGripTouchMove, this));
}
addEventListener(UIEventType::TouchBegin, CC_CALLBACK_1(GSlider::onTouchBegin, this));
}
void GSlider::setup_afterAdd(ByteBuffer* buffer, int beginPos)
{
GComponent::setup_afterAdd(buffer, beginPos);
if (!buffer->seek(beginPos, 6))
{
update();
return;
}
if ((ObjectType)buffer->readByte() != _packageItem->objectType)
{
update();
return;
}
_value = buffer->readInt();
_max = buffer->readInt();
if (buffer->version >= 2)
_min = buffer->readInt();
update();
}
void GSlider::onTouchBegin(EventContext* context)
{
if (!changeOnClick)
return;
InputEvent* evt = context->getInput();
if (evt->getButton() != EventMouse::MouseButton::BUTTON_LEFT)
return;
Vec2 pt = _gripObject->globalToLocal(evt->getPosition());
float percent = clampf((_value - _min) / (_max - _min), 0, 1);
float delta = 0;
if (_barObjectH != nullptr)
delta = pt.x / _barMaxWidth;
if (_barObjectV != nullptr)
delta = pt.y / _barMaxHeight;
if (_reverse)
percent -= delta;
else
percent += delta;
updateWithPercent(percent, true);
}
void GSlider::onGripTouchBegin(EventContext* context)
{
if (context->getInput()->getButton() != EventMouse::MouseButton::BUTTON_LEFT)
return;
canDrag = true;
context->stopPropagation();
context->captureTouch();
_clickPos = globalToLocal(context->getInput()->getPosition());
_clickPercent = clampf((_value - _min) / (_max - _min), 0, 1);
}
void GSlider::onGripTouchMove(EventContext* context)
{
if (!canDrag)
return;
Vec2 pt = globalToLocal(context->getInput()->getPosition());
float deltaX = pt.x - _clickPos.x;
float deltaY = pt.y - _clickPos.y;
if (_reverse)
{
deltaX = -deltaX;
deltaY = -deltaY;
}
float percent;
if (_barObjectH != nullptr)
percent = _clickPercent + deltaX / _barMaxWidth;
else
percent = _clickPercent + deltaY / _barMaxHeight;
updateWithPercent(percent, true);
}
NS_FGUI_END

View File

@ -0,0 +1,72 @@
#ifndef __GSLIDER_H__
#define __GSLIDER_H__
#include "FairyGUIMacros.h"
#include "GComponent.h"
#include "cocos2d.h"
NS_FGUI_BEGIN
class GSlider : public GComponent
{
public:
GSlider();
virtual ~GSlider();
CREATE_FUNC(GSlider);
ProgressTitleType getTitleType() const { return _titleType; }
void setTitleType(ProgressTitleType value);
double getMin() const { return _min; }
void setMin(double value);
double getMax() const { return _max; }
void setMax(double value);
double getValue() const { return _value; }
void setValue(double value);
bool getWholeNumbers() const { return _wholeNumbers; }
void setWholeNumbers(bool value);
bool changeOnClick;
bool canDrag;
protected:
virtual void handleSizeChanged() override;
virtual void constructExtension(ByteBuffer* buffer) override;
virtual void setup_afterAdd(ByteBuffer* buffer, int beginPos) override;
void update();
void updateWithPercent(float percent, bool manual);
private:
void onTouchBegin(EventContext* context);
void onGripTouchBegin(EventContext* context);
void onGripTouchMove(EventContext* context);
double _min;
double _max;
double _value;
ProgressTitleType _titleType;
bool _reverse;
bool _wholeNumbers;
GObject* _titleObject;
GObject* _barObjectH;
GObject* _barObjectV;
float _barMaxWidth;
float _barMaxHeight;
float _barMaxWidthDelta;
float _barMaxHeightDelta;
GObject* _gripObject;
cocos2d::Vec2 _clickPos;
float _clickPercent;
float _barStartX;
float _barStartY;
};
NS_FGUI_END
#endif

View File

@ -0,0 +1,377 @@
#include "GTextField.h"
#include "utils/ByteBuffer.h"
#include "utils/ToolSet.h"
NS_FGUI_BEGIN
USING_NS_CC;
GTextField::GTextField()
: _templateVars(nullptr),
_ubbEnabled(false),
_autoSize(AutoSizeType::BOTH)
{
}
GTextField::~GTextField()
{
CC_SAFE_DELETE(_templateVars);
}
void GTextField::setText(const std::string& value)
{
_text = value;
setTextFieldText();
updateGear(6);
updateSize();
}
void GTextField::setUBBEnabled(bool value)
{
if (_ubbEnabled != value)
{
_ubbEnabled = value;
setTextFieldText();
updateSize();
}
}
void GTextField::setColor(const cocos2d::Color3B& value)
{
TextFormat* tf = getTextFormat();
if (tf->color != value)
{
tf->color = value;
applyTextFormat();
}
}
void GTextField::setFontSize(float value)
{
TextFormat* tf = getTextFormat();
if (tf->fontSize != value)
{
tf->fontSize = value;
applyTextFormat();
}
}
void GTextField::setOutlineColor(const cocos2d::Color3B& value)
{
TextFormat* tf = getTextFormat();
if (tf->outlineColor != value)
{
tf->outlineColor = value;
applyTextFormat();
}
}
void GTextField::setTemplateVars(cocos2d::ValueMap* value)
{
if (_templateVars == nullptr && value == nullptr)
return;
if (value == nullptr)
CC_SAFE_DELETE(_templateVars);
else
{
if (_templateVars == nullptr)
_templateVars = new cocos2d::ValueMap();
*_templateVars = *value;
}
flushVars();
}
GTextField* GTextField::setVar(const std::string& name, const cocos2d::Value& value)
{
if (_templateVars == nullptr)
_templateVars = new cocos2d::ValueMap();
(*_templateVars)[name] = value;
return this;
}
void GTextField::flushVars()
{
setTextFieldText();
updateSize();
}
void GTextField::updateSize()
{
}
cocos2d::Value GTextField::getProp(ObjectPropID propId)
{
switch (propId)
{
case ObjectPropID::Color:
return Value(ToolSet::colorToInt(getColor()));
case ObjectPropID::OutlineColor:
return Value(ToolSet::colorToInt(getOutlineColor()));
case ObjectPropID::FontSize:
return Value(getFontSize());
default:
return GObject::getProp(propId);
}
}
void GTextField::setProp(ObjectPropID propId, const cocos2d::Value& value)
{
switch (propId)
{
case ObjectPropID::Color:
setColor(ToolSet::intToColor(value.asUnsignedInt()));
break;
case ObjectPropID::OutlineColor:
setOutlineColor(ToolSet::intToColor(value.asUnsignedInt()));
break;
case ObjectPropID::FontSize:
setFontSize(value.asInt());
break;
default:
GObject::setProp(propId, value);
break;
}
}
void GTextField::setup_beforeAdd(ByteBuffer* buffer, int beginPos)
{
GObject::setup_beforeAdd(buffer, beginPos);
buffer->seek(beginPos, 5);
TextFormat* tf = getTextFormat();
tf->face = buffer->readS();
tf->fontSize = buffer->readShort();
tf->color = (Color3B)buffer->readColor();
tf->align = (TextHAlignment)buffer->readByte();
tf->verticalAlign = (TextVAlignment)buffer->readByte();
tf->lineSpacing = buffer->readShort();
tf->letterSpacing = buffer->readShort();
_ubbEnabled = buffer->readBool();
setAutoSize((AutoSizeType)buffer->readByte());
tf->underline = buffer->readBool();
tf->italics = buffer->readBool();
tf->bold = buffer->readBool();
if (buffer->readBool())
setSingleLine(true);
if (buffer->readBool())
{
tf->outlineColor = (Color3B)buffer->readColor();
tf->outlineSize = buffer->readFloat();
tf->enableEffect(TextFormat::OUTLINE);
}
if (buffer->readBool())
{
tf->shadowColor = (Color3B)buffer->readColor();
float f1 = buffer->readFloat();
float f2 = buffer->readFloat();
tf->shadowOffset = Vec2(f1, -f2);
tf->enableEffect(TextFormat::SHADOW);
}
if (buffer->readBool())
_templateVars = new cocos2d::ValueMap();
}
void GTextField::setup_afterAdd(ByteBuffer* buffer, int beginPos)
{
GObject::setup_afterAdd(buffer, beginPos);
applyTextFormat();
buffer->seek(beginPos, 6);
const std::string& str = buffer->readS();
if (!str.empty())
setText(str);
}
std::string GTextField::parseTemplate(const char* text)
{
const char* pString = text;
ssize_t pos;
ssize_t pos2;
std::string tag, attr;
std::string repl;
std::string out;
while (*pString != '\0')
{
const char* p = strchr(pString, '{');
if (!p)
{
out.append(pString);
break;
}
pos = p - pString;
if (pos > 0 && *(p - 1) == '\\')
{
out.append(pString, pos - 1);
out.append("{");
pString += pos + 1;
continue;
}
out.append(pString, pos);
pString += pos;
p = strchr(pString, '}');
if (!p)
{
out.append(pString);
break;
}
pos = p - pString;
if (pos == 1)
{
out.append(pString, 0, 2);
pString += 2;
continue;
}
tag.assign(pString + 1, pos - 1);
attr.clear();
repl.clear();
pos2 = tag.find('=');
if (pos2 != -1)
{
auto it = _templateVars->find(tag.substr(0, pos2));
if (it != _templateVars->end())
out.append(it->second.asString());
else
out.append(tag.substr(pos2 + 1));
}
else
{
auto it = _templateVars->find(tag);
if (it != _templateVars->end())
out.append(it->second.asString());
}
pString += pos + 1;
}
return out;
}
//---------------------------
GBasicTextField::GBasicTextField() : _label(nullptr),
_updatingSize(false)
{
_touchDisabled = true;
}
GBasicTextField::~GBasicTextField()
{
}
void GBasicTextField::handleInit()
{
_label = FUILabel::create();
_label->retain();
_displayObject = _label;
}
void GBasicTextField::applyTextFormat()
{
_label->applyTextFormat();
updateGear(4);
if (!_underConstruct)
updateSize();
}
void GBasicTextField::setAutoSize(AutoSizeType value)
{
_autoSize = value;
switch (value)
{
case AutoSizeType::NONE:
_label->setOverflow(Label::Overflow::CLAMP);
break;
case AutoSizeType::BOTH:
_label->setOverflow(Label::Overflow::NONE);
break;
case AutoSizeType::HEIGHT:
_label->setOverflow(Label::Overflow::RESIZE_HEIGHT);
break;
case AutoSizeType::SHRINK:
_label->setOverflow(Label::Overflow::SHRINK);
break;
}
if (_autoSize == AutoSizeType::BOTH)
_label->setDimensions(0, 0);
else if (_autoSize == AutoSizeType::HEIGHT)
_label->setDimensions(_size.width, 0);
else
_label->setDimensions(_size.width, _size.height);
if (!_underConstruct)
updateSize();
}
void GBasicTextField::setSingleLine(bool value)
{
_label->enableWrap(!value);
if (!_underConstruct)
updateSize();
}
void GBasicTextField::setTextFieldText()
{
if (_templateVars != nullptr)
_label->setText(parseTemplate(_text.c_str()));
else
_label->setText(_text);
}
void GBasicTextField::updateSize()
{
if (_updatingSize)
return;
_updatingSize = true;
Size sz = _label->getContentSize();
if (_autoSize == AutoSizeType::BOTH)
setSize(sz.width, sz.height);
else if (_autoSize == AutoSizeType::HEIGHT)
setHeight(sz.height);
_updatingSize = false;
}
void GBasicTextField::handleSizeChanged()
{
if (_updatingSize)
return;
if (_autoSize != AutoSizeType::BOTH)
{
_label->setDimensions(_size.width, _size.height);
if (_autoSize == AutoSizeType::HEIGHT)
{
if (!_text.empty())
setSizeDirectly(_size.width, _label->getContentSize().height);
}
}
}
void GBasicTextField::handleGrayedChanged()
{
GObject::handleGrayedChanged();
_label->setGrayed(_finalGrayed);
}
NS_FGUI_END

View File

@ -0,0 +1,98 @@
#ifndef __GTEXTFIELD_H__
#define __GTEXTFIELD_H__
#include "cocos2d.h"
#include "FairyGUIMacros.h"
#include "GObject.h"
#include "display/FUILabel.h"
NS_FGUI_BEGIN
class GTextField : public GObject
{
public:
GTextField();
virtual ~GTextField();
virtual const std::string& getText() const override { return _text; }
void setText(const std::string& value) override;
bool isUBBEnabled() const { return _ubbEnabled; }
virtual void setUBBEnabled(bool value);
AutoSizeType getAutoSize() const { return _autoSize; }
virtual void setAutoSize(AutoSizeType value) {};
virtual bool isSingleLine() const { return false; }
virtual void setSingleLine(bool value) {};
virtual TextFormat* getTextFormat() const = 0;
virtual void applyTextFormat() = 0;
virtual const cocos2d::Size& getTextSize() { return _displayObject->getContentSize(); }
cocos2d::Color3B getColor() const { return getTextFormat()->color; }
void setColor(const cocos2d::Color3B& value);
float getFontSize() const { return getTextFormat()->fontSize; }
void setFontSize(float value);
cocos2d::Color3B getOutlineColor() const { return getTextFormat()->outlineColor; }
void setOutlineColor(const cocos2d::Color3B& value);
cocos2d::ValueMap* getTemplateVars() { return _templateVars; }
void setTemplateVars(cocos2d::ValueMap* value);
GTextField* setVar(const std::string& name, const cocos2d::Value& value);
void flushVars();
virtual cocos2d::Value getProp(ObjectPropID propId) override;
virtual void setProp(ObjectPropID propId, const cocos2d::Value& value) override;
protected:
virtual void setTextFieldText() = 0;
virtual void updateSize();
virtual void setup_beforeAdd(ByteBuffer* buffer, int beginPos) override;
virtual void setup_afterAdd(ByteBuffer* buffer, int beginPos) override;
std::string parseTemplate(const char* text);
std::string _text;
bool _ubbEnabled;
AutoSizeType _autoSize;
cocos2d::ValueMap* _templateVars;
};
class GBasicTextField : public GTextField
{
public:
GBasicTextField();
virtual ~GBasicTextField();
CREATE_FUNC(GBasicTextField);
virtual void setAutoSize(AutoSizeType value) override;
virtual bool isSingleLine() const override { return _label->isWrapEnabled(); }
virtual void setSingleLine(bool value) override;
virtual TextFormat* getTextFormat() const override { return _label->getTextFormat(); }
virtual void applyTextFormat() override;
protected:
virtual void handleInit() override;
virtual void handleSizeChanged() override;
virtual void handleGrayedChanged() override;
virtual void setTextFieldText() override;
virtual void updateSize() override;
private:
FUILabel* _label;
bool _updatingSize;
};
NS_FGUI_END
#endif

View File

@ -0,0 +1,131 @@
#include "GTextInput.h"
#include "UIPackage.h"
#include "GRoot.h"
#include "ui/UIEditBox/UIEditBox.h"
#include "utils/ByteBuffer.h"
#include "utils/UBBParser.h"
#include "utils/ToolSet.h"
NS_FGUI_BEGIN
USING_NS_CC;
GTextInput::GTextInput()
{
}
GTextInput::~GTextInput()
{
}
void GTextInput::handleInit()
{
_input = FUIInput::create();
_input->retain();
_input->setDelegate(this);
_displayObject = _input;
this->addEventListener(UIEventType::TouchEnd, [this](EventContext*) {
_input->openKeyboard();
});
}
bool GTextInput::isSingleLine() const
{
return _input->isSingleLine();
}
void GTextInput::setSingleLine(bool value)
{
_input->setSingleLine(value);
}
void GTextInput::applyTextFormat()
{
_input->applyTextFormat();
}
void GTextInput::setPrompt(const std::string & value)
{
if (value.empty())
_input->setPlaceHolder(value.c_str());
else
{
UBBParser* parser = UBBParser::getInstance();
_input->setPlaceHolder(parser->parse(value.c_str(), true).c_str());
if (!parser->lastColor.empty())
_input->setPlaceholderFontColor(ToolSet::hexToColor(parser->lastColor.c_str()));
if (!parser->lastFontSize.empty())
_input->setPlaceholderFontSize(Value(parser->lastFontSize).asInt());
}
}
void GTextInput::setPassword(bool value)
{
_input->setPassword(value);
}
void GTextInput::setKeyboardType(int value)
{
_input->setKeyboardType(value);
}
void GTextInput::setMaxLength(int value)
{
_input->setMaxLength(value);
}
void GTextInput::setRestrict(const std::string & value)
{
}
void GTextInput::handleSizeChanged()
{
_input->setContentSize(_size);
}
void GTextInput::setup_beforeAdd(ByteBuffer* buffer, int beginPos)
{
GTextField::setup_beforeAdd(buffer, beginPos);
buffer->seek(beginPos, 4);
const std::string* str;
if ((str = buffer->readSP()))
setPrompt(*str);
if ((str = buffer->readSP()))
setRestrict(*str);
int iv = buffer->readInt();
if (iv != 0)
setMaxLength(iv);
iv = buffer->readInt();
if (iv != 0)
setKeyboardType(iv);
if (buffer->readBool())
setPassword(true);
}
void GTextInput::setTextFieldText()
{
if (_templateVars != nullptr)
_input->setText(parseTemplate(_text.c_str()));
else
_input->setText(_text);
}
void GTextInput::editBoxReturn(cocos2d::ui::EditBox * editBox)
{
//found that this will trigger even when focus is lost
//if (isSingleLine())
// dispatchEvent(UIEventType::Submit);
}
void GTextInput::editBoxTextChanged(cocos2d::ui::EditBox* editBox, const std::string& text)
{
_text.clear();
_text.append(_input->getText());
}
NS_FGUI_END

View File

@ -0,0 +1,47 @@
#ifndef __GTEXTINPUT_H__
#define __GTEXTINPUT_H__
#include "cocos2d.h"
#include "FairyGUIMacros.h"
#include "GTextField.h"
#include "display/FUIInput.h"
NS_FGUI_BEGIN
class GTextInput : public GTextField, cocos2d::ui::EditBoxDelegate
{
public:
GTextInput();
virtual ~GTextInput();
CREATE_FUNC(GTextInput);
virtual bool isSingleLine() const override;
virtual void setSingleLine(bool value) override;
virtual TextFormat* getTextFormat() const override { return _input->getTextFormat(); }
virtual void applyTextFormat() override;
void setPrompt(const std::string& value);
void setPassword(bool value);
void setKeyboardType(int value);
void setMaxLength(int value);
void setRestrict(const std::string& value);
protected:
virtual void handleInit() override;
virtual void handleSizeChanged() override;
virtual void setup_beforeAdd(ByteBuffer* buffer, int beginPos) override;
virtual void setTextFieldText() override;
virtual void editBoxReturn(cocos2d::ui::EditBox* editBox) override;
virtual void editBoxTextChanged(cocos2d::ui::EditBox* editBox, const std::string& text) override;
private:
FUIInput* _input;
};
NS_FGUI_END
#endif

View File

@ -0,0 +1,412 @@
#include "GTree.h"
#include "GButton.h"
#include "GList.h"
#include "utils/ByteBuffer.h"
NS_FGUI_BEGIN
USING_NS_CC;
GTree::GTree()
: _rootNode(nullptr),
_indent(30),
_clickToExpand(0),
_expandedStatusInEvt(false)
{
}
GTree::~GTree()
{
CC_SAFE_RELEASE(_rootNode);
}
void GTree::handleInit()
{
GList::handleInit();
_rootNode = GTreeNode::create(true);
_rootNode->setTree(this);
_rootNode->setExpaned(true);
_rootNode->retain();
}
GTreeNode* GTree::getSelectedNode() const
{
int i = getSelectedIndex();
if (i != -1)
return getChildAt(i)->_treeNode;
else
return nullptr;
}
void GTree::getSelectedNodes(std::vector<GTreeNode*>& result) const
{
std::vector<int> ids;
getSelection(ids);
for (auto& it : ids)
{
GTreeNode* node = getChildAt(it)->_treeNode;
result.push_back(node);
}
}
void GTree::selectNode(GTreeNode* node, bool scrollItToView)
{
GTreeNode* parentNode = node->_parent;
while (parentNode != nullptr && parentNode != _rootNode)
{
parentNode->setExpaned(true);
parentNode = parentNode->_parent;
}
if (node->_cell != nullptr)
addSelection(getChildIndex(node->_cell), scrollItToView);
}
void GTree::unselectNode(GTreeNode* node)
{
if (node->_cell != nullptr)
removeSelection(getChildIndex(node->_cell));
}
void GTree::expandAll(GTreeNode* folderNode)
{
folderNode->setExpaned(true);
for (auto& it : folderNode->_children)
{
if (it->isFolder())
expandAll(it);
}
}
void GTree::collapseAll(GTreeNode* folderNode)
{
if (folderNode != _rootNode)
folderNode->setExpaned(false);
for (auto& it : folderNode->_children)
{
if (it->isFolder())
collapseAll(it);
}
}
void GTree::createCell(GTreeNode* node)
{
const std::string& url = node->_resURL.empty() ? getDefaultItem() : node->_resURL;
GComponent* child = getItemPool()->getObject(url)->as<GComponent>();
CCASSERT(child, "Unable to create tree cell");
child->_treeNode = node;
node->setCell(child);
GObject* indentObj = node->_cell->getChild("indent");
if (indentObj != nullptr)
indentObj->setWidth((node->_level - 1) * _indent);
GController* cc;
cc = child->getController("expanded");
if (cc != nullptr)
{
cc->addEventListener(UIEventType::Changed, CC_CALLBACK_1(GTree::onExpandedStateChanged, this));
cc->setSelectedIndex(node->isExpanded() ? 1 : 0);
}
cc = child->getController("leaf");
if (cc != nullptr)
cc->setSelectedIndex(node->isFolder() ? 0 : 1);
if (node->isFolder())
child->addEventListener(UIEventType::TouchBegin, CC_CALLBACK_1(GTree::onCellTouchBegin, this));
if (treeNodeRender != nullptr)
treeNodeRender(node, child);
}
void GTree::afterInserted(GTreeNode* node)
{
if (node->_cell == nullptr)
createCell(node);
int index = getInsertIndexForNode(node);
addChildAt(node->_cell, index);
if (treeNodeRender != nullptr)
treeNodeRender(node, node->_cell);
if (node->isFolder() && node->isExpanded())
checkChildren(node, index);
}
int GTree::getInsertIndexForNode(GTreeNode* node)
{
GTreeNode* prevNode = node->getPrevSibling();
if (prevNode == nullptr)
prevNode = node->getParent();
int insertIndex;
if (prevNode->_cell != nullptr)
insertIndex = getChildIndex(prevNode->_cell) + 1;
else
insertIndex = 0;
int myLevel = node->_level;
int cnt = numChildren();
for (int i = insertIndex; i < cnt; i++)
{
GTreeNode* testNode = getChildAt(i)->_treeNode;
if (testNode->_level <= myLevel)
break;
insertIndex++;
}
return insertIndex;
}
void GTree::afterRemoved(GTreeNode* node)
{
removeNode(node);
}
void GTree::afterExpanded(GTreeNode* node)
{
if (node == _rootNode)
{
checkChildren(_rootNode, 0);
return;
}
if (treeNodeWillExpand != nullptr)
treeNodeWillExpand(node, true);
if (node->_cell == nullptr)
return;
if (treeNodeRender != nullptr)
treeNodeRender(node, node->_cell);
GController* cc = node->_cell->getController("expanded");
if (cc != nullptr)
cc->setSelectedIndex(1);
if (node->_cell->getParent() != nullptr)
checkChildren(node, getChildIndex(node->_cell));
}
void GTree::afterCollapsed(GTreeNode* node)
{
if (node == _rootNode)
{
checkChildren(_rootNode, 0);
return;
}
if (treeNodeWillExpand != nullptr)
treeNodeWillExpand(node, false);
if (node->_cell == nullptr)
return;
if (treeNodeRender != nullptr)
treeNodeRender(node, node->_cell);
GController* cc = node->_cell->getController("expanded");
if (cc != nullptr)
cc->setSelectedIndex(0);
if (node->_cell->getParent() != nullptr)
hideFolderNode(node);
}
void GTree::afterMoved(GTreeNode* node)
{
int startIndex = getChildIndex(node->_cell);
int endIndex;
if (node->isFolder())
endIndex = getFolderEndIndex(startIndex, node->_level);
else
endIndex = startIndex + 1;
int insertIndex = getInsertIndexForNode(node);
int cnt = endIndex - startIndex;
if (insertIndex < startIndex)
{
for (int i = 0; i < cnt; i++)
{
GObject* obj = getChildAt(startIndex + i);
setChildIndex(obj, insertIndex + i);
}
}
else
{
for (int i = 0; i < cnt; i++)
{
GObject* obj = getChildAt(startIndex);
setChildIndex(obj, insertIndex);
}
}
}
int GTree::getFolderEndIndex(int startIndex, int level)
{
int cnt = numChildren();
for (int i = startIndex + 1; i < cnt; i++)
{
GTreeNode* node = getChildAt(i)->_treeNode;
if (node->_level <= level)
return i;
}
return cnt;
}
int GTree::checkChildren(GTreeNode* folderNode, int index)
{
int cnt = folderNode->numChildren();
for (int i = 0; i < cnt; i++)
{
index++;
GTreeNode* node = folderNode->getChildAt(i);
if (node->_cell == nullptr)
createCell(node);
if (node->_cell->getParent() == nullptr)
addChildAt(node->_cell, index);
if (node->isFolder() && node->isExpanded())
index = checkChildren(node, index);
}
return index;
}
void GTree::hideFolderNode(GTreeNode* folderNode)
{
int cnt = folderNode->numChildren();
for (int i = 0; i < cnt; i++)
{
GTreeNode* node = folderNode->getChildAt(i);
if (node->_cell != nullptr && node->_cell->getParent() != nullptr)
removeChild(node->_cell);
if (node->isFolder() && node->isExpanded())
hideFolderNode(node);
}
}
void GTree::removeNode(GTreeNode* node)
{
if (node->_cell != nullptr)
{
if (node->_cell->getParent() != nullptr)
removeChild(node->_cell);
getItemPool()->returnObject(node->_cell);
node->_cell->_treeNode = nullptr;
node->_cell = nullptr;
}
if (node->isFolder())
{
int cnt = node->numChildren();
for (int i = 0; i < cnt; i++)
{
GTreeNode* node2 = node->getChildAt(i);
removeNode(node2);
}
}
}
void GTree::onCellTouchBegin(EventContext* context)
{
GTreeNode* node = ((GObject*)context->getSender())->_treeNode;
_expandedStatusInEvt = node->isExpanded();
}
void GTree::onExpandedStateChanged(EventContext* context)
{
GController* cc = (GController*)context->getSender();
GTreeNode* node = cc->getParent()->_treeNode;
node->setExpaned(cc->getSelectedIndex() == 1);
}
void GTree::dispatchItemEvent(GObject* item, EventContext* context)
{
if (_clickToExpand != 0)
{
GTreeNode* node = item->_treeNode;
if (node != nullptr && _expandedStatusInEvt == node->isExpanded())
{
if (_clickToExpand == 2)
{
if (context->getInput()->isDoubleClick())
node->setExpaned(!node->isExpanded());
}
else
node->setExpaned(!node->isExpanded());
}
}
GList::dispatchItemEvent(item, context);
}
void GTree::setup_beforeAdd(ByteBuffer* buffer, int beginPos)
{
GList::setup_beforeAdd(buffer, beginPos);
buffer->seek(beginPos, 9);
_indent = buffer->readInt();
_clickToExpand = buffer->readByte();
}
void GTree::readItems(ByteBuffer* buffer)
{
int nextPos;
std::string str;
bool isFolder;
GTreeNode* lastNode = nullptr;
int level;
int prevLevel = 0;
int cnt = buffer->readShort();
for (int i = 0; i < cnt; i++)
{
nextPos = buffer->readShort();
nextPos += buffer->getPos();
str = buffer->readS();
if (!str.empty())
{
str = getDefaultItem();
if (str.empty())
{
buffer->setPos(nextPos);
continue;
}
}
isFolder = buffer->readBool();
level = buffer->readByte();
GTreeNode* node = GTreeNode::create(isFolder, str);
node->setExpaned(true);
if (i == 0)
_rootNode->addChild(node);
else
{
if (level > prevLevel)
lastNode->addChild(node);
else if (level < prevLevel)
{
for (int j = level; j <= prevLevel; j++)
lastNode = lastNode->getParent();
lastNode->addChild(node);
}
else
lastNode->getParent()->addChild(node);
}
lastNode = node;
prevLevel = level;
setupItem(buffer, node->_cell);
buffer->setPos(nextPos);
}
}
NS_FGUI_END

View File

@ -0,0 +1,73 @@
#ifndef __GTREE_H__
#define __GTREE_H__
#include "FairyGUIMacros.h"
#include "GList.h"
#include "GTreeNode.h"
#include "cocos2d.h"
NS_FGUI_BEGIN
class GList;
class GComponent;
class GTree : public GList
{
public:
typedef std::function<void(GTreeNode* node, GComponent* obj)> TreeNodeRenderFunction;
typedef std::function<void(GTreeNode* node, bool expand)> TreeNodeWillExpandFunction;
GTree();
virtual ~GTree();
CREATE_FUNC(GTree);
int getIndent() const { return _indent; }
void setIndent(int value) { _indent = value; }
int getClickToExpand() const { return _clickToExpand; }
void setClickToExpand(int value) { _clickToExpand = value; }
GTreeNode* getRootNode() const { return _rootNode; }
GTreeNode* getSelectedNode() const;
void getSelectedNodes(std::vector<GTreeNode*>& result) const;
void selectNode(GTreeNode* node, bool scrollItToView = false);
void unselectNode(GTreeNode* node);
void expandAll(GTreeNode* folderNode);
void collapseAll(GTreeNode* folderNode);
TreeNodeRenderFunction treeNodeRender;
TreeNodeWillExpandFunction treeNodeWillExpand;
protected:
virtual void handleInit() override;
virtual void setup_beforeAdd(ByteBuffer* buffer, int beginPos) override;
virtual void readItems(ByteBuffer* buffer) override;
virtual void dispatchItemEvent(GObject* item, EventContext* context) override;
private:
void createCell(GTreeNode* node);
void afterInserted(GTreeNode* node);
int getInsertIndexForNode(GTreeNode* node);
void afterRemoved(GTreeNode* node);
void afterExpanded(GTreeNode* node);
void afterCollapsed(GTreeNode* node);
void afterMoved(GTreeNode* node);
int checkChildren(GTreeNode* folderNode, int index);
void hideFolderNode(GTreeNode* folderNode);
void removeNode(GTreeNode* node);
int getFolderEndIndex(int startIndex, int level);
void onCellTouchBegin(EventContext* context);
void onExpandedStateChanged(EventContext* context);
int _indent;
GTreeNode* _rootNode;
int _clickToExpand;
bool _expandedStatusInEvt;
friend class GTreeNode;
};
NS_FGUI_END
#endif

View File

@ -0,0 +1,310 @@
#include "GTreeNode.h"
#include "GComponent.h"
#include "GTree.h"
NS_FGUI_BEGIN
USING_NS_CC;
GTreeNode* GTreeNode::create(bool isFolder, const std::string& resURL)
{
GTreeNode* pRet = new (std::nothrow) GTreeNode();
if (pRet != nullptr && pRet->init(isFolder, resURL))
{
pRet->autorelease();
}
else
{
CC_SAFE_DELETE(pRet);
}
return pRet;
}
GTreeNode::GTreeNode()
: _tree(nullptr),
_parent(nullptr),
_cell(nullptr),
_level(0),
_expanded(false),
_isFolder(false)
{
}
GTreeNode::~GTreeNode()
{
for (auto& it : _children)
it->_parent = nullptr;
_children.clear();
if (_parent)
_parent->removeChild(this);
CC_SAFE_RELEASE(_cell);
}
bool GTreeNode::init(bool isFolder, const std::string& resURL)
{
_isFolder = isFolder;
_resURL = resURL;
return true;
}
void GTreeNode::setExpaned(bool value)
{
if (!_isFolder)
return;
if (_expanded != value)
{
_expanded = value;
if (_tree != nullptr)
{
if (_expanded)
_tree->afterExpanded(this);
else
_tree->afterCollapsed(this);
}
}
}
const std::string& GTreeNode::getText() const
{
if (_cell != nullptr)
return _cell->getText();
else
return STD_STRING_EMPTY;
}
void GTreeNode::setText(const std::string& value)
{
if (_cell != nullptr)
return _cell->setText(value);
}
const std::string& GTreeNode::getIcon() const
{
if (_cell != nullptr)
return _cell->getIcon();
else
return STD_STRING_EMPTY;
}
void GTreeNode::setIcon(const std::string& value)
{
if (_cell != nullptr)
return _cell->setIcon(value);
}
GTreeNode* GTreeNode::addChild(GTreeNode* child)
{
addChildAt(child, (int)_children.size());
return child;
}
GTreeNode* GTreeNode::addChildAt(GTreeNode* child, int index)
{
CCASSERT(child != nullptr, "Argument must be non-nil");
if (child->_parent == this)
{
setChildIndex(child, index);
}
else
{
child->retain();
if (child->_parent != nullptr)
child->_parent->removeChild(child);
child->_parent = this;
int cnt = (int)_children.size();
if (index == cnt)
_children.pushBack(child);
else
_children.insert(index, child);
child->release();
child->_level = _level + 1;
child->setTree(_tree);
if ((_tree != nullptr && this == _tree->getRootNode()) || (_cell != nullptr && _cell->getParent() != nullptr && _expanded))
_tree->afterInserted(child);
}
return child;
}
void GTreeNode::removeChild(GTreeNode* child)
{
CCASSERT(child != nullptr, "Argument must be non-nil");
int childIndex = (int)_children.getIndex(child);
if (childIndex != -1)
removeChildAt(childIndex);
}
void GTreeNode::removeChildAt(int index)
{
CCASSERT(index >= 0 && index < _children.size(), "Invalid child index");
GTreeNode* child = _children.at(index);
child->_parent = nullptr;
if (_tree != nullptr)
{
child->setTree(nullptr);
_tree->afterRemoved(child);
}
_children.erase(index);
}
void GTreeNode::removeChildren(int beginIndex, int endIndex)
{
if (endIndex < 0 || endIndex >= _children.size())
endIndex = (int)_children.size() - 1;
for (int i = beginIndex; i <= endIndex; ++i)
removeChildAt(beginIndex);
}
GTreeNode* GTreeNode::getChildAt(int index) const
{
CCASSERT(index >= 0 && index < _children.size(), "Invalid child index");
return _children.at(index);
}
GTreeNode* GTreeNode::getPrevSibling() const
{
if (_parent == nullptr)
return nullptr;
ssize_t i = _parent->_children.getIndex((GTreeNode*)this);
if (i <= 0)
return nullptr;
return _parent->_children.at(i - 1);
}
GTreeNode* GTreeNode::getNextSibling() const
{
if (_parent == nullptr)
return nullptr;
ssize_t i = _parent->_children.getIndex((GTreeNode*)this);
if (i < 0 || i >= _parent->_children.size() - 1)
return nullptr;
return _parent->_children.at(i + 1);
}
int GTreeNode::getChildIndex(const GTreeNode* child) const
{
CCASSERT(child != nullptr, "Argument must be non-nil");
return (int)_children.getIndex((GTreeNode*)child);
}
void GTreeNode::setChildIndex(GTreeNode* child, int index)
{
CCASSERT(child != nullptr, "Argument must be non-nil");
int oldIndex = (int)_children.getIndex(child);
CCASSERT(oldIndex != -1, "Not a child of this container");
moveChild(child, oldIndex, index);
}
int GTreeNode::setChildIndexBefore(GTreeNode* child, int index)
{
CCASSERT(child != nullptr, "Argument must be non-nil");
int oldIndex = (int)_children.getIndex(child);
CCASSERT(oldIndex != -1, "Not a child of this container");
if (oldIndex < index)
return moveChild(child, oldIndex, index - 1);
else
return moveChild(child, oldIndex, index);
}
int GTreeNode::moveChild(GTreeNode* child, int oldIndex, int index)
{
int cnt = (int)_children.size();
if (index > cnt)
index = cnt;
if (oldIndex == index)
return oldIndex;
child->retain();
_children.erase(oldIndex);
if (index >= cnt)
_children.pushBack(child);
else
_children.insert(index, child);
child->release();
if ((_tree != nullptr && this == _tree->getRootNode()) || (_cell != nullptr && _cell->getParent() != nullptr && _expanded))
_tree->afterMoved(child);
return index;
}
void GTreeNode::swapChildren(GTreeNode* child1, GTreeNode* child2)
{
CCASSERT(child1 != nullptr, "Argument1 must be non-nil");
CCASSERT(child2 != nullptr, "Argument2 must be non-nil");
int index1 = (int)_children.getIndex(child1);
int index2 = (int)_children.getIndex(child2);
CCASSERT(index1 != -1, "Not a child of this container");
CCASSERT(index2 != -1, "Not a child of this container");
swapChildrenAt(index1, index2);
}
void GTreeNode::swapChildrenAt(int index1, int index2)
{
GTreeNode* child1 = _children.at(index1);
GTreeNode* child2 = _children.at(index2);
setChildIndex(child1, index2);
setChildIndex(child2, index1);
}
int GTreeNode::numChildren() const
{
return (int)_children.size();
}
void GTreeNode::setTree(GTree* value)
{
_tree = value;
if (_tree != nullptr && _tree->treeNodeWillExpand != nullptr && _expanded)
_tree->treeNodeWillExpand(this, true);
if (_isFolder)
{
for (auto& child : _children)
{
child->_level = _level + 1;
child->setTree(value);
}
}
}
void GTreeNode::setCell(GComponent* value)
{
if (_cell != value)
{
CC_SAFE_RELEASE(_cell);
_cell = value;
CC_SAFE_RETAIN(_cell);
if (_cell)
_cell->setData(this);
}
}
NS_FGUI_END

View File

@ -0,0 +1,74 @@
#ifndef __GTREENODE_H__
#define __GTREENODE_H__
#include "FairyGUIMacros.h"
#include "cocos2d.h"
NS_FGUI_BEGIN
class GTree;
class GComponent;
class GTreeNode : public cocos2d::Ref
{
public:
static GTreeNode* create(bool isFolder = false, const std::string& resURL = cocos2d::STD_STRING_EMPTY);
GTreeNode();
virtual ~GTreeNode();
GTreeNode* getParent() const { return _parent; }
GTree* getTree() const { return _tree; }
GComponent* getCell() const { return _cell; }
const cocos2d::Value& getData() const { return _data; }
void setData(const cocos2d::Value& value) { _data = value; }
bool isExpanded() const { return _expanded; }
void setExpaned(bool value);
bool isFolder() const { return _isFolder; }
const std::string& getText() const;
void setText(const std::string& value);
const std::string& getIcon() const;
void setIcon(const std::string& value);
GTreeNode* addChild(GTreeNode* child);
GTreeNode* addChildAt(GTreeNode* child, int index);
void removeChild(GTreeNode* child);
void removeChildAt(int index);
void removeChildren() { removeChildren(0, -1); }
void removeChildren(int beginIndex, int endIndex);
GTreeNode* getChildAt(int index) const;
GTreeNode* getPrevSibling() const;
GTreeNode* getNextSibling() const;
int getChildIndex(const GTreeNode* child) const;
void setChildIndex(GTreeNode* child, int index);
int setChildIndexBefore(GTreeNode* child, int index);
void swapChildren(GTreeNode* child1, GTreeNode* child2);
void swapChildrenAt(int index1, int index2);
int numChildren() const;
private:
bool init(bool isFolder, const std::string& resURL);
int moveChild(GTreeNode* child, int oldIndex, int index);
void setTree(GTree* value);
void setCell(GComponent* value);
GTree* _tree;
GTreeNode* _parent;
GComponent* _cell;
int _level;
bool _expanded;
bool _isFolder;
cocos2d::Value _data;
cocos2d::Vector<GTreeNode*> _children;
std::string _resURL;
friend class GTree;
};
NS_FGUI_END
#endif

View File

@ -0,0 +1,38 @@
#include "Margin.h"
NS_FGUI_BEGIN
const Margin Margin::ZERO = Margin(0, 0, 0, 0);
Margin::Margin(void) : left(0), top(0), right(0), bottom(0)
{
}
Margin::Margin(float l, float t, float r, float b) : left(l), top(t), right(r), bottom(b)
{
}
Margin::Margin(const Margin& other) : left(other.left), top(other.top), right(other.right), bottom(other.bottom)
{
}
Margin& Margin::operator= (const Margin& other)
{
setMargin(other.left, other.top, other.right, other.bottom);
return *this;
}
void Margin::setMargin(float l, float t, float r, float b)
{
left = l;
top = t;
right = r;
bottom = b;
}
bool Margin::equals(const Margin &target) const
{
return (left == target.left && top == target.top && right == target.right && bottom == target.bottom);
}
NS_FGUI_END

View File

@ -0,0 +1,78 @@
#ifndef __MARGIN_H__
#define __MARGIN_H__
#include "FairyGUIMacros.h"
NS_FGUI_BEGIN
//copy from cocos2d::ui::Margin
class Margin
{
public:
/**
* Left margin.
*/
float left;
/**
* Top margin.
*/
float top;
/**
* Right margin.
*/
float right;
/**
* Bottom margin.
*/
float bottom;
public:
/**
* Default constructor.
*/
Margin();
/**
* Construct a Margin instance with left, top, right and bottom margins.
*@param l Left margin in float.
*@param t Top margin in float.
*@param r Right margin in float.
*@param b Bottom margin in float.
*/
Margin(float l, float t, float r, float b);
/**
* Copy constructor.
*/
Margin(const Margin& other);
/**
* Copy assignment operator.
*/
Margin& operator= (const Margin& other);
/**
* Change margin with left, top, right and bottom margin.
*@param l Left margin in float.
*@param t Top margin in float.
*@param r Right margin in float.
*@param b Bottom margin in float.
*/
void setMargin(float l, float t, float r, float b);
/**
* Test equality of two margins.
*@param target A Margin instance.
*@return True if two margins are equal, false otherwise.
*/
bool equals(const Margin& target) const;
/**
* A margin constant with all margins equal zero.
*/
static const Margin ZERO;
};
NS_FGUI_END
#endif

View File

@ -0,0 +1,75 @@
#include "PackageItem.h"
#include "GRoot.h"
#include "UIPackage.h"
#include "display/BitmapFont.h"
#include "utils/ByteBuffer.h"
NS_FGUI_BEGIN
PackageItem::PackageItem() : owner(nullptr),
objectType(ObjectType::COMPONENT),
width(0),
height(0),
rawData(nullptr),
texture(nullptr),
spriteFrame(nullptr),
scale9Grid(nullptr),
scaleByTile(false),
tileGridIndice(0),
animation(nullptr),
repeatDelay(0),
swing(false),
extensionCreator(nullptr),
translated(false),
bitmapFont(nullptr),
branches(nullptr),
highResolution(nullptr)
{
}
PackageItem::~PackageItem()
{
CC_SAFE_DELETE(scale9Grid);
CC_SAFE_DELETE(rawData);
if (bitmapFont) //bitmapfont will be released by fontatlas
bitmapFont->releaseAtlas();
bitmapFont = nullptr;
CC_SAFE_RELEASE(animation);
CC_SAFE_RELEASE(texture);
CC_SAFE_RELEASE(spriteFrame);
CC_SAFE_DELETE(branches);
CC_SAFE_DELETE(highResolution);
}
void PackageItem::load()
{
owner->getItemAsset(this);
}
PackageItem* PackageItem::getBranch()
{
if (branches != nullptr && owner->_branchIndex != -1)
{
std::string itemId = (*branches)[owner->_branchIndex];
if (!itemId.empty())
return owner->getItem(itemId);
}
return this;
}
PackageItem* PackageItem::getHighResolution()
{
if (highResolution != nullptr && GRoot::contentScaleLevel > 0)
{
std::string itemId = (*highResolution)[GRoot::contentScaleLevel - 1];
if (!itemId.empty())
return owner->getItem(itemId);
}
return this;
}
NS_FGUI_END

View File

@ -0,0 +1,69 @@
#ifndef __PACKAGEITEM_H__
#define __PACKAGEITEM_H__
#include "FairyGUIMacros.h"
#include "cocos2d.h"
NS_FGUI_BEGIN
class UIPackage;
class UIObjectFactory;
class GComponent;
class BitmapFont;
class PixelHitTestData;
class ByteBuffer;
class PackageItem : public cocos2d::Ref
{
public:
PackageItem();
virtual ~PackageItem();
void load();
PackageItem* getBranch();
PackageItem* getHighResolution();
public:
UIPackage* owner;
PackageItemType type;
ObjectType objectType;
std::string id;
std::string name;
int width;
int height;
std::string file;
ByteBuffer* rawData;
std::vector<std::string>* branches;
std::vector<std::string>* highResolution;
//atlas
cocos2d::Texture2D* texture;
//image
cocos2d::Rect* scale9Grid;
bool scaleByTile;
int tileGridIndice;
cocos2d::SpriteFrame* spriteFrame;
PixelHitTestData* pixelHitTestData;
//movieclip
cocos2d::Animation* animation;
float delayPerUnit;
float repeatDelay;
bool swing;
//component
std::function<GComponent*()> extensionCreator;
bool translated;
//font
BitmapFont* bitmapFont;
//skeleton
cocos2d::Vec2* skeletonAnchor;
};
NS_FGUI_END
#endif

View File

@ -0,0 +1,239 @@
#include "PopupMenu.h"
#include "GRoot.h"
#include "UIPackage.h"
#include "GList.h"
#include "GButton.h"
#include "UIConfig.h"
NS_FGUI_BEGIN
USING_NS_CC;
PopupMenu* PopupMenu::create(const std::string & resourceURL)
{
PopupMenu *pRet = new(std::nothrow) PopupMenu();
if (pRet && pRet->init(resourceURL))
{
pRet->autorelease();
return pRet;
}
else
{
delete pRet;
pRet = nullptr;
return nullptr;
}
}
PopupMenu::PopupMenu() :
_contentPane(nullptr),
_list(nullptr)
{
}
PopupMenu::~PopupMenu()
{
CC_SAFE_RELEASE(_contentPane);
}
bool PopupMenu::init(const std::string & resourceURL)
{
std::string url = resourceURL;
if (url.empty())
{
url = UIConfig::popupMenu;
if (url.empty())
{
CCLOGWARN("FairyGUI: UIConfig.popupMenu not defined");
return false;
}
}
_contentPane = UIPackage::createObjectFromURL(url)->as<GComponent>();
_contentPane->retain();
_contentPane->addEventListener(UIEventType::Enter, CC_CALLBACK_1(PopupMenu::onEnter, this));
_list = _contentPane->getChild("list")->as<GList>();
_list->removeChildrenToPool();
_list->addRelation(_contentPane, RelationType::Width);
_list->removeRelation(_contentPane, RelationType::Height);
_contentPane->addRelation(_list, RelationType::Height);
_list->addEventListener(UIEventType::ClickItem, CC_CALLBACK_1(PopupMenu::onClickItem, this));
return true;
}
GButton * PopupMenu::addItem(const std::string & caption, EventCallback callback)
{
GButton* item = _list->addItemFromPool()->as<GButton>();
item->setTitle(caption);
item->setGrayed(false);
GController* c = item->getController("checked");
if (c != nullptr)
c->setSelectedIndex(0);
item->removeEventListener(UIEventType::ClickMenu);
if (callback)
item->addEventListener(UIEventType::ClickMenu, callback);
return item;
}
GButton * PopupMenu::addItemAt(const std::string & caption, int index, EventCallback callback)
{
GButton* item = _list->getFromPool(_list->getDefaultItem())->as<GButton>();
_list->addChildAt(item, index);
item->setTitle(caption);
item->setGrayed(false);
GController* c = item->getController("checked");
if (c != nullptr)
c->setSelectedIndex(0);
item->removeEventListener(UIEventType::ClickMenu);
if (callback)
item->addEventListener(UIEventType::ClickMenu, callback);
return item;
}
void PopupMenu::addSeperator()
{
if (UIConfig::popupMenu_seperator.empty())
{
CCLOGWARN("FairyGUI: UIConfig.popupMenu_seperator not defined");
return;
}
_list->addItemFromPool(UIConfig::popupMenu_seperator);
}
const std::string & PopupMenu::getItemName(int index) const
{
GButton* item = _list->getChildAt(index)->as<GButton>();
return item->name;
}
void PopupMenu::setItemText(const std::string & name, const std::string & caption)
{
GButton* item = _list->getChild(name)->as<GButton>();
item->setTitle(caption);
}
void PopupMenu::setItemVisible(const std::string & name, bool visible)
{
GButton* item = _list->getChild(name)->as<GButton>();
if (item->isVisible() != visible)
{
item->setVisible(visible);
_list->setBoundsChangedFlag();
}
}
void PopupMenu::setItemGrayed(const std::string & name, bool grayed)
{
GButton* item = _list->getChild(name)->as<GButton>();
item->setGrayed(grayed);
}
void PopupMenu::setItemCheckable(const std::string & name, bool checkable)
{
GButton* item = _list->getChild(name)->as<GButton>();
GController* c = item->getController("checked");
if (c != nullptr)
{
if (checkable)
{
if (c->getSelectedIndex() == 0)
c->setSelectedIndex(1);
}
else
c->setSelectedIndex(0);
}
}
void PopupMenu::setItemChecked(const std::string & name, bool check)
{
GButton* item = _list->getChild(name)->as<GButton>();
GController* c = item->getController("checked");
if (c != nullptr)
c->setSelectedIndex(check ? 2 : 1);
}
bool PopupMenu::isItemChecked(const std::string & name) const
{
GButton* item = _list->getChild(name)->as<GButton>();
GController* c = item->getController("checked");
if (c != nullptr)
return c->getSelectedIndex() == 2;
else
return false;
}
bool PopupMenu::removeItem(const std::string & name)
{
GObject* item = _list->getChild(name);
if (item != nullptr)
{
int index = _list->getChildIndex(item);
_list->removeChildToPoolAt(index);
item->removeEventListener(UIEventType::ClickMenu);
return true;
}
else
return false;
}
void PopupMenu::clearItems()
{
int cnt = _list->numChildren();
for (int i = 0; i < cnt; i++)
_list->getChildAt(i)->removeEventListener(UIEventType::ClickMenu);
_list->removeChildrenToPool();
}
int PopupMenu::getItemCount() const
{
return _list->numChildren();
}
void PopupMenu::show(GObject * target, PopupDirection dir)
{
GRoot* r = target != nullptr ? target->getRoot() : UIRoot;
r->showPopup(_contentPane, dynamic_cast<GRoot*>(target) ? nullptr : target, dir);
}
void PopupMenu::onClickItem(EventContext * context)
{
GButton* item = ((GObject*)context->getData())->as<GButton>();
if (item == nullptr)
return;
if (item->isGrayed())
{
_list->setSelectedIndex(-1);
return;
}
GController* c = item->getController("checked");
if (c != nullptr && c->getSelectedIndex() != 0)
{
if (c->getSelectedIndex() == 1)
c->setSelectedIndex(2);
else
c->setSelectedIndex(1);
}
GRoot* r = (GRoot*)_contentPane->getParent();
r->hidePopup(_contentPane);
item->dispatchEvent(UIEventType::ClickMenu, context->getData());
}
void PopupMenu::onEnter(EventContext * context)
{
_list->setSelectedIndex(-1);
_list->resizeToFit(INT_MAX, 10);
}
NS_FGUI_END

View File

@ -0,0 +1,55 @@
#ifndef __POPUPMENU_H__
#define __POPUPMENU_H__
#include "FairyGUIMacros.h"
#include "cocos2d.h"
#include "event/UIEventDispatcher.h"
NS_FGUI_BEGIN
class GObject;
class GComponent;
class GButton;
class GList;
class PopupMenu : public cocos2d::Ref
{
public:
static PopupMenu* create(const std::string& resourceURL);
static PopupMenu* create() { return create(""); }
PopupMenu();
virtual ~PopupMenu();
GButton* addItem(const std::string& caption, EventCallback callback);
GButton* addItemAt(const std::string& caption, int index, EventCallback callback);
void addSeperator();
const std::string& getItemName(int index) const;
void setItemText(const std::string& name, const std::string& caption);
void setItemVisible(const std::string& name, bool visible);
void setItemGrayed(const std::string& name, bool grayed);
void setItemCheckable(const std::string& name, bool checkable);
void setItemChecked(const std::string& name, bool check);
bool isItemChecked(const std::string& name) const;
bool removeItem(const std::string& name);
void clearItems();
int getItemCount() const;
GComponent* getContentPane() const { return _contentPane; }
GList* getList() const { return _list; }
void show() { show(nullptr, PopupDirection::AUTO); }
void show(GObject* target, PopupDirection dir);
protected:
bool init(const std::string& resourceURL);
GComponent* _contentPane;
GList* _list;
private:
void onClickItem(EventContext* context);
void onEnter(EventContext* context);
};
NS_FGUI_END
#endif

View File

@ -0,0 +1,655 @@
#include "RelationItem.h"
#include "GComponent.h"
#include "GGroup.h"
#include "event/UIEventType.h"
#include "utils/WeakPtr.h"
NS_FGUI_BEGIN
USING_NS_CC;
RelationItem::RelationItem(GObject* owner) : _target(nullptr)
{
_owner = owner;
}
RelationItem::~RelationItem()
{
releaseRefTarget(_target.ptr());
}
void RelationItem::setTarget(GObject* value)
{
GObject* old = _target.ptr();
if (old != value)
{
if (old)
releaseRefTarget(old);
_target = value;
if (value)
addRefTarget(value);
}
}
void RelationItem::add(RelationType relationType, bool usePercent)
{
if (relationType == RelationType::Size)
{
add(RelationType::Width, usePercent);
add(RelationType::Height, usePercent);
return;
}
for (auto& it : _defs)
{
if (it.type == relationType)
return;
}
internalAdd(relationType, usePercent);
}
void RelationItem::internalAdd(RelationType relationType, bool usePercent)
{
if (relationType == RelationType::Size)
{
internalAdd(RelationType::Width, usePercent);
internalAdd(RelationType::Height, usePercent);
return;
}
RelationDef info;
info.percent = usePercent;
info.type = relationType;
info.axis = (relationType <= RelationType::Right_Right || relationType == RelationType::Width || (relationType >= RelationType::LeftExt_Left && relationType <= RelationType::RightExt_Right)) ? 0 : 1;
_defs.push_back(info);
if (usePercent || relationType == RelationType::Left_Center || relationType == RelationType::Center_Center || relationType == RelationType::Right_Center || relationType == RelationType::Top_Middle || relationType == RelationType::Middle_Middle || relationType == RelationType::Bottom_Middle)
_owner->setPixelSnapping(true);
}
void RelationItem::remove(RelationType relationType)
{
if (relationType == RelationType::Size)
{
remove(RelationType::Width);
remove(RelationType::Height);
return;
}
for (auto it = _defs.begin(); it != _defs.end(); ++it)
{
if (it->type == relationType)
{
_defs.erase(it);
break;
}
}
}
void RelationItem::copyFrom(const RelationItem& source)
{
setTarget(source._target.ptr());
_defs.clear();
for (auto& it : source._defs)
_defs.push_back(it);
}
bool RelationItem::isEmpty() const
{
return _defs.size() == 0;
}
void RelationItem::applyOnSelfSizeChanged(float dWidth, float dHeight, bool applyPivot)
{
if (_target == nullptr || _defs.size() == 0)
return;
float ox = _owner->_position.x;
float oy = _owner->_position.y;
for (auto& it : _defs)
{
switch (it.type)
{
case RelationType::Center_Center:
_owner->setX(_owner->_position.x - (0.5 - (applyPivot ? _owner->_pivot.x : 0)) * dWidth);
break;
case RelationType::Right_Center:
case RelationType::Right_Left:
case RelationType::Right_Right:
_owner->setX(_owner->_position.x - (1 - (applyPivot ? _owner->_pivot.x : 0)) * dWidth);
break;
case RelationType::Middle_Middle:
_owner->setY(_owner->_position.y - (0.5 - (applyPivot ? _owner->_pivot.y : 0)) * dHeight);
break;
case RelationType::Bottom_Middle:
case RelationType::Bottom_Top:
case RelationType::Bottom_Bottom:
_owner->setY(_owner->_position.y - (1 - (applyPivot ? _owner->_pivot.y : 0)) * dHeight);
break;
default:
break;
}
}
if (ox != _owner->_position.x || oy != _owner->_position.y)
{
ox = _owner->_position.x - ox;
oy = _owner->_position.y - oy;
_owner->updateGearFromRelations(1, ox, oy);
if (_owner->_parent != nullptr)
{
const Vector<Transition*>& arr = _owner->_parent->getTransitions();
for (auto& it : arr)
it->updateFromRelations(_owner->id, ox, oy);
}
}
}
void RelationItem::applyOnXYChanged(GObject* target, const RelationDef& info, float dx, float dy)
{
float tmp;
switch (info.type)
{
case RelationType::Left_Left:
case RelationType::Left_Center:
case RelationType::Left_Right:
case RelationType::Center_Center:
case RelationType::Right_Left:
case RelationType::Right_Center:
case RelationType::Right_Right:
_owner->setX(_owner->_position.x + dx);
break;
case RelationType::Top_Top:
case RelationType::Top_Middle:
case RelationType::Top_Bottom:
case RelationType::Middle_Middle:
case RelationType::Bottom_Top:
case RelationType::Bottom_Middle:
case RelationType::Bottom_Bottom:
_owner->setY(_owner->_position.y + dy);
break;
case RelationType::Width:
case RelationType::Height:
break;
case RelationType::LeftExt_Left:
case RelationType::LeftExt_Right:
if (_owner != target->getParent())
{
tmp = _owner->getXMin();
_owner->setWidth(_owner->_rawSize.width - dx);
_owner->setXMin(tmp + dx);
}
else
_owner->setWidth(_owner->_rawSize.width - dx);
break;
case RelationType::RightExt_Left:
case RelationType::RightExt_Right:
if (_owner != target->getParent())
{
tmp = _owner->getXMin();
_owner->setWidth(_owner->_rawSize.width + dx);
_owner->setXMin(tmp);
}
else
_owner->setWidth(_owner->_rawSize.width + dx);
break;
case RelationType::TopExt_Top:
case RelationType::TopExt_Bottom:
if (_owner != target->getParent())
{
tmp = _owner->getYMin();
_owner->setHeight(_owner->_rawSize.height - dy);
_owner->setYMin(tmp + dy);
}
else
_owner->setHeight(_owner->_rawSize.height - dy);
break;
case RelationType::BottomExt_Top:
case RelationType::BottomExt_Bottom:
if (_owner != target->getParent())
{
tmp = _owner->getYMin();
_owner->setHeight(_owner->_rawSize.height + dy);
_owner->setYMin(tmp);
}
else
_owner->setHeight(_owner->_rawSize.height + dy);
break;
default:
break;
}
}
void RelationItem::applyOnSizeChanged(GObject* target, const RelationDef& info)
{
float pos = 0, pivot = 0, delta = 0;
if (info.axis == 0)
{
if (target != _owner->_parent)
{
pos = target->_position.x;
if (target->_pivotAsAnchor)
pivot = target->_pivot.x;
}
if (info.percent)
{
if (_targetData.z != 0)
delta = target->_size.width / _targetData.z;
}
else
delta = target->_size.width - _targetData.z;
}
else
{
if (target != _owner->_parent)
{
pos = target->_position.y;
if (target->_pivotAsAnchor)
pivot = target->_pivot.y;
}
if (info.percent)
{
if (_targetData.w != 0)
delta = target->_size.height / _targetData.w;
}
else
delta = target->_size.height - _targetData.w;
}
float v, tmp;
switch (info.type)
{
case RelationType::Left_Left:
if (info.percent)
_owner->setXMin(pos + (_owner->getXMin() - pos) * delta);
else if (pivot != 0)
_owner->setX(_owner->_position.x + delta * (-pivot));
break;
case RelationType::Left_Center:
if (info.percent)
_owner->setXMin(pos + (_owner->getXMin() - pos) * delta);
else
_owner->setX(_owner->_position.x + delta * (0.5f - pivot));
break;
case RelationType::Left_Right:
if (info.percent)
_owner->setXMin(pos + (_owner->getXMin() - pos) * delta);
else
_owner->setX(_owner->_position.x + delta * (1 - pivot));
break;
case RelationType::Center_Center:
if (info.percent)
_owner->setXMin(pos + (_owner->getXMin() + _owner->_rawSize.width * 0.5f - pos) * delta - _owner->_rawSize.width * 0.5f);
else
_owner->setX(_owner->_position.x + delta * (0.5f - pivot));
break;
case RelationType::Right_Left:
if (info.percent)
_owner->setXMin(pos + (_owner->getXMin() + _owner->_rawSize.width - pos) * delta - _owner->_rawSize.width);
else if (pivot != 0)
_owner->setX(_owner->_position.x + delta * (-pivot));
break;
case RelationType::Right_Center:
if (info.percent)
_owner->setXMin(pos + (_owner->getXMin() + _owner->_rawSize.width - pos) * delta - _owner->_rawSize.width);
else
_owner->setX(_owner->_position.x + delta * (0.5f - pivot));
break;
case RelationType::Right_Right:
if (info.percent)
_owner->setXMin(pos + (_owner->getXMin() + _owner->_rawSize.width - pos) * delta - _owner->_rawSize.width);
else
_owner->setX(_owner->_position.x + delta * (1 - pivot));
break;
case RelationType::Top_Top:
if (info.percent)
_owner->setYMin(pos + (_owner->getYMin() - pos) * delta);
else if (pivot != 0)
_owner->setY(_owner->_position.y + delta * (-pivot));
break;
case RelationType::Top_Middle:
if (info.percent)
_owner->setYMin(pos + (_owner->getYMin() - pos) * delta);
else
_owner->setY(_owner->_position.y + delta * (0.5f - pivot));
break;
case RelationType::Top_Bottom:
if (info.percent)
_owner->setYMin(pos + (_owner->getYMin() - pos) * delta);
else
_owner->setY(_owner->_position.y + delta * (1 - pivot));
break;
case RelationType::Middle_Middle:
if (info.percent)
_owner->setYMin(pos + (_owner->getYMin() + _owner->_rawSize.height * 0.5f - pos) * delta - _owner->_rawSize.height * 0.5f);
else
_owner->setY(_owner->_position.y + delta * (0.5f - pivot));
break;
case RelationType::Bottom_Top:
if (info.percent)
_owner->setYMin(pos + (_owner->getYMin() + _owner->_rawSize.height - pos) * delta - _owner->_rawSize.height);
else if (pivot != 0)
_owner->setY(_owner->_position.y + delta * (-pivot));
break;
case RelationType::Bottom_Middle:
if (info.percent)
_owner->setYMin(pos + (_owner->getYMin() + _owner->_rawSize.height - pos) * delta - _owner->_rawSize.height);
else
_owner->setY(_owner->_position.y + delta * (0.5f - pivot));
break;
case RelationType::Bottom_Bottom:
if (info.percent)
_owner->setYMin(pos + (_owner->getYMin() + _owner->_rawSize.height - pos) * delta - _owner->_rawSize.height);
else
_owner->setY(_owner->_position.y + delta * (1 - pivot));
break;
case RelationType::Width:
if (_owner->_underConstruct && _owner == target->_parent)
v = _owner->sourceSize.width - target->initSize.width;
else
v = _owner->_rawSize.width - _targetData.z;
if (info.percent)
v = v * delta;
if (_target == _owner->_parent)
{
if (_owner->_pivotAsAnchor)
{
tmp = _owner->getXMin();
_owner->setSize(target->_size.width + v, _owner->_rawSize.height, true);
_owner->setXMin(tmp);
}
else
_owner->setSize(target->_size.width + v, _owner->_rawSize.height, true);
}
else
_owner->setWidth(target->_size.width + v);
break;
case RelationType::Height:
if (_owner->_underConstruct && _owner == target->_parent)
v = _owner->sourceSize.height - target->initSize.height;
else
v = _owner->_rawSize.height - _targetData.w;
if (info.percent)
v = v * delta;
if (_target == _owner->_parent)
{
if (_owner->_pivotAsAnchor)
{
tmp = _owner->getYMin();
_owner->setSize(_owner->_rawSize.width, target->_size.height + v, true);
_owner->setYMin(tmp);
}
else
_owner->setSize(_owner->_rawSize.width, target->_size.height + v, true);
}
else
_owner->setHeight(target->_size.height + v);
break;
case RelationType::LeftExt_Left:
tmp = _owner->getXMin();
if (info.percent)
v = pos + (tmp - pos) * delta - tmp;
else
v = delta * (-pivot);
_owner->setWidth(_owner->_rawSize.width - v);
_owner->setXMin(tmp + v);
break;
case RelationType::LeftExt_Right:
tmp = _owner->getXMin();
if (info.percent)
v = pos + (tmp - pos) * delta - tmp;
else
v = delta * (1 - pivot);
_owner->setWidth(_owner->_rawSize.width - v);
_owner->setXMin(tmp + v);
break;
case RelationType::RightExt_Left:
tmp = _owner->getXMin();
if (info.percent)
v = pos + (tmp + _owner->_rawSize.width - pos) * delta - (tmp + _owner->_rawSize.width);
else
v = delta * (-pivot);
_owner->setWidth(_owner->_rawSize.width + v);
_owner->setXMin(tmp);
break;
case RelationType::RightExt_Right:
tmp = _owner->getXMin();
if (info.percent)
{
if (_owner == target->_parent)
{
if (_owner->_underConstruct)
_owner->setWidth(pos + target->_size.width - target->_size.width * pivot +
(_owner->sourceSize.width - pos - target->initSize.width + target->initSize.width * pivot) * delta);
else
_owner->setWidth(pos + (_owner->_rawSize.width - pos) * delta);
}
else
{
v = pos + (tmp + _owner->_rawSize.width - pos) * delta - (tmp + _owner->_rawSize.width);
_owner->setWidth(_owner->_rawSize.width + v);
_owner->setXMin(tmp);
}
}
else
{
if (_owner == target->_parent)
{
if (_owner->_underConstruct)
_owner->setWidth(_owner->sourceSize.width + (target->_size.width - target->initSize.width) * (1 - pivot));
else
_owner->setWidth(_owner->_rawSize.width + delta * (1 - pivot));
}
else
{
v = delta * (1 - pivot);
_owner->setWidth(_owner->_rawSize.width + v);
_owner->setXMin(tmp);
}
}
break;
case RelationType::TopExt_Top:
tmp = _owner->getYMin();
if (info.percent)
v = pos + (tmp - pos) * delta - tmp;
else
v = delta * (-pivot);
_owner->setHeight(_owner->_rawSize.height - v);
_owner->setYMin(tmp + v);
break;
case RelationType::TopExt_Bottom:
tmp = _owner->getYMin();
if (info.percent)
v = pos + (tmp - pos) * delta - tmp;
else
v = delta * (1 - pivot);
_owner->setHeight(_owner->_rawSize.height - v);
_owner->setYMin(tmp + v);
break;
case RelationType::BottomExt_Top:
tmp = _owner->getYMin();
if (info.percent)
v = pos + (tmp + _owner->_rawSize.height - pos) * delta - (tmp + _owner->_rawSize.height);
else
v = delta * (-pivot);
_owner->setHeight(_owner->_rawSize.height + v);
_owner->setYMin(tmp);
break;
case RelationType::BottomExt_Bottom:
tmp = _owner->getYMin();
if (info.percent)
{
if (_owner == target->_parent)
{
if (_owner->_underConstruct)
_owner->setHeight(pos + target->_size.height - target->_size.height * pivot +
(_owner->sourceSize.height - pos - target->initSize.height + target->initSize.height * pivot) * delta);
else
_owner->setHeight(pos + (_owner->_rawSize.height - pos) * delta);
}
else
{
v = pos + (tmp + _owner->_rawSize.height - pos) * delta - (tmp + _owner->_rawSize.height);
_owner->setHeight(_owner->_rawSize.height + v);
_owner->setYMin(tmp);
}
}
else
{
if (_owner == target->_parent)
{
if (_owner->_underConstruct)
_owner->setHeight(_owner->sourceSize.height + (target->_size.height - target->initSize.height) * (1 - pivot));
else
_owner->setHeight(_owner->_rawSize.height + delta * (1 - pivot));
}
else
{
v = delta * (1 - pivot);
_owner->setHeight(_owner->_rawSize.height + v);
_owner->setYMin(tmp);
}
}
break;
default:
break;
}
}
void RelationItem::addRefTarget(GObject* target)
{
if (!target)
return;
if (target != _owner->_parent)
target->addEventListener(UIEventType::PositionChange, CC_CALLBACK_1(RelationItem::onTargetXYChanged, this), EventTag(this));
target->addEventListener(UIEventType::SizeChange, CC_CALLBACK_1(RelationItem::onTargetSizeChanged, this), EventTag(this));
_targetData.x = target->_position.x;
_targetData.y = target->_position.y;
_targetData.z = target->_size.width;
_targetData.w = target->_size.height;
}
void RelationItem::releaseRefTarget(GObject* target)
{
if (!target)
return;
target->removeEventListener(UIEventType::PositionChange, EventTag(this));
target->removeEventListener(UIEventType::SizeChange, EventTag(this));
}
void RelationItem::onTargetXYChanged(EventContext* context)
{
GObject* target = (GObject*)context->getSender();
if (_owner->relations()->handling != nullptr || (_owner->_group != nullptr && _owner->_group->_updating != 0))
{
_targetData.x = target->_position.x;
_targetData.y = target->_position.y;
return;
}
_owner->relations()->handling = target;
float ox = _owner->_position.x;
float oy = _owner->_position.y;
float dx = target->_position.x - _targetData.x;
float dy = target->_position.y - _targetData.y;
for (auto& it : _defs)
applyOnXYChanged(target, it, dx, dy);
_targetData.x = target->_position.x;
_targetData.y = target->_position.y;
if (ox != _owner->_position.x || oy != _owner->_position.y)
{
ox = _owner->_position.x - ox;
oy = _owner->_position.y - oy;
_owner->updateGearFromRelations(1, ox, oy);
if (_owner->_parent != nullptr)
{
const Vector<Transition*>& arr = _owner->_parent->getTransitions();
for (auto& it : arr)
it->updateFromRelations(_owner->id, ox, oy);
}
}
_owner->relations()->handling = nullptr;
}
void RelationItem::onTargetSizeChanged(EventContext* context)
{
GObject* target = (GObject*)context->getSender();
if (_owner->relations()->handling != nullptr || (_owner->_group != nullptr && _owner->_group->_updating != 0))
{
_targetData.z = target->_size.width;
_targetData.w = target->_size.height;
return;
}
_owner->relations()->handling = target;
float ox = _owner->_position.x;
float oy = _owner->_position.y;
float ow = _owner->_rawSize.width;
float oh = _owner->_rawSize.height;
for (auto& it : _defs)
applyOnSizeChanged(target, it);
_targetData.z = target->_size.width;
_targetData.w = target->_size.height;
if (ox != _owner->_position.x || oy != _owner->_position.y)
{
ox = _owner->_position.x - ox;
oy = _owner->_position.y - oy;
_owner->updateGearFromRelations(1, ox, oy);
if (_owner->_parent != nullptr)
{
const Vector<Transition*>& arr = _owner->_parent->getTransitions();
for (auto& it : arr)
it->updateFromRelations(_owner->id, ox, oy);
}
}
if (ow != _owner->_rawSize.width || oh != _owner->_rawSize.height)
{
ow = _owner->_rawSize.width - ow;
oh = _owner->_rawSize.height - oh;
_owner->updateGearFromRelations(2, ow, oh);
}
_owner->relations()->handling = nullptr;
}
NS_FGUI_END

View File

@ -0,0 +1,95 @@
#ifndef __RELATIONITEM_H__
#define __RELATIONITEM_H__
#include "cocos2d.h"
#include "FairyGUIMacros.h"
#include "utils/WeakPtr.h"
NS_FGUI_BEGIN
class GObject;
class EventContext;
enum class RelationType
{
Left_Left,
Left_Center,
Left_Right,
Center_Center,
Right_Left,
Right_Center,
Right_Right,
Top_Top,
Top_Middle,
Top_Bottom,
Middle_Middle,
Bottom_Top,
Bottom_Middle,
Bottom_Bottom,
Width,
Height,
LeftExt_Left,
LeftExt_Right,
RightExt_Left,
RightExt_Right,
TopExt_Top,
TopExt_Bottom,
BottomExt_Top,
BottomExt_Bottom,
Size
};
class RelationDef
{
public:
bool percent;
RelationType type;
int axis;
RelationDef() {}
RelationDef(const RelationDef& source)
{
this->percent = source.percent;
this->type = source.type;
this->axis = source.axis;
}
};
class RelationItem
{
public:
RelationItem(GObject* owner);
~RelationItem();
GObject* getTarget() { return _target.ptr(); }
void setTarget(GObject* value);
void add(RelationType relationType, bool usePercent);
void internalAdd(RelationType relationType, bool usePercent);
void remove(RelationType relationType);
void copyFrom(const RelationItem& source);
bool isEmpty() const;
void applyOnSelfSizeChanged(float dWidth, float dHeight, bool applyPivot);
private:
void applyOnXYChanged(GObject* target, const RelationDef& info, float dx, float dy);
void applyOnSizeChanged(GObject* target, const RelationDef& info);
void addRefTarget(GObject* target);
void releaseRefTarget(GObject* target);
void onTargetXYChanged(EventContext* context);
void onTargetSizeChanged(EventContext* context);
GObject* _owner;
WeakPtr _target;
std::vector<RelationDef> _defs;
cocos2d::Vec4 _targetData;
};
NS_FGUI_END
#endif

View File

@ -0,0 +1,145 @@
#include "Relations.h"
#include "GComponent.h"
#include "utils/ByteBuffer.h"
NS_FGUI_BEGIN
USING_NS_CC;
Relations::Relations(GObject* owner) :
handling(nullptr)
{
_owner = owner;
}
Relations::~Relations()
{
clearAll();
}
void Relations::add(GObject * target, RelationType relationType)
{
add(target, relationType, false);
}
void Relations::add(GObject * target, RelationType relationType, bool usePercent)
{
CCASSERT(target, "target is null");
for (auto it = _items.begin(); it != _items.end(); ++it)
{
if ((*it)->getTarget() == target)
{
(*it)->add(relationType, usePercent);
return;
}
}
RelationItem* newItem = new RelationItem(_owner);
newItem->setTarget(target);
newItem->add(relationType, usePercent);
_items.push_back(newItem);
}
void Relations::remove(GObject * target, RelationType relationType)
{
for (auto it = _items.begin(); it != _items.end(); )
{
if ((*it)->getTarget() == target)
{
(*it)->remove(relationType);
if ((*it)->isEmpty())
{
delete (*it);
it = _items.erase(it);
}
else
it++;
}
else
it++;
}
}
bool Relations::contains(GObject * target)
{
for (auto it = _items.begin(); it != _items.end(); ++it)
{
if ((*it)->getTarget() == target)
return true;
}
return false;
}
void Relations::clearFor(GObject * target)
{
for (auto it = _items.begin(); it != _items.end(); )
{
if ((*it)->getTarget() == target)
{
delete (*it);
it = _items.erase(it);
}
else
it++;
}
}
void Relations::clearAll()
{
for (auto it = _items.begin(); it != _items.end(); ++it)
delete (*it);
_items.clear();
}
void Relations::copyFrom(const Relations & source)
{
clearAll();
for (auto it = source._items.begin(); it != source._items.end(); ++it)
{
RelationItem* item = new RelationItem(_owner);
item->copyFrom(**it);
_items.push_back(item);
}
}
void Relations::onOwnerSizeChanged(float dWidth, float dHeight, bool applyPivot)
{
for (auto it = _items.begin(); it != _items.end(); ++it)
(*it)->applyOnSelfSizeChanged(dWidth, dHeight, applyPivot);
}
bool Relations::isEmpty() const
{
return _items.size() == 0;
}
void Relations::setup(ByteBuffer * buffer, bool parentToChild)
{
int cnt = buffer->readByte();
GObject* target;
for (int i = 0; i < cnt; i++)
{
int targetIndex = buffer->readShort();
if (targetIndex == -1)
target = _owner->getParent();
else if (parentToChild)
target = (dynamic_cast<GComponent*>(_owner))->getChildAt(targetIndex);
else
target = _owner->getParent()->getChildAt(targetIndex);
RelationItem* newItem = new RelationItem(_owner);
newItem->setTarget(target);
_items.push_back(newItem);
int cnt2 = buffer->readByte();
for (int j = 0; j < cnt2; j++)
{
RelationType rt = (RelationType)buffer->readByte();
bool usePercent = buffer->readBool();
newItem->internalAdd(rt, usePercent);
}
}
}
NS_FGUI_END

View File

@ -0,0 +1,39 @@
#ifndef __RELATIONS_H__
#define __RELATIONS_H__
#include "cocos2d.h"
#include "FairyGUIMacros.h"
#include "RelationItem.h"
NS_FGUI_BEGIN
class GObject;
class ByteBuffer;
class Relations
{
public:
Relations(GObject* owner);
~Relations();
void add(GObject* target, RelationType relationType);
void add(GObject* target, RelationType relationType, bool usePercent);
void remove(GObject* target, RelationType relationType);
bool contains(GObject* target);
void clearFor(GObject* target);
void clearAll();
void copyFrom(const Relations& source);
void onOwnerSizeChanged(float dWidth, float dHeight, bool applyPivot);
bool isEmpty() const;
void setup(ByteBuffer* buffer, bool parentToChild);
GObject* handling;
private:
GObject* _owner;
std::vector<RelationItem*> _items;
};
NS_FGUI_END
#endif

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,219 @@
#ifndef __SCROLLPANE_H__
#define __SCROLLPANE_H__
#include "FairyGUIMacros.h"
#include "Margin.h"
#include "cocos2d.h"
NS_FGUI_BEGIN
class GObject;
class GComponent;
class GScrollBar;
class FUIContainer;
class FUIInnerContainer;
class GController;
class EventContext;
class ByteBuffer;
class GTweener;
class ScrollPane : public cocos2d::Ref
{
public:
ScrollPane(GComponent* owner);
virtual ~ScrollPane();
void setup(ByteBuffer* buffer);
GComponent* getOwner() const { return _owner; }
GComponent* getHeader() const { return _header; }
GComponent* getFooter() const { return _footer; }
GScrollBar* getVtScrollBar() const { return _vtScrollBar; }
GScrollBar* getHzScrollBar() const { return _hzScrollBar; }
bool isBouncebackEffect() const { return _bouncebackEffect; }
void setBouncebackEffect(bool value) { _bouncebackEffect = value; }
bool isTouchEffect() const { return _touchEffect; }
void setTouchEffect(bool value) { _touchEffect = value; }
bool isInertiaDisabled() const { return _inertiaDisabled; }
void setInertiaDisabled(bool value) { _inertiaDisabled = value; }
float getScrollStep() const { return _scrollStep; }
void setScrollStep(float value);
bool isSnapToItem() const { return _snapToItem; }
void setSnapToItem(bool value) { _snapToItem = value; }
bool isPageMode() const { return _pageMode; }
void setPageMode(bool value) { _pageMode = value; }
GController* getPageController() const { return _pageController; }
void setPageController(GController* value) { _pageController = value; }
bool isMouseWheelEnabled() const { return _mouseWheelEnabled; }
void setMouseWheelEnabled(bool value) { _mouseWheelEnabled = value; }
float getDecelerationRate() const { return _decelerationRate; }
void setDecelerationRate(float value) { _decelerationRate = value; }
float getPosX() const { return _xPos; }
void setPosX(float value, bool ani = false);
float getPosY() const { return _yPos; }
void setPosY(float value, bool ani = false);
float getPercX() const;
void setPercX(float value, bool ani = false);
float getPercY() const;
void setPercY(float value, bool ani = false);
bool isBottomMost() const;
bool isRightMost() const;
void scrollLeft(float ratio = 1, bool ani = false);
void scrollRight(float ratio = 1, bool ani = false);
void scrollUp(float ratio = 1, bool ani = false);
void scrollDown(float ratio = 1, bool ani = false);
void scrollTop(bool ani = false);
void scrollBottom(bool ani = false);
void scrollToView(GObject* obj, bool ani = false, bool setFirst = false);
void scrollToView(const cocos2d::Rect& rect, bool ani = false, bool setFirst = false);
bool isChildInView(GObject* obj) const;
int getPageX() const;
void setPageX(int value, bool ani = false);
int getPageY() const;
void setPageY(int value, bool ani = false);
float getScrollingPosX() const;
float getScrollingPosY() const;
const cocos2d::Size& getContentSize() const { return _contentSize; }
const cocos2d::Size& getViewSize() const { return _viewSize; }
void lockHeader(int size);
void lockFooter(int size);
void cancelDragging();
static ScrollPane* getDraggingPane() { return _draggingPane; }
private:
void onOwnerSizeChanged();
void adjustMaskContainer();
void setContentSize(float wv, float hv);
void changeContentSizeOnScrolling(float deltaWidth, float deltaHeight, float deltaPosX, float deltaPosY);
void setViewWidth(float value);
void setViewHeight(float value);
void setSize(float wv, float hv);
void handleSizeChanged();
void handleControllerChanged(GController* c);
void updatePageController();
GObject* hitTest(const cocos2d::Vec2& pt, const cocos2d::Camera* camera);
void posChanged(bool ani);
CALL_LATER_FUNC(ScrollPane, refresh);
void refresh2();
void updateScrollBarPos();
void updateScrollBarVisible();
void updateScrollBarVisible2(GScrollBar* bar);
float getLoopPartSize(float division, int axis);
bool loopCheckingCurrent();
void loopCheckingTarget(cocos2d::Vec2& endPos);
void loopCheckingTarget(cocos2d::Vec2& endPos, int axis);
void loopCheckingNewPos(float& value, int axis);
void alignPosition(cocos2d::Vec2& pos, bool inertialScrolling);
float alignByPage(float pos, int axis, bool inertialScrolling);
cocos2d::Vec2 updateTargetAndDuration(const cocos2d::Vec2& orignPos);
float updateTargetAndDuration(float pos, int axis);
void fixDuration(int axis, float oldChange);
void startTween(int type);
void killTween();
void tweenUpdate(float dt);
float runTween(int axis, float dt);
void checkRefreshBar();
void onTouchBegin(EventContext* context);
void onTouchMove(EventContext* context);
void onTouchEnd(EventContext* context);
void onMouseWheel(EventContext* context);
void onRollOver(EventContext* context);
void onRollOut(EventContext* context);
void onBarTweenComplete(GTweener* tweener);
ScrollType _scrollType;
float _scrollStep;
float _mouseWheelStep;
Margin _scrollBarMargin;
bool _bouncebackEffect;
bool _touchEffect;
bool _scrollBarDisplayAuto;
bool _vScrollNone;
bool _hScrollNone;
bool _needRefresh;
int _refreshBarAxis;
bool _displayOnLeft;
bool _snapToItem;
bool _displayInDemand;
bool _mouseWheelEnabled;
bool _inertiaDisabled;
float _decelerationRate;
bool _pageMode;
bool _floating;
bool _dontClipMargin;
float _xPos;
float _yPos;
cocos2d::Size _viewSize;
cocos2d::Size _contentSize;
cocos2d::Size _overlapSize;
cocos2d::Size _pageSize;
cocos2d::Vec2 _containerPos;
cocos2d::Vec2 _beginTouchPos;
cocos2d::Vec2 _lastTouchPos;
cocos2d::Vec2 _lastTouchGlobalPos;
cocos2d::Vec2 _velocity;
float _velocityScale;
clock_t _lastMoveTime;
bool _dragged;
bool _isHoldAreaDone;
int _aniFlag;
int _loop;
bool _hover;
int _headerLockedSize;
int _footerLockedSize;
int _tweening;
cocos2d::Vec2 _tweenStart;
cocos2d::Vec2 _tweenChange;
cocos2d::Vec2 _tweenTime;
cocos2d::Vec2 _tweenDuration;
GComponent* _owner;
FUIContainer* _maskContainer;
FUIInnerContainer* _container;
GScrollBar* _hzScrollBar;
GScrollBar* _vtScrollBar;
GComponent* _header;
GComponent* _footer;
GController* _pageController;
static int _gestureFlag;
static ScrollPane* _draggingPane;
friend class GComponent;
friend class GList;
friend class GScrollBar;
};
NS_FGUI_END
#endif

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,94 @@
#ifndef __TRANSITION_H__
#define __TRANSITION_H__
#include "FairyGUIMacros.h"
#include "cocos2d.h"
NS_FGUI_BEGIN
class GObject;
class GComponent;
class TransitionItem;
class GTweener;
class ByteBuffer;
class Transition : public cocos2d::Ref
{
public:
typedef std::function<void()> PlayCompleteCallback;
typedef std::function<void()> TransitionHook;
Transition(GComponent* owner);
virtual ~Transition();
GComponent* getOwner() const { return _owner; }
bool isPlaying() const { return _playing; }
void play(PlayCompleteCallback callback = nullptr);
void play(int times, float delay, PlayCompleteCallback callback = nullptr);
void play(int times, float delay, float startTime, float endTime, PlayCompleteCallback callback = nullptr);
void playReverse(PlayCompleteCallback callback = nullptr);
void playReverse(int times, float delay, PlayCompleteCallback callback = nullptr);
void changePlayTimes(int value);
void stop();
void stop(bool setToComplete, bool processCallback);
void setAutoPlay(bool autoPlay, int times, float delay);
void setPaused(bool paused);
void setValue(const std::string& label, const cocos2d::ValueVector& values);
void setHook(const std::string& label, TransitionHook callback);
void clearHooks();
void setTarget(const std::string& label, GObject* newTarget);
void setDuration(const std::string& label, float value);
float getLabelTime(const std::string& label) const;
float getTimeScale() const { return _timeScale; }
void setTimeScale(float value);
void updateFromRelations(const std::string& targetId, float dx, float dy);
void onOwnerAddedToStage();
void onOwnerRemovedFromStage();
void setup(ByteBuffer* buffer);
std::string name;
private:
void play(int times, float delay, float startTime, float endTime, PlayCompleteCallback onComplete, bool reverse);
void stopItem(TransitionItem* item, bool setToComplete);
void onDelayedPlay();
void internalPlay();
void playItem(TransitionItem* item);
void skipAnimations();
void onDelayedPlayItem(GTweener* tweener);
void onTweenStart(GTweener* tweener);
void onTweenUpdate(GTweener* tweener);
void onTweenComplete(GTweener* tweener);
void onPlayTransCompleted(TransitionItem* item);
void callHook(TransitionItem* item, bool tweenEnd);
void checkAllComplete();
void applyValue(TransitionItem* item);
void decodeValue(TransitionItem* item, ByteBuffer* buffer, void* value);
GComponent* _owner;
std::vector<TransitionItem*> _items;
int _totalTimes;
int _totalTasks;
bool _playing;
bool _paused;
float _ownerBaseX;
float _ownerBaseY;
PlayCompleteCallback _onComplete;
int _options;
bool _reversed;
float _totalDuration;
bool _autoPlay;
int _autoPlayTimes;
float _autoPlayDelay;
float _timeScale;
float _startTime;
float _endTime;
};
NS_FGUI_END
#endif

View File

@ -0,0 +1,291 @@
#include "TranslationHelper.h"
#include "PackageItem.h"
#include "UIPackage.h"
#if defined(ENGINEX_VERSION)
#include "pugixml/pugixml_imp.hpp"
#else
#include "tinyxml2/tinyxml2.h"
#endif
#include "utils/ByteBuffer.h"
USING_NS_CC;
NS_FGUI_BEGIN
using namespace std;
std::unordered_map<std::string, std::unordered_map<std::string, std::string>> TranslationHelper::strings;
void TranslationHelper::loadFromXML(const char* xmlString, size_t nBytes)
{
strings.clear();
#if defined(ENGINEX_VERSION)
pugi::xml_document doc;
if (doc.load_buffer(xmlString, nBytes)) {
auto root = doc.document_element();
auto ele = doc.child("string");
while (ele)
{
std::string key = ele.attribute("name").value();
std::string text = ele.text().as_string();
size_t i = key.find("-");
if (i == std::string::npos)
continue;
std::string key2 = key.substr(0, i);
std::string key3 = key.substr(i + 1);
std::unordered_map<std::string, std::string>& col = strings[key2];
col[key3] = text;
ele = ele.next_sibling("string");
}
}
#else
tinyxml2::XMLDocument* xml = new tinyxml2::XMLDocument();
xml->Parse(xmlString, nBytes);
tinyxml2::XMLElement* root = xml->RootElement();
tinyxml2::XMLElement* ele = root->FirstChildElement("string");
while (ele)
{
std::string key = ele->Attribute("name");
std::string text = ele->GetText();
size_t i = key.find("-");
if (i == std::string::npos)
continue;
std::string key2 = key.substr(0, i);
std::string key3 = key.substr(i + 1);
std::unordered_map<std::string, std::string>& col = strings[key2];
col[key3] = text;
ele = ele->NextSiblingElement("string");
}
delete xml;
#endif
}
void TranslationHelper::translateComponent(PackageItem* item)
{
if (strings.empty())
return;
auto col = strings.find(item->owner->getId() + item->id);
if (col == strings.end())
return;
std::unordered_map<std::string, std::string>& strings = col->second;
ByteBuffer* buffer = item->rawData;
buffer->seek(0, 2);
int childCount = buffer->readShort();
for (int i = 0; i < childCount; i++)
{
int dataLen = buffer->readShort();
int curPos = buffer->getPos();
buffer->seek(curPos, 0);
ObjectType baseType = (ObjectType)buffer->readByte();
ObjectType type = baseType;
buffer->skip(4);
const string& elementId = buffer->readS();
if (type == ObjectType::COMPONENT)
{
if (buffer->seek(curPos, 6))
type = (ObjectType)buffer->readByte();
}
buffer->seek(curPos, 1);
auto it = strings.find(elementId + "-tips");
if (it != strings.end())
buffer->writeS(it->second);
buffer->seek(curPos, 2);
int gearCnt = buffer->readShort();
for (int j = 0; j < gearCnt; j++)
{
int nextPos = buffer->readShort();
nextPos += buffer->getPos();
if (buffer->readByte() == 6) //gearText
{
buffer->skip(2); //controller
int valueCnt = buffer->readShort();
for (int k = 0; k < valueCnt; k++)
{
const string& page = buffer->readS();
if (!page.empty())
{
if ((it = strings.find(elementId + "-texts_" + Value(k).asString())) != strings.end())
buffer->writeS(it->second);
else
buffer->skip(2);
}
}
if (buffer->readBool() && (it = strings.find(elementId + "-texts_def")) != strings.end())
buffer->writeS(it->second);
}
buffer->setPos(nextPos);
}
if (baseType == ObjectType::COMPONENT && buffer->version >= 2)
{
buffer->seek(curPos, 4);
buffer->skip(2); //pageController
buffer->skip(4 * buffer->readShort());
int cpCount = buffer->readShort();
for (int k = 0; k < cpCount; k++)
{
std::string target = buffer->readS();
int propertyId = buffer->readShort();
if (propertyId == 0 && (it = strings.find(elementId + "-cp-" + target)) != strings.end())
buffer->writeS(it->second);
else
buffer->skip(2);
}
}
switch (type)
{
case ObjectType::TEXT:
case ObjectType::RICHTEXT:
case ObjectType::INPUTTEXT:
{
if ((it = strings.find(elementId)) != strings.end())
{
buffer->seek(curPos, 6);
buffer->writeS(it->second);
}
if ((it = strings.find(elementId + "-prompt")) != strings.end())
{
buffer->seek(curPos, 4);
buffer->writeS(it->second);
}
break;
}
case ObjectType::LIST:
{
buffer->seek(curPos, 8);
buffer->skip(2);
int itemCount = buffer->readShort();
for (int j = 0; j < itemCount; j++)
{
int nextPos = buffer->readUshort();
nextPos += buffer->getPos();
buffer->skip(2); //url
if (type == ObjectType::TREE)
buffer->skip(2);
//title
if ((it = strings.find(elementId + "-" + Value(j).asString())) != strings.end())
buffer->writeS(it->second);
else
buffer->skip(2);
//selected title
if ((it = strings.find(elementId + "-" + Value(j).asString() + "-0")) != strings.end())
buffer->writeS(it->second);
else
buffer->skip(2);
if (buffer->version >= 2)
{
buffer->skip(6);
buffer->skip(buffer->readShort() * 4); //controllers
int cpCount = buffer->readShort();
for (int k = 0; k < cpCount; k++)
{
std::string target = buffer->readS();
int propertyId = buffer->readShort();
if (propertyId == 0 && (it = strings.find(elementId + "-" + Value(j).asString() + "-" + target)) != strings.end())
buffer->writeS(it->second);
else
buffer->skip(2);
}
}
buffer->setPos(nextPos);
}
break;
}
case ObjectType::LABEL:
{
if (buffer->seek(curPos, 6) && (ObjectType)buffer->readByte() == type)
{
if ((it = strings.find(elementId)) != strings.end())
buffer->writeS(it->second);
else
buffer->skip(2);
buffer->skip(2);
if (buffer->readBool())
buffer->skip(4);
buffer->skip(4);
if (buffer->readBool() && (it = strings.find(elementId + "-prompt")) != strings.end())
buffer->writeS(it->second);
}
break;
}
case ObjectType::BUTTON:
{
if (buffer->seek(curPos, 6) && (ObjectType)buffer->readByte() == type)
{
if ((it = strings.find(elementId)) != strings.end())
buffer->writeS(it->second);
else
buffer->skip(2);
if ((it = strings.find(elementId + "-0")) != strings.end())
buffer->writeS(it->second);
}
break;
}
case ObjectType::COMBOBOX:
{
if (buffer->seek(curPos, 6) && (ObjectType)buffer->readByte() == type)
{
int itemCount = buffer->readShort();
for (int j = 0; j < itemCount; j++)
{
int nextPos = buffer->readShort();
nextPos += buffer->getPos();
if ((it = strings.find(elementId + "-" + Value(j).asString())) != strings.end())
buffer->writeS(it->second);
buffer->setPos(nextPos);
}
if ((it = strings.find(elementId)) != strings.end())
buffer->writeS(it->second);
}
break;
}
default:
break;
}
buffer->setPos(curPos + dataLen);
}
}
NS_FGUI_END

View File

@ -0,0 +1,22 @@
#ifndef __TRANSLATIONHELPER_H_
#define __TRANSLATIONHELPER_H_
#include "FairyGUIMacros.h"
#include "cocos2d.h"
NS_FGUI_BEGIN
class PackageItem;
class TranslationHelper
{
public:
static std::unordered_map<std::string, std::unordered_map<std::string, std::string>> strings;
static void loadFromXML(const char *xmlString, size_t nBytes);
static void translateComponent(PackageItem* item);
};
NS_FGUI_END
#endif

View File

@ -0,0 +1,63 @@
#include "UIConfig.h"
NS_FGUI_BEGIN
USING_NS_CC;
std::string UIConfig::defaultFont = "";
std::string UIConfig::buttonSound = "";
float UIConfig::buttonSoundVolumeScale = 1;
int UIConfig::defaultScrollStep = 25;
float UIConfig::defaultScrollDecelerationRate = 0.967f;
bool UIConfig::defaultScrollTouchEffect = true;
bool UIConfig::defaultScrollBounceEffect = true;
ScrollBarDisplayType UIConfig::defaultScrollBarDisplay = ScrollBarDisplayType::DEFAULT;
std::string UIConfig::verticalScrollBar = "";
std::string UIConfig::horizontalScrollBar = "";
int UIConfig::touchDragSensitivity = 10;
int UIConfig::clickDragSensitivity = 2;
int UIConfig::touchScrollSensitivity = 20;
int UIConfig::defaultComboBoxVisibleItemCount = 10;
std::string UIConfig::globalModalWaiting = "";
std::string UIConfig::tooltipsWin = "";
Color4F UIConfig::modalLayerColor = Color4F(0, 0, 0, 0.4f);
bool UIConfig::bringWindowToFrontOnClick = true;
std::string UIConfig::windowModalWaiting = "";
std::string UIConfig::popupMenu = "";
std::string UIConfig::popupMenu_seperator = "";
std::unordered_map<std::string, UIConfig::FontNameItem> UIConfig::_fontNames;
void UIConfig::registerFont(const std::string& aliasName, const std::string& realName)
{
FontNameItem fi;
fi.name = realName;
bool tmp = FileUtils::getInstance()->isPopupNotify();
FileUtils::getInstance()->setPopupNotify(false);
fi.ttf = FileUtils::getInstance()->isFileExist(realName);
FileUtils::getInstance()->setPopupNotify(tmp);
_fontNames[aliasName] = fi;
}
const std::string& UIConfig::getRealFontName(const std::string& aliasName, bool* isTTF)
{
std::unordered_map<std::string, UIConfig::FontNameItem>::const_iterator it;
if (aliasName.empty())
it = _fontNames.find(UIConfig::defaultFont);
else
it = _fontNames.find(aliasName);
if (it != _fontNames.end())
{
if(isTTF)
*isTTF = it->second.ttf;
return it->second.name;
}
else
{
if (isTTF)
*isTTF = false;
return aliasName;
}
}
NS_FGUI_END

View File

@ -0,0 +1,48 @@
#ifndef __UICONFIG_H__
#define __UICONFIG_H__
#include "cocos2d.h"
#include "FairyGUIMacros.h"
NS_FGUI_BEGIN
class UIConfig
{
public:
static std::string defaultFont;
static std::string buttonSound;
static float buttonSoundVolumeScale;
static int defaultScrollStep;
static float defaultScrollDecelerationRate;
static bool defaultScrollTouchEffect;
static bool defaultScrollBounceEffect;
static ScrollBarDisplayType defaultScrollBarDisplay;
static std::string verticalScrollBar;
static std::string horizontalScrollBar;
static int touchDragSensitivity;
static int clickDragSensitivity;
static int touchScrollSensitivity;
static int defaultComboBoxVisibleItemCount;
static std::string globalModalWaiting;
static cocos2d::Color4F modalLayerColor;
static std::string tooltipsWin;
static bool bringWindowToFrontOnClick;
static std::string windowModalWaiting;
static std::string popupMenu;
static std::string popupMenu_seperator;
static void registerFont(const std::string& aliasName, const std::string& realName);
static const std::string& getRealFontName(const std::string& aliasName, bool* isTTF = nullptr);
private:
struct FontNameItem
{
std::string name;
bool ttf;
};
static std::unordered_map<std::string, FontNameItem> _fontNames;
};
NS_FGUI_END
#endif

View File

@ -0,0 +1,145 @@
#include "UIObjectFactory.h"
#include "GButton.h"
#include "GComboBox.h"
#include "GComponent.h"
#include "GGraph.h"
#include "GGroup.h"
#include "GImage.h"
#include "GLabel.h"
#include "GList.h"
#include "GLoader.h"
#include "GMovieClip.h"
#include "GProgressBar.h"
#include "GRichTextField.h"
#include "GScrollBar.h"
#include "GSlider.h"
#include "GTextField.h"
#include "GTextInput.h"
#include "GTree.h"
#include "GLoader3D.h"
#include "UIPackage.h"
#include "utils/ToolSet.h"
NS_FGUI_BEGIN
using namespace std;
unordered_map<string, UIObjectFactory::GComponentCreator> UIObjectFactory::_packageItemExtensions;
UIObjectFactory::GLoaderCreator UIObjectFactory::_loaderCreator;
void UIObjectFactory::setPackageItemExtension(const string& url, GComponentCreator creator)
{
if (url.size() == 0)
{
CCLOG("Invaild url: %s", url.c_str());
return;
}
PackageItem* pi = UIPackage::getItemByURL(url);
if (pi)
pi->extensionCreator = creator;
_packageItemExtensions[url] = creator;
}
GObject* UIObjectFactory::newObject(PackageItem* pi)
{
GObject* obj;
if (pi->extensionCreator != nullptr)
obj = pi->extensionCreator();
else
obj = newObject(pi->objectType);
if (obj != nullptr)
obj->_packageItem = pi;
return obj;
}
GObject* UIObjectFactory::newObject(ObjectType type)
{
switch (type)
{
case ObjectType::IMAGE:
return GImage::create();
case ObjectType::MOVIECLIP:
return GMovieClip::create();
case ObjectType::COMPONENT:
return GComponent::create();
case ObjectType::TEXT:
return GBasicTextField::create();
case ObjectType::RICHTEXT:
return GRichTextField::create();
case ObjectType::INPUTTEXT:
return GTextInput::create();
case ObjectType::GROUP:
return GGroup::create();
case ObjectType::LIST:
return GList::create();
case ObjectType::GRAPH:
return GGraph::create();
case ObjectType::LOADER:
if (_loaderCreator != nullptr)
return _loaderCreator();
else
return GLoader::create();
case ObjectType::BUTTON:
return GButton::create();
case ObjectType::LABEL:
return GLabel::create();
case ObjectType::PROGRESSBAR:
return GProgressBar::create();
case ObjectType::SLIDER:
return GSlider::create();
case ObjectType::SCROLLBAR:
return GScrollBar::create();
case ObjectType::COMBOBOX:
return GComboBox::create();
case ObjectType::TREE:
return GTree::create();
case ObjectType::LOADER3D:
return GLoader3D::create();
default:
return nullptr;
}
}
void UIObjectFactory::setLoaderExtension(GLoaderCreator creator)
{
_loaderCreator = creator;
}
void UIObjectFactory::resolvePackageItemExtension(PackageItem* pi)
{
auto it = _packageItemExtensions.find(UIPackage::URL_PREFIX + pi->owner->getId() + pi->id);
if (it != _packageItemExtensions.end())
{
pi->extensionCreator = it->second;
return;
}
it = _packageItemExtensions.find(UIPackage::URL_PREFIX + pi->owner->getName() + "/" + pi->name);
if (it != _packageItemExtensions.end())
{
pi->extensionCreator = it->second;
return;
}
pi->extensionCreator = nullptr;
}
NS_FGUI_END

View File

@ -0,0 +1,35 @@
#ifndef __UIOBJECTFACTORY_H__
#define __UIOBJECTFACTORY_H__
#include "cocos2d.h"
#include "FairyGUIMacros.h"
#include "GComponent.h"
#include "PackageItem.h"
#include "GLoader.h"
NS_FGUI_BEGIN
class UIObjectFactory
{
public:
typedef std::function<GComponent*()> GComponentCreator;
typedef std::function<GLoader*()> GLoaderCreator;
static void setPackageItemExtension(const std::string& url, GComponentCreator creator);
static GObject* newObject(PackageItem* pi);
static GObject* newObject(ObjectType type);
static void setLoaderExtension(GLoaderCreator creator);
private:
static void resolvePackageItemExtension(PackageItem* pi);
static std::unordered_map<std::string, GComponentCreator> _packageItemExtensions;
static GLoaderCreator _loaderCreator;
friend class UIPackage;
};
NS_FGUI_END
#endif

View File

@ -0,0 +1,884 @@
#include "UIPackage.h"
#include "UIObjectFactory.h"
#include "display/BitmapFont.h"
#include "event/HitTest.h"
#include "utils/ByteBuffer.h"
#include "utils/ToolSet.h"
NS_FGUI_BEGIN
USING_NS_CC;
using namespace std;
const string UIPackage::URL_PREFIX = "ui://";
int UIPackage::_constructing = 0;
std::string UIPackage::_branch;
std::unordered_map<std::string, std::string> UIPackage::_vars;
const unsigned char* emptyTextureData = new unsigned char[16]{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
std::unordered_map<std::string, UIPackage*> UIPackage::_packageInstById;
std::unordered_map<std::string, UIPackage*> UIPackage::_packageInstByName;
std::vector<UIPackage*> UIPackage::_packageList;
Texture2D* UIPackage::_emptyTexture;
struct AtlasSprite
{
PackageItem* atlas;
Rect rect;
Size originalSize;
Vec2 offset;
bool rotated;
};
UIPackage::UIPackage()
: _branchIndex(-1)
{
}
UIPackage::~UIPackage()
{
for (auto& it : _items)
it->release();
for (auto& it : _sprites)
delete it.second;
}
void UIPackage::setBranch(const std::string& value)
{
_branch = value;
for (auto& it : _packageList)
{
if (it->_branches.size() > 0)
{
it->_branchIndex = ToolSet::findInStringArray(it->_branches, value);
}
}
}
const std::string& UIPackage::getVar(const std::string& key)
{
auto it = _vars.find(key);
if (it != _vars.end())
return it->second;
else
return STD_STRING_EMPTY;
}
void UIPackage::setVar(const std::string& key, const std::string& value)
{
_vars[key] = value;
}
UIPackage* UIPackage::getById(const string& id)
{
auto it = _packageInstById.find(id);
if (it != _packageInstById.end())
return it->second;
else
return nullptr;
}
UIPackage* UIPackage::getByName(const string& name)
{
auto it = _packageInstByName.find(name);
if (it != _packageInstByName.end())
return it->second;
else
return nullptr;
}
UIPackage* UIPackage::addPackage(const string& assetPath)
{
auto it = _packageInstById.find(assetPath);
if (it != _packageInstById.end())
return it->second;
if (_emptyTexture == nullptr)
{
Image* emptyImage = new Image();
emptyImage->initWithRawData(emptyTextureData, 16, 2, 2, 4, false);
_emptyTexture = new Texture2D();
_emptyTexture->initWithImage(emptyImage);
delete emptyImage;
}
Data data;
if (FileUtils::getInstance()->getContents(assetPath + ".fui", &data) != FileUtils::Status::OK)
{
CCLOGERROR("FairyGUI: cannot load package from '%s'", assetPath.c_str());
return nullptr;
}
ssize_t size;
char* p = (char*)data.takeBuffer(&size);
ByteBuffer buffer(p, 0, (int)size, true);
UIPackage* pkg = new UIPackage();
pkg->_assetPath = assetPath;
if (!pkg->loadPackage(&buffer))
{
delete pkg;
return nullptr;
}
_packageInstById[pkg->getId()] = pkg;
_packageInstByName[pkg->getName()] = pkg;
_packageInstById[assetPath] = pkg;
_packageList.push_back(pkg);
return pkg;
}
void UIPackage::removePackage(const string& packageIdOrName)
{
UIPackage* pkg = UIPackage::getByName(packageIdOrName);
if (!pkg)
pkg = getById(packageIdOrName);
if (pkg)
{
auto it = std::find(_packageList.cbegin(), _packageList.cend(), pkg);
if (it != _packageList.cend())
_packageList.erase(it);
_packageInstById.erase(pkg->getId());
_packageInstById.erase(pkg->_assetPath);
_packageInstByName.erase(pkg->getName());
pkg->release();
}
else
CCLOGERROR("FairyGUI: invalid package name or id: %s", packageIdOrName.c_str());
}
void UIPackage::removeAllPackages()
{
for (auto& it : _packageList)
it->release();
_packageInstById.clear();
_packageInstByName.clear();
_packageList.clear();
}
GObject* UIPackage::createObject(const string& pkgName, const string& resName)
{
UIPackage* pkg = UIPackage::getByName(pkgName);
if (pkg)
return pkg->createObject(resName);
else
{
CCLOGERROR("FairyGUI: package not found - %s", pkgName.c_str());
return nullptr;
}
}
GObject* UIPackage::createObjectFromURL(const string& url)
{
PackageItem* pi = UIPackage::getItemByURL(url);
if (pi)
return pi->owner->createObject(pi);
else
{
CCLOGERROR("FairyGUI: resource not found - %s", url.c_str());
return nullptr;
}
}
string UIPackage::getItemURL(const string& pkgName, const string& resName)
{
UIPackage* pkg = UIPackage::getByName(pkgName);
if (pkg)
{
PackageItem* pi = pkg->getItemByName(resName);
if (pi)
return URL_PREFIX + pkg->getId() + pi->id;
}
return STD_STRING_EMPTY;
}
PackageItem* UIPackage::getItemByURL(const string& url)
{
if (url.size() == 0)
return nullptr;
ssize_t pos1 = url.find('/');
if (pos1 == -1)
return nullptr;
ssize_t pos2 = url.find('/', pos1 + 2);
if (pos2 == -1)
{
if (url.size() > 13)
{
string pkgId = url.substr(5, 8);
UIPackage* pkg = getById(pkgId);
if (pkg != nullptr)
{
string srcId = url.substr(13);
return pkg->getItem(srcId);
}
}
}
else
{
string pkgName = url.substr(pos1 + 2, pos2 - pos1 - 2);
UIPackage* pkg = getByName(pkgName);
if (pkg != nullptr)
{
string srcName = url.substr(pos2 + 1);
return pkg->getItemByName(srcName);
}
}
return nullptr;
}
string UIPackage::normalizeURL(const string& url)
{
if (url.size() == 0)
return url;
ssize_t pos1 = url.find('/');
if (pos1 == -1)
return url;
ssize_t pos2 = url.find('/', pos1 + 2);
if (pos2 == -1)
return url;
else
{
string pkgName = url.substr(pos1 + 2, pos2 - pos1 - 2);
string srcName = url.substr(pos2 + 1);
return getItemURL(pkgName, srcName);
}
}
void* UIPackage::getItemAsset(const std::string& pkgName, const std::string& resName, PackageItemType type)
{
UIPackage* pkg = UIPackage::getByName(pkgName);
if (pkg)
{
PackageItem* pi = pkg->getItemByName(resName);
if (pi)
{
if (type != PackageItemType::UNKNOWN && pi->type != type)
return nullptr;
else
return pkg->getItemAsset(pi);
}
}
return nullptr;
}
void* UIPackage::getItemAssetByURL(const std::string& url, PackageItemType type)
{
PackageItem* pi = UIPackage::getItemByURL(url);
if (pi)
{
if (type != PackageItemType::UNKNOWN && pi->type != type)
return nullptr;
else
return pi->owner->getItemAsset(pi);
}
else
return nullptr;
}
PackageItem* UIPackage::getItem(const string& itemId)
{
auto it = _itemsById.find(itemId);
if (it != _itemsById.end())
return it->second;
else
return nullptr;
}
PackageItem* UIPackage::getItemByName(const string& itemName)
{
auto it = _itemsByName.find(itemName);
if (it != _itemsByName.end())
return it->second;
else
return nullptr;
}
GObject* UIPackage::createObject(const string& resName)
{
PackageItem* pi = getItemByName(resName);
CCASSERT(pi, StringUtils::format("FairyGUI: resource not found - %s in %s",
resName.c_str(), _name.c_str())
.c_str());
return createObject(pi);
}
GObject* UIPackage::createObject(PackageItem* item)
{
GObject* g = UIObjectFactory::newObject(item);
if (g == nullptr)
return nullptr;
_constructing++;
g->constructFromResource();
_constructing--;
return g;
}
bool UIPackage::loadPackage(ByteBuffer* buffer)
{
if (buffer->readUint() != 0x46475549)
{
CCLOGERROR("FairyGUI: old package format found in '%s'", _assetPath.c_str());
return false;
}
buffer->version = buffer->readInt();
bool ver2 = buffer->version >= 2;
buffer->readBool(); //compressed
_id = buffer->readString();
_name = buffer->readString();
buffer->skip(20);
int indexTablePos = buffer->getPos();
int cnt;
buffer->seek(indexTablePos, 4);
cnt = buffer->readInt();
_stringTable.resize(cnt);
for (int i = 0; i < cnt; i++)
_stringTable[i] = buffer->readString();
buffer->setStringTable(&_stringTable);
buffer->seek(indexTablePos, 0);
cnt = buffer->readShort();
for (int i = 0; i < cnt; i++)
{
std::unordered_map<std::string, std::string> info;
info["id"] = buffer->readS();
info["name"] = buffer->readS();
_dependencies.push_back(info);
}
bool branchIncluded = false;
if (ver2)
{
cnt = buffer->readShort();
if (cnt > 0)
{
buffer->readSArray(_branches, cnt);
if (_branch.size() > 0)
_branchIndex = ToolSet::findInStringArray(_branches, _branch);
}
branchIncluded = cnt > 0;
}
buffer->seek(indexTablePos, 1);
PackageItem* pi;
string path = _assetPath;
size_t pos = path.find('/');
string shortPath = pos == -1 ? STD_STRING_EMPTY : path.substr(0, pos + 1);
path += "_";
cnt = buffer->readShort();
for (int i = 0; i < cnt; i++)
{
int nextPos = buffer->readInt();
nextPos += buffer->getPos();
pi = new PackageItem();
pi->owner = this;
pi->type = (PackageItemType)buffer->readByte();
pi->id = buffer->readS();
pi->name = buffer->readS();
buffer->skip(2); //path
pi->file = buffer->readS();
buffer->readBool(); //exported
pi->width = buffer->readInt();
pi->height = buffer->readInt();
switch (pi->type)
{
case PackageItemType::IMAGE:
{
pi->objectType = ObjectType::IMAGE;
int scaleOption = buffer->readByte();
if (scaleOption == 1)
{
pi->scale9Grid = new Rect();
pi->scale9Grid->origin.x = buffer->readInt();
pi->scale9Grid->origin.y = buffer->readInt();
pi->scale9Grid->size.width = buffer->readInt();
pi->scale9Grid->size.height = buffer->readInt();
pi->tileGridIndice = buffer->readInt();
}
else if (scaleOption == 2)
pi->scaleByTile = true;
buffer->readBool(); //smoothing
break;
}
case PackageItemType::MOVIECLIP:
{
buffer->readBool(); //smoothing
pi->objectType = ObjectType::MOVIECLIP;
pi->rawData = buffer->readBuffer();
break;
}
case PackageItemType::FONT:
{
pi->rawData = buffer->readBuffer();
break;
}
case PackageItemType::COMPONENT:
{
int extension = buffer->readByte();
if (extension > 0)
pi->objectType = (ObjectType)extension;
else
pi->objectType = ObjectType::COMPONENT;
pi->rawData = buffer->readBuffer();
UIObjectFactory::resolvePackageItemExtension(pi);
break;
}
case PackageItemType::ATLAS:
case PackageItemType::SOUND:
case PackageItemType::MISC:
{
pi->file = path + pi->file;
break;
}
case PackageItemType::SPINE:
case PackageItemType::DRAGONBONES:
{
pi->file = shortPath + pi->file;
pi->skeletonAnchor = new Vec2();
pi->skeletonAnchor->x = buffer->readFloat();
pi->skeletonAnchor->y = buffer->readFloat();
break;
}
default:
break;
}
if (ver2)
{
std::string str = buffer->readS(); //branch
if (!str.empty())
pi->name = str + "/" + pi->name;
int branchCnt = buffer->readUbyte();
if (branchCnt > 0)
{
if (branchIncluded)
{
pi->branches = new std::vector<std::string>();
buffer->readSArray(*pi->branches, branchCnt);
}
else
_itemsById[buffer->readS()] = pi;
}
int highResCnt = buffer->readUbyte();
if (highResCnt > 0)
{
pi->highResolution = new std::vector<std::string>();
buffer->readSArray(*pi->highResolution, highResCnt);
}
}
_items.push_back(pi);
_itemsById[pi->id] = pi;
if (!pi->name.empty())
_itemsByName[pi->name] = pi;
buffer->setPos(nextPos);
}
buffer->seek(indexTablePos, 2);
cnt = buffer->readShort();
for (int i = 0; i < cnt; i++)
{
int nextPos = buffer->readShort();
nextPos += buffer->getPos();
const string& itemId = buffer->readS();
pi = _itemsById[buffer->readS()];
AtlasSprite* sprite = new AtlasSprite();
sprite->atlas = pi;
sprite->rect.origin.x = buffer->readInt();
sprite->rect.origin.y = buffer->readInt();
sprite->rect.size.width = buffer->readInt();
sprite->rect.size.height = buffer->readInt();
sprite->rotated = buffer->readBool();
if (ver2 && buffer->readBool())
{
sprite->offset.x = buffer->readInt();
sprite->offset.y = buffer->readInt();
sprite->originalSize.width = buffer->readInt();
sprite->originalSize.height = buffer->readInt();
}
else
{
sprite->offset.setZero();
sprite->originalSize.width = sprite->rect.size.width;
sprite->originalSize.height = sprite->rect.size.height;
}
_sprites[itemId] = sprite;
buffer->setPos(nextPos);
}
if (buffer->seek(indexTablePos, 3))
{
cnt = buffer->readShort();
for (int i = 0; i < cnt; i++)
{
int nextPos = buffer->readInt();
nextPos += buffer->getPos();
auto it = _itemsById.find(buffer->readS());
if (it != _itemsById.end())
{
pi = it->second;
if (pi->type == PackageItemType::IMAGE)
{
pi->pixelHitTestData = new PixelHitTestData();
pi->pixelHitTestData->load(buffer);
}
}
buffer->setPos(nextPos);
}
}
return true;
}
void* UIPackage::getItemAsset(PackageItem* item)
{
switch (item->type)
{
case PackageItemType::IMAGE:
if (item->spriteFrame == nullptr)
loadImage(item);
return item->spriteFrame;
case PackageItemType::ATLAS:
if (item->texture == nullptr)
loadAtlas(item);
return item->texture;
case PackageItemType::FONT:
if (item->bitmapFont == nullptr)
loadFont(item);
return item->bitmapFont;
case PackageItemType::MOVIECLIP:
if (item->animation == nullptr)
loadMovieClip(item);
return item->animation;
default:
return nullptr;
}
}
void UIPackage::loadAtlas(PackageItem* item)
{
Image* image = new Image();
#if COCOS2D_VERSION < 0x00031702
Image::setPNGPremultipliedAlphaEnabled(false);
#endif
if (!image->initWithImageFile(item->file))
{
item->texture = _emptyTexture;
_emptyTexture->retain();
delete image;
#if COCOS2D_VERSION < 0x00031702
Image::setPNGPremultipliedAlphaEnabled(true);
#endif
CCLOGWARN("FairyGUI: texture '%s' not found in %s", item->file.c_str(), _name.c_str());
return;
}
#if COCOS2D_VERSION < 0x00031702
Image::setPNGPremultipliedAlphaEnabled(true);
#endif
Texture2D* tex = new Texture2D();
tex->initWithImage(image);
item->texture = tex;
delete image;
string alphaFilePath;
string ext = FileUtils::getInstance()->getFileExtension(item->file);
size_t pos = item->file.find_last_of('.');
if (pos != -1)
alphaFilePath = item->file.substr(0, pos) + "!a" + ext;
else
alphaFilePath = item->file + "!a" + ext;
bool hasAlphaTexture = ToolSet::isFileExist(alphaFilePath);
if (hasAlphaTexture)
{
image = new Image();
if (!image->initWithImageFile(alphaFilePath))
{
delete image;
return;
}
#if defined(ENGINEX_VERSION)
if(image->getFileType() == Image::Format::ETC)
tex->updateWithImage(image, Texture2D::getDefaultAlphaPixelFormat(), 1, TextureFormatEXT::ETC1_ALPHA);
#else
tex = new Texture2D();
tex->initWithImage(image);
item->texture->setAlphaTexture(tex);
tex->release();
#endif
delete image;
}
}
AtlasSprite* UIPackage::getSprite(const std::string& spriteId)
{
auto it = _sprites.find(spriteId);
if (it != _sprites.end())
return it->second;
else
return nullptr;
}
//note: SpriteFrame.ref=1 not autorelease.
SpriteFrame* UIPackage::createSpriteTexture(AtlasSprite* sprite)
{
getItemAsset(sprite->atlas);
//not using createWithTexture for saving a autorelease call.
SpriteFrame* spriteFrame = new SpriteFrame();
spriteFrame->initWithTexture(sprite->atlas->texture, sprite->rect, sprite->rotated,
Vec2(sprite->offset.x - (sprite->originalSize.width - sprite->rect.size.width) / 2, -(sprite->offset.y - (sprite->originalSize.height - sprite->rect.size.height) / 2)),
sprite->originalSize);
return spriteFrame;
}
void UIPackage::loadImage(PackageItem* item)
{
AtlasSprite* sprite = getSprite(item->id);
if (sprite != nullptr)
item->spriteFrame = createSpriteTexture(sprite);
else
{
item->spriteFrame = new (std::nothrow) SpriteFrame();
item->spriteFrame->initWithTexture(_emptyTexture, Rect());
}
if (item->scaleByTile)
{
#if COCOS2D_VERSION >= 0x00040000
Texture2D::TexParams tp(backend::SamplerFilter::LINEAR, backend::SamplerFilter::LINEAR,
backend::SamplerAddressMode::REPEAT, backend::SamplerAddressMode::REPEAT);
#else
Texture2D::TexParams tp = { GL_LINEAR, GL_LINEAR, GL_REPEAT, GL_REPEAT };
#endif
item->spriteFrame->getTexture()->setTexParameters(tp);
}
}
void UIPackage::loadMovieClip(PackageItem* item)
{
item->animation = Animation::create();
item->animation->retain();
ByteBuffer* buffer = item->rawData;
buffer->seek(0, 0);
float interval = buffer->readInt() / 1000.0f;
item->swing = buffer->readBool();
item->repeatDelay = buffer->readInt() / 1000.0f;
buffer->seek(0, 1);
int frameCount = buffer->readShort();
Vector<AnimationFrame*> frames(frameCount);
Size mcSizeInPixels = Size(item->width, item->height);
Size mcSize = CC_SIZE_PIXELS_TO_POINTS(mcSizeInPixels);
AtlasSprite* sprite;
SpriteFrame* spriteFrame;
for (int i = 0; i < frameCount; i++)
{
int nextPos = buffer->readShort();
nextPos += buffer->getPos();
Rect rect;
rect.origin.x = buffer->readInt();
rect.origin.y = buffer->readInt();
rect.size.width = buffer->readInt();
rect.size.height = buffer->readInt();
float addDelay = buffer->readInt() / 1000.0f;
const string& spriteId = buffer->readS();
if (!spriteId.empty() && (sprite = getSprite(spriteId)) != nullptr)
{
spriteFrame = createSpriteTexture(sprite);
spriteFrame->setOriginalSizeInPixels(mcSizeInPixels);
spriteFrame->setOriginalSize(mcSize);
}
else
{
//dont use createWithTexture
spriteFrame = new (std::nothrow) SpriteFrame();
spriteFrame->initWithTexture(_emptyTexture, Rect());
}
spriteFrame->setOffset(Vec2(rect.origin.x - (mcSize.width - rect.size.width) / 2, -(rect.origin.y - (mcSize.height - rect.size.height) / 2)));
AnimationFrame* frame = AnimationFrame::create(spriteFrame, addDelay / interval + 1, ValueMapNull);
frames.pushBack(frame);
//tranfer to AnimationFrame
spriteFrame->release();
buffer->setPos(nextPos);
}
item->animation->initWithAnimationFrames(frames, interval, 1);
delete buffer;
item->rawData = nullptr;
}
void UIPackage::loadFont(PackageItem* item)
{
item->bitmapFont = BitmapFont::create();
FontAtlas* fontAtlas = new FontAtlas(*item->bitmapFont);
item->bitmapFont->_fontAtlas = fontAtlas;
ByteBuffer* buffer = item->rawData;
buffer->seek(0, 0);
bool ttf = buffer->readBool();
item->bitmapFont->_canTint = buffer->readBool();
item->bitmapFont->_resizable = buffer->readBool();
buffer->readBool(); //hasChannel
int fontSize = buffer->readInt();
int xadvance = buffer->readInt();
int lineHeight = buffer->readInt();
Texture2D* mainTexture = nullptr;
AtlasSprite* mainSprite = nullptr;
if (ttf && (mainSprite = getSprite(item->id)) != nullptr)
mainTexture = (Texture2D*)getItemAsset(mainSprite->atlas);
buffer->seek(0, 1);
FontLetterDefinition def;
int bx = 0, by = 0;
int bw = 0, bh = 0;
PackageItem* charImg = nullptr;
int cnt = buffer->readInt();
for (int i = 0; i < cnt; i++)
{
int nextPos = buffer->readShort();
nextPos += buffer->getPos();
memset(&def, 0, sizeof(def));
unsigned short ch = buffer->readUshort();
const string& img = buffer->readS();
bx = buffer->readInt();
by = buffer->readInt();
def.offsetX = buffer->readInt();
def.offsetY = buffer->readInt();
bw = buffer->readInt();
bh = buffer->readInt();
def.xAdvance = buffer->readInt();
buffer->readByte(); //channel
if (ttf)
{
Rect tempRect = Rect(bx + mainSprite->rect.origin.x, by + mainSprite->rect.origin.y, bw, bh);
tempRect = CC_RECT_PIXELS_TO_POINTS(tempRect);
def.U = tempRect.origin.x;
def.V = tempRect.origin.y;
def.width = tempRect.size.width;
def.height = tempRect.size.height;
def.validDefinition = true;
}
else
{
charImg = getItem(img);
if (charImg)
{
charImg = charImg->getBranch();
bw = charImg->width;
bh = charImg->height;
AtlasSprite* sprite = getSprite(img);
if (sprite != nullptr)
{
def.offsetX += sprite->offset.x;
def.offsetY += sprite->offset.y;
}
charImg = charImg->getHighResolution();
getItemAsset(charImg);
Rect tempRect = charImg->spriteFrame->getRectInPixels();
tempRect = CC_RECT_PIXELS_TO_POINTS(tempRect);
def.U = tempRect.origin.x;
def.V = tempRect.origin.y;
def.width = tempRect.size.width;
def.height = tempRect.size.height;
if (mainTexture == nullptr)
mainTexture = charImg->spriteFrame->getTexture();
def.validDefinition = true;
if (def.xAdvance == 0)
{
if (xadvance == 0)
def.xAdvance = def.offsetX + bw;
else
def.xAdvance = xadvance;
}
if (fontSize == 0)
fontSize = bh;
lineHeight = MAX(fontSize, lineHeight);
}
}
fontAtlas->addLetterDefinition(ch, def);
buffer->setPos(nextPos);
}
if (mainTexture != nullptr)
fontAtlas->addTexture(mainTexture, 0);
fontAtlas->setLineHeight(lineHeight);
item->bitmapFont->_originalFontSize = fontSize;
delete buffer;
item->rawData = nullptr;
}
NS_FGUI_END

View File

@ -0,0 +1,89 @@
#ifndef __UIPACKAGE_H__
#define __UIPACKAGE_H__
#include "FairyGUIMacros.h"
#include "GObject.h"
#include "PackageItem.h"
#include "cocos2d.h"
NS_FGUI_BEGIN
struct AtlasSprite;
class ByteBuffer;
class UIPackage : public cocos2d::Ref
{
public:
UIPackage();
~UIPackage();
static UIPackage* getById(const std::string& id);
static UIPackage* getByName(const std::string& name);
static UIPackage* addPackage(const std::string& descFilePath);
static void removePackage(const std::string& packageIdOrName);
static void removeAllPackages();
static GObject* createObject(const std::string& pkgName, const std::string& resName);
static GObject* createObjectFromURL(const std::string& url);
static std::string getItemURL(const std::string& pkgName, const std::string& resName);
static PackageItem* getItemByURL(const std::string& url);
static std::string normalizeURL(const std::string& url);
static void* getItemAsset(const std::string& pkgName, const std::string& resName, PackageItemType type = PackageItemType::UNKNOWN);
static void* getItemAssetByURL(const std::string& url, PackageItemType type = PackageItemType::UNKNOWN);
static cocos2d::Texture2D* getEmptyTexture() { return _emptyTexture; }
const std::string& getId() const { return _id; }
const std::string& getName() const { return _name; }
PackageItem* getItem(const std::string& itemId);
PackageItem* getItemByName(const std::string& itemName);
void* getItemAsset(PackageItem* item);
static const std::string& getBranch() { return _branch; }
static void setBranch(const std::string& value);
static const std::string& getVar(const std::string& key);
static void setVar(const std::string& key, const std::string& value);
static int _constructing;
static const std::string URL_PREFIX;
private:
bool loadPackage(ByteBuffer* buffer);
void loadAtlas(PackageItem* item);
AtlasSprite* getSprite(const std::string& spriteId);
cocos2d::SpriteFrame* createSpriteTexture(AtlasSprite* sprite);
void loadImage(PackageItem* item);
void loadMovieClip(PackageItem* item);
void loadFont(PackageItem* item);
GObject* createObject(const std::string& resName);
GObject* createObject(PackageItem* item);
private:
std::string _id;
std::string _name;
std::string _assetPath;
std::vector<PackageItem*> _items;
std::unordered_map<std::string, PackageItem*> _itemsById;
std::unordered_map<std::string, PackageItem*> _itemsByName;
std::unordered_map<std::string, AtlasSprite*> _sprites;
std::string _customId;
std::vector<std::string> _stringTable;
std::vector<std::unordered_map<std::string, std::string>> _dependencies;
std::vector<std::string> _branches;
int _branchIndex;
static std::unordered_map<std::string, UIPackage*> _packageInstById;
static std::unordered_map<std::string, UIPackage*> _packageInstByName;
static std::vector<UIPackage*> _packageList;
static std::unordered_map<std::string, std::string> _vars;
static std::string _branch;
static cocos2d::Texture2D* _emptyTexture;
friend class PackageItem;
};
NS_FGUI_END
#endif

View File

@ -0,0 +1,296 @@
#include "Window.h"
#include "GRoot.h"
#include "UIPackage.h"
#include "UIConfig.h"
NS_FGUI_BEGIN
USING_NS_CC;
Window::Window() :
_requestingCmd(0),
_frame(nullptr),
_contentPane(nullptr),
_modalWaitPane(nullptr),
_closeButton(nullptr),
_dragArea(nullptr),
_contentArea(nullptr),
_modal(false),
_inited(false),
_loading(false)
{
_bringToFontOnClick = UIConfig::bringWindowToFrontOnClick;
}
Window::~Window()
{
CC_SAFE_RELEASE(_contentPane);
CC_SAFE_RELEASE(_frame);
CC_SAFE_RELEASE(_closeButton);
CC_SAFE_RELEASE(_dragArea);
CC_SAFE_RELEASE(_modalWaitPane);
}
void Window::handleInit()
{
GComponent::handleInit();
addEventListener(UIEventType::TouchBegin, CC_CALLBACK_1(Window::onTouchBegin, this));
}
void Window::setContentPane(GComponent* value)
{
if (_contentPane != value)
{
if (_contentPane != nullptr)
{
removeChild(_contentPane);
CC_SAFE_RELEASE(_frame);
_contentPane->release();
}
_contentPane = value;
if (_contentPane != nullptr)
{
_contentPane->retain();
addChild(_contentPane);
setSize(_contentPane->getWidth(), _contentPane->getHeight());
_contentPane->addRelation(this, RelationType::Size);
_frame = dynamic_cast<GComponent*>(_contentPane->getChild("frame"));
if (_frame != nullptr)
{
_frame->retain();
setCloseButton(_frame->getChild("closeButton"));
setDragArea(_frame->getChild("dragArea"));
setContentArea(_frame->getChild("contentArea"));
}
}
else
_frame = nullptr;
}
}
void Window::setCloseButton(GObject * value)
{
if (_closeButton != nullptr)
{
_closeButton->removeClickListener(EventTag(this));
_closeButton->release();
}
_closeButton = value;
if (_closeButton != nullptr)
{
_closeButton->retain();
_closeButton->addClickListener(CC_CALLBACK_1(Window::closeEventHandler, this), EventTag(this));
}
}
void Window::setDragArea(GObject * value)
{
if (_dragArea != value)
{
if (_dragArea != nullptr)
{
_dragArea->setDraggable(false);
_dragArea->removeEventListener(UIEventType::DragStart, EventTag(this));
_dragArea->release();
}
_dragArea = value;
if (_dragArea != nullptr)
{
_dragArea->retain();
if (dynamic_cast<GGraph*>(_dragArea) && ((GGraph*)_dragArea)->isEmpty())
((GGraph*)_dragArea)->drawRect(_dragArea->getWidth(), _dragArea->getHeight(), 0, Color4F(0, 0, 0, 0), Color4F(0, 0, 0, 0));
_dragArea->setDraggable(true);
_dragArea->addEventListener(UIEventType::DragStart, CC_CALLBACK_1(Window::onDragStart, this), EventTag(this));
}
}
}
void Window::show()
{
UIRoot->showWindow(this);
}
void Window::hide()
{
if (isShowing())
doHideAnimation();
}
void Window::hideImmediately()
{
UIRoot->hideWindowImmediately(this);
}
void Window::toggleStatus()
{
if (isTop())
hide();
else
show();
}
void Window::bringToFront()
{
UIRoot->bringToFront(this);
}
bool Window::isTop() const
{
return _parent != nullptr && _parent->getChildIndex(this) == _parent->numChildren() - 1;
}
void Window::showModalWait(int requestingCmd)
{
if (requestingCmd != 0)
_requestingCmd = requestingCmd;
if (!UIConfig::windowModalWaiting.empty())
{
if (_modalWaitPane == nullptr)
{
_modalWaitPane = UIPackage::createObjectFromURL(UIConfig::windowModalWaiting);
_modalWaitPane->retain();
}
layoutModalWaitPane();
addChild(_modalWaitPane);
}
}
void Window::layoutModalWaitPane()
{
if (_contentArea != nullptr)
{
Vec2 pt = _frame->localToGlobal(Vec2::ZERO);
pt = globalToLocal(pt);
_modalWaitPane->setPosition((int)pt.x + _contentArea->getX(), (int)pt.y + _contentArea->getY());
_modalWaitPane->setSize(_contentArea->getWidth(), _contentArea->getHeight());
}
else
_modalWaitPane->setSize(_size.width, _size.height);
}
bool Window::closeModalWait(int requestingCmd)
{
if (requestingCmd != 0)
{
if (_requestingCmd != requestingCmd)
return false;
}
_requestingCmd = 0;
if (_modalWaitPane != nullptr && _modalWaitPane->getParent() != nullptr)
removeChild(_modalWaitPane);
return true;
}
void Window::initWindow()
{
if (_inited || _loading)
return;
if (!_uiSources.empty())
{
_loading = false;
int cnt = (int)_uiSources.size();
for (int i = 0; i < cnt; i++)
{
IUISource* lib = _uiSources.at(i);
if (!lib->isLoaded())
{
lib->load(CC_CALLBACK_0(Window::onUILoadComplete, this));
_loading = true;
}
}
if (!_loading)
_initWindow();
}
else
_initWindow();
}
void Window::_initWindow()
{
_inited = true;
onInit();
if (isShowing())
doShowAnimation();
}
void Window::addUISource(IUISource * uiSource)
{
_uiSources.pushBack(uiSource);
}
void Window::doShowAnimation()
{
onShown();
}
void Window::doHideAnimation()
{
hideImmediately();
}
void Window::closeEventHandler(EventContext * context)
{
hide();
}
void Window::onUILoadComplete()
{
int cnt = (int)_uiSources.size();
for (int i = 0; i < cnt; i++)
{
IUISource* lib = _uiSources.at(i);
if (!lib->isLoaded())
return;
}
_loading = false;
_initWindow();
}
void Window::onEnter()
{
GComponent::onEnter();
if (!_inited)
initWindow();
else
doShowAnimation();
}
void Window::onExit()
{
GComponent::onExit();
closeModalWait();
onHide();
}
void Window::onTouchBegin(EventContext * context)
{
if (isShowing() && _bringToFontOnClick)
{
bringToFront();
}
}
void Window::onDragStart(EventContext * context)
{
context->preventDefault();
startDrag(context->getInput()->getTouchId());
}
NS_FGUI_END

View File

@ -0,0 +1,99 @@
#ifndef __WINDOW_H__
#define __WINDOW_H__
#include "FairyGUIMacros.h"
#include "cocos2d.h"
#include "GComponent.h"
NS_FGUI_BEGIN
class IUISource : public cocos2d::Ref
{
public:
virtual const std::string& getFileName() = 0;
virtual void setFileName(const std::string& value) = 0;
virtual bool isLoaded() = 0;
virtual void load(std::function<void()> callback) = 0;
};
class Window : public GComponent
{
public:
Window();
virtual ~Window();
CREATE_FUNC(Window);
void show();
void hide();
void hideImmediately();
void toggleStatus();
void bringToFront();
bool isShowing() const { return _parent != nullptr; }
bool isTop() const;
bool isModal() const { return _modal; }
void setModal(bool value) { _modal = value; }
void showModalWait() { showModalWait(0); }
void showModalWait(int requestingCmd);
bool closeModalWait() { return closeModalWait(0); }
bool closeModalWait(int requestingCmd);
void initWindow();
void addUISource(IUISource* uiSource);
bool isBringToFrontOnClick() { return _bringToFontOnClick; }
void setBringToFrontOnClick(bool value) { _bringToFontOnClick = value; }
GComponent* getContentPane() const { return _contentPane; }
void setContentPane(GComponent* value);
GComponent* getFrame() const { return _frame; }
GObject* getCloseButton() const { return _closeButton; }
void setCloseButton(GObject* value);
GObject* getDragArea() const { return _dragArea; }
void setDragArea(GObject* value);
GObject* getContentArea() const { return _contentArea; }
void setContentArea(GObject* value) { _contentArea = value; }
GObject* getModalWaitingPane() const { return _modalWaitPane; }
protected:
virtual void handleInit() override;
virtual void onInit() {};
virtual void onShown() {};
virtual void onHide() {};
virtual void doShowAnimation();
virtual void doHideAnimation();
virtual void onEnter() override;
virtual void onExit() override;
void closeEventHandler(EventContext*context);
GComponent* _contentPane;
private:
void layoutModalWaitPane();
void onUILoadComplete();
void _initWindow();
void onTouchBegin(EventContext* context);
void onDragStart(EventContext* context);
int _requestingCmd;
GComponent* _frame;
GObject* _modalWaitPane;
GObject* _closeButton;
GObject* _dragArea;
GObject* _contentArea;
bool _modal;
bool _bringToFontOnClick;
cocos2d::Vector<IUISource*> _uiSources;
bool _inited;
bool _loading;
};
NS_FGUI_END
#endif

View File

@ -0,0 +1,50 @@
#include "ChangePageAction.h"
#include "Controller.h"
#include "GComponent.h"
#include "utils/ByteBuffer.h"
NS_FGUI_BEGIN
USING_NS_CC;
void ChangePageAction::setup(ByteBuffer* buffer)
{
ControllerAction::setup(buffer);
objectId = buffer->readS();
controllerName = buffer->readS();
targetPage = buffer->readS();
}
void ChangePageAction::enter(GController* controller)
{
if (controllerName.empty())
return;
GComponent* gcom;
if (!objectId.empty())
gcom = controller->getParent()->getChildById(objectId)->as<GComponent>();
else
gcom = controller->getParent();
if (gcom != nullptr)
{
GController* cc = gcom->getController(controllerName);
if (cc != nullptr && cc != controller && !cc->changing)
{
if (targetPage.compare("~1") == 0)
{
if (controller->getSelectedIndex() < cc->getPageCount())
cc->setSelectedIndex(controller->getSelectedIndex());
}
else if (targetPage.compare("~2") == 0)
cc->setSelectedPage(controller->getSelectedPage());
else
cc->setSelectedPageId(targetPage);
}
}
}
void ChangePageAction::leave(GController* controller)
{
}
NS_FGUI_END

View File

@ -0,0 +1,24 @@
#ifndef __CHANGEPAGEACTION_H__
#define __CHANGEPAGEACTION_H__
#include "ControllerAction.h"
NS_FGUI_BEGIN
class ChangePageAction : public ControllerAction
{
public:
virtual void setup(ByteBuffer * buffer) override;
std::string objectId;
std::string controllerName;
std::string targetPage;
protected:
virtual void enter(GController* controller) override;
virtual void leave(GController* controller) override;
};
NS_FGUI_END
#endif

View File

@ -0,0 +1,56 @@
#include "ControllerAction.h"
#include "Controller.h"
#include "ChangePageAction.h"
#include "PlayTransitionAction.h"
#include "utils/ByteBuffer.h"
#include "utils/ToolSet.h"
NS_FGUI_BEGIN
USING_NS_CC;
ControllerAction * ControllerAction::createAction(int type)
{
switch (type)
{
case 0:
return new PlayTransitionAction();
case 1:
return new ChangePageAction();
}
return nullptr;
}
ControllerAction::ControllerAction()
{
}
ControllerAction::~ControllerAction()
{
}
void ControllerAction::run(GController * controller, const std::string & prevPage, const std::string & curPage)
{
if ((fromPage.empty() || std::find(fromPage.cbegin(), fromPage.cend(), prevPage) != fromPage.cend())
&& (toPage.empty() || std::find(toPage.cbegin(), toPage.cend(), curPage) != toPage.cend()))
enter(controller);
else
leave(controller);
}
void ControllerAction::setup(ByteBuffer * buffer)
{
int cnt;
cnt = buffer->readShort();
fromPage.resize(cnt);
for (int i = 0; i < cnt; i++)
fromPage[i].assign(buffer->readS());
cnt = buffer->readShort();
toPage.resize(cnt);
for (int i = 0; i < cnt; i++)
toPage[i].assign(buffer->readS());
}
NS_FGUI_END

View File

@ -0,0 +1,33 @@
#ifndef __CONTROLLERACTION_H__
#define __CONTROLLERACTION_H__
#include "FairyGUIMacros.h"
#include "cocos2d.h"
NS_FGUI_BEGIN
class GController;
class ByteBuffer;
class ControllerAction
{
public:
static ControllerAction* createAction(int types);
ControllerAction();
virtual ~ControllerAction();
void run(GController* controller, const std::string& prevPage, const std::string& curPage);
virtual void setup(ByteBuffer * buffer);
std::vector<std::string> fromPage;
std::vector<std::string> toPage;
protected:
virtual void enter(GController* controller) = 0;
virtual void leave(GController* controller) = 0;
};
NS_FGUI_END
#endif

View File

@ -0,0 +1,46 @@
#include "PlayTransitionAction.h"
#include "Controller.h"
#include "GComponent.h"
#include "utils/ByteBuffer.h"
NS_FGUI_BEGIN
USING_NS_CC;
PlayTransitionAction::PlayTransitionAction() :
playTimes(1), delay(0), stopOnExit(false), _currentTransition(nullptr)
{
}
void PlayTransitionAction::setup(ByteBuffer * buffer)
{
ControllerAction::setup(buffer);
transitionName = buffer->readS();
playTimes = buffer->readInt();
delay = buffer->readFloat();
stopOnExit = buffer->readBool();
}
void PlayTransitionAction::enter(GController * controller)
{
Transition* trans = controller->getParent()->getTransition(transitionName);
if (trans != nullptr)
{
if (_currentTransition != nullptr && _currentTransition->isPlaying())
trans->changePlayTimes(playTimes);
else
trans->play(playTimes, delay, nullptr);
_currentTransition = trans;
}
}
void PlayTransitionAction::leave(GController * controller)
{
if (stopOnExit && _currentTransition != nullptr)
{
_currentTransition->stop();
_currentTransition = nullptr;
}
}
NS_FGUI_END

View File

@ -0,0 +1,30 @@
#ifndef __PLAYTRNASITIONACTION_H__
#define __PLAYTRNASITIONACTION_H__
#include "ControllerAction.h"
NS_FGUI_BEGIN
class Transition;
class PlayTransitionAction : public ControllerAction
{
public:
PlayTransitionAction();
virtual void setup(ByteBuffer * buffer) override;
std::string transitionName;
int playTimes;
float delay;
bool stopOnExit;
protected:
virtual void enter(GController* controller) override;
virtual void leave(GController* controller) override;
Transition* _currentTransition;
};
NS_FGUI_END
#endif

View File

@ -0,0 +1,24 @@
#include "BitmapFont.h"
USING_NS_FGUI;
BitmapFont::BitmapFont():_fontAtlas(nullptr),_originalFontSize(0),_resizable(false)
{
}
BitmapFont::~BitmapFont()
{
}
BitmapFont * BitmapFont::create()
{
BitmapFont *font = new BitmapFont();
font->autorelease();
return font;
}
int * BitmapFont::getHorizontalKerningForTextUTF32(const std::u32string & text, int & outNumLetters) const
{
return nullptr;
}

View File

@ -0,0 +1,37 @@
#ifndef __BITMAPFONT_H__
#define __BITMAPFONT_H__
#include "FairyGUIMacros.h"
#include "cocos2d.h"
#include "PackageItem.h"
NS_FGUI_BEGIN
class BitmapFont : public cocos2d::Font
{
public:
BitmapFont();
virtual ~BitmapFont();
static BitmapFont* create();
virtual int* getHorizontalKerningForTextUTF32(const std::u32string& text, int &outNumLetters) const override;
virtual cocos2d::FontAtlas *createFontAtlas() override { return _fontAtlas; }
void releaseAtlas() { _fontAtlas->release(); }
void setFontSize(float fontSize) {}
int getOriginalFontSize()const { return _originalFontSize; }
bool isResizable() { return _resizable; }
bool canTint() { return _canTint; }
private:
float _originalFontSize;
bool _resizable;
bool _canTint;
cocos2d::FontAtlas* _fontAtlas;
friend class UIPackage;
};
NS_FGUI_END
#endif

View File

@ -0,0 +1,507 @@
#include "FUIContainer.h"
#include "base/CCStencilStateManager.h"
#include "utils/ToolSet.h"
#include "GComponent.h"
NS_FGUI_BEGIN
USING_NS_CC;
#if COCOS2D_VERSION < 0x00040000
#if (CC_TARGET_PLATFORM == CC_PLATFORM_MAC || CC_TARGET_PLATFORM == CC_PLATFORM_WIN32 || CC_TARGET_PLATFORM == CC_PLATFORM_LINUX)
#define CC_CLIPPING_NODE_OPENGLES 0
#else
#define CC_CLIPPING_NODE_OPENGLES 1
#endif
#if CC_CLIPPING_NODE_OPENGLES
static void setProgram(Node *n, GLProgram *p)
{
n->setGLProgram(p);
auto& children = n->getChildren();
for (const auto &child : children) {
setProgram(child, p);
}
}
#endif
#endif // COCOS2D_VERSION < 0x00040000
RectClippingSupport::RectClippingSupport() :
_clippingEnabled(false),
_scissorOldState(false),
_clippingRectDirty(true)
{
}
StencilClippingSupport::StencilClippingSupport() :
_stencil(nullptr),
_originStencilProgram(nullptr),
_stencilStateManager(new StencilStateManager())
{
}
FUIContainer::FUIContainer() :
_rectClippingSupport(nullptr),
_stencilClippingSupport(nullptr),
gOwner(nullptr)
{
}
FUIContainer::~FUIContainer()
{
CC_SAFE_DELETE(_rectClippingSupport);
if (_stencilClippingSupport)
{
if (_stencilClippingSupport->_stencil)
{
_stencilClippingSupport->_stencil->stopAllActions();
_stencilClippingSupport->_stencil->release();
}
CC_SAFE_DELETE(_stencilClippingSupport->_stencilStateManager);
delete _stencilClippingSupport;
}
}
bool FUIContainer::isClippingEnabled() const
{
if (_rectClippingSupport != nullptr)
return _rectClippingSupport->_clippingEnabled;
else
return false;
}
void FUIContainer::setClippingEnabled(bool value)
{
if (_rectClippingSupport == nullptr)
{
if (!value)
return;
_rectClippingSupport = new RectClippingSupport();
}
_rectClippingSupport->_clippingEnabled = value;
}
const Rect & FUIContainer::getClippingRegion() const
{
if (_rectClippingSupport != nullptr)
return _rectClippingSupport->_clippingRegion;
else
return Rect::ZERO;
}
void FUIContainer::setClippingRegion(const Rect & clippingRegion)
{
if (_rectClippingSupport == nullptr)
_rectClippingSupport = new RectClippingSupport();
_rectClippingSupport->_clippingRegion = clippingRegion;
}
cocos2d::Node * FUIContainer::getStencil() const
{
if (_stencilClippingSupport != nullptr)
return _stencilClippingSupport->_stencil;
else
return nullptr;
}
void FUIContainer::setStencil(cocos2d::Node * stencil)
{
if (_stencilClippingSupport == nullptr)
{
if (stencil == nullptr)
return;
_stencilClippingSupport = new StencilClippingSupport();
}
//early out if the stencil is already set
if (_stencilClippingSupport->_stencil == stencil)
return;
#if CC_ENABLE_GC_FOR_NATIVE_OBJECTS
auto sEngine = ScriptEngineManager::getInstance()->getScriptEngine();
if (sEngine)
{
if (_stencilClippingSupport->_stencil)
sEngine->releaseScriptObject(this, _stencilClippingSupport->_stencil);
if (stencil)
sEngine->retainScriptObject(this, stencil);
}
#endif // CC_ENABLE_GC_FOR_NATIVE_OBJECTS
//cleanup current stencil
if (_stencilClippingSupport->_stencil != nullptr && _stencilClippingSupport->_stencil->isRunning())
{
_stencilClippingSupport->_stencil->onExitTransitionDidStart();
_stencilClippingSupport->_stencil->onExit();
}
CC_SAFE_RELEASE_NULL(_stencilClippingSupport->_stencil);
//initialise new stencil
_stencilClippingSupport->_stencil = stencil;
CC_SAFE_RETAIN(_stencilClippingSupport->_stencil);
if (_stencilClippingSupport->_stencil != nullptr && this->isRunning())
{
_stencilClippingSupport->_stencil->onEnter();
if (this->_isTransitionFinished)
{
_stencilClippingSupport->_stencil->onEnterTransitionDidFinish();
}
}
if (_stencilClippingSupport->_stencil != nullptr)
#if COCOS2D_VERSION >= 0x00040000
_stencilClippingSupport->_originStencilProgram = _stencilClippingSupport->_stencil->getProgramState();
#else
_stencilClippingSupport->_originStencilProgram = _stencilClippingSupport->_stencil->getGLProgram();
#endif
}
float FUIContainer::getAlphaThreshold() const
{
if (_stencilClippingSupport != nullptr)
return _stencilClippingSupport->_stencilStateManager->getAlphaThreshold();
else
return 1;
}
void FUIContainer::setAlphaThreshold(float alphaThreshold)
{
if (_stencilClippingSupport == nullptr)
_stencilClippingSupport = new StencilClippingSupport();
#if COCOS2D_VERSION >= 0x00040000
if (alphaThreshold == 1 && alphaThreshold != _stencilClippingSupport->_stencilStateManager->getAlphaThreshold()) {
if (_stencilClippingSupport->_stencil) {
restoreAllProgramStates();
}
}
#else
#if CC_CLIPPING_NODE_OPENGLES
if (alphaThreshold == 1 && alphaThreshold != _stencilClippingSupport->_stencilStateManager->getAlphaThreshold())
{
// should reset program used by _stencil
if (_stencilClippingSupport->_stencil)
setProgram(_stencilClippingSupport->_stencil, _stencilClippingSupport->_originStencilProgram);
}
#endif
#endif
_stencilClippingSupport->_stencilStateManager->setAlphaThreshold(alphaThreshold);
}
bool FUIContainer::isInverted() const
{
if (_stencilClippingSupport != nullptr)
return _stencilClippingSupport->_stencilStateManager->isInverted();
else
return false;
}
void FUIContainer::setInverted(bool inverted)
{
if (_stencilClippingSupport == nullptr)
_stencilClippingSupport = new StencilClippingSupport();
_stencilClippingSupport->_stencilStateManager->setInverted(inverted);
}
void FUIContainer::onEnter()
{
#if CC_ENABLE_SCRIPT_BINDING
if (_scriptType == kScriptTypeJavascript)
{
if (ScriptEngineManager::sendNodeEventToJSExtended(this, kNodeOnEnter))
return;
}
#endif
Node::onEnter();
if (_stencilClippingSupport != nullptr && _stencilClippingSupport->_stencil != nullptr)
_stencilClippingSupport->_stencil->onEnter();
if (_rectClippingSupport != nullptr)
_rectClippingSupport->_clippingRectDirty = true;
}
void FUIContainer::onEnterTransitionDidFinish()
{
#if CC_ENABLE_SCRIPT_BINDING
if (_scriptType == kScriptTypeJavascript)
{
if (ScriptEngineManager::sendNodeEventToJSExtended(this, kNodeOnEnterTransitionDidFinish))
return;
}
#endif
Node::onEnterTransitionDidFinish();
if (_stencilClippingSupport != nullptr && _stencilClippingSupport->_stencil != nullptr)
{
_stencilClippingSupport->_stencil->onEnterTransitionDidFinish();
}
}
void FUIContainer::onExitTransitionDidStart()
{
#if CC_ENABLE_SCRIPT_BINDING
if (_scriptType == kScriptTypeJavascript)
{
if (ScriptEngineManager::sendNodeEventToJSExtended(this, kNodeOnExitTransitionDidStart))
return;
}
#endif
if (_stencilClippingSupport != nullptr && _stencilClippingSupport->_stencil != nullptr)
_stencilClippingSupport->_stencil->onExitTransitionDidStart();
Node::onExitTransitionDidStart();
}
void FUIContainer::onExit()
{
#if CC_ENABLE_SCRIPT_BINDING
if (_scriptType == kScriptTypeJavascript)
{
if (ScriptEngineManager::sendNodeEventToJSExtended(this, kNodeOnExit))
return;
}
#endif
if (_stencilClippingSupport != nullptr && _stencilClippingSupport->_stencil != nullptr)
_stencilClippingSupport->_stencil->onExit();
Node::onExit();
}
void FUIContainer::setCameraMask(unsigned short mask, bool applyChildren)
{
Node::setCameraMask(mask, applyChildren);
if (_stencilClippingSupport != nullptr && _stencilClippingSupport->_stencil != nullptr)
_stencilClippingSupport->_stencil->setCameraMask(mask, applyChildren);
}
void FUIContainer::setContentSize(const Size & contentSize)
{
Node::setContentSize(contentSize);
if (_rectClippingSupport)
_rectClippingSupport->_clippingRectDirty = true;
}
#if COCOS2D_VERSION >= 0x00040000
void FUIContainer::setProgramStateRecursively(Node* node, backend::ProgramState* programState)
{
_originalStencilProgramState[node] = node->getProgramState();
node->setProgramState(programState);
auto& children = node->getChildren();
for (const auto &child : children) {
setProgramStateRecursively(child, programState);
}
}
void FUIContainer::restoreAllProgramStates()
{
for (auto item : _originalStencilProgramState)
{
auto node = item.first;
auto programState = item.second;
node->setProgramState(programState);
}
}
#endif
void FUIContainer::onBeforeVisitScissor()
{
auto glview = Director::getInstance()->getOpenGLView();
_rectClippingSupport->_scissorOldState = glview->isScissorEnabled();
Rect clippingRect = getClippingRect();
if (false == _rectClippingSupport->_scissorOldState)
{
#if COCOS2D_VERSION >= 0x00040000
Director::getInstance()->getRenderer()->setScissorTest(true);
#else
glEnable(GL_SCISSOR_TEST);
#endif
}
else
{
_rectClippingSupport->_clippingOldRect = glview->getScissorRect();
clippingRect = ToolSet::intersection(clippingRect, _rectClippingSupport->_clippingOldRect);
}
glview->setScissorInPoints(clippingRect.origin.x,
clippingRect.origin.y,
clippingRect.size.width,
clippingRect.size.height);
}
void FUIContainer::onAfterVisitScissor()
{
if (_rectClippingSupport->_scissorOldState)
{
auto glview = Director::getInstance()->getOpenGLView();
glview->setScissorInPoints(_rectClippingSupport->_clippingOldRect.origin.x,
_rectClippingSupport->_clippingOldRect.origin.y,
_rectClippingSupport->_clippingOldRect.size.width,
_rectClippingSupport->_clippingOldRect.size.height);
}
else
{
// revert scissor test
#if COCOS2D_VERSION >= 0x00040000
Director::getInstance()->getRenderer()->setScissorTest(false);
#else
glDisable(GL_SCISSOR_TEST);
#endif
}
}
const Rect& FUIContainer::getClippingRect()
{
if (_rectClippingSupport->_clippingRectDirty)
{
Vec2 worldPos = convertToWorldSpaceAR(_rectClippingSupport->_clippingRegion.origin);
AffineTransform t = getNodeToWorldAffineTransform();
float scissorWidth = _rectClippingSupport->_clippingRegion.size.width*t.a;
float scissorHeight = _rectClippingSupport->_clippingRegion.size.height*t.d;
_rectClippingSupport->_clippingRect.setRect(worldPos.x - (scissorWidth * _anchorPoint.x), worldPos.y - (scissorHeight * _anchorPoint.y), scissorWidth, scissorHeight);
_rectClippingSupport->_clippingRectDirty = false;
}
return _rectClippingSupport->_clippingRect;
}
void FUIContainer::visit(cocos2d::Renderer * renderer, const cocos2d::Mat4 & parentTransform, uint32_t parentFlags)
{
if (_stencilClippingSupport != nullptr)
{
if (!_visible || _children.empty())
return;
uint32_t flags = processParentFlags(parentTransform, parentFlags);
// IMPORTANT:
// To ease the migration to v3.0, we still support the Mat4 stack,
// but it is deprecated and your code should not rely on it
Director* director = Director::getInstance();
CCASSERT(nullptr != director, "Director is null when setting matrix stack");
director->pushMatrix(MATRIX_STACK_TYPE::MATRIX_STACK_MODELVIEW);
director->loadMatrix(MATRIX_STACK_TYPE::MATRIX_STACK_MODELVIEW, _modelViewTransform);
//Add group command
_stencilClippingSupport->_groupCommand.init(_globalZOrder);
renderer->addCommand(&_stencilClippingSupport->_groupCommand);
renderer->pushGroup(_stencilClippingSupport->_groupCommand.getRenderQueueID());
#if COCOS2D_VERSION >= 0x00040000
_stencilClippingSupport->_stencilStateManager->onBeforeVisit(_globalZOrder);
#else
_stencilClippingSupport->_beforeVisitCmd.init(_globalZOrder);
_stencilClippingSupport->_beforeVisitCmd.func = CC_CALLBACK_0(StencilStateManager::onBeforeVisit, _stencilClippingSupport->_stencilStateManager);
renderer->addCommand(&_stencilClippingSupport->_beforeVisitCmd);
#endif
auto alphaThreshold = this->getAlphaThreshold();
if (alphaThreshold < 1)
{
#if COCOS2D_VERSION >= 0x00040000
auto* program = backend::Program::getBuiltinProgram(backend::ProgramType::POSITION_TEXTURE_COLOR_ALPHA_TEST);
auto programState = new (std::nothrow) backend::ProgramState(program);
auto alphaLocation = programState->getUniformLocation("u_alpha_value");
programState->setUniform(alphaLocation, &alphaThreshold, sizeof(alphaThreshold));
setProgramStateRecursively(_stencilClippingSupport->_stencil, programState);
CC_SAFE_RELEASE_NULL(programState);
#else
#if CC_CLIPPING_NODE_OPENGLES
// since glAlphaTest do not exists in OES, use a shader that writes
// pixel only if greater than an alpha threshold
GLProgram *program = GLProgramCache::getInstance()->getGLProgram(GLProgram::SHADER_NAME_POSITION_TEXTURE_ALPHA_TEST_NO_MV);
GLint alphaValueLocation = glGetUniformLocation(program->getProgram(), GLProgram::UNIFORM_NAME_ALPHA_TEST_VALUE);
// set our alphaThreshold
program->use();
program->setUniformLocationWith1f(alphaValueLocation, alphaThreshold);
// we need to recursively apply this shader to all the nodes in the stencil node
// FIXME: we should have a way to apply shader to all nodes without having to do this
setProgram(_stencilClippingSupport->_stencil, program);
#endif
#endif
}
_stencilClippingSupport->_stencil->visit(renderer, _modelViewTransform, flags);
_stencilClippingSupport->_afterDrawStencilCmd.init(_globalZOrder);
_stencilClippingSupport->_afterDrawStencilCmd.func = CC_CALLBACK_0(StencilStateManager::onAfterDrawStencil, _stencilClippingSupport->_stencilStateManager);
renderer->addCommand(&_stencilClippingSupport->_afterDrawStencilCmd);
int i = 0;
bool visibleByCamera = isVisitableByVisitingCamera();
if (!_children.empty())
{
sortAllChildren();
// draw children zOrder < 0
for (auto size = _children.size(); i < size; ++i)
{
auto node = _children.at(i);
if (node && node->getLocalZOrder() < 0)
node->visit(renderer, _modelViewTransform, flags);
else
break;
}
// self draw
if (visibleByCamera)
this->draw(renderer, _modelViewTransform, flags);
for (auto it = _children.cbegin() + i, itCend = _children.cend(); it != itCend; ++it)
(*it)->visit(renderer, _modelViewTransform, flags);
}
else if (visibleByCamera)
{
this->draw(renderer, _modelViewTransform, flags);
}
_stencilClippingSupport->_afterVisitCmd.init(_globalZOrder);
_stencilClippingSupport->_afterVisitCmd.func = CC_CALLBACK_0(StencilStateManager::onAfterVisit, _stencilClippingSupport->_stencilStateManager);
renderer->addCommand(&_stencilClippingSupport->_afterVisitCmd);
renderer->popGroup();
director->popMatrix(MATRIX_STACK_TYPE::MATRIX_STACK_MODELVIEW);
}
else if (_rectClippingSupport != nullptr && _rectClippingSupport->_clippingEnabled)
{
if (parentFlags & FLAGS_DIRTY_MASK)
{
_rectClippingSupport->_clippingRectDirty = true;
}
#if COCOS2D_VERSION >= 0x00040000
_rectClippingSupport->_groupCommand.init(_globalZOrder);
renderer->addCommand(&_rectClippingSupport->_groupCommand);
renderer->pushGroup(_rectClippingSupport->_groupCommand.getRenderQueueID());
#endif
_rectClippingSupport->_beforeVisitCmdScissor.init(_globalZOrder);
_rectClippingSupport->_beforeVisitCmdScissor.func = CC_CALLBACK_0(FUIContainer::onBeforeVisitScissor, this);
renderer->addCommand(&_rectClippingSupport->_beforeVisitCmdScissor);
Node::visit(renderer, parentTransform, parentFlags);
_rectClippingSupport->_afterVisitCmdScissor.init(_globalZOrder);
_rectClippingSupport->_afterVisitCmdScissor.func = CC_CALLBACK_0(FUIContainer::onAfterVisitScissor, this);
renderer->addCommand(&_rectClippingSupport->_afterVisitCmdScissor);
#if COCOS2D_VERSION >= 0x00040000
renderer->popGroup();
#endif
}
else
Node::visit(renderer, parentTransform, parentFlags);
}
NS_FGUI_END

View File

@ -0,0 +1,115 @@
#ifndef __FUICONTAINER_H__
#define __FUICONTAINER_H__
#include "cocos2d.h"
#include "FairyGUIMacros.h"
NS_FGUI_BEGIN
class GObject;
class RectClippingSupport
{
public:
RectClippingSupport();
cocos2d::Rect _clippingRegion;
bool _clippingEnabled;
bool _scissorOldState;
cocos2d::Rect _clippingOldRect;
cocos2d::Rect _clippingRect;
bool _clippingRectDirty;
#if COCOS2D_VERSION >= 0x00040000
cocos2d::GroupCommand _groupCommand;
cocos2d::CallbackCommand _beforeVisitCmdScissor;
cocos2d::CallbackCommand _afterVisitCmdScissor;
#else
cocos2d::CustomCommand _beforeVisitCmdScissor;
cocos2d::CustomCommand _afterVisitCmdScissor;
#endif
};
class StencilClippingSupport
{
public:
StencilClippingSupport();
cocos2d::Node* _stencil;
cocos2d::StencilStateManager* _stencilStateManager;
cocos2d::GroupCommand _groupCommand;
#if COCOS2D_VERSION >= 0x00040000
cocos2d::backend::ProgramState* _originStencilProgram;
cocos2d::CallbackCommand _beforeVisitCmd;
cocos2d::CallbackCommand _afterDrawStencilCmd;
cocos2d::CallbackCommand _afterVisitCmd;
#else
cocos2d::GLProgram* _originStencilProgram;
cocos2d::CustomCommand _beforeVisitCmd;
cocos2d::CustomCommand _afterDrawStencilCmd;
cocos2d::CustomCommand _afterVisitCmd;
#endif
};
class FUIContainer : public cocos2d::Node
{
public:
FUIContainer();
virtual ~FUIContainer();
CREATE_FUNC(FUIContainer);
bool isClippingEnabled() const;
void setClippingEnabled(bool value);
const cocos2d::Rect& getClippingRegion() const;
void setClippingRegion(const cocos2d::Rect& clippingRegion);
cocos2d::Node* getStencil() const;
void setStencil(cocos2d::Node* stencil);
float getAlphaThreshold() const;
void setAlphaThreshold(float alphaThreshold);
bool isInverted() const;
void setInverted(bool inverted);
void onEnter() override;
void onEnterTransitionDidFinish() override;
void onExitTransitionDidStart() override;
void onExit() override;
void visit(cocos2d::Renderer *renderer, const cocos2d::Mat4 &parentTransform, uint32_t parentFlags) override;
void setCameraMask(unsigned short mask, bool applyChildren = true) override;
virtual void setContentSize(const cocos2d::Size& contentSize) override;
GObject* gOwner;
private:
void onBeforeVisitScissor();
void onAfterVisitScissor();
const cocos2d::Rect& getClippingRect();
RectClippingSupport* _rectClippingSupport;
StencilClippingSupport* _stencilClippingSupport;
#if COCOS2D_VERSION >= 0x00040000
void setProgramStateRecursively(Node* node, cocos2d::backend::ProgramState* programState);
void restoreAllProgramStates();
std::unordered_map<Node*, cocos2d::backend::ProgramState*> _originalStencilProgramState;
#endif
};
//internal use
class FUIInnerContainer : public cocos2d::Node
{
public:
CREATE_FUNC(FUIInnerContainer);
void setPosition2(const cocos2d::Vec2 &position) { setPosition(position.x, _parent->getContentSize().height - position.y); }
cocos2d::Vec2 getPosition2() { return cocos2d::Vec2(_position.x, _parent->getContentSize().height - _position.y); }
void setPosition2(float x, float y) { setPosition(x, _parent->getContentSize().height - y); }
void setPositionY2(float y) { setPositionY(_parent->getContentSize().height - y); }
float getPositionY2(void) const { return _parent->getContentSize().height - _position.y; }
};
NS_FGUI_END
#endif

View File

@ -0,0 +1,102 @@
#include "FUIInput.h"
#include "UIPackage.h"
#include "GTextInput.h"
#include "UIConfig.h"
NS_FGUI_BEGIN
USING_NS_CC;
FUIInput * FUIInput::create()
{
FUIInput* pRet = new (std::nothrow) FUIInput();
if (pRet != nullptr && pRet->initWithSizeAndBackgroundSprite(Size(100, 100),
(ui::Scale9Sprite*)ui::Scale9Sprite::createWithTexture(UIPackage::getEmptyTexture())))
{
pRet->autorelease();
pRet->continueInit();
}
else
{
CC_SAFE_DELETE(pRet);
}
return pRet;
}
FUIInput::FUIInput() :
_textFormat(new TextFormat()),
_password(false),
_keyboardType(0)
{
}
FUIInput::~FUIInput()
{
delete _textFormat;
}
std::string FUIInput::getText() const
{
return ui::EditBox::getText();
}
void FUIInput::setText(const std::string & value)
{
ui::EditBox::setText(value.c_str());
}
void FUIInput::applyTextFormat()
{
setFontName(UIConfig::getRealFontName(_textFormat->face).c_str());
setFontSize(_textFormat->fontSize);
setPlaceholderFontSize(_textFormat->fontSize);
setFontColor(_textFormat->color);
//setPlaceholderFontColor(_textFormat->color);
}
bool FUIInput::isSingleLine() const
{
return getInputMode() == ui::EditBox::InputMode::SINGLE_LINE;
}
void FUIInput::setSingleLine(bool value)
{
setInputMode(ui::EditBox::InputMode::SINGLE_LINE);
}
void FUIInput::setPassword(bool value)
{
_password = value;
setInputFlag(ui::EditBox::InputFlag::PASSWORD);
}
void FUIInput::setKeyboardType(int value)
{
//if (!_password)
//setInputMode((ui::EditBox::InputMode)value);
}
void FUIInput::openKeyboard()
{
#if COCOS2D_VERSION >= 0x00031700
EditBox::openKeyboard();
#else
touchDownAction(this, cocos2d::ui::Widget::TouchEventType::ENDED);
#endif
}
void FUIInput::continueInit()
{
applyTextFormat();
//disable default behavior
this->setTouchEnabled(false);
this->addTouchEventListener(CC_CALLBACK_2(FUIInput::_touchDownAction, this));
}
void FUIInput::_touchDownAction(cocos2d::Ref *sender, cocos2d::ui::Widget::TouchEventType controlEvent)
{
//do nothing
}
NS_FGUI_END

View File

@ -0,0 +1,48 @@
#ifndef __FUIINPUT_H__
#define __FUIINPUT_H__
#include "cocos2d.h"
#include "FairyGUIMacros.h"
#include "ui/UIEditBox/UIEditBox.h"
#include "TextFormat.h"
NS_FGUI_BEGIN
class FUIInput : public cocos2d::ui::EditBox
{
public:
static FUIInput* create();
FUIInput();
virtual ~FUIInput();
std::string getText() const;
void setText(const std::string& value);
TextFormat* getTextFormat() const { return _textFormat; }
void applyTextFormat();
bool isSingleLine() const;
void setSingleLine(bool value);
bool isPassword() const { return _password; }
void setPassword(bool value);
int keyboardType() const { return _keyboardType; }
void setKeyboardType(int value);
void openKeyboard();
private:
void continueInit();
void _touchDownAction(cocos2d::Ref *sender, cocos2d::ui::Widget::TouchEventType controlEvent);
TextFormat* _textFormat;
bool _password;
int _keyboardType;
};
NS_FGUI_END
#endif

View File

@ -0,0 +1,184 @@
#include "FUILabel.h"
#include "BitmapFont.h"
#include "UIConfig.h"
#include "UIPackage.h"
NS_FGUI_BEGIN
USING_NS_CC;
static Color3B toGrayed(const Color3B& source)
{
Color3B c = source;
c.r = c.g = c.b = c.r * 0.299f + c.g * 0.587f + c.b * 0.114f;
return c;
}
FUILabel::FUILabel() : _fontSize(-1),
_bmFontCanTint(false),
_textFormat(new TextFormat()),
_grayed(false)
{
}
FUILabel::~FUILabel()
{
delete _textFormat;
}
void FUILabel::setText(const std::string& value)
{
if (_fontSize < 0)
applyTextFormat();
setString(value);
}
void FUILabel::applyTextFormat()
{
if (_fontSize < 0 /**first time**/ || _fontName != _textFormat->face)
{
_fontName = _textFormat->face;
Label::LabelType oldType = _currentLabelType;
if (_fontName.find("ui://") != -1)
{
setBMFontFilePath(_fontName);
}
else
{
bool ttf = false;
const std::string& fontName = UIConfig::getRealFontName(_fontName, &ttf);
if (ttf)
{
_fontConfig.fontFilePath = fontName;
_fontConfig.fontSize = _textFormat->fontSize;
setTTFConfig(_fontConfig);
}
else
{
setSystemFontName(fontName);
}
if (oldType == LabelType::BMFONT)
setTextColor((Color4B)_textFormat->color);
}
}
if (_fontSize != _textFormat->fontSize)
{
_fontSize = _textFormat->fontSize;
if (_currentLabelType == LabelType::STRING_TEXTURE)
{
setSystemFontSize(_fontSize);
}
else if (_currentLabelType == LabelType::BMFONT)
{
setBMFontSize(_fontSize);
}
else
{
_fontConfig.fontSize = _fontSize;
setTTFConfig(_fontConfig);
}
}
if (_currentLabelType != LabelType::BMFONT)
setTextColor((Color4B)(_grayed ? toGrayed(_textFormat->color) : _textFormat->color));
else if (_bmFontCanTint)
setColor(_grayed ? toGrayed(_textFormat->color) : _textFormat->color);
if (_textFormat->underline)
enableUnderline();
else
disableEffect(LabelEffect::UNDERLINE);
if (_textFormat->italics)
enableItalics();
else
disableEffect(LabelEffect::ITALICS);
if (_textFormat->bold && _currentLabelType != LabelType::STRING_TEXTURE)
enableBold();
else
disableEffect(LabelEffect::BOLD);
setLineSpacing(_textFormat->lineSpacing);
setHorizontalAlignment(_textFormat->align);
setVerticalAlignment(_textFormat->verticalAlign);
if (_textFormat->hasEffect(TextFormat::OUTLINE))
enableOutline((Color4B)(_grayed ? toGrayed(_textFormat->outlineColor) : _textFormat->outlineColor), _textFormat->outlineSize);
else
disableEffect(LabelEffect::OUTLINE);
if (_textFormat->hasEffect(TextFormat::SHADOW))
enableShadow((Color4B)(_grayed ? toGrayed(_textFormat->shadowColor) : _textFormat->shadowColor), _textFormat->shadowOffset);
else if (!_textFormat->bold)
disableEffect(LabelEffect::SHADOW);
}
bool FUILabel::setBMFontFilePath(const std::string& bmfontFilePath, const Vec2& imageOffset, float fontSize)
{
BitmapFont* bmFont = (BitmapFont*)UIPackage::getItemAssetByURL(bmfontFilePath, PackageItemType::FONT);
if (bmFont == nullptr)
{
reset();
return false;
}
//assign the default fontSize
if (std::abs(fontSize) < FLT_EPSILON)
{
float originalFontSize = bmFont->getOriginalFontSize();
_bmFontSize = originalFontSize / CC_CONTENT_SCALE_FACTOR();
}
if (fontSize > 0.0f && bmFont->isResizable())
{
_bmFontSize = fontSize;
}
_bmFontPath = bmfontFilePath;
_bmFontCanTint = bmFont->canTint();
_currentLabelType = LabelType::BMFONT;
setFontAtlas(bmFont->createFontAtlas());
return true;
}
void FUILabel::setGrayed(bool value)
{
if (_grayed != value)
{
_grayed = value;
if (_currentLabelType != LabelType::BMFONT)
setTextColor((Color4B)(_grayed ? toGrayed(_textFormat->color) : _textFormat->color));
else if (_bmFontCanTint)
setColor(_grayed ? toGrayed(_textFormat->color) : _textFormat->color);
if (_textFormat->hasEffect(TextFormat::OUTLINE))
enableOutline((Color4B)(_grayed ? toGrayed(_textFormat->outlineColor) : _textFormat->outlineColor), _textFormat->outlineSize);
if (_textFormat->hasEffect(TextFormat::SHADOW))
enableShadow((Color4B)(_grayed ? toGrayed(_textFormat->shadowColor) : _textFormat->shadowColor), _textFormat->shadowOffset);
}
}
void FUILabel::updateBMFontScale()
{
auto font = _fontAtlas->getFont();
if (_currentLabelType == LabelType::BMFONT)
{
BitmapFont* bmFont = (BitmapFont*)font;
float originalFontSize = bmFont->getOriginalFontSize();
_bmfontScale = _bmFontSize * CC_CONTENT_SCALE_FACTOR() / originalFontSize;
}
else
{
_bmfontScale = 1.0f;
}
}
NS_FGUI_END

View File

@ -0,0 +1,45 @@
#ifndef __FUILABEL_H__
#define __FUILABEL_H__
#include "cocos2d.h"
#include "FairyGUIMacros.h"
#include "TextFormat.h"
NS_FGUI_BEGIN
class FUILabel : public cocos2d::Label
{
public:
FUILabel();
virtual ~FUILabel();
CREATE_FUNC(FUILabel);
const std::string& getText() const { return getString(); }
void setText(const std::string& value);
TextFormat* getTextFormat() const { return _textFormat; }
void applyTextFormat();
virtual bool setBMFontFilePath(const std::string& bmfontFilePath, const cocos2d::Vec2& imageOffset = cocos2d::Vec2::ZERO, float fontSize = 0) override;
void setGrayed(bool value);
protected:
/*
cocos2d的源码2d/CCLabel.h672updateBMFontScale函数打上virtual修饰符
FontFnt类型的代码使FontFntFontFnt只支持从外部文件中载入配置BMFontConfiguration是定义在cpp里的
*/
virtual void updateBMFontScale() override;
private:
TextFormat* _textFormat;
std::string _fontName;
int _fontSize;
bool _bmFontCanTint;
bool _grayed;
};
NS_FGUI_END
#endif

View File

@ -0,0 +1,780 @@
#include "FUIRichText.h"
#include <sstream>
#include <vector>
#include <locale>
#include <algorithm>
#include "utils/ToolSet.h"
#include "UIPackage.h"
NS_FGUI_BEGIN
USING_NS_CC;
using namespace std;
#if (CC_TARGET_PLATFORM == CC_PLATFORM_WIN32) || (CC_TARGET_PLATFORM == CC_PLATFORM_WINRT)
#define strcasecmp _stricmp
#endif
static const int GUTTER_X = 2;
static const int GUTTER_Y = 2;
static int getPrevWord(const std::string& text, int idx)
{
// start from idx-1
for (int i = idx - 1; i >= 0; --i)
{
if (!std::isalnum(text[i], std::locale()))
return i;
}
return -1;
}
static bool isWrappable(const std::string& text)
{
for (size_t i = 0, size = text.length(); i < size; ++i)
{
if (!std::isalnum(text[i], std::locale()))
return true;
}
return false;
}
static float getPaddingAmount(TextHAlignment alignment, const float leftOver) {
switch (alignment) {
case TextHAlignment::CENTER:
return leftOver / 2.f;
case TextHAlignment::RIGHT:
return leftOver;
default:
CCASSERT(false, "invalid horizontal alignment!");
return 0.f;
}
}
static bool isWhitespace(char c) {
return std::isspace(c, std::locale());
}
static void ltrim(std::string& s) {
s.erase(s.begin(), std::find_if_not(s.begin(),
s.end(),
isWhitespace));
}
static void rtrim(std::string& s) {
s.erase(std::find_if_not(s.rbegin(),
s.rend(),
isWhitespace).base(),
s.end());
}
static float stripTrailingWhitespace(const std::vector<cocos2d::Node*>& row) {
if (!row.empty()) {
if (auto label = dynamic_cast<Label*>(row.back())) {
const auto width = label->getContentSize().width;
auto str = label->getString();
rtrim(str);
if (label->getString() != str) {
label->setString(str);
return label->getContentSize().width - width;
}
}
}
return 0.0f;
}
static std::string getSubStringOfUTF8String(const std::string& str, std::string::size_type start, std::string::size_type length)
{
std::u32string utf32;
if (!StringUtils::UTF8ToUTF32(str, utf32)) {
CCLOGERROR("Can't convert string to UTF-32: %s", str.c_str());
return "";
}
if (utf32.size() < start) {
CCLOGERROR("'start' is out of range: %ld, %s", static_cast<long>(start), str.c_str());
return "";
}
std::string result;
if (!StringUtils::UTF32ToUTF8(utf32.substr(start, length), result)) {
CCLOGERROR("Can't convert internal UTF-32 string to UTF-8: %s", str.c_str());
return "";
}
return result;
}
class FUIRichElement
{
public:
enum class Type
{
TEXT,
IMAGE,
LINK
};
FUIRichElement(Type type);
virtual ~FUIRichElement() {};
Type _type;
std::string text;
TextFormat textFormat;
int width;
int height;
FUIRichElement* link;
};
FUIRichElement::FUIRichElement(Type type) :
_type(type),
width(0),
height(0),
link(nullptr)
{
};
class FUIXMLVisitor : public SAXDelegator
{
public:
explicit FUIXMLVisitor(FUIRichText* richText);
virtual ~FUIXMLVisitor();
void startElement(void *ctx, const char *name, const char **atts) override;
void endElement(void *ctx, const char *name) override;
void textHandler(void *ctx, const char *s, size_t len) override;
private:
ValueMap tagAttrMapWithXMLElement(const char ** attrs);
int attributeInt(const ValueMap& vm, const std::string& key, int defaultValue);
void pushTextFormat();
void popTextFormat();
void addNewLine(bool check);
void finishTextBlock();
FUIRichText* _richText;
std::vector<TextFormat> _textFormatStack;
std::vector<FUIRichElement*> _linkStack;
TextFormat _format;
size_t _textFormatStackTop;
int _skipText;
bool _ignoreWhiteSpace;
std::string _textBlock;
};
FUIXMLVisitor::FUIXMLVisitor(FUIRichText* richText)
: _richText(richText),
_textFormatStackTop(0),
_skipText(0),
_ignoreWhiteSpace(false)
{
_format = *_richText->_defaultTextFormat;
}
FUIXMLVisitor::~FUIXMLVisitor()
{
}
void FUIXMLVisitor::pushTextFormat()
{
if (_textFormatStack.size() <= _textFormatStackTop)
_textFormatStack.push_back(_format);
else
_textFormatStack[_textFormatStackTop] = _format;
_textFormatStackTop++;
}
void FUIXMLVisitor::popTextFormat()
{
if (_textFormatStackTop > 0)
{
_format = _textFormatStack[_textFormatStackTop - 1];
_textFormatStackTop--;
}
}
void FUIXMLVisitor::addNewLine(bool check)
{
FUIRichElement* lastElement = _richText->_richElements.empty() ? nullptr : _richText->_richElements.back();
if (lastElement && lastElement->_type == FUIRichElement::Type::TEXT)
{
if (!check || lastElement->text.back() != '\n')
lastElement->text += "\n";
return;
}
FUIRichElement* element = new FUIRichElement(FUIRichElement::Type::TEXT);
element->textFormat = _format;
element->text = "\n";
_richText->_richElements.push_back(element);
if (!_linkStack.empty())
element->link = _linkStack.back();
}
void FUIXMLVisitor::finishTextBlock()
{
if (!_textBlock.empty())
{
FUIRichElement* element = new FUIRichElement(FUIRichElement::Type::TEXT);
element->textFormat = _format;
element->text = _textBlock;
_textBlock.clear();
_richText->_richElements.push_back(element);
if (!_linkStack.empty())
element->link = _linkStack.back();
}
}
#pragma warning(once:4307)
void FUIXMLVisitor::startElement(void* /*ctx*/, const char *elementName, const char **atts)
{
finishTextBlock();
if (strcasecmp(elementName, "b") == 0)
{
pushTextFormat();
_format.bold = true;
}
else if (strcasecmp(elementName, "i") == 0)
{
pushTextFormat();
_format.italics = true;
}
else if (strcasecmp(elementName, "u") == 0)
{
pushTextFormat();
_format.underline = true;
}
else if (strcasecmp(elementName, "font") == 0)
{
pushTextFormat();
ValueMap&& tagAttrValueMap = tagAttrMapWithXMLElement(atts);
_format.fontSize = attributeInt(tagAttrValueMap, "size", _format.fontSize);
auto it = tagAttrValueMap.find("color");
if (it != tagAttrValueMap.end())
{
_format.color = (Color3B)ToolSet::hexToColor(it->second.asString().c_str());
_format._hasColor = true;
}
}
else if (strcasecmp(elementName, "br") == 0)
{
addNewLine(false);
}
else if (strcasecmp(elementName, "img") == 0)
{
std::string src;
ValueMap&& tagAttrValueMap = tagAttrMapWithXMLElement(atts);
int width = 0;
int height = 0;
auto it = tagAttrValueMap.find("src");
if (it != tagAttrValueMap.end()) {
src = it->second.asString();
}
if (!src.empty()) {
PackageItem* pi = UIPackage::getItemByURL(src);
if (pi)
{
width = pi->width;
height = pi->height;
}
}
width = attributeInt(tagAttrValueMap, "width", width);
height = attributeInt(tagAttrValueMap, "height", height);
if (width == 0)
width = 5;
if (height == 0)
height = 10;
FUIRichElement* element = new FUIRichElement(FUIRichElement::Type::IMAGE);
element->width = width;
element->height = height;
element->text = src;
_richText->_richElements.push_back(element);
if (!_linkStack.empty())
element->link = _linkStack.back();
}
else if (strcasecmp(elementName, "a") == 0)
{
pushTextFormat();
std::string href;
ValueMap&& tagAttrValueMap = tagAttrMapWithXMLElement(atts);
auto it = tagAttrValueMap.find("href");
if (it != tagAttrValueMap.end())
href = it->second.asString();
FUIRichElement* element = new FUIRichElement(FUIRichElement::Type::LINK);
element->text = href;
_richText->_richElements.push_back(element);
_linkStack.push_back(element);
if (_richText->_anchorTextUnderline)
_format.underline = true;
if (!_format._hasColor)
_format.color = _richText->_anchorFontColor;
}
else if (strcasecmp(elementName, "p") == 0 || strcasecmp(elementName, "ui") == 0 || strcasecmp(elementName, "div") == 0
|| strcasecmp(elementName, "li") == 0)
{
addNewLine(true);
}
else if (strcasecmp(elementName, "html") == 0 || strcasecmp(elementName, "body") == 0)
{
//full html
_ignoreWhiteSpace = true;
}
else if (strcasecmp(elementName, "head") == 0 || strcasecmp(elementName, "style") == 0 || strcasecmp(elementName, "script") == 0
|| strcasecmp(elementName, "form") == 0)
{
_skipText++;
}
}
void FUIXMLVisitor::endElement(void* /*ctx*/, const char *elementName)
{
finishTextBlock();
if (strcasecmp(elementName, "b") == 0 || strcasecmp(elementName, "i") == 0 || strcasecmp(elementName, "u") == 0
|| strcasecmp(elementName, "font") == 0)
{
popTextFormat();
}
else if (strcasecmp(elementName, "a") == 0)
{
popTextFormat();
if (!_linkStack.empty())
_linkStack.pop_back();
}
else if (strcasecmp(elementName, "head") == 0 || strcasecmp(elementName, "style") == 0 || strcasecmp(elementName, "script") == 0
|| strcasecmp(elementName, "form") == 0)
{
_skipText--;
}
}
#pragma warning(default:4307)
void FUIXMLVisitor::textHandler(void* /*ctx*/, const char *str, size_t len)
{
if (_skipText != 0)
return;
if (_ignoreWhiteSpace)
{
string s(str, len);
ltrim(s);
rtrim(s);
_textBlock += s;
}
else
_textBlock += string(str, len);
}
ValueMap FUIXMLVisitor::tagAttrMapWithXMLElement(const char ** attrs)
{
ValueMap tagAttrValueMap;
for (const char** attr = attrs; *attr != nullptr; attr = (attrs += 2)) {
if (attr[0] && attr[1]) {
tagAttrValueMap[attr[0]] = attr[1];
}
}
return tagAttrValueMap;
}
int FUIXMLVisitor::attributeInt(const ValueMap& valueMap, const std::string& key, int defaultValue)
{
auto it = valueMap.find(key);
if (it != valueMap.end()) {
string str = it->second.asString();
if (!str.empty() && str.back() == '%')
return ceil(atoi(str.substr(0, str.size() - 1).c_str()) / 100.0f*defaultValue);
else
return atoi(str.c_str());
}
else
return defaultValue;
}
FUIRichText::FUIRichText() :
_formatTextDirty(true),
_textChanged(false),
_leftSpaceWidth(0.0f),
_textRectWidth(0.0f),
_numLines(0),
_overflow(Label::Overflow::NONE),
_anchorTextUnderline(true),
_anchorFontColor(Color3B::BLUE),
_defaultTextFormat(new TextFormat())
{
}
FUIRichText::~FUIRichText()
{
for (auto &it : _richElements)
delete it;
}
bool FUIRichText::init()
{
if (!Node::init())
return false;
return true;
}
void FUIRichText::setDimensions(float width, float height)
{
if ((_numLines > 1 && width != _dimensions.width) || width < _contentSize.width)
_formatTextDirty = true;
_dimensions.setSize(width, height);
}
void FUIRichText::setText(const std::string & value)
{
_formatTextDirty = true;
_textChanged = true;
_text = value;
}
void FUIRichText::applyTextFormat()
{
_textChanged = true;
_formatTextDirty = true;
}
void FUIRichText::setOverflow(cocos2d::Label::Overflow overflow)
{
if (_overflow != overflow)
{
_overflow = overflow;
_formatTextDirty = true;
}
}
const Size & FUIRichText::getContentSize() const
{
if (_formatTextDirty)
const_cast<FUIRichText*>(this)->formatText();
return Node::getContentSize();
}
void FUIRichText::setAnchorTextUnderline(bool enable)
{
if (_anchorTextUnderline != enable)
{
_anchorTextUnderline = enable;
_formatTextDirty = true;
}
}
void FUIRichText::setAnchorFontColor(const cocos2d::Color3B & color)
{
_anchorFontColor = color;
_formatTextDirty = true;
}
const char* FUIRichText::hitTestLink(const cocos2d::Vec2 & worldPoint)
{
Rect rect;
for (auto &child : _children)
{
FUIRichElement* element = (FUIRichElement*)child->getUserData();
if (!element || !element->link)
continue;
rect.size = child->getContentSize();
if (rect.containsPoint(child->convertToNodeSpace(worldPoint)))
return element->link->text.c_str();
}
return nullptr;
}
void FUIRichText::visit(cocos2d::Renderer * renderer, const cocos2d::Mat4 & parentTransform, uint32_t parentFlags)
{
if (_visible)
formatText();
Node::visit(renderer, parentTransform, parentFlags);
}
void FUIRichText::formatText()
{
if (!_formatTextDirty)
return;
if (_textChanged)
{
_textChanged = false;
_richElements.clear();
_numLines = 0;
if (!_text.empty())
{
string xmlText = "<dummy>" + _text + "</dummy>";
FUIXMLVisitor visitor(this);
SAXParser parser;
parser.setDelegator(&visitor);
parser.parseIntrusive(&xmlText.front(), xmlText.length());
}
}
removeAllChildrenWithCleanup(true);
_elementRenders.clear();
_imageLoaders.clear();
if (_overflow == Label::Overflow::NONE)
_textRectWidth = FLT_MAX;
else
_textRectWidth = _dimensions.width - GUTTER_X * 2;
int size = (int)_richElements.size();
if (size == 0)
{
formarRenderers();
_formatTextDirty = false;
return;
}
addNewLine();
for (int i = 0; i < size; ++i)
{
FUIRichElement* element = static_cast<FUIRichElement*>(_richElements.at(i));
switch (element->_type)
{
case FUIRichElement::Type::TEXT:
{
FastSplitter fs;
fs.start(element->text.c_str(), (int)element->text.size(), '\n');
bool first = true;
while (fs.next())
{
if (!first)
addNewLine();
if (fs.getTextLength() > 0)
handleTextRenderer(element, element->textFormat, string(fs.getText(), fs.getTextLength()));
first = false;
}
break;
}
case FUIRichElement::Type::IMAGE:
handleImageRenderer(element);
break;
default:
break;
}
}
formarRenderers();
_formatTextDirty = false;
}
void FUIRichText::addNewLine()
{
_leftSpaceWidth = _textRectWidth;
_elementRenders.emplace_back();
_numLines++;
}
void FUIRichText::handleTextRenderer(FUIRichElement* element, const TextFormat& format, const std::string& text)
{
FUILabel* textRenderer = FUILabel::create();
textRenderer->setCascadeOpacityEnabled(true);
textRenderer->getTextFormat()->setFormat(format);
textRenderer->applyTextFormat();
textRenderer->setString(text);
textRenderer->setUserData(element);
float textRendererWidth = textRenderer->getContentSize().width;
_leftSpaceWidth -= textRendererWidth;
if (_leftSpaceWidth >= 0)
{
_elementRenders.back().push_back(textRenderer);
return;
}
int leftLength = findSplitPositionForWord(textRenderer, text);
//The minimum cut length is 1, otherwise will cause the infinite loop.
if (0 == leftLength) leftLength = 1;
std::string leftWords = getSubStringOfUTF8String(text, 0, leftLength);
int rightStart = leftLength;
if (std::isspace(text[rightStart], std::locale()))
rightStart++;
std::string cutWords = getSubStringOfUTF8String(text, rightStart, text.length() - leftLength);
if (leftLength > 0)
{
FUILabel* leftRenderer = FUILabel::create();
leftRenderer->setCascadeOpacityEnabled(true);
leftRenderer->getTextFormat()->setFormat(format);
leftRenderer->applyTextFormat();
leftRenderer->setString(getSubStringOfUTF8String(leftWords, 0, leftLength));
leftRenderer->setUserData(element);
_elementRenders.back().push_back(leftRenderer);
}
if (cutWords.length() > 0)
{
addNewLine();
handleTextRenderer(element, format, cutWords);
}
}
int FUIRichText::findSplitPositionForWord(cocos2d::Label* label, const std::string& text)
{
auto originalLeftSpaceWidth = _leftSpaceWidth + label->getContentSize().width;
bool startingNewLine = (_textRectWidth == originalLeftSpaceWidth);
if (!isWrappable(text))
{
if (startingNewLine)
return (int)text.length();
return 0;
}
for (int idx = (int)text.size() - 1; idx >= 0; )
{
int newidx = getPrevWord(text, idx);
if (newidx >= 0)
{
idx = newidx;
auto leftStr = getSubStringOfUTF8String(text, 0, idx);
label->setString(leftStr);
if (label->getContentSize().width <= originalLeftSpaceWidth)
return idx;
}
else
{
if (startingNewLine)
return idx;
return 0;
}
}
// no spaces... return the original label + size
label->setString(text);
return (int)text.size();
}
void FUIRichText::handleImageRenderer(FUIRichElement* element)
{
GLoader* loader = GLoader::create();
_imageLoaders.pushBack(loader);
loader->setSize(element->width, element->height);
loader->setFill(LoaderFillType::SCALE_FREE);
loader->setURL(element->text);
loader->displayObject()->setUserData(element);
_leftSpaceWidth -= (element->width + 4);
if (_leftSpaceWidth < 0.0f)
{
addNewLine();
_elementRenders.back().push_back(loader->displayObject());
_leftSpaceWidth -= (element->width + 4);
}
else
{
_elementRenders.back().push_back(loader->displayObject());
}
}
void FUIRichText::formarRenderers()
{
float nextPosY = GUTTER_Y;
float textWidth = 0;
float textHeight = 0;
for (auto& row : _elementRenders)
{
if (nextPosY != GUTTER_Y)
nextPosY += _defaultTextFormat->lineSpacing - 3;
float nextPosX = GUTTER_X;
float lineHeight = 0.0f;
float lineTextHeight = 0.0f;
for (auto& node : row)
{
lineHeight = MAX(node->getContentSize().height, lineHeight);
if (((FUIRichElement*)node->getUserData())->_type == FUIRichElement::Type::TEXT)
lineTextHeight = MAX(node->getContentSize().height, lineTextHeight);
}
nextPosY += lineHeight;
for (auto& node : row)
{
node->setAnchorPoint(Vec2::ZERO);
int adjustment = 0;
if (((FUIRichElement*)node->getUserData())->_type == FUIRichElement::Type::IMAGE)
{
nextPosX += 2;
adjustment = floor((lineHeight - node->getContentSize().height) / 2);
}
else //text
{
adjustment = floor((lineHeight - lineTextHeight) / 2);
}
node->setPosition(nextPosX, _dimensions.height - nextPosY + adjustment);
this->addChild(node, 1);
nextPosX += node->getContentSize().width;
if (((FUIRichElement*)node->getUserData())->_type == FUIRichElement::Type::IMAGE)
nextPosX += 2;
}
nextPosX += GUTTER_X;
if (nextPosX > textWidth)
textWidth = nextPosX;
if (_overflow != Label::Overflow::NONE)
doHorizontalAlignment(row, nextPosX);
}
if (textWidth == GUTTER_X + GUTTER_X)
textWidth = 0;
else if (_numLines > 1 || (_defaultTextFormat->align != TextHAlignment::LEFT && _overflow != Label::Overflow::NONE))
textWidth = MAX(_dimensions.width, textWidth);
if (nextPosY != GUTTER_Y)
textHeight = nextPosY + GUTTER_Y;
else
textHeight = 0;
setContentSize(Size(textWidth, textHeight));
float oldDimensionsHeight = _dimensions.height;
if (_overflow == Label::Overflow::NONE)
_dimensions = _contentSize;
else if (_overflow == Label::Overflow::RESIZE_HEIGHT)
_dimensions.height = _contentSize.height;
float delta = _contentSize.height - oldDimensionsHeight;
if (_defaultTextFormat->verticalAlign == TextVAlignment::CENTER)
delta -= floor((_dimensions.height - textHeight) * 0.5f);
else if (_defaultTextFormat->verticalAlign == TextVAlignment::BOTTOM)
delta -= _dimensions.height - textHeight;
if (delta != 0)
{
Vec2 offset(0, delta);
for (auto& row : _elementRenders)
{
for (auto& node : row)
{
node->setPosition(node->getPosition() + offset);
}
}
}
_elementRenders.clear();
}
void FUIRichText::doHorizontalAlignment(const std::vector<cocos2d::Node*> &row, float rowWidth) {
if (_defaultTextFormat->align != TextHAlignment::LEFT) {
const auto diff = stripTrailingWhitespace(row);
const auto leftOver = _dimensions.width - (rowWidth + diff);
const float leftPadding = getPaddingAmount(_defaultTextFormat->align, leftOver);
const Vec2 offset(leftPadding, 0.f);
for (auto& node : row) {
node->setPosition(node->getPosition() + offset);
}
}
}
NS_FGUI_END

View File

@ -0,0 +1,74 @@
#ifndef __FUIRICHTEXT_H__
#define __FUIRICHTEXT_H__
#include "cocos2d.h"
#include "FairyGUIMacros.h"
#include "TextFormat.h"
NS_FGUI_BEGIN
class FUIXMLVisitor;
class GLoader;
class FUIRichElement;
class FUIRichText : public cocos2d::Node
{
public:
FUIRichText();
virtual ~FUIRichText();
CREATE_FUNC(FUIRichText);
const cocos2d::Size& getDimensions() const { return _dimensions; }
void setDimensions(float width, float height);
void setText(const std::string& value);
TextFormat* getTextFormat() const { return _defaultTextFormat; }
void applyTextFormat();
cocos2d::Label::Overflow getOverflow()const { return _overflow; }
void setOverflow(cocos2d::Label::Overflow overflow);
bool isAnchorTextUnderline() { return _anchorTextUnderline; }
void setAnchorTextUnderline(bool enable);
const cocos2d::Color3B& getAnchorFontColor() { return _anchorFontColor; }
void setAnchorFontColor(const cocos2d::Color3B& color);
const char* hitTestLink(const cocos2d::Vec2& worldPoint);
virtual void visit(cocos2d::Renderer *renderer, const cocos2d::Mat4 &parentTransform, uint32_t parentFlags) override;
virtual const cocos2d::Size& getContentSize() const override;
protected:
virtual bool init() override;
void formatText();
void formarRenderers();
void handleTextRenderer(FUIRichElement* element, const TextFormat& format, const std::string& text);
void handleImageRenderer(FUIRichElement* element);
void addNewLine();
int findSplitPositionForWord(cocos2d::Label* label, const std::string& text);
void doHorizontalAlignment(const std::vector<cocos2d::Node*>& row, float rowWidth);
std::vector<FUIRichElement*> _richElements;
std::vector<std::vector<Node*>> _elementRenders;
cocos2d::Vector<GLoader*> _imageLoaders;
bool _formatTextDirty;
bool _textChanged;
cocos2d::Size _dimensions;
float _leftSpaceWidth;
float _textRectWidth;
int _numLines;
cocos2d::Label::Overflow _overflow;
TextFormat* _defaultTextFormat;
bool _anchorTextUnderline;
cocos2d::Color3B _anchorFontColor;
std::string _text;
friend class FUIXMLVisitor;
};
NS_FGUI_END
#endif

View File

@ -0,0 +1,535 @@
#include "FUISprite.h"
NS_FGUI_BEGIN
USING_NS_CC;
#define kProgressTextureCoordsCount 4
// kProgressTextureCoords holds points {0,1} {0,0} {1,0} {1,1} we can represent it as bits
const char kProgressTextureCoords = 0x4b;
Texture2D* FUISprite::_empty = nullptr;
FUISprite::FUISprite()
: _fillMethod(FillMethod::None),
_fillOrigin(FillOrigin::Left),
_fillAmount(0),
_fillClockwise(false),
_vertexDataCount(0),
_vertexData(nullptr),
_vertexIndex(nullptr),
_scaleByTile(false)
{
}
FUISprite::~FUISprite()
{
CC_SAFE_FREE(_vertexData);
CC_SAFE_FREE(_vertexIndex);
}
void FUISprite::clearContent()
{
setTexture(nullptr);
CC_SAFE_RELEASE_NULL(_spriteFrame);
setCenterRectNormalized(Rect(0, 0, 1, 1));
_empty = _texture;
}
void FUISprite::setScale9Grid(Rect* value)
{
if (value == nullptr)
{
setCenterRectNormalized(Rect(0, 0, 1, 1));
return;
}
Rect insets = *value;
// When Insets == Zero --> we should use a 1/3 of its untrimmed size
if (insets.equals(Rect::ZERO))
{
insets = Rect(_originalContentSize.width / 3.0f,
_originalContentSize.height / 3.0f,
_originalContentSize.width / 3.0f,
_originalContentSize.height / 3.0f);
}
// emulate invalid insets. shouldn't be supported, but the original code supported it.
if (insets.origin.x > _originalContentSize.width)
insets.origin.x = 0;
if (insets.origin.y > _originalContentSize.height)
insets.origin.y = 0;
if (insets.size.width > _originalContentSize.width)
insets.size.width = 1;
if (insets.size.height > _originalContentSize.height)
insets.size.height = 1;
// we have to convert from untrimmed to trimmed
// Sprite::setCenterRect is using trimmed values (to be compatible with Cocos Creator)
// Scale9Sprite::setCapInsects uses untrimmed values (which makes more sense)
// use _rect coordinates. recenter origin to calculate the
// intersecting rectangle
// can't use _offsetPosition since it is calculated using bottom-left as origin,
// and the center rect is calculated using top-left
insets.origin.x -= (_originalContentSize.width - _rect.size.width) / 2 + _unflippedOffsetPositionFromCenter.x;
insets.origin.y -= (_originalContentSize.height - _rect.size.height) / 2 - _unflippedOffsetPositionFromCenter.y;
// intersecting rectangle
const float x1 = std::max(insets.origin.x, 0.0f);
const float y1 = std::max(insets.origin.y, 0.0f);
const float x2 = std::min(insets.origin.x + insets.size.width, 0.0f + _rect.size.width);
const float y2 = std::min(insets.origin.y + insets.size.height, 0.0f + _rect.size.height);
// centerRect uses the trimmed frame origin as 0,0.
// so, recenter inset rect
insets.setRect(x1,
y1,
x2 - x1,
y2 - y1);
// Only update center rect while in slice mode.
setCenterRect(insets);
}
void FUISprite::setScaleByTile(bool value)
{
_scaleByTile = value;
}
void FUISprite::setGrayed(bool value)
{
#if defined(ENGINEX_VERSION)
auto isETC1 = getTexture();
Sprite::setProgramState(cocos2d::backend::ProgramType::POSITION_TEXTURE);
#elif COCOS2D_VERSION >= 0x00040000
auto isETC1 = getTexture() && getTexture()->getAlphaTextureName();
if (value) {
Sprite::updateShaders(positionTextureColor_vert, (isETC1)?etc1Gray_frag:grayScale_frag);
} else {
Sprite::updateShaders(positionTextureColor_vert, (isETC1)?etc1_frag:positionTextureColor_frag);
}
#else
GLProgramState* glState = nullptr;
if (value)
glState = GLProgramState::getOrCreateWithGLProgramName(GLProgram::SHADER_NAME_POSITION_GRAYSCALE, getTexture());
else
glState = GLProgramState::getOrCreateWithGLProgramName(GLProgram::SHADER_NAME_POSITION_TEXTURE_COLOR_NO_MVP, getTexture());
setGLProgramState(glState);
#endif
}
void FUISprite::setFillMethod(FillMethod value)
{
if (_fillMethod != value)
{
_fillMethod = value;
if (_fillMethod != FillMethod::None)
setupFill();
else
{
CC_SAFE_FREE(_vertexData);
CC_SAFE_FREE(_vertexIndex);
}
}
}
void FUISprite::setFillOrigin(FillOrigin value)
{
if (_fillOrigin != value)
{
_fillOrigin = value;
if (_fillMethod != FillMethod::None)
setupFill();
}
}
void FUISprite::setFillClockwise(bool value)
{
if (_fillClockwise != value)
{
_fillClockwise = value;
if (_fillMethod != FillMethod::None)
setupFill();
}
}
void FUISprite::setFillAmount(float value)
{
if (_fillAmount != value)
{
_fillAmount = value;
if (_fillMethod != FillMethod::None)
setupFill();
}
}
void FUISprite::setContentSize(const Size& size)
{
if (_scaleByTile)
setTextureRect(Rect(Vec2::ZERO, size));
else
Sprite::setContentSize(size);
}
void FUISprite::setupFill()
{
if (_fillMethod == FillMethod::Horizontal || _fillMethod == FillMethod::Vertical)
updateBar();
else
updateRadial();
}
//from CCFUISprite.h
///
// @returns the vertex position from the texture coordinate
///
Tex2F FUISprite::textureCoordFromAlphaPoint(Vec2 alpha)
{
Tex2F ret(0.0f, 0.0f);
V3F_C4B_T2F_Quad quad = getQuad();
Vec2 min(quad.bl.texCoords.u, quad.bl.texCoords.v);
Vec2 max(quad.tr.texCoords.u, quad.tr.texCoords.v);
// Fix bug #1303 so that progress timer handles sprite frame texture rotation
if (isTextureRectRotated())
{
std::swap(alpha.x, alpha.y);
}
return Tex2F(min.x * (1.f - alpha.x) + max.x * alpha.x, min.y * (1.f - alpha.y) + max.y * alpha.y);
}
Vec3 FUISprite::vertexFromAlphaPoint(Vec2 alpha)
{
Vec3 ret(0.0f, 0.0f, 0.0f);
V3F_C4B_T2F_Quad quad = getQuad();
Vec2 min(quad.bl.vertices.x, quad.bl.vertices.y);
Vec2 max(quad.tr.vertices.x, quad.tr.vertices.y);
ret.x = min.x * (1.f - alpha.x) + max.x * alpha.x;
ret.y = min.y * (1.f - alpha.y) + max.y * alpha.y;
return ret;
}
void FUISprite::updateColor(void)
{
Sprite::updateColor();
if (_vertexData)
{
Color4B sc = getQuad().tl.colors;
for (int i = 0; i < _vertexDataCount; ++i)
{
_vertexData[i].colors = sc;
}
}
}
///
// Update does the work of mapping the texture onto the triangles
// It now doesn't occur the cost of free/alloc data every update cycle.
// It also only changes the percentage point but no other points if they have not
// been modified.
//
// It now deals with flipped texture. If you run into this problem, just use the
// sprite property and enable the methods flipX, flipY.
///
void FUISprite::updateRadial(void)
{
float angle = 2.f * ((float)M_PI) * (_fillClockwise ? (1.0f - _fillAmount) : _fillAmount);
// We find the vector to do a hit detection based on the percentage
// We know the first vector is the one @ 12 o'clock (top,mid) so we rotate
// from that by the progress angle around the _midpoint pivot
Vec2 midpoint(0.5f, 0.5f);
Vec2 topMid(0.5f, 1.f);
Vec2 percentagePt = topMid.rotateByAngle(midpoint, angle);
int index = 0;
Vec2 hit;
if (_fillAmount == 0.f)
{
// More efficient since we don't always need to check intersection
// If the alpha is zero then the hit point is top mid and the index is 0.
hit = topMid;
index = 0;
}
else if (_fillAmount == 1.f)
{
// More efficient since we don't always need to check intersection
// If the alpha is one then the hit point is top mid and the index is 4.
hit = topMid;
index = 4;
}
else
{
// We run a for loop checking the edges of the texture to find the
// intersection point
// We loop through five points since the top is split in half
float min_t = FLT_MAX;
for (int i = 0; i <= kProgressTextureCoordsCount; ++i)
{
int pIndex = (i + (kProgressTextureCoordsCount - 1)) % kProgressTextureCoordsCount;
Vec2 edgePtA = boundaryTexCoord(i % kProgressTextureCoordsCount);
Vec2 edgePtB = boundaryTexCoord(pIndex);
// Remember that the top edge is split in half for the 12 o'clock position
// Let's deal with that here by finding the correct endpoints
if (i == 0)
{
edgePtB = edgePtA.lerp(edgePtB, 1 - midpoint.x);
}
else if (i == 4)
{
edgePtA = edgePtA.lerp(edgePtB, 1 - midpoint.x);
}
// s and t are returned by ccpLineIntersect
float s = 0, t = 0;
if (Vec2::isLineIntersect(edgePtA, edgePtB, midpoint, percentagePt, &s, &t))
{
// Since our hit test is on rays we have to deal with the top edge
// being in split in half so we have to test as a segment
if ((i == 0 || i == 4))
{
// s represents the point between edgePtA--edgePtB
if (!(0.f <= s && s <= 1.f))
{
continue;
}
}
// As long as our t isn't negative we are at least finding a
// correct hitpoint from _midpoint to percentagePt.
if (t >= 0.f)
{
// Because the percentage line and all the texture edges are
// rays we should only account for the shortest intersection
if (t < min_t)
{
min_t = t;
index = i;
}
}
}
}
// Now that we have the minimum magnitude we can use that to find our intersection
hit = midpoint + ((percentagePt - midpoint) * min_t);
}
// The size of the vertex data is the index from the hitpoint
// the 3 is for the _midpoint, 12 o'clock point and hitpoint position.
bool sameIndexCount = true;
int triangleCount = 0;
if (_vertexDataCount != index + 3)
{
sameIndexCount = false;
CC_SAFE_FREE(_vertexData);
CC_SAFE_FREE(_vertexIndex);
_vertexDataCount = 0;
}
if (!_vertexData)
{
_vertexDataCount = index + 3;
triangleCount = _vertexDataCount - 2;
_vertexData = (V3F_C4B_T2F*)malloc(_vertexDataCount * sizeof(*_vertexData));
_vertexIndex = (unsigned short *)malloc(triangleCount * 3 * sizeof(*_vertexIndex));
CCASSERT(_vertexData, "FUISprite. Not enough memory");
}
else
{
triangleCount = _vertexDataCount - 2;
}
updateColor();
if (!sameIndexCount)
{
// First we populate the array with the _midpoint, then all
// vertices/texcoords/colors of the 12 'o clock start and edges and the hitpoint
_vertexData[0].texCoords = textureCoordFromAlphaPoint(midpoint);
_vertexData[0].vertices = vertexFromAlphaPoint(midpoint);
_vertexData[1].texCoords = textureCoordFromAlphaPoint(topMid);
_vertexData[1].vertices = vertexFromAlphaPoint(topMid);
for (int i = 0; i < index; ++i)
{
Vec2 alphaPoint = boundaryTexCoord(i);
_vertexData[i + 2].texCoords = textureCoordFromAlphaPoint(alphaPoint);
_vertexData[i + 2].vertices = vertexFromAlphaPoint(alphaPoint);
}
}
// hitpoint will go last
_vertexData[_vertexDataCount - 1].texCoords = textureCoordFromAlphaPoint(hit);
_vertexData[_vertexDataCount - 1].vertices = vertexFromAlphaPoint(hit);
for (int i = 0; i < triangleCount; i++) {
_vertexIndex[i * 3] = 0;
_vertexIndex[i * 3 + 1] = i + 1;
_vertexIndex[i * 3 + 2] = i + 2;
}
_fillTriangles.verts = _vertexData;
_fillTriangles.vertCount = _vertexDataCount;
_fillTriangles.indices = _vertexIndex;
_fillTriangles.indexCount = triangleCount * 3;
}
///
// Update does the work of mapping the texture onto the triangles for the bar
// It now doesn't occur the cost of free/alloc data every update cycle.
// It also only changes the percentage point but no other points if they have not
// been modified.
//
// It now deals with flipped texture. If you run into this problem, just use the
// sprite property and enable the methods flipX, flipY.
///
void FUISprite::updateBar(void)
{
Vec2 min, max;
if (_fillMethod == FillMethod::Horizontal)
{
if (_fillOrigin == FillOrigin::Left || _fillOrigin == FillOrigin::Top)
{
min = Vec2(0, 0);
max = Vec2(_fillAmount, 1);
}
else
{
min = Vec2(1 - _fillAmount, 0);
max = Vec2(1, 1);
}
}
else
{
if (_fillOrigin == FillOrigin::Left || _fillOrigin == FillOrigin::Top)
{
min = Vec2(0, 1 - _fillAmount);
max = Vec2(1, 1);
}
else
{
min = Vec2(0, 0);
max = Vec2(1, _fillAmount);
}
}
if (!_vertexData)
{
_vertexDataCount = 4;
_vertexData = (V3F_C4B_T2F*)malloc(_vertexDataCount * sizeof(*_vertexData));
_vertexIndex = (unsigned short*)malloc(6 * sizeof(*_vertexIndex));
CCASSERT(_vertexData, "FUISprite. Not enough memory");
}
// TOPLEFT
_vertexData[0].texCoords = textureCoordFromAlphaPoint(Vec2(min.x, max.y));
_vertexData[0].vertices = vertexFromAlphaPoint(Vec2(min.x, max.y));
// BOTLEFT
_vertexData[1].texCoords = textureCoordFromAlphaPoint(Vec2(min.x, min.y));
_vertexData[1].vertices = vertexFromAlphaPoint(Vec2(min.x, min.y));
// TOPRIGHT
_vertexData[2].texCoords = textureCoordFromAlphaPoint(Vec2(max.x, max.y));
_vertexData[2].vertices = vertexFromAlphaPoint(Vec2(max.x, max.y));
// BOTRIGHT
_vertexData[3].texCoords = textureCoordFromAlphaPoint(Vec2(max.x, min.y));
_vertexData[3].vertices = vertexFromAlphaPoint(Vec2(max.x, min.y));
_vertexIndex[0] = 0;
_vertexIndex[1] = 1;
_vertexIndex[2] = 2;
_vertexIndex[3] = 2;
_vertexIndex[4] = 1;
_vertexIndex[5] = 3;
_fillTriangles.verts = _vertexData;
_fillTriangles.vertCount = 4;
_fillTriangles.indices = _vertexIndex;
_fillTriangles.indexCount = 6;
updateColor();
}
Vec2 FUISprite::boundaryTexCoord(char index)
{
if (index < kProgressTextureCoordsCount)
{
if (!_fillClockwise)
{
return Vec2((kProgressTextureCoords >> (7 - (index << 1))) & 1, (kProgressTextureCoords >> (7 - ((index << 1) + 1))) & 1);
}
else
{
return Vec2((kProgressTextureCoords >> ((index << 1) + 1)) & 1, (kProgressTextureCoords >> (index << 1)) & 1);
}
}
return Vec2::ZERO;
}
void FUISprite::draw(cocos2d::Renderer* renderer, const cocos2d::Mat4& transform, uint32_t flags)
{
if (_texture == _empty)
return;
if (_fillMethod == FillMethod::None)
Sprite::draw(renderer, transform, flags);
else
{
#if COCOS2D_VERSION >= 0x00040000
setMVPMatrixUniform();
#endif
#if CC_USE_CULLING
// Don't calculate the culling if the transform was not updated
auto visitingCamera = Camera::getVisitingCamera();
auto defaultCamera = Camera::getDefaultCamera();
if (visitingCamera == nullptr) {
_insideBounds = true;
}
else if (visitingCamera == defaultCamera) {
_insideBounds = ((flags & FLAGS_TRANSFORM_DIRTY) || visitingCamera->isViewProjectionUpdated()) ? renderer->checkVisibility(transform, _contentSize) : _insideBounds;
}
else
{
// XXX: this always return true since
_insideBounds = renderer->checkVisibility(transform, _contentSize);
}
if(_insideBounds)
#endif
{
_trianglesCommand.init(_globalZOrder,
_texture,
#if COCOS2D_VERSION < 0x00040000
getGLProgramState(),
#endif
_blendFunc,
_fillTriangles,
transform,
flags);
renderer->addCommand(&_trianglesCommand);
}
}
}
NS_FGUI_END

View File

@ -0,0 +1,66 @@
#ifndef __FUISPRITE_H__
#define __FUISPRITE_H__
#include "cocos2d.h"
#include "FairyGUIMacros.h"
NS_FGUI_BEGIN
class FUISprite : public cocos2d::Sprite
{
public:
FUISprite();
virtual ~FUISprite();
CREATE_FUNC(FUISprite);
void clearContent();
void setScale9Grid(cocos2d::Rect* value);
void setGrayed(bool value);
FillMethod getFillMethod() const { return _fillMethod; }
void setFillMethod(FillMethod value);
FillOrigin getFillOrigin() const { return _fillOrigin; }
void setFillOrigin(FillOrigin value);
bool isFillClockwise() const { return _fillClockwise; }
void setFillClockwise(bool value);
float getFillAmount() const { return _fillAmount; }
void setFillAmount(float value);
bool isScaleByTile() const { return _scaleByTile; }
void setScaleByTile(bool value);
virtual void setContentSize(const cocos2d::Size& size) override;
protected:
virtual void draw(cocos2d::Renderer *renderer, const cocos2d::Mat4 &transform, uint32_t flags) override;
cocos2d::Tex2F textureCoordFromAlphaPoint(cocos2d::Vec2 alpha);
cocos2d::Vec3 vertexFromAlphaPoint(cocos2d::Vec2 alpha);
void updateBar(void);
void updateRadial(void);
virtual void updateColor(void) override;
cocos2d::Vec2 boundaryTexCoord(char index);
void setupFill();
private:
FillMethod _fillMethod;
FillOrigin _fillOrigin;
float _fillAmount;
bool _fillClockwise;
bool _scaleByTile;
int _vertexDataCount;
cocos2d::TrianglesCommand::Triangles _fillTriangles;
cocos2d::V3F_C4B_T2F *_vertexData;
unsigned short *_vertexIndex;
static cocos2d::Texture2D* _empty;
};
NS_FGUI_END
#endif

View File

@ -0,0 +1,59 @@
#include "TextFormat.h"
NS_FGUI_BEGIN
USING_NS_CC;
TextFormat::TextFormat() :
fontSize(12),
color(Color3B::BLACK),
bold(false),
italics(false),
underline(false),
lineSpacing(3),
letterSpacing(0),
align(TextHAlignment::LEFT),
verticalAlign(TextVAlignment::TOP),
effect(0),
outlineSize(1),
shadowBlurRadius(0),
_hasColor(false)
{
}
TextFormat::TextFormat(const TextFormat & other)
{
*this = other;
}
TextFormat & TextFormat::operator=(const TextFormat & other)
{
if (this != &other)
{
face = other.face;
fontSize = other.fontSize;
color = other.color;
bold = other.bold;
italics = other.italics;
underline = other.underline;
lineSpacing = other.lineSpacing;
letterSpacing = other.letterSpacing;
align = other.align;
verticalAlign = other.verticalAlign;
effect = other.effect;
outlineColor = other.outlineColor;
outlineSize = other.outlineSize;
shadowColor = other.shadowColor;
shadowOffset = other.shadowOffset;
shadowBlurRadius = other.shadowBlurRadius;
glowColor = other.glowColor;
_hasColor = other._hasColor;
}
return *this;
}
void TextFormat::setFormat(const TextFormat & format)
{
*this = format;
}
NS_FGUI_END

View File

@ -0,0 +1,50 @@
#ifndef __TEXTFORMAT_H__
#define __TEXTFORMAT_H__
#include "cocos2d.h"
#include "FairyGUIMacros.h"
NS_FGUI_BEGIN
class TextFormat
{
public:
TextFormat();
TextFormat(const TextFormat & other);
TextFormat &operator =(const TextFormat & other);
void setFormat(const TextFormat& format);
void enableEffect(int effectFlag) { effect |= effectFlag; }
void disableEffect(int effectFlag) { effect &= ~effectFlag; }
bool hasEffect(int effectFlag) const { return (effect & effectFlag) != 0; }
static const int OUTLINE = 1;
static const int SHADOW = 2;
static const int GLOW = 4;
std::string face;
float fontSize;
cocos2d::Color3B color;
bool bold;
bool italics;
bool underline;
int lineSpacing;
int letterSpacing;
cocos2d::TextHAlignment align;
cocos2d::TextVAlignment verticalAlign;
int effect;
cocos2d::Color3B outlineColor;
int outlineSize;
cocos2d::Color3B shadowColor;
cocos2d::Size shadowOffset;
int shadowBlurRadius;
cocos2d::Color3B glowColor;
//internal use
bool _hasColor;
};
NS_FGUI_END
#endif

View File

@ -0,0 +1,23 @@
#include "EventContext.h"
#include "GObject.h"
NS_FGUI_BEGIN
EventContext::EventContext() :
_sender(nullptr),
_data(nullptr),
_inputEvent(nullptr),
_isStopped(false),
_defaultPrevented(false),
_touchCapture(0),
_type(0)
{
}
EventContext::~EventContext()
{
}
NS_FGUI_END

View File

@ -0,0 +1,46 @@
#ifndef __EVENTCONTEXT_H__
#define __EVENTCONTEXT_H__
#include "FairyGUIMacros.h"
#include "cocos2d.h"
#include "InputEvent.h"
NS_FGUI_BEGIN
class GObject;
class InputProcessor;
class EventContext
{
public:
EventContext();
~EventContext();
int getType() const { return _type; }
cocos2d::Ref* getSender() const { return _sender; }
InputEvent* getInput() const { return _inputEvent; }
void stopPropagation() { _isStopped = true; }
void preventDefault() { _defaultPrevented = true; }
bool isDefaultPrevented() { return _defaultPrevented; }
void captureTouch() { _touchCapture = 1; }
void uncaptureTouch() { _touchCapture = 2; }
const cocos2d::Value& getDataValue() const { return _dataValue; }
void* getData() const { return _data; }
private:
cocos2d::Ref* _sender;
InputEvent* _inputEvent;
cocos2d::Value _dataValue;
void* _data;
bool _isStopped;
bool _defaultPrevented;
int _touchCapture;
int _type;
friend class UIEventDispatcher;
};
NS_FGUI_END
#endif

View File

@ -0,0 +1,58 @@
#include "HitTest.h"
#include "GComponent.h"
#include "utils/ByteBuffer.h"
USING_NS_CC;
NS_FGUI_BEGIN
PixelHitTestData::PixelHitTestData() :
pixels(nullptr),
pixelsLength(0),
pixelWidth(0),
scale(1)
{
}
PixelHitTestData::~PixelHitTestData()
{
CC_SAFE_DELETE(pixels);
}
void PixelHitTestData::load(ByteBuffer* buffer)
{
buffer->skip(4);
pixelWidth = buffer->readInt();
scale = 1.0f / buffer->readByte();
pixelsLength = buffer->readInt();
pixels = new unsigned char[pixelsLength];
for (size_t i = 0; i < pixelsLength; i++)
pixels[i] = buffer->readByte();
}
PixelHitTest::PixelHitTest(PixelHitTestData * data, int offsetX, int offsetY) :
offsetX(offsetX),
offsetY(offsetY),
scaleX(1),
scaleY(1),
_data(data)
{
}
bool PixelHitTest::hitTest(GComponent * obj, const cocos2d::Vec2 & localPoint)
{
int x = floor((localPoint.x / scaleX - offsetX) * _data->scale);
int y = floor(((obj->getHeight() - localPoint.y) / scaleY - offsetY) * _data->scale);
if (x < 0 || y < 0 || x >= _data->pixelWidth)
return false;
ssize_t pos = y * _data->pixelWidth + x;
ssize_t pos2 = pos / 8;
ssize_t pos3 = pos % 8;
if (pos2 >= 0 && pos2 < (ssize_t)_data->pixelsLength)
return ((_data->pixels[pos2] >> pos3) & 0x1) > 0;
else
return false;
}
NS_FGUI_END

Some files were not shown because too many files have changed in this diff Show More