ToyPaletteComponentSprite.cpp 8.93 KB
//
//  ToyPaletteComponentSprite.cpp
//  SteveMaggieCpp
//
//  Created by Katarzyna Kalinowska-Górska on 17.05.2017.
//
//

#include <stdio.h>
#include "ToyPaletteComponentSprite.h"
#include "cocos2d.h"
#include "ToyJSONParseUtils.h"
#include "ToySoundsRepo.h"
#include "ToyPaletteNode.h"
#include "ToyGeometryUtils.h"
#include "ToyResourceUtilities.h"

ToyPaletteComponentSprite* ToyPaletteComponentSprite::createWithFile(std::string filePath, bool swallowTouches)
{
    ToyPaletteComponentSprite * sprite = new (std::nothrow) ToyPaletteComponentSprite();
    if(sprite && sprite->initWithFile(filePath, swallowTouches))
    {
        sprite->autorelease();
        return sprite;
    }
    CC_SAFE_DELETE(sprite);
    return nullptr;
}

bool ToyPaletteComponentSprite::initWithFile(std::string filePath, bool swallowTouches)
{
    if(!ToyPlainSprite::initWithFile(filePath)){
        return false;
    }
    
    _enabled = true;
    _pressed = false;
    _chosen = false;
    _allowChoosing = true;
    
    _chosenScale = 1.35;
    _pressedScale = 1.1;
    _normalScale = 1;
    
    _chosenRotation = 20;
    _normalRotation = 0;
    
    _chosenDepth = 10;
    _pressedDepth = 10;
    _normalDepth = 0;
    
    _colour = cocos2d::Color3B(0,0,0);
    _brushSize = 0;
    
    _touchSize = cocos2d::Size(0,0);
    _soundPath = "";
    
    this->configureTouchListeners(swallowTouches);
    
    return true;
}

void ToyPaletteComponentSprite::loadPropertiesFromJSON(const rapidjson::Value& jsonValue, ToyLayoutViewInterface* scene, const std::string resFolder, const std::string altResFolder)
{
    ToyPlainSprite::loadPropertiesFromJSON(jsonValue, scene, resFolder, altResFolder);
    
    if(ToyJSONParseUtils::hasMemberInt(jsonValue, "depth")){
        _normalDepth = jsonValue["depth"].GetInt();
    }
    
    if(ToyJSONParseUtils::hasMemberFloat(jsonValue, "scale")){
        _normalScale = jsonValue["scale"].GetFloat();
    }
    
    if(ToyJSONParseUtils::hasMemberFloat(jsonValue, "rotation")){
        _normalRotation = jsonValue["rotation"].GetFloat();
    }
    
    if(ToyJSONParseUtils::hasMemberFloat(jsonValue, "chosenScale")){
        _chosenScale = jsonValue["chosenScale"].GetFloat();
    }
    
    if(ToyJSONParseUtils::hasMemberFloat(jsonValue, "chosenRotation")){
        _chosenRotation = jsonValue["chosenRotation"].GetFloat();
    }
    
    if(ToyJSONParseUtils::hasMemberFloat(jsonValue, "pressedScale")){
        _pressedScale = jsonValue["pressedScale"].GetFloat();
    }
    
    if(ToyJSONParseUtils::hasMemberColor3B(jsonValue, "colour")){
        _colour = ToyJSONParseUtils::getColor3B(jsonValue["colour"]);
    }
    
    if(ToyJSONParseUtils::hasMemberFloat(jsonValue, "brushSize")){ //TODO refactor as additional data void* or something
        _brushSize = jsonValue["brushSize"].GetFloat();
    }
    
    if(ToyJSONParseUtils::hasMemberSize(jsonValue, "touchSize")){
        _touchSize = ToyJSONParseUtils::getMemberSize(jsonValue, "touchSize");
    }
    
    if(ToyJSONParseUtils::hasMemberString(jsonValue, "soundPath")){
        _soundPath = ToyResourceUtilities::getInstance().getFullPathForDownloadedFile(jsonValue["soundPath"].GetString(), false);
    }
}

//void ToyPaletteComponentSprite::onEnter()
//{
//    ToyPlainSprite::onEnter();
//    
//    
//}

void ToyPaletteComponentSprite::configureTouchListeners(bool swallowTouches)
{
    auto touchListener = cocos2d::EventListenerTouchOneByOne::create();
    touchListener->setSwallowTouches(swallowTouches);
    
    touchListener->onTouchBegan = [&](cocos2d::Touch* touch, cocos2d::Event* event){
    
        if(_enabled && this->getTouchArea().containsPoint(touch->getLocation())){
            
            _pressed = true;
            this->setScale(_pressedScale);
            this->getParent()->reorderChild(this, _pressedDepth);
            this->notifyParentPalette();
        
            return true;
        }
        
        return false;
    };
    
    touchListener->onTouchEnded = touchListener->onTouchCancelled = [&](cocos2d::Touch* touch, cocos2d::Event* event){
        
         if(!_allowChoosing){
                
            this->setScale(_normalScale);
            this->getParent()->reorderChild(this, _normalDepth);
            
         } else if(!this->setChosen(true, true)){ //if chosen did not change, adjust scale approppriately
            if(_chosen){
                this->setScale(_chosenScale);
                this->getParent()->reorderChild(this, _chosenDepth);
            } else {
                this->setScale(_normalScale);
                this->getParent()->reorderChild(this, _normalDepth);
            }
        };
        
        _pressed = false;
        this->notifyParentPalette();
    };
    
    
    _eventDispatcher->addEventListenerWithSceneGraphPriority(touchListener, this);
}

bool ToyPaletteComponentSprite::isChosen()
{
    return _chosen;
}

bool ToyPaletteComponentSprite::setChosen(bool chosen, bool animated, bool silent, bool notifyParentPalette)
{
    if(!_enabled || _chosen == chosen){
        return false;
    }
    
    if(animated){
    
         if(chosen){
         
            auto scaleAction = cocos2d::ScaleTo::create(0.2, _chosenScale);
            auto rotateAction = cocos2d::RotateTo::create(0.2, _chosenRotation);
            this->runAction(cocos2d::Spawn::create(scaleAction, rotateAction, NULL));
         
         } else {
         
            auto scaleAction = cocos2d::ScaleTo::create(0.2, _normalScale);
            auto rotateAction = cocos2d::RotateTo::create(0.2, _normalRotation);
            this->runAction(cocos2d::Spawn::create(scaleAction, rotateAction, NULL));
         }
    
    } else {
    
         if(chosen){
            this->setScale(_chosenScale);
            this->setRotation(_chosenRotation);
         } else {
            this->setScale(_normalScale);
            this->setRotation(_normalRotation);
         }
     }
     
     _chosen = chosen;
     auto newZ = chosen ? _chosenDepth : _normalDepth;
     this->getParent()->reorderChild(this, newZ);
     
     if(_chosen && _soundPath != "" && !silent){
//         printf(_soundPath.c_str());
         ToySoundsRepo::playSound(_soundPath);
//        CocosDenshion::SimpleAudioEngine::getInstance()->playEffect(_soundPath.c_str(), false);
     }
     
     this->notifyParentPalette();
     
     return true;
}

void ToyPaletteComponentSprite::setEnabled(bool isEnabled, bool adjustOpacity, bool animated)
{
    if(!isEnabled){
        this->setChosen(false, false);
    }
    
    _enabled = isEnabled;
    
    if(adjustOpacity){
        if(animated){
           if(_enabled){
                this->runAction(cocos2d::FadeIn::create(0.2));
            } else {
                this->runAction(cocos2d::FadeTo::create(0.2, 128));
            }
            
        } else {
            if(_enabled){
                this->setOpacity(255);
            } else {
                this->setOpacity(128);
            }
        }
    }

}

void ToyPaletteComponentSprite::notifyParentPalette()
{
    auto parent = dynamic_cast<ToyLayoutObject*>(this->getParent());
    if(parent->className == "PaletteNode"){
        auto parentToyPaletteNode = dynamic_cast<ToyPaletteNode*>(parent);
        parentToyPaletteNode->paletteComponentStateChanged(this, _chosen, _pressed);
    }
}

cocos2d::Rect ToyPaletteComponentSprite::getTouchArea() //warning: only good fo anchor point 0.5,0.5
{
    if(_touchSize.width > 0 && _touchSize.height > 0){
        auto locationToWorld = this->getParent()->convertToWorldSpace(this->getPosition());
        return cocos2d::Rect(locationToWorld.x - _touchSize.width/2, locationToWorld.y - _touchSize.height/2, _touchSize.width, _touchSize.height);
    }

    return ToyGeometryUtils::getBoundingBoxToWorld(this, true);
}

cocos2d::Color3B ToyPaletteComponentSprite::getColour()
{
    return _colour;
}

float ToyPaletteComponentSprite::getBrushSize()
{
    return _brushSize;
}

// Scenario Object

void ToyPaletteComponentSprite::setProperty(std::string propertyName, const rapidjson::Value& newValue, ActionParseDelegate* parseDelegate)
{
    ToyPlainSprite::setProperty(propertyName, newValue, parseDelegate);
    
    if(propertyName == "allowChoosing"){
        if(newValue.IsBool()){
            _allowChoosing = newValue.GetBool();
        }
        else if(newValue.IsInt()){
            _allowChoosing = newValue.GetInt();
        }
    }
}

void ToyPaletteComponentSprite::callFunctionByName(std::string methodName, const rapidjson::Value* arguments, ActionParseDelegate* parseDelegate, std::function<void()> callback)
{
    ToyPlainSprite::callFunctionByName(methodName, arguments, parseDelegate);
    
    if(methodName == "setEnabled"){
        if((*arguments).IsArray()){
            auto args = (*arguments).GetArray();
            this->setEnabled(args[0].GetBool(), args[1].GetBool(), args[2].GetBool());
        }
    }
}

std::string ToyPaletteComponentSprite::getPropertyAsString(std::string propertyName)
{
    if(propertyName == "chosen"){
        return _chosen ? "true" : "false";
    }
    
    return "NULL";
}