#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_NULL(_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