cocosedx3.3 模态弹出框的实现

参考:http://blog.sina.com.cn/s/blog_705a5ff00101ox4s.html

谢谢上面的哥们。


在上面的基础上作了些调整,直接支持键盘手柄和触摸事件的屏蔽功能


直接上代码吧



#ifndef __H_POPUPLAYER_H__
#define __H_POPUPLAYER_H__
#include "cocos2d.h"
#include "cocos-ext.h"

class PopupLayer:public cocos2d::Layer
{
public:
PopupLayer();
~PopupLayer();
CREATE_FUNC(PopupLayer);
virtual bool init();
static PopupLayer *create(const char *backGroundImage);
//设置标题
void setTitle(const char *title, int fontSize = 20);
//设置文本内容,padding 为文字到对话框两边预留的距离,这是可控的,距上方的距离亦是如此
void setContentText(const char *text, int fontSize = 20, int padding = 50, int paddingTop = 150);
void setCallBackFunc(Ref *target, cocos2d::SEL_CallFuncN callfuncN);
void addButton(const char *normalImage, const char *selectedImage, const char *title, int tag = 0);
void setFocus(int index = 0);//设置第index个button高亮
virtual void onEnter();
virtual void onExit();


private:
//焦点index
int m_focusIndex;
//文字内容两边的空白区域
int m_contentPadding;
int m_contentPaddingTop;
Ref *m_callBackListener;
cocos2d::SEL_CallFuncN m_callBack;
//用 CC_SYNTHESIZE_RETAIN 定义Menu*类型变量m_pMenu, 并且定义 MenuButton 的set/get方法
CC_SYNTHESIZE_RETAIN(cocos2d::Menu*, m_pMenu, MenuButton);
CC_SYNTHESIZE_RETAIN(cocos2d::Sprite*, m_sfBackGround, SpriteBackGround);
CC_SYNTHESIZE_RETAIN(cocos2d::ui::Scale9Sprite*, m_s9BackGround, Sprite9BackGround);
CC_SYNTHESIZE_RETAIN(cocos2d::Label*, m_ltTitle, LabelTitle);
CC_SYNTHESIZE_RETAIN(cocos2d::Label*, m_ltContentText, LabelContentText);


//键盘/手柄事件
void onKeyUpKeyboard(cocos2d::EventKeyboard::KeyCode keycode, cocos2d::EventKeyboard * event);
void onKeyUpController(cocos2d::Controller *controller, cocos2d::EventController *event);
//响应事件
void buttonCallBack(Ref *pSender); 
//设置button效果
void setHighLight();
//删除自己
void destroyFromParent();
//按下 确认\左\右键
void keyEnterEvent();
void keyLeftEvent();
void keyRightEvent();


};




#endif


===========================================================================

#include "PopupLayer.h"
USING_NS_CC;


PopupLayer::PopupLayer()
{
m_contentPadding = 0;
m_contentPaddingTop = 0;
m_callBackListener = nullptr;
m_callBack = nullptr;


m_pMenu = nullptr;
m_sfBackGround = nullptr;
m_s9BackGround = nullptr;
m_ltTitle = nullptr;
m_ltContentText = nullptr;


m_focusIndex = 0;




}


PopupLayer::~PopupLayer()
{
CC_SAFE_RELEASE(m_pMenu);
CC_SAFE_RELEASE(m_sfBackGround);
CC_SAFE_RELEASE(m_s9BackGround);
CC_SAFE_RELEASE(m_ltTitle);
CC_SAFE_RELEASE(m_ltContentText);


}


bool PopupLayer::init()
{
if (!Layer::init())
{
return false;
}


//半透明层
Size visibleSize = Director::getInstance()->getVisibleSize();
LayerColor *layerColor = LayerColor::create(Color4B(0, 0, 0, 100), visibleSize.width, visibleSize.height);
this->addChild(layerColor);


//初始化需要的Menu
Menu *menu = Menu::create();
menu->setPosition(Vec2::ZERO);
setMenuButton(menu);


屏蔽下层点击事件
//EventListenerTouchOneByOne *listener = EventListenerTouchOneByOne::create();
//listener->onTouchBegan = [](Touch *touch, Event *event)
//{
// return true; 
//};
//listener->setSwallowTouches(true);
//_eventDispatcher->addEventListenerWithSceneGraphPriority(listener, this);


//keyboard事件
auto keyEvent = EventListenerKeyboard::create();
keyEvent->onKeyReleased = [&](EventKeyboard::KeyCode keyCode, Event* event)
{
this->onKeyUpKeyboard(keyCode, (EventKeyboard *)event);
};
_eventDispatcher->addEventListenerWithSceneGraphPriority(keyEvent, this);


//屏蔽下层cotroller事件
auto controllerEvent = EventListenerController::create();
controllerEvent->onKeyUp = [&](Controller *controller, int keycode, Event *event)
{
CCLOG("屏蔽下层cotroller事件 onkeyup");
this->onKeyUpController(controller, (EventController *)event);
};
_eventDispatcher->addEventListenerWithSceneGraphPriority(controllerEvent, this);




return true;
}




void PopupLayer::onKeyUpController(Controller *controller, EventController *event)
{


Controller::Key keycode = (Controller::Key)event->getKeyCode();
CCLOG("keycode====>%d", keycode);
switch (keycode)
{
case Controller::Key::BUTTON_A:
keyEnterEvent();
break;
case Controller::Key::BUTTON_B:
destroyFromParent();
break;
case Controller::Key::BUTTON_DPAD_DOWN:
case Controller::Key::BUTTON_DPAD_LEFT:
keyLeftEvent();
break;
case Controller::Key::BUTTON_DPAD_UP:
case Controller::Key::BUTTON_DPAD_RIGHT:
keyRightEvent();
break;
}
}
void PopupLayer::onKeyUpKeyboard(EventKeyboard::KeyCode keycode, EventKeyboard * event)
{
//CCLOG("PopupLayer::onKeyUpKeyboard->keycode[%d]", keycode);
switch (keycode)
{
case EventKeyboard::KeyCode::KEY_KP_ENTER:
keyEnterEvent();
break;
case EventKeyboard::KeyCode::KEY_ESCAPE:
destroyFromParent();
break;
case  EventKeyboard::KeyCode::KEY_DOWN_ARROW:
case  EventKeyboard::KeyCode::KEY_LEFT_ARROW:
keyLeftEvent();
break;
case  EventKeyboard::KeyCode::KEY_UP_ARROW:
case  EventKeyboard::KeyCode::KEY_RIGHT_ARROW:
keyRightEvent();
break;

default:
break;
}
}
PopupLayer* PopupLayer::create(const char *backGroundImage)
{
PopupLayer *popup = PopupLayer::create();
popup->setSpriteBackGround(Sprite::create(backGroundImage));
popup->setSprite9BackGround(ui::Scale9Sprite::create(backGroundImage));
return popup;
}


//标题
void PopupLayer::setTitle(const char *title, int fontSize)
{
Label *lbTitle = Label::createWithSystemFont(title, "Helvetica", fontSize);
lbTitle->setColor(Color3B(255, 0, 0));
this->setLabelTitle(lbTitle);
}


//内容
void PopupLayer::setContentText(const char *text, int fontSize, int padding, int paddingTop)
{
Label *lbText = Label::createWithSystemFont(text, "Helvetica", fontSize);
lbText->setColor(Color3B(255, 0, 0));
this->setLabelContentText(lbText);
m_contentPadding = padding;
m_contentPaddingTop = paddingTop;
}
//设置回调
void PopupLayer::setCallBackFunc(Ref *target, SEL_CallFuncN callFuncN)
{
m_callBackListener = target;
m_callBack = callFuncN;
}
//响应回调事件
void PopupLayer::buttonCallBack(Ref *pSender)
{
if (m_callBackListener && m_callBack)
{
(m_callBackListener->*m_callBack)((Node *)pSender);
}
destroyFromParent();


}
//添加按钮
void PopupLayer::addButton(const char *normalImage, const char *selectedImage, const char *title, int tag)
{
Size visibleSize = Director::getInstance()->getVisibleSize();
Vec2 center = Vec2(visibleSize.width / 2, visibleSize.height / 2);




MenuItemImage *menuImage = MenuItemImage::create(normalImage, selectedImage, CC_CALLBACK_1(PopupLayer::buttonCallBack, this));
menuImage->setTag(tag);
menuImage->setPosition(center);


Label *lbFont = Label::createWithSystemFont(title, "Helevtica", 30);
lbFont->setColor(Color3B(255,0,0));
lbFont->setPosition(menuImage->getContentSize()/2);
lbFont->setTag(110);
menuImage->addChild(lbFont);


this->getMenuButton()->addChild(menuImage);
}




void PopupLayer::setFocus(int index)
{
Menu *menuItem = this->getMenuButton();
if (menuItem)
{
if (index >= 0 && index < menuItem->getChildrenCount())
{
m_focusIndex = index;
}
}
}


void PopupLayer::setHighLight()
{
//按钮
Menu *menuItem = this->getMenuButton();
if (menuItem)
{
Vector<Node *> vct;
vct.pushBack(menuItem->getChildren());
for (int i = 0; i < vct.size(); i++)
{
MenuItemImage *menuImage = (MenuItemImage *)vct.at(i);
Label *label = (Label*)menuImage->getChildByTag(110);
Label *lbFont = Label::createWithSystemFont(label->getString(), "Helevtica", 30);
lbFont->setColor(Color3B(255, 0, 0));
lbFont->setPosition(menuImage->getContentSize() / 2);


if (m_focusIndex == i)
{


menuImage->setNormalImage(Sprite::create("general/img/dailog_ok_select.png"));
//menuImage->setScale(1.1f);
}
else
{
menuImage->setNormalImage(Sprite::create("general/img/dialog_ok_normal.png"));
//menuImage->setScale(1.0f);
}
menuImage->addChild(lbFont);


}
vct.clear();
}
}




void PopupLayer::keyLeftEvent()
{
Menu *menuItem = this->getMenuButton();
if (menuItem)
{
int buttonMax = menuItem->getChildrenCount();
m_focusIndex -= 1;
if (m_focusIndex < 0)
{
m_focusIndex = buttonMax - 1;
}
setHighLight();
}


}
void PopupLayer::keyRightEvent()
{
Menu *menuItem = this->getMenuButton();
if (menuItem)
{
int buttonMax = menuItem->getChildrenCount();
m_focusIndex += 1;
if (m_focusIndex >= buttonMax)
{
m_focusIndex = 0;
}
setHighLight();
}
}
void PopupLayer::keyEnterEvent()
{
Menu *menuItem = this->getMenuButton();
if (menuItem)
{
Vector<Node *> vct;
vct.pushBack(menuItem->getChildren());
for (int i = 0; i < vct.size(); i++)
{
MenuItemImage *menuImage = (MenuItemImage *)vct.at(i);
if (m_focusIndex == i)
{
PopupLayer::buttonCallBack(menuImage);
return;
}


}
vct.clear();
}
}


void PopupLayer::destroyFromParent()
{
//恢复下层点击按键手柄等事件
getScheduler()->performFunctionInCocosThread([&]() {
Node * parent = this->getParent();
this->removeFromParent();
Director::getInstance()->getEventDispatcher()->resumeEventListenersForTarget(parent, true);
});


}


//全部参数设定好后,在运行时动态加载
void PopupLayer::onEnter()
{
Layer::onEnter();


Size visibleSize = Director::getInstance()->getVisibleSize();
Vec2 center = Vec2(visibleSize.width / 2, visibleSize.height / 2);
Size backGroundSize;


//背景
if (this->getContentSize().equals(Size::ZERO))//传入参数大小为0时
{
Sprite *sp = this->getSpriteBackGround();
sp->setPosition(center);
this->addChild(sp);
backGroundSize = sp->getTexture()->getContentSize();
}
else
{
ui::Scale9Sprite *backGround = this->getSprite9BackGround();
backGround->setContentSize(this->getContentSize());
backGround->setPosition(center);
backGroundSize = this->getContentSize();
this->addChild(backGround);
}


//标题
Label *lbTitle = this->getLabelTitle();
if (lbTitle)
{
lbTitle->setPosition(center + Vec2(0, backGroundSize.height / 2 - 25.0f));
this->addChild(lbTitle);


}
//内容
Label *lbContentText = this->getLabelContentText();
if (lbContentText)
{
lbContentText->setPosition(center);
lbContentText->setDimensions(backGroundSize.width - m_contentPadding * 2, backGroundSize.height - m_contentPaddingTop);
lbContentText->setHorizontalAlignment(kCCTextAlignmentCenter);
//lbContentText->setHorizontalAlignment(kCCTextAlignmentLeft);
this->addChild(lbContentText);
}


//按钮
Menu *menuItem = this->getMenuButton();
if (menuItem)
{
Vector<Node *> vct;
vct.pushBack(menuItem->getChildren());
float buttonWidth = backGroundSize.width / (menuItem->getChildrenCount() + 1);
for (int i = 0; i < vct.size(); i++)
{
Node *node = (Node *)vct.at(i);
node->setPosition(Vec2(visibleSize.width/2 - backGroundSize.width/2 + buttonWidth *(i+1),
visibleSize.height / 2 - backGroundSize.height / 3));
}
vct.clear();
this->addChild(menuItem);
setHighLight();


}


//弹出效果
Sequence *popupActions = Sequence::create(
ScaleTo::create(0.0, 0.0),
ScaleTo::create(0.06, 1.05),
ScaleTo::create(0.08, 0.95),
ScaleTo::create(0.08, 1.0),
NULL
);
this->runAction(popupActions);
//暂停下层点击按键手柄等事件
_eventDispatcher->pauseEventListenersForTarget(this->getParent(), true);
}


void PopupLayer::onExit()
{
Layer::onExit();
}




调用处
//用法:
定义一个弹出层,传入一张背景图片
//PopupLayer* popup = PopupLayer::create("popupBackGround.png");
ContentSize是可选的设置,可以不设置,如果设置则把它当做9图缩放
//popup->setContentSize(CCSizeMake(800, 560));
//popup->setTitle("Message");
//popup->setContentText("Most people... blunder round this cityMost people  blunder round this cityMost people  blunder round this cityMost people  blunder round this city.", 20, 20, 150);
设置回调函数,回调传回一个CCNode以获取tag判断点击的按钮
这只是作为一种封装实现,如果使用delegate那就能够更灵活的控制参数了
添加按钮,设置图片、文字,tag信息
//popup->addButton("yesNormal.png", "yesSelect.png", "Ok", -500);
//popup->addButton("noNormal.png", "noSelect.png", "Cancel", 1);
//popup->setCallBackFunc(this, callfuncN_selector(HelloWorld::buttonCallBack));
//this->addChild(popup);

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
资源包主要包含以下内容: ASP项目源码:每个资源包中都包含完整的ASP项目源码,这些源码采用了经典的ASP技术开发,结构清晰、注释详细,帮助用户轻松理解整个项目的逻辑和实现方式。通过这些源码,用户可以学习到ASP的基本语法、服务器端脚本编写方法、数据库操作、用户权限管理等关键技术。 数据库设计文件:为了方便用户更好地理解系统的后台逻辑,每个项目中都附带了完整的数据库设计文件。这些文件通常包括数据库结构图、数据表设计文档,以及示例数据SQL脚本。用户可以通过这些文件快速搭建项目所需的数据库环境,并了解各个数据表之间的关系和作用。 详细的开发文档:每个资源包都附有详细的开发文档,文档内容包括项目背景介绍、功能模块说明、系统流程图、用户界面设计以及关键代码解析等。这些文档为用户提供了深入的学习材料,使得即便是从零开始的开发者也能逐步掌握项目开发的全过程。 项目演示与使用指南:为帮助用户更好地理解和使用这些ASP项目,每个资源包中都包含项目的演示文件和使用指南。演示文件通常以视频或图文形式展示项目的主要功能和操作流程,使用指南则详细说明了如何配置开发环境、部署项目以及常见问题的解决方法。 毕业设计参考:对于正在准备毕业设计的学生来说,这些资源包是绝佳的参考材料。每个项目不仅功能完善、结构清晰,还符合常见的毕业设计要求和标准。通过这些项目,学生可以学习到如何从零开始构建一个完整的Web系统,并积累丰富的项目经验。
资源包主要包含以下内容: ASP项目源码:每个资源包中都包含完整的ASP项目源码,这些源码采用了经典的ASP技术开发,结构清晰、注释详细,帮助用户轻松理解整个项目的逻辑和实现方式。通过这些源码,用户可以学习到ASP的基本语法、服务器端脚本编写方法、数据库操作、用户权限管理等关键技术。 数据库设计文件:为了方便用户更好地理解系统的后台逻辑,每个项目中都附带了完整的数据库设计文件。这些文件通常包括数据库结构图、数据表设计文档,以及示例数据SQL脚本。用户可以通过这些文件快速搭建项目所需的数据库环境,并了解各个数据表之间的关系和作用。 详细的开发文档:每个资源包都附有详细的开发文档,文档内容包括项目背景介绍、功能模块说明、系统流程图、用户界面设计以及关键代码解析等。这些文档为用户提供了深入的学习材料,使得即便是从零开始的开发者也能逐步掌握项目开发的全过程。 项目演示与使用指南:为帮助用户更好地理解和使用这些ASP项目,每个资源包中都包含项目的演示文件和使用指南。演示文件通常以视频或图文形式展示项目的主要功能和操作流程,使用指南则详细说明了如何配置开发环境、部署项目以及常见问题的解决方法。 毕业设计参考:对于正在准备毕业设计的学生来说,这些资源包是绝佳的参考材料。每个项目不仅功能完善、结构清晰,还符合常见的毕业设计要求和标准。通过这些项目,学生可以学习到如何从零开始构建一个完整的Web系统,并积累丰富的项目经验。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值