一:用户UI使用与分析
如图,ssRender Edito工具有六个窗口
Project窗口显示创建的节点,工程的层级关系
Properties窗口显示选中节点的属性名与属性值
Preview窗口显示当前工程的预览效果
Resource窗口用于管理当前工程用到的资源文件,包括图片,插件,自定义图片等
Interaction窗口用于管理交互行为,例如绑定,事件与计时器
Log窗口显示日志和调试信息等
(一)节点分类
(1)Page节点
一个项目中只能包含一个Page,相当于一块"幕布","幕布"的大小由属性width和hight控制(以像素为单位),该项目内所有的显示效果只能在这块幕布上显示,超出幕布范围的节点将没有显示效果。
在学习的过程中,当时我有这样一个疑问:超出"幕布"范围的节点是否占用资源,是否被渲染呢?还请接着往下看。
(2)Layer与FastBoot
Layer节点与FastBoot是Page节点下的子节点,相当于Page"幕布"上的不同显示"图层"
它们基本一致,只不过FastBoot节点会优先渲染,可以将显示优先级更高的效果(比如开机动画)放在FastBoot节点中,可以快速渲染,优先显示。
如图,Layer节点有一个Visible属性,用于控制是否可见。
现在就能回答上方的那个小疑问了,当图层超出了"幕布"范围,若选中了Visible属性,那么即使图层没有显示,但是依旧会占用后台资源,所以当实现一些移出屏幕的动画效果时,记得在超出Page范围后取消Visible属性!
(3)Item节点
Item节点可在Layer层级下创建,虽然此节点下能挂载如上方右侧图片所示的其他节点,但是此节点也算是第一个可以编辑显示效果的节点。
Item的一般属性有:
X、Y、Z:控制Item节点在Layer图层下横向、纵向,竖向位移像素值
Width、Hight:控制Item节点的宽高长度
Rotation:控制Item节点的旋转角度
Scal:控制Item节点的缩放比例(默认值为1)
Opacity:控制Item节点的透明度(初值为1,值为0时透明)
Item的Material属性包括:
Source:可以拖拽Resource窗口下Image资源到该属性下,在Item中显示。拖拽完成后,Item节点的Width和Hight属性将会自动变为Image资源的宽高像素
Color:控制Item的底色
Item的Customization属性:
用于挂载Resource窗口中Property内的属性资源,以达到控制显示效果的目的。
(4)Button节点
与Item节点中的属性基本一致,同样可以挂载其他节点。
与Item区别点:响应的事件不同
在Interaction窗口中的Events事件,Item仅有PropertyChanged事件,即某一个属性值变化时可以相应。但是Button节点多了Clicked点击事件,Pressed按压事件,Released松开事件和Moving移动时间
(5)Text节点
属性与Item大致相同,但是Material属性不同,不能显示图片,只能编辑文本内容与格式。
Text属性:编辑文本内容
Font属性:编辑文本的字体格式
FontSize属性:编辑文本的字体大小
FontColor属性:编辑文字颜色
(6)Group节点
Group的一般属性与Item节点基本一致
特殊属性为FPS,用于控制组内节点每秒刷新帧数,可以在复杂场景下,分组设置不同区域的刷新率,降低不重要区域的刷新频率,以提高整体画面的流畅度。
(7)View节点
View的一般属性与Item节点基本一致,View节点能且只能创建下一分级的ViewItem节点,ViewItem节点与Item节点基本类似,但是ViewItem只能挂载在View节点下,且不可创建下一分级节点.
View的特殊属性如下:
Index属性:控制显示view目录下的,第index-1个ViewItem节点显示在view节点
Span属性:view下ViewItem节点之间的间距,一般设置为ViewItem节点的像素宽度或高度
MaxCount属性:View可以同时显示的最多的ViewItem节点的数量
Orientation:ViewItem节点的滑动方式,设置为Horizontal时为水平移动,设置为vertical时为铅直移动
(8)SeqImage节点
SeqImage基本属性与Item一致
SwqImage特殊属性如下:
Index属性:控制当前SeqImage 节点下的子节点的顺序(从 0 开始~子节点最大数-1)
Transition:选择切换 Index(子节点)时的不同切换方式
Duration:切换子节点时的动画持续时间。
EasingType:选择切换子节点时的动画曲线类型。
Tips:
看上去seqImage和View很像,但是它们有如下不同:
1.seqImage支持创建除了view节点以外的多种其他类型的节点,且均可通过控制Index来进行显示。但是View节点只支持创建ViewItem节点。
2.View不仅支持通过改变index属性来控制viewitem节点显示,而且还支持滑动来改变ViewItem节点的显示,定制特殊的滑动切换效果。seqImage只能控制子节点的显示与否,并不能控制子节点改变时的切换效果
(二)实际案例应用
ssRender Edit有一个特性,就是层级的优先性:同一目录下,在Project的中越靠下的层级优先性会越高,会被优先显示,且能够遮挡优先性低的图层,就好比同一个幕布,不同的场景不能同时占用同一块区域一样,注意好优先级顺序,能让我们构思设计出更好的渲染效果。
1.使用Group与Item设计表显时速
可以使用Text与speed属性进行绑定,但是Text是纯文本内容,显示效果并不算好,想要模拟镜像反射效果的表显时速,只能使用镜像Image进行动态绑定切换.
(1)引入资源
创建Layer命名为MainPage用作设计主页面,从Resource的Image加入背景图片,数字图片,指针图片等Image资源;
创建Group命名为Velocity,创建三个Item节点分别用作表示百位、十位与个位。拖拽Image资源到各个Item节点的Image属性上。
(2)创建与绑定speed变量
我们按照如下顺序,创建一个时刻变化的speed属性(用于表显speed的绑定)
将speed属性拖拽到Velocity(Group)的Customization中,点击绑定标志
编辑绑定脚本实现speed自增;
(3)表显数字绑定
首先获取speed时速,对int型的speed时速进行除法运算与模运算,获取个十百位数字,不同数字显示不同的源Image图片.
个位: 十位: 百位:
这时注意到,时速100以下时,百位不显示;时速10以下时,十位不显示.所以我们将十位和百位的Visible属性与speed属性绑定,实现同步显示(Visible=1时显示,Visible=0时消失):
百位: 十位:
同时我们要处理好数字的显示位置,让单位数、双位数、三位数时都居中显示(同理,将三个Item的X属性与speed绑定,speed<10,speed<100,speed>=100时分别在不同位置)
2.speed与表显指针绑定
同上述,创建Item节点命名为Point,引入Image资源文件,拖拽到本节点的Source属性上,调整好本节点的XY属性值,让指针图片居中显示.
选择Point(Item)节点的Rotation(旋转)属性,调试出指针范围,本案例范围为(-144,144),根据speed时速值,算出对应表达式,点击绑定按钮,实现指针与speed时速的绑定:
同时选中Behavior,设置时间与动画(如上图),即可实现指针的缓动效果(如下图):
3.仪表板数字变大效果与指针绑定
上面介绍过Item的一般属性中有一个Scale,用来控制缩放效果,将本属性与Point(Item)的Rotation(旋转角度)进行绑定,即可实现指针转动接近哪位仪表班数字时,该数字变大,远离数字时,数字恢复原本大小。
其余数字同理,只需要注意不同的Rotation角度即可。
Tips:
为什么仪表板数字缩放效果不与speed进行绑定,要与Point的Rotation进行绑定呢?
因为设置了Point(Item)的旋转为缓动效果,不设置缓动效果的话,指针旋转变化速度太快,显示效果失真。但是设置为缓动效果后,时速speed与point旋转角度变化有一定延迟,所以仪表板数字缩放效果要与指针进行绑定!
4.SeqImage节点设计Manual菜单
创建SeqImage节点,命名为ManuFocus,拖拽带有纯灰色菜单的Image背景到ManuFocus的Source属性中。添加5个Item节点分别控制主题、导航、胎压、行车信息以及设置的橙色区域的显示。
设置五个菜单按钮的XY值到对应位置,ManuFocus的Index属性发生变化时,对应的Item节点显示效果也会发生变化:
5.使用View节点创建音乐滑动菜单
工程结构如图所示,导入对应图盘资源,设置span(各个ViewItem节点的间隔)为ViewItem节点的宽度,设置MaxCount为1(同时只能显示一个ViewItem),Orientation(滑动方式)为Vertical,设置好musicList的XY属性,让音乐列表在正确的位置显示,做好的效果如下:
二:Plus:Plugin文件数据传输
上述的案例应用中,例如speed时速属性,是自己设置的自增属性,本节内容就是介绍如何通过Plugin文件实现后台数据与前端UI的互通绑定。
(一)创建属性
SSR_PLUGIN_PROPERTY_DEF_BEGIN(DataSource)
// grou_name name type default_value min max tooltip ctrl_type
SSR_PLUGIN_PROPERTY("INDEX_INT","INDEX",TYPE_INT,"0",0,4,"this is the manual page index",PCT_TextBoxBind)
SSR_PLUGIN_PROPERTY("ALT_SWITCH","OFF_ON",TYPE_INT,"0",0,1,"control Manual index alt off/on",PCT_CheckBox)
SSR_PLUGIN_PROPERTY("SLEEP_INT","SLEEP",TYPE_INT,"1500",100,10000,"this is data_updata circulate time",PCT_TextBoxBind)
SSR_PLUGIN_PROPERTY("INDEX_INT", "SPEED", TYPE_INT, "0", 0, 240, "this is speed", PCT_TextBoxBind)
SSR_PLUGIN_PROPERTY_DEF_END()
四个属性分别代表菜单切换焦点、切换标签、切换时间以及时速。
(二)数据读取与写入
为了更新数据,将会建立线程,ssrThread_dataProc()是线程的入口函数,创建线程时将会调用此入口函数.
为了模拟汽车时速,将会用到C++的随机数函数uniform_int_distribution来产生均匀分布的整数
通过getPropertyValue(ssr对象,"属性名")函数来获取属性值
通过setPropertyValue(ssr对象,"属性名",属性值)函数来传值
void* ssrThread_dataProc(void* arg) //线程入口函数
{
SSRObject* ssrObject = (SSRObject*)arg;
DataSource* dataSource = (DataSource*)ssrObject->m_ssRptr_plugin; //获取当前传入到线程内的DataSource
if (dataSource)//若传入了datasource
{
//当前对象被creat
while (dataSource->m_runningFlg)
{
dataSource->enterLock();
if (dataSource->isRunning())
{
dataSource->updateDB(ssrObject);//调用update方法更新属性
}
dataSource->leaveLock();
Common::sleep(Common::str2int(dataSource->m_renderEngine->getPropertySystem()->getPropertyValue(ssrObject, "SLEEP")));
//获取UI中的sleep时间(多久更新一次数据)
}
}
return NULL;
}
void DataSource::deleteSSRObject(SSRObject* ssrObject)//delete方法
{
enterLock();
m_runningFlg = false;
if (ssrObject)
{
delete ssrObject;
ssrObject = NULL;
}
leaveLock();
}
SSRObject* DataSource::createSSRObject()
{
#ifdef TYPE_PLUGIN_DATA
SSRObject* ssrObj = new SSRObject;
#else
SSRObject* ssrObj = new Item;
#endif
ssrObj->m_ssRptr_plugin = this;//plugin instance in Resource 资源中的插件实例
ssrObj->m_ssRtype = OBJECT_TYPE_PLUGIN;//real object type define 定义类型
m_runningFlg = true; //creat tag
pthread_create(&m_thread, NULL, ssrThread_dataProc, (void *)ssrObj);//创建线程:
return ssrObj;
}
bool DataSource::updateDB(SSRObject* ssrObject)
{
if (m_runningFlg == true)
{
DataSource* dataSource = (DataSource*)ssrObject->m_ssRptr_plugin;
switch_button = Common::str2int(dataSource->m_renderEngine->getPropertySystem()->getPropertyValue(ssrObject, "OFF_ON"));
if (switch_button == 1) {
int index = Common::str2int(dataSource->m_renderEngine->getPropertySystem()->getPropertyValue(ssrObject, "INDEX"));
if (index == 4) {
index = 0;
}
else {
index++;
}
//获取分布均匀的随机数,模拟汽车时速变化
default_random_engine e;
uniform_int_distribution<int> u(0, 240); //左闭右闭区间,speed为0-240
e.seed(time(0));
int speed = u(e);
//传值
m_renderEngine->getPropertySystem()->setPropertyValue(ssrObject, "SPEED", Common::int2str(speed));
m_renderEngine->getPropertySystem()->setPropertyValue(ssrObject, "INDEX", Common::int2str(index));
}
}
return true;
}
(三)编译与引入
右键项目名称,点击生成
在UI中点击New Plugin倒入上一步生成的.DLL文件
拖拽到Page中
双击打开,就能看到我们set的属性名称与属性值了
(四)绑定
修改Velocity(Group)中个、十、百Item的Visible和Source绑定,与plugin文件的SPEED进行绑定
修改指针Point(item)的Rotation与SPEED的绑定
再将菜单焦点的index与Plugin的INDEX进行绑定
小结:
本篇文章主要介绍了个人在使用ssRender Edit工具时的学习见解,并使用数据类型的plugin插件对简单的项目工程进行了实现,接下来将会继续分享本人的学习历程与个人理解!