充分利用C++11特性,Cocos2dx对话框的实现

一般一个对话框会分为模态对话框和非模态对话框两种,模态对话框是指在用户想要对对话框以外的应用程序进行操作时,必须首先对该对话框进行响应。如单击【确定】或【取消】按钮等将该对话框关闭。非模态(Modeless)对话框,又叫做无模式对话框,当用户打开非模态对话框时,依然可以操作其他窗口。例如,Windows提供的记事本程序中的【查找】对话框。(抄自百度百科)

目前我需要的一个对话框功能列表如下:

1.需要显示一段提示信息,可能是一段对话可能是一个问题。
2.必须有确认按钮,可能会有取消按钮
3.确认按钮的功能可自定义

下面是我的实现思路。

1.首先有一个初始化对话框的函数,将对话框初始化到内存中,因为对话框是一个很常用的功能,所以直接加入内存中就好了。
2.然后对话框需要载入功能和移除功能,这两样就是对话框的核心功能了
3.对话框需要按钮回调,一个是确认,一个是取消,确认可能还需要执行某些其他功能,我们可以用回调来实现,取消就直接关闭对话框,没什么好说的。
4.对话框分模态和非模态两种,模态就是在对话框层中加一个触摸屏蔽。

遵循着上面的思路,我对于对话框的函数设计如下:

	//对话框
protected:
	//初始化对话框
	void InitDialog();
	/* 加载对话框
	 * @parm:msg 消息 显示在界面上的提示消息
	 * @parm:fun 回调函数 给确定按钮调用的
	 * @parm:isNeedCancel 是否需要取消按钮
	 * @parm:isModalDialog 是否是模态对话框
	 */
	void LoadDialog(std::string msg,std::function<void(Ref*)>  fun,bool isNeedCancel = false,bool isModalDialog = true);
	//对话框加载完成
	void LoadDialogFinish(Armature *a, MovementEventType b, std::string c);
	//隐藏对话框
	void HideDialog();
	//隐藏对话框完成
	void HideDialogFinish(Armature *a, MovementEventType b, std::string c);
	//对话框取消按钮回调
	void PressDialogCancelBtn(Ref *pSender, Widget::TouchEventType type);
	//对话框确认按钮回调
	void PressDialogConfirmBtn(Ref *pSender, Widget::TouchEventType type);

为什么会有对话框加载完成和对话框隐藏完成呢?是因为我把对话框的加载和隐藏做成了两个动画,所以需要这两个附加的函数。

OK 不多说,下面是函数的具体实现:

//----------------------------------------------------------对话框-------------------------------------------------------
//初始化对话框
void MomoScene::InitDialog()
{
	ArmatureDataManager::getInstance()->addArmatureFileInfo("publish/DialogAnimation.ExportJson");
	Dialog = Armature::create("DialogAnimation");
	Dialog->retain();
	Dialog->setPosition(getCenterPoint());
	m_UI_Dialog->addChild(Dialog);
	Dialog->setVisible(false);

	//加载信息
	m_DialogMsg = Label::create();
	m_DialogMsg->retain();
	m_DialogMsg->setVisible(false);
	m_DialogMsg->setColor(Color3B::WHITE);
	m_DialogMsg->enableGlow(Color4B::WHITE);
	m_DialogMsg->setPosition(Point(0,0));
	Dialog->addChild(m_DialogMsg,20);
	//加载确认按钮
	m_DialogConfirm = Button::create("Dialog_btn/confirm.png","Dialog_btn/confirm_press.png");
	m_DialogConfirm->retain();
	m_DialogConfirm->setPosition(Point(-80,-100));
	m_DialogConfirm->setVisible(false);
	Dialog->addChild(m_DialogConfirm);
	//加载取消按钮
	m_DialogCancel = Button::create("Dialog_btn/cacel.png","Dialog_btn/cacel_press.png");
	m_DialogCancel->retain();
	m_DialogCancel->setPosition(Point(80,-100));
	m_DialogCancel->setVisible(false);
	Dialog->addChild(m_DialogCancel);
}

//加载对话框
void MomoScene::LoadDialog(std::string msg,std::function<void(Ref*)>  fun,bool isNeedCancel,bool isModalDialog)
{
	Dialog->setVisible(true);
	Dialog->getAnimation()->playWithIndex(0);
	Dialog->getAnimation()
		->setMovementEventCallFunc(CC_CALLBACK_3(MomoScene::LoadDialogFinish,this));
	m_DialogMsg->setString(msg);
	m_Dialog_ConfirmCallback = fun;
	//是否需要关闭按钮
	if(isNeedCancel == true)
	{
		m_DialogConfirm->addTouchEventListener(CC_CALLBACK_2(MomoScene::PressDialogConfirmBtn,this));
		m_DialogCancel->addTouchEventListener(CC_CALLBACK_2(MomoScene::PressDialogCancelBtn, this));
		m_DialogConfirm->setVisible(true);
		m_DialogCancel->setVisible(true);
	}
	else
	{
		m_DialogConfirm->addTouchEventListener(CC_CALLBACK_2(MomoScene::PressDialogConfirmBtn,this));
		m_DialogConfirm->setPosition(Point(0,-100));
		m_DialogConfirm->setVisible(true);
		m_DialogCancel->setVisible(false);
	}
	//模态对话框需要做一个吞噬触摸层
	if(isModalDialog == true)
	{
		auto listener1 = EventListenerTouchOneByOne::create();//创建一个触摸监听
		listener1->setSwallowTouches(true);//设置不想向下传递触摸
		listener1->onTouchBegan = [](Touch* touch, Event* event){
			CCLOG("touch Swallow");
			return true;
		};
		_eventDispatcher->addEventListenerWithSceneGraphPriority(listener1,m_UI_Dialog);
	}
}
void MomoScene::LoadDialogFinish(Armature *a, MovementEventType b, std::string c)
{
	//动画完成
	if(b == COMPLETE)
	{
		Dialog->getAnimation()->setMovementEventCallFunc(nullptr);
		m_DialogMsg->setVisible(true);
	}
}
//隐藏对话框
void MomoScene::HideDialog()
{
	m_DialogMsg->setVisible(false);
	m_DialogConfirm->setVisible(false);
	m_DialogCancel->setVisible(false);
	//移除触摸屏蔽
	_eventDispatcher->removeEventListenersForTarget(m_UI_Dialog);

	Dialog->getAnimation()->playWithIndex(1);
	Dialog->getAnimation()
		->setMovementEventCallFunc(CC_CALLBACK_3(MomoScene::HideDialogFinish,this));
}
//隐藏对话框完成
void MomoScene::HideDialogFinish(Armature *a, MovementEventType b, std::string c)
{
	//动画完成
	if(b == COMPLETE)
	{
		Dialog->getAnimation()->setMovementEventCallFunc(nullptr);
		a->setVisible(false);
		a->setOpacity(255);
	}
}

//对话框取消按钮
void MomoScene::PressDialogCancelBtn(Ref *pSender, Widget::TouchEventType type)
{
	switch(type)
	{
	case Widget::TouchEventType::ENDED:
		HideDialog();
		break;
	}
}
//对话框确认按钮
void MomoScene::PressDialogConfirmBtn(Ref *pSender, Widget::TouchEventType type)
{
	switch(type)
	{
	case Widget::TouchEventType::ENDED:
		HideDialog();
		if(m_Dialog_ConfirmCallback != nullptr)
			m_Dialog_ConfirmCallback(NULL);
		break;
	}
}

值得一提的是 所有以m_开头的变量全部是类的成员变量,下面也给出这些变量的定义,其中有几个变量在类的构造函数中有初始化,也给出来

	//标志变量
public:
	bool m_IsNeedExit;
	//UI变量
public:
	Sprite* m_spr_ExitTip; //退出提示
	Armature* Dialog; //对话框
	Label* m_DialogMsg; //对话框消息
	Button* m_DialogConfirm; //对话框确认按钮
	Button* m_DialogCancel;  //对话框取消按钮
	//层变量
	Layer* m_UI_Dialog;			//对话框层 最高层
	Layer* m_UI_Tool;			//工具栏层 次高层
	Layer* m_UI_Game;			//游戏层 低层
	Layer* m_UI_Background;		//背景层 底层
	//回调函数变量
public:
	std::function<void(Ref*)> m_Dialog_ConfirmCallback; //对话框确认回调
	//------------------------------函数----------------------------------
public:
	MomoScene():m_IsNeedExit(false),m_Dialog_ConfirmCallback(nullptr){};
	~MomoScene(){};

下面是对话框的使用方法:

		auto fun = [=](Ref* e){
			CCLog("OK You enter the Confirm");
		};
		LoadDialog("You Enter Continue",fun,true);

上述对话框的实现效果如下:(因为素材不太好,为了更好的展示效果,我在显示对话框的时候将菜单移除了)

表示不知道GIF图片要怎么展示出来 就先看着截图吧

时间: 2024-08-11 07:33:30

充分利用C++11特性,Cocos2dx对话框的实现的相关文章

c++11特性与cocos2d-x 3.0之std::bind与std::function

昨天同事让帮忙写一小功能,才发现cocos2d-x 3.0 和 cocos2d-x 3.0rc0 差别还是相当大的. 发现Label这一个控件,3.0就比rc0版本多了一个创建函数,更为关键的是3.0内的Label锚点是在ccp(0.5,0.5),而一直3.0rc0是ccp(0,0). 累觉不爱.尽管cocos2d-x改变太快,兼容性一次次的暴露出不足,但是,总归是向好的方向进行.于是下载了3.0来玩玩~ cocos new 出新的项目之后,仔细阅读代码,才发现了一句3.0区别于2.0的代码:

C++primer(第五版)第九章 顺序容器(容器的运用及其部分习题解答,C++11特性总结,重点章节内容较多)

顺序容器:为程序员提供了控制元素存储和访问顺序的能力.(无序容器)           1.顺序容器的概述           A.顺序容器的类型           vector:可变大小数组.支持快速随机访问.在尾部之外的位置插入或删除元素可能很慢.          deque:双端队列.支持快速随机访问.在头尾位置插入/删除速度很快.           list:双向链表.只支持双向顺序访问.在list中任何位置进行插入/删除操作速度都很快.          forword_list

C++开发者都应该使用的10个C++11特性

本文由 伯乐在线 - 治不好你我就不是兽医 翻译自 Marius Bancila.欢迎加入技术翻译小组.转载请参见文章末尾处的要求. [感谢冯上(@治不好你我就不是兽医 )的热心翻译.如果其他朋友也有不错的原创或译文,可以尝试推荐给伯乐在线.] 在C++11新标准中,语言本身和标准库都增加了很多新内容,本文只涉及了一些皮毛.不过我相信这些新特性当中有一些,应该成为所有C++开发者的常规装备.你也许看到过许多类似介绍各种C++11特性的文章.下面是我总结的,C++开发者都需要学习和使用的C++11

目前主流编译器对C++11特性的支持情况

1. GCC编译器(从编译器GCC4.8.X的版本完全支持) (1)目前C++11特性,之前成为C++0X特性,从GCC4.3的后续版本中逐步对C++11进行支持. (2)从官方信息可以看到,目前从完全对C++11特性进行支持的是从编译器GCC4.8.X的版本. 参考网址:https://gcc.gnu.org/projects/cxx-status.html#cxx11 2. Clang编译器 Clang 是一个 C++ 编写.基于 LLVM.发布于 LLVM BSD 许可证下的 C/C++/

利用C++ 11特性实现多线程计数器

许多并行计算程序,需要确定待计算数据的编号,或者说,多线程间通过编号而耦合.此时,通过利用C++ 11提供的atomic_?type类型,可实现多线程安全的计数器,从而,降低多线程间的耦合,以便于书写多线程程序. 以计数器实现为例子,演示了多线程计数器的实现技术方法,代码如下: //目的: 测试利用C++ 11特性实现计数器的方法 //操作系统:ubuntu 14.04 //publish_date: 2015-1-31 //注意所使用的编译命令: g++ -Wl,--no-as-needed

C++primer(第五版)第二章的学习笔记(也有对部分习题的解答和指出c++11特性)

算术类型分为两类:整型(字符和bool在内)和浮点型. C/C++算术类型 类型 含义 最小尺寸 bool 布尔类型 未定义 char 字符 8位 wchar_t 宽字符 16位 char16_t Unicode字符 16位 char32_t Unicode字符 32位 short 短整型 16位 int  整型 16位 long 长整型 32位 long long 长整型 64位 unsigned long 无符号长整型 32位 double 双精度浮点数 10位有效数字 long doubl

每个C++开发者都应该使用的十个C++11特性

这篇文章讨论了一系列所有开发者都应该学习和使用的C++11特性,在新的C++标准中,语言和标准库都加入了很多新属性,这篇文章只会介绍一些皮毛,然而,我相信有一些特征用法应该会成为C++开发者的日常用法之一.你也许已经找到很多类似介绍C++11标准特征的文章,这篇文章可以看成是那些常用特征描述的一个集合. 目录: auto关键字 nullptr关键字 基于区间的循环 Override和final 强类型枚举 智能指针 Lambdas表达式 非成员begin()和end() static_asser

C++开发者都应该使用的10个C++11特性 转

http://blog.jobbole.com/44015/2013/07/26 | 分类: C/C++, 开发 | 5 条评论 | 标签: C++11, C语言 分享到: 127 本文由 伯乐在线 - 治不好你我就不是兽医 翻译自 Marius Bancila.未经许可,禁止转载! 欢迎加入:技术翻译小组,或分享原创到伯乐头条. [感谢冯上(@治不好你我就不是兽医 )的热心翻译.如果其他朋友也有不错的原创或译文,可以尝试推荐给伯乐在线.] 在C++11新标准中,语言本身和标准库都增加了很多新内

VSVC2010中常用的C++11特性

static_assert 声明 static_assert 声明在编译时测试软件断言,这与在运行时进行测试的其他断言机制不同. 如果断言失败,则编译也将失败,且系统将发出指定的错误消息. const int nValue = 3; static_assert(nValue < 10, "Error"); 这样编译时就会报出Error的错误提示信息. decltype作为操作符 用于返回表达式的数据类型. int Add(int a, int b) { return a+b; }