SceneWithUtils.cpp 6.11 KB
//
//  SceneWithUtils.cpp
//  SteveMaggieCpp
//
//  Created by Katarzyna Kalinowska-Górska on 11.05.2017.
//
//

#include <stdio.h>
#include "SceneWithUtils.h"
#include "TouchInterceptingLayer.h"
#include "GeometryUtils.h"
#include "MiscUtils.h"

bool SceneWithUtils::init()
{
    if(!cocos2d::Scene::init())
    {
        return false;
    }
    
    _currentDialogView = NULL;
    _currentLoadingView = NULL;
    _dialogDismissCallback = [](){};
    _dialogPresentCallback = [](){};
    _scenePresentCallback = [](){};
    _sceneDismissCallback = [](){};
    _backgroundMusicFilePath = "";
    
    _touchOutsideDismissesDialog = true;
    
    return true;
}

void SceneWithUtils::onEnterTransitionDidFinish()
{
    cocos2d::Scene::onEnterTransitionDidFinish();
    _scenePresentCallback();
}

void SceneWithUtils::onExit()
{
    cocos2d::Scene::onExit();
    _sceneDismissCallback();
}

void SceneWithUtils::presentDialog(cocos2d::Node* dialogView, AnimationType presentAnimationType, AnimationType dismissAnimationType, const std::function<void()> presentCallback)
{
    auto winSize = cocos2d::Director::getInstance()->getWinSize();
    auto defaultDialogViewPosition = cocos2d::Point(winSize.width/2, winSize.height/2);
    auto defaultDialogViewAnchorPoint = cocos2d::Point(0.5,  0.5);
    
    this->presentDialog(dialogView, presentAnimationType, dismissAnimationType, defaultDialogViewPosition, defaultDialogViewAnchorPoint, presentCallback);
}

void SceneWithUtils::presentDialog(cocos2d::Node* dialogView, AnimationType presentAnimationType, AnimationType dismissAnimationType, cocos2d::Point dialogViewPosition, cocos2d::Point dialogViewAnchorPoint, const std::function<void()> presentCallback)
{
    if(dialogView != NULL){
    
        _dialogPresentCallback = presentCallback;
        
        this->dismissCurrentDialog();
        
        this->_currentDialogView = dialogView;
        this->_dialogDismissAnimationType = dismissAnimationType;
        
        auto dialogOverlayView = cocos2d::Layer::create();
        auto interceptingLayer = TouchInterceptingLayer::create(cocos2d::Color4B(0,0,0,200));
        
        dialogOverlayView->setAnchorPoint(dialogViewAnchorPoint);
        dialogOverlayView->setPosition(dialogViewPosition);
        dialogOverlayView->setIgnoreAnchorPointForPosition(false);
        
        dialogOverlayView->addChild(interceptingLayer, 0);
        dialogOverlayView->addChild(dialogView, 1);
        this->addChild(dialogOverlayView);
        
        dialogView->setIgnoreAnchorPointForPosition(false);
        dialogView->setAnchorPoint(dialogViewAnchorPoint);
        dialogView->setPosition(dialogViewPosition);
        
        interceptingLayer->setOnTouchCallback([&](cocos2d::Touch* touch){
        
            if(_touchOutsideDismissesDialog){
                auto dialogViewBBToWorld = GeometryUtils::getBoundingBoxToWorld(_currentDialogView);
                auto touchPointLocation = touch->getLocationInView();
                if(!dialogViewBBToWorld.containsPoint(touchPointLocation)){
                    this->dismissCurrentDialog();
                }
            }
        });
        
        if(presentAnimationType == SceneWithUtils::AnimationType::NONE){
            _dialogPresentCallback();
        } else {
            this->_animateDialogView(dialogOverlayView, presentAnimationType, _dialogPresentCallback);
        }
    }

}

void SceneWithUtils::dismissCurrentDialog()
{
    this->dismissCurrentDialog(_dialogDismissCallback);
}

void SceneWithUtils::dismissCurrentDialog(const std::function<void()> dismissCallback)
{
    if(this->_currentDialogView != NULL){
 
        _dialogDismissCallback = dismissCallback;
        _fullDismissCallback = [&](){
        
            if(this->_currentDialogView){
                this->removeChild(this->_currentDialogView->getParent());
                this->_currentDialogView = NULL;
            }
            _dialogDismissCallback();
        };
     
        if(_dialogDismissAnimationType == SceneWithUtils::AnimationType::NONE){
            _fullDismissCallback();
        } else {
            this->_animateDialogView(this->_currentDialogView->getParent(), this->_dialogDismissAnimationType, _fullDismissCallback);
        }
    }

}

void SceneWithUtils::presetDialogDismissCallback(const std::function<void()> dismissCallback)
{
    _dialogDismissCallback = dismissCallback;
}

SceneWithUtils::AnimationType SceneWithUtils::animationTypeFromString(std::string animationType)
{
    if(animationType == "SCALE_UP"){
        return SCALE_UP;
    }
    else if(animationType == "SCALE_DOWN"){
        return SCALE_DOWN;
    } else if(animationType == "FADE_OUT"){
        return FADE_OUT;
    } else if(animationType == "FADE_IN"){
        return FADE_IN;
    }
    
    return NONE;
}

void SceneWithUtils::setScenePresentCallback(std::function<void()> callback)
{
    _scenePresentCallback = callback;
}

void SceneWithUtils::setSceneDismissCallback(std::function<void()> callback)
{
    _sceneDismissCallback = callback;
}

///////////////////////////////////////

void SceneWithUtils::_animateDialogView(cocos2d::Node* dialogView, AnimationType animationType, const std::function<void()>& callback)
{
    auto callbackAction = cocos2d::CallFunc::create([&](){
        callback();
    });

    switch (animationType) {
        case SCALE_UP:
            dialogView->setScale(0);
            dialogView->runAction(cocos2d::Sequence::create(cocos2d::ScaleTo::create(0.2, 1), callbackAction, nullptr));
            break;

        case SCALE_DOWN:
            dialogView->setScale(1);
            dialogView->runAction(cocos2d::Sequence::create(cocos2d::ScaleTo::create(0.2, 0), callbackAction, nullptr));
            break;

        case FADE_OUT:
            dialogView->runAction(cocos2d::Sequence::create(cocos2d::FadeOut::create(MiscUtils::StandardAnimationTime), callbackAction, nullptr));
            
        case FADE_IN:
            dialogView->setOpacity(0);
            dialogView->runAction(cocos2d::Sequence::create(cocos2d::FadeIn::create(MiscUtils::StandardAnimationTime), callbackAction, nullptr));
            
        default:
            dialogView->runAction(callbackAction);
            break;
    }
}