SimpleButton.cpp 6.91 KB
//
//  SimpleButton.cpp
//  SteveMaggieCpp
//
//  Created by Katarzyna Kalinowska-Górska on 17.05.2017.
//
//

#include <stdio.h>
#include "SimpleButton.h"
#include "JSONParseUtils.h"
#include "ValueStorage.h"
#include "GeometryUtils.h"
#include "MiscConfig.h"
#include "ScalingUtils.h"
#include "StaticActionParser.h"

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

bool SimpleButton::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 SimpleButton::loadPropertiesFromJSON(const rapidjson::Value& jsonValue, LayoutViewInterface* scene, const std::string resFolder, const std::string altResFolder)
{
    this->loadCommonPropertiesFromJSON(jsonValue);
    
    if(jsonValue.HasMember("imagePath")){
        std::string imagePath = jsonValue["imagePath"].GetString();
        if(JSONParseUtils::checkMemberBool(jsonValue, "useAlternativePath", true))
        {
            imagePath = altResFolder + imagePath;
        } else {
            imagePath = resFolder + imagePath;
        }
        
        this->loadTextures(imagePath, imagePath, imagePath);
    }
    
    if(JSONParseUtils::hasMemberFloat(jsonValue, "scale")){
        _originalScale = jsonValue["scale"].GetFloat();
    }
    
    if(ScalingUtils::isSmallDevice()){
        if(ScalingUtils::isElementTooSmallForSmallDevice(getContentSize().width) || (JSONParseUtils::hasMemberBool(jsonValue, "scaleUpForSmallDevices") && jsonValue["scaleUpForSmallDevices"].GetBool() == true)){
                _originalScale *= ScalingUtils::getScaleForSmallDevice();
                setScale(_originalScale);
        }
    }
    
    if(JSONParseUtils::hasMemberPoint(jsonValue, "anchorPoint")){
        this->setAnchorPoint(JSONParseUtils::getMemberPoint(jsonValue, "anchorPoint"));
    }
    
    if(JSONParseUtils::hasMemberBool(jsonValue, "adjustScaleOnPress")){
        _adjustScaleOnPress = jsonValue["adjustScaleOnPress"].GetBool();
    }
    
    if(JSONParseUtils::hasMemberObject(jsonValue, "buttonActionData")){
        
        const auto& buttonActionData = jsonValue["buttonActionData"];
        
        static int containerNumber = 0;
        std::string Container = "SimpleButtonContainer" + std::to_string((containerNumber++)%100);
        
        if(JSONParseUtils::hasMemberObject(buttonActionData, "onTouchBegan")){
            
            const auto& onTouchBeganJson = buttonActionData["onTouchBegan"];
            
            auto key = ValueStorage::getInstance().storeValue(onTouchBeganJson, Container);
            
            _buttonOwnTouchBehaviour.onTouchBegan = std::bind([&](std::string storedValueKey, std::string container) {

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

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

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

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

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

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

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

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

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

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

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

           if (_adjustScaleOnPress) {
               simpleButton->setScale(MiscConfig::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);
}