AniSimpleButton.cpp 7.07 KB
//
//  AniSimpleButton.cpp
//  SteveMaggieCpp
//
//  Created by Katarzyna Kalinowska-Górska on 17.05.2017.
//
//

#include <stdio.h>
#include "AniSimpleButton.h"
#include "AniJSONParseUtils.h"
#include "AniValueStorage.h"
#include "AniGeometryUtils.h"
#include "AniMiscConfig.h"
#include "AniScalingUtils.h"
#include "AniStaticActionParser.h"

AniSimpleButton* AniSimpleButton::create()
{
    AniSimpleButton * button = new (std::nothrow) AniSimpleButton();
    if(button && button->init())
    {
        button->autorelease();
        return button;
    }
    CC_SAFE_DELETE(button);
    return nullptr;
}

bool AniSimpleButton::init()
{
    if(!cocos2d::ui::Button::init()){
        return false;
    }
    
    _originalScale = 1;
    _adjustScaleOnPress = true;
    _touchBeganCallback = [](std::string objectName, cocos2d::ui::Widget::TouchEventType){};
    _touchEndedCallback = [](std::string objectName,cocos2d::ui::Widget::TouchEventType){};
    _touchCancelledCallback = [](std::string objectName,cocos2d::ui::Widget::TouchEventType){};
    _buttonOwnTouchBehaviour.onTouchBegan = [](){};
    _buttonOwnTouchBehaviour.onTouchEnded = [](){};
    _buttonOwnTouchBehaviour.onTouchCancelled = [](){};
    _cascadeOpacityEnabled = true;
    
    this->configureTouchListeners();
    
    setScale(_originalScale);
    
    return true;
}

void AniSimpleButton::loadPropertiesFromJSON(const rapidjson::Value& jsonValue, AniLayoutViewInterface* scene, const std::string resFolder, const std::string altResFolder)
{
    this->loadCommonPropertiesFromJSON(jsonValue);
    
    if(jsonValue.HasMember("imagePath")){
        std::string imagePath = jsonValue["imagePath"].GetString();
        if(AniJSONParseUtils::checkMemberBool(jsonValue, "useAlternativePath", true))
        {
            imagePath = altResFolder + imagePath;
        } else {
            imagePath = resFolder + imagePath;
        }
        
        this->loadTextures(imagePath, imagePath, imagePath);
    }
    
    if(AniJSONParseUtils::hasMemberFloat(jsonValue, "scale")){
        _originalScale = jsonValue["scale"].GetFloat();
    }
    
    if(AniScalingUtils::isSmallDevice()){
        if(AniScalingUtils::isElementTooSmallForSmallDevice(getContentSize().width) || (AniJSONParseUtils::hasMemberBool(jsonValue, "scaleUpForSmallDevices") && jsonValue["scaleUpForSmallDevices"].GetBool() == true)){
                _originalScale *= AniScalingUtils::getScaleForSmallDevice();
                setScale(_originalScale);
        }
    }
    
    if(AniJSONParseUtils::hasMemberPoint(jsonValue, "anchorPoint")){
        this->setAnchorPoint(AniJSONParseUtils::getMemberPoint(jsonValue, "anchorPoint"));
    }
    
    if(AniJSONParseUtils::hasMemberBool(jsonValue, "adjustScaleOnPress")){
        _adjustScaleOnPress = jsonValue["adjustScaleOnPress"].GetBool();
    }
    
    if(AniJSONParseUtils::hasMemberObject(jsonValue, "buttonAniActionData")){
        
        const auto& buttonAniActionData = jsonValue["buttonAniActionData"];
        
        static int containerNumber = 0;
        std::string Container = "AniSimpleButtonContainer" + std::to_string((containerNumber++)%100);
        
        if(AniJSONParseUtils::hasMemberObject(buttonAniActionData, "onTouchBegan")){
            
            const auto& onTouchBeganJson = buttonAniActionData["onTouchBegan"];
            
            auto key = AniValueStorage::getInstance().storeValue(onTouchBeganJson, Container);
            
            _buttonOwnTouchBehaviour.onTouchBegan = std::bind([&](std::string storedValueKey, std::string container) {

                auto storedOnTouchBeganJson = AniValueStorage::getInstance().getStoredValue(storedValueKey, container);
                AniStaticActionParser::parseStaticAction(*storedOnTouchBeganJson);
            }, key, Container);
            
        }
        
        if(AniJSONParseUtils::hasMemberObject(buttonAniActionData, "onTouchEnded")){
            
            const auto& onTouchEndedJson = buttonAniActionData["onTouchEnded"];
            auto key = AniValueStorage::getInstance().storeValue(onTouchEndedJson, Container);
            
            _buttonOwnTouchBehaviour.onTouchEnded = std::bind([&](std::string storedValueKey, std::string container) {
                AniStaticActionParser::parseStaticAction(*AniValueStorage::getInstance().getStoredValue(storedValueKey, container));
            }, key, Container);
            
        }
        
        //TODO onTouchCancelled, if required
    }
}

void AniSimpleButton::prepareSize(const rapidjson::Value& jsonValue, float& width, float& height)
{
    auto size = this->getNormalTextureSize();
    width = size.width*_originalScale;
    height = size.height*_originalScale;
}

bool AniSimpleButton::isWidget()
{
    return true;
}

void AniSimpleButton::setOnTouchBeganCallback(std::function<void(std::string, cocos2d::ui::Widget::TouchEventType)> callback)
{
    _touchBeganCallback = callback;
}

void AniSimpleButton::setOnTouchEndedCallback(std::function<void(std::string, cocos2d::ui::Widget::TouchEventType)> callback)
{
    _touchEndedCallback = callback;
}

void AniSimpleButton::setOnTouchCancelledCallback(std::function<void(std::string, cocos2d::ui::Widget::TouchEventType)> callback)
{
    _touchCancelledCallback = callback;
}

void AniSimpleButton::setOriginalScale(float scale)
{
    _originalScale = scale;
}

float AniSimpleButton::getOriginalScale()
{
    return _originalScale;
}

void AniSimpleButton::imitateTouchDown()
{
    if (_adjustScaleOnPress)
    {
        this->setScale(AniMiscConfig::HighlightedButtonScale*_originalScale);
    }
}

void AniSimpleButton::imitateTouchUp()
{
    if (_adjustScaleOnPress)
    {
        this->setScale(_originalScale);
    }
}

void AniSimpleButton::configureTouchListeners()
{
    Widget::ccWidgetTouchCallback touchListener = [&](Ref* button,Widget::TouchEventType touchEventType){
        
        auto simpleButton = dynamic_cast<AniSimpleButton*>(button);
        
        if(touchEventType == Widget::TouchEventType::BEGAN){

           if (_adjustScaleOnPress) {
               simpleButton->setScale(AniMiscConfig::HighlightedButtonScale*_originalScale);
           }
           simpleButton->_buttonOwnTouchBehaviour.onTouchBegan();
           simpleButton->_touchBeganCallback(simpleButton->objectName, cocos2d::ui::Widget::TouchEventType::BEGAN);
        
        }
        
        else if(touchEventType == Widget::TouchEventType::ENDED){
            if (_adjustScaleOnPress) {
                simpleButton->setScale(_originalScale);
            }
            simpleButton->_buttonOwnTouchBehaviour.onTouchEnded();
            simpleButton->_touchEndedCallback(simpleButton->objectName, cocos2d::ui::Widget::TouchEventType::ENDED);
        }
        
        else if(touchEventType == Widget::TouchEventType::CANCELED){
            if (_adjustScaleOnPress) {
                simpleButton->setScale(_originalScale);
            }
            simpleButton->_buttonOwnTouchBehaviour.onTouchCancelled();
            simpleButton->_touchCancelledCallback(simpleButton->objectName, cocos2d::ui::Widget::TouchEventType::CANCELED);
        }
        
    };

    this->addTouchEventListener(touchListener);
}