SOUI分层窗口¶
本文介绍SOUI中分层窗口的概念、使用方法及应用场景。
分层窗口概述¶
什么是分层窗口¶
分层窗口是一种特殊的窗口类型,具有以下特点: - 独立的渲染层 - 支持整体透明度控制 - 支持逐点透明(每个像素可以有不同的透明度) - 子窗口渲染到独立的缓存层
分层窗口的优势¶
- 整体效果控制
- 可以设置整个窗口的透明度
- 支持平滑的动画效果
-
提供更好的视觉体验
-
性能优化
- 独立的渲染缓存
- 减少重绘操作
-
优化内存使用
-
开发便利
- 简化透明效果实现
- 更容易管理复杂界面
- 提供更多设计可能
使用分层窗口¶
1. XML定义¶
使用layeredWindow
属性来创建分层窗口:
<window pos="10,10,300,200" layeredWindow="1" alpha="200">
<!-- 子窗口内容 -->
<text pos="10,10,100,30">分层窗口示例</text>
<button pos="10,40,100,70">按钮</button>
</window>
2. 属性说明¶
layeredWindow="1"
:启用分层窗口alpha="200"
:设置窗口透明度(0-255)pos
:窗口位置和大小
3. 动态面板示例¶
<window pos="0,0,-0,-0" clipClient="1" skin="skin_bkgnd">
<!-- 可折叠的侧边栏 -->
<flywnd pos="-210,10,-0,-10"
posEnd="-10,10,@210,-10"
alpha="100"
layeredWindow="1">
<!-- 折叠控制按钮 -->
<toggle pos="0,|-15,@10,@30"
skin="_skin.sys.tree.toggle"
name="switch"
cursor="hand"/>
<!-- 内容区域 -->
<window pos="10,0,-0,-0" colorBkgnd="#ff0000">
<!-- 面板内容 -->
</window>
</flywnd>
</window>
应用场景¶
1. 半透明面板¶
<window layeredWindow="1" alpha="180">
<window pos="0,0,-0,-0" colorBkgnd="#ffffff">
<!-- 面板内容 -->
</window>
</window>
2. 弹出提示¶
<window layeredWindow="1" alpha="220" show="0"
pos="100,100,300,200">
<text pos="10,10,-10,-10">这是一个提示信息</text>
</window>
3. 动画效果¶
// 控制透明度动画
void AnimatePanel(SWindow* pWindow)
{
for(int alpha = 0; alpha <= 255; alpha += 10)
{
pWindow->SetAttribute(L"alpha", SStringW().Format(L"%d",alpha));
Sleep(16); // 约60fps
}
}
实现细节¶
1. 渲染过程¶
class SLayeredWindow : public SWindow
{
protected:
void OnPaint(IRenderTarget *pRT)
{
// 1. 渲染到分层缓存
CAutoRefPtr<IRenderTarget> pRTLayer;
GETRENDERFACTORY->CreateRenderTarget(&pRTLayer, GetClientRect().Width(), GetClientRect().Height());
// 2. 渲染子窗口
SWindow::RedrawRegion(pRTLayer, rgn);
// 3. 应用透明度
BYTE alpha = GetAlpha();
pRT->AlphaBlend(rcDraw, pRTLayer, rcSrc, alpha);
}
};
2. 性能优化¶
-
缓存管理
void ManageLayerCache() { // 只在必要时更新缓存 if(m_bLayoutDirty || m_bContentDirty) { UpdateLayerCache(); } }
-
更新策略
void UpdateStrategy() { // 智能判断是否需要更新 if(OnlyAlphaChanged()) { // 只更新透明度 UpdateAlpha(); } else { // 完全更新 UpdateAll(); } }
最佳实践¶
1. 合理使用¶
- 只在必要时使用分层窗口
- 控制分层窗口数量
- 注意内存使用
2. 性能考虑¶
<!-- 避免过多嵌套的分层窗口 -->
<window layeredWindow="1">
<window layeredWindow="1"> <!-- 避免 -->
<!-- 内容 -->
</window>
</window>
<!-- 建议做法 -->
<window layeredWindow="1">
<window> <!-- 普通窗口 -->
<!-- 内容 -->
</window>
</window>
3. 内存管理¶
// 分层窗口销毁时清理资源
void OnDestroy()
{
if(m_pLayerRT)
{
m_pLayerRT = NULL;
}
__super::OnDestroy();
}
注意事项¶
- 性能影响
- 分层窗口需要额外的内存
- 可能影响渲染性能
-
注意使用数量
-
更新控制
- 合理控制更新频率
- 避免不必要的重绘
-
使用适当的缓存策略
-
动画效果
- 使用平滑的透明度变化
- 控制动画帧率
- 避免过于频繁的更新