/*--------------------------CMyButton--------------------------
* strategy pattern
* texture 혹은 label로 초기화하여 사용하는 Button
* Lambda혹은 함수포인터, 함수객체를 인자로 받는다.
* 눌렀을때 체크
* 누르고 있을 때 체크
* 끝났을 때 체크
* ------------------------------------------------------------*/
/* 버튼의 상태 */
enum eMYBUTTON_STATE{
BEGIN = 0,
EXECUTE = 1,
END = 2,
}
/* 텍스쳐와 함께 버튼 생성
* normalImg와 selectedImg를 인자로 전달*/
CMyButton* CMyButton::createWithTexture(
std::string normalTextureName, // 선택 전 버튼의 텍스쳐 이름
std::string selectedTextureName, // 선택 중 버튼의 텍스쳐 이름
eMYBUTTON_STATE state, // 버튼 상태 (해당 상태일 때 함수 호출됨)
const std::function<void(void)> &func) // 람다 혹은 함수포인터 혹은 함수객체 전달(매개 변수는 void)
/* 문자열과 함께 버튼 생성 */
CMyButton* CMyButton::createWithString(
std::string normalTextureName, // 버튼의 텍스쳐 이름
std::string labelString, // 버튼의 label 내용
int fontSize, // 폰트 사이즈
eMYBUTTON_STATE state, // 버튼 상태 (해당 상태일 때 함수 호출됨)
const std::function<void(void)> &func) // 람다 혹은 함수포인터 혹은 함수객체 전달(매개 변수는 void)
/* 버튼의 함수 포인터 리스트에 함수 포인터 추가 */
void AddState(eMYBUTTON_STATE state, // 상태 (해당 상태일 때 함수 호출됨)
const std::function<void(void)> &func) // 람다 혹은 함수포인터 혹은 함수객체 전달(매개 변수는 void)
/* 터치된 좌표를 버튼의 좌표로 변환 한 후에 버튼이 터치되었는지 검사 */
bool touchHits(Touch *touch)
{
const Rect area(0, 0, m_pNormalTexture->getContentSize().width,
m_pNormalTexture->getContentSize().height);
// world to nodespace 좌표 변환
return area.containsPoint(m_pNormalTexture->convertToNodeSpace(touch->getLocation()));
}
/* 버튼이 눌렸을 때 BEGIN */
bool onTouchBegan(Touch *touch, Event *event)
{
CC_UNUSED_PARAM(event);
if (m_pNormalTexture){
// 좌표 변환 후 터치 체크
m_IsSelect = touchHits(touch);
// 버튼의 좌표에서 진짜로 터치되었을 경우
if (m_IsSelect){
// BEGIN 상태일때 호출해야할 함수가 있다면 호출
std::for_each(m_BeginFuncList.begin(), m_BeginFuncList.end(),
[](const std::function<void(void)> &func){
func();
});
// 선택 시 이미지가 있다면 이미지 교체
if (m_SelectedTextureName != ""){
m_pNormalTexture->setTexture(m_SelectedTextureName);
}
else { // 교체될 이미지가 없다면 크기를 키움
m_pNormalTexture->setScale(1.1f);
}
}
}
return m_IsSelect;
}
/* 버튼에서 떨어졌을 때 END */
void CMyButton::onTouchEnded(Touch *touch, Event *event)
{
CC_UNUSED_PARAM(event);
if (m_pNormalTexture){
// END 상태일때 호출해야할 함수가 있다면 호출
std::for_each(m_EndFuncList.begin(), m_EndFuncList.end(),
[](const std::function<void(void)> &func){
func();
});
// 이미지가 바뀌었었다면 다시 원래대로 바꿈
if (m_SelectedTextureName != ""){
m_pNormalTexture->setTexture(m_NormalTextureName);
}
else{ // 바뀔이미지가 없다면 크기를 원래대로 바꿈
m_pNormalTexture->setScale(1.0f);
}
// 버튼 눌림 종료
m_IsSelect = false;
}
}
/* 버튼이 눌리고 있는 중일때 EXECUTE */
void Execute(float delta)
{
// 버튼 눌림 상태이며, EXECUTE 상태일 때 실행되어야 할 함수가 1개 이상일 때
if (m_IsSelect && m_ExecuteFuncList.size())
{
// EXECUTE 상태일때 호출해야할 함수가 있다면 호출
std::for_each(m_ExecuteFuncList.begin(), m_ExecuteFuncList.end(),
[](const std::function<void(void)> &func){
func();
});
}
}
/* lambda, 함수 포인터를 리스트로 저장
* 각 상태일 때 호출할 함수를 저장하는 리스트 */
std::vector<std::function<void(void)>> m_BeginFuncList;
std::vector<std::function<void(void)>> m_ExecuteFuncList;
std::vector<std::function<void(void)>> m_EndFuncList;