DEMO对应的工程是CLAYUIEXP3,对应运行程序为CLAYUIEXP3.exe
呵呵,不是讯雷的主界面,是讯雷的配置界面。配置界面里的动态效果基本都是按钮变色,淡入淡出的效果,再就是放大缩小,其中的一个难点是有一个发绿光的框会在你选中的焦点控件之间跳来跳去,这些效果在此次DEMO里都有包含,下面我会慢慢给大家讲解如何制作这些效果。
前面有同学反映CLAYUI只能使用雅黑字体,其他字体会有报错现象,这主要是由于CLAYUI还未加入对点阵字体的支持。现在,CLAYUI支持了点阵字体,WINDOWS里的大部分字体都可以用了,当然,可能有少数字体仍然会出现问题。
说点题外话
这次DEMO使用的是黑体,发现了一个有点莫名其妙的现象,黑体在字体大小是16时使用的是点阵字,而在小于16时使用的又是矢量字体,既然有矢量字体为何还要用点阵字体,而且16的点阵字的效果还没有小于16的矢量字体的效果好,不知道为什么会出现这个现象,由于CLAYUI字体渲染使用的是freetype,也许是freetype的问题,呵呵,有同好的同学可以来一起讨论讨论。freetype的字体反走样效果不是很好,或许我应该考虑自己渲染字体,或者直接使用GDI+来渲染字体。
然后这次的界面使用的都是矢量,没有用一张位图,所以体积是比较小的,当然,由于CLAYUI目前的内存占用量仍然是在20-30M,所以文件体积在这里意义就不是很大了。当然,也有其他的好处,由于都是矢量,所以,缩放,旋转都不会失真,效率也可以。如果换成是位图的话,缩放与旋转都要慢许多。
然后,感觉自己的FLASH技术提高了不少......所以,界面的表现部分没有讯雷那么好看
好,下面来讲界面,这次教程就不会像前几次,一行代码一行代码讲解了,因为再讲就重复了,对下面有不清楚的朋友可以先看看本博客内的其他教程
整个界面的主类对应的是工程里的CEXP3FRAME
先是界面左边的一列标签,“常用设置”,“任务默认属性”之类的,这些可以使用CLAYUI中的Radiobox来实现,他们实质上就是换了个样式的Radiobox,在这个DEMO里,控件的样式就没有像前几次教程里使用代码来做了,是直接用界面编辑器来完成的。这次DEMO里增加了几种专门为仿讯雷而做的控件样式。
然后是右边的分页,分页对应的类是工程里的CXLframe,分页是分开做的,一个分页做成一个界面文件,在CEXP3FRAME的UserAction里得到左边标签的CLAYUI_LCLICK消息,然后读取,加载到CEXP3FRAME里。右边的分页讯雷没有做动画过渡效果,我就做了几个比较简单的过渡效果,从左到右,从右到左,从外向里,代码在类CXLframe的LoadFromMem里,如下:
- float w, h;
- GetFrameSize(w, h);
- float centerx, centery;
- int random = rand()%3;
- float dis;
- //从外向里
- if(random == 0)
- {
- centerx = w / 2;
- centery = h / 2;
- dis = 250;
- }
- //从右向左
- else if(random == 1)
- {
- dis = 500;
- centerx = w + dis;
- centery = h / 2;
- }
- //从左向右
- else if(random == 2)
- {
- dis = 500;
- centerx = -dis;
- centery = h / 2;
- }
- int i;
- int num = m_framelist.m_spritenum;
- char aname[10];
- int duration = 500;
- for(i = 0; i < num; i ++)
- {
- CLAYUI_FRAME* frame = GetChildByIndex(i);
- float tx, ty;
- frame->GetTrans(tx, ty);
- float vx, vy;
- vx = tx - centerx;
- vy = ty - centery;
- float len = sqrt(pow(vx, 2) + pow(vy, 2));
- vx = vx / len;
- vy = vy / len;
- sprintf(aname, "aa%d", i);
- //创建动画
- CLAYUI_ALPHA_ANIM* alpha = new CLAYUI_ALPHA_ANIM();
- //设置动画的标识
- alpha->SetIdname(aname);
- //初始化
- alpha->Init(0, 100, duration, this);
- //将动画对象加入到m_sys_listbox中
- AddAnimation(alpha);
- alpha->SetTarget(frame);
- //播放动画
- alpha->Play();
- sprintf(aname, "am%d", i);
- CLAYUI_MOVE_ANIM* move = new CLAYUI_MOVE_ANIM();
- move->SetIdname(aname);
- move->Init(tx + dis * vx, ty + dis * vy, tx, ty, duration, this);
- AddAnimation(move);
- move->SetTarget(frame);
- move->Play();
- }
原理就是遍厉分页里的所有控件,给每个控件加一个MOVE动画,让他们从从左到右,从右到左,从外向里运动,另外还加了一个ALPHA动画,实现了淡入淡出效果
最后,就是在combobox之间跳动的框,首先说一下原理,这个跳动的框是一个frame,与combobox控件一样都是CXLframe的子frame,由CXLframe来控制它的运动,一开始,框是隐藏的,ALPHA透明度为0,一旦鼠标捕捉到了一个combobox,就给框一个ALPHA动画,让它的透明度渐变为100,同时给它一个MOVE动画,移动到焦点combobox的坐标处,这样,就完成了框的跳动,那么框还要包裹整个combobox,所以,需要在CXLframe的Update更新函数里,得到当前焦点combobox的包围盒大小,同时设置框的大小与此一致。原理就是这样了,下面来说说代码的实现:
首先,加载“框”,一个已经做好的界面文件,当然,也可以使用代码来实现。加载代码在CXLframe的LoadFromMem函数里,如下:
在代码的最后,将这个框的Enable设为了FALSE,目的是让这个框不响应其他消息,避免将其它控件覆盖,然后设置它为绿色,设置一个阴影,模拟发光效果。
然后在CXLframe的Update函数里,不断更新框的位置与大小,代码就不贴了,大家可以直接看工程。这里,有一个细节,当combobox获得焦点时,它会马上被提到其他控件的最前面,那么,跳动的框一定要在combobox的下面,不然,会发生遮挡不正常的现象,处理也很简单,先把框提到其他控件的最前面,再把焦点combobox提到最前面,代码如下:
SetForeground(m_combobox_bbox); //框
SetForeground(m_curfocuscombo); //焦点combobox