HSceneWithUtils.cpp 7.63 KB
//
//  HSceneWithUtils.cpp
//  SteveMaggieCpp
//
//  Created by Katarzyna Kalinowska-Górska on 11.05.2017.
//
//

#include <stdio.h>
#include "HSceneWithUtils.h"
#include "HTouchInterceptingLayer.h"
#include "HGeometryUtils.h"
#include "HMiscUtils.h"
#include "HSoundUtils.h"

const std::string HSceneWithUtils::BG_MUSIC_PLAYING_USER_DEFAULTS_KEY = "BG_MUSIC_PLAYING_USER_DEFAULTS_KEY";

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

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

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

void HSceneWithUtils::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 HSceneWithUtils::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 = HTouchInterceptingLayer::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 = HGeometryUtils::getBoundingBoxToWorld(_currentDialogView);
                auto touchPointLocation = touch->getLocationInView();
                if(!dialogViewBBToWorld.containsPoint(touchPointLocation)){
                    this->dismissCurrentDialog();
                }
            }
        });
        
        if(presentAnimationType == HSceneWithUtils::AnimationType::NONE){
            _dialogPresentCallback();
        } else {
            this->_animateDialogView(dialogOverlayView, presentAnimationType, _dialogPresentCallback);
        }
    }

}

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

void HSceneWithUtils::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 == HSceneWithUtils::AnimationType::NONE){
            _fullDismissCallback();
        } else {
            this->_animateDialogView(this->_currentDialogView->getParent(), this->_dialogDismissAnimationType, _fullDismissCallback);
        }
    }

}

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

HSceneWithUtils::AnimationType HSceneWithUtils::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;
}

// playing background music
void HSceneWithUtils::setBackgroundMusicFilePath(std::string musicPath)
{
    _backgroundMusicFilePath = musicPath;
}

bool HSceneWithUtils::isBackgroundMusicPlaying()
{
    return HSoundUtils::isMusicPlaying();
}

bool HSceneWithUtils::playBackgroundMusic(bool onlyIfWasPlayingBefore)
{
    bool playBgMusic = onlyIfWasPlayingBefore ? cocos2d::UserDefault::getInstance()->getBoolForKey(BG_MUSIC_PLAYING_USER_DEFAULTS_KEY.c_str(), true) : true;
    if(playBgMusic && !_backgroundMusicFilePath.empty()){
        HSoundUtils::playMusic(_backgroundMusicFilePath.c_str());
        cocos2d::UserDefault::getInstance()->setBoolForKey(BG_MUSIC_PLAYING_USER_DEFAULTS_KEY.c_str(), true);
        cocos2d::UserDefault::getInstance()->flush();
        return true;
    }
    
    cocos2d::UserDefault::getInstance()->setBoolForKey(BG_MUSIC_PLAYING_USER_DEFAULTS_KEY.c_str(), false);
    cocos2d::UserDefault::getInstance()->flush();
    return false;
}

void HSceneWithUtils::pauseBackgroundMusic()
{
    HSoundUtils::pauseMusic();
}

void HSceneWithUtils::resumeBackgroundMusic()
{
    HSoundUtils::resumeMusic();
}

void HSceneWithUtils::stopBackgroundMusic(bool savePreference)
{
    HSoundUtils::stopMusic();
    if(savePreference){
        cocos2d::UserDefault::getInstance()->setBoolForKey(BG_MUSIC_PLAYING_USER_DEFAULTS_KEY.c_str(), false);
        cocos2d::UserDefault::getInstance()->flush();
    }
}

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

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

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

void HSceneWithUtils::_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(HMiscUtils::StandardAnimationTime), callbackAction, nullptr));
            
        case FADE_IN:
            dialogView->setOpacity(0);
            dialogView->runAction(cocos2d::Sequence::create(cocos2d::FadeIn::create(HMiscUtils::StandardAnimationTime), callbackAction, nullptr));
            
        default:
            dialogView->runAction(callbackAction);
            break;
    }
}