Skip to content

SOUI分层窗口

Warning

The current page still doesn't have a translation for this language.

You can read it through google translate.

本文介绍SOUI中分层窗口的概念、使用方法及应用场景。

分层窗口概述

什么是分层窗口

分层窗口是一种特殊的窗口类型,具有以下特点: - 独立的渲染层 - 支持整体透明度控制 - 支持逐点透明(每个像素可以有不同的透明度) - 子窗口渲染到独立的缓存层

分层窗口的优势

  1. 整体效果控制
  2. 可以设置整个窗口的透明度
  3. 支持平滑的动画效果
  4. 提供更好的视觉体验

  5. 性能优化

  6. 独立的渲染缓存
  7. 减少重绘操作
  8. 优化内存使用

  9. 开发便利

  10. 简化透明效果实现
  11. 更容易管理复杂界面
  12. 提供更多设计可能

使用分层窗口

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. 性能优化

  1. 缓存管理

    void ManageLayerCache()
    {
        // 只在必要时更新缓存
        if(m_bLayoutDirty || m_bContentDirty)
        {
            UpdateLayerCache();
        }
    }
    

  2. 更新策略

    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();
}

注意事项

  1. 性能影响
  2. 分层窗口需要额外的内存
  3. 可能影响渲染性能
  4. 注意使用数量

  5. 更新控制

  6. 合理控制更新频率
  7. 避免不必要的重绘
  8. 使用适当的缓存策略

  9. 动画效果

  10. 使用平滑的透明度变化
  11. 控制动画帧率
  12. 避免过于频繁的更新