Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

第16章:高级容器

为什么这很重要

前面的章节覆盖了基础容器(View、SolidView、RoundedView)和列表容器(PortalList)。但构建复杂应用还需要更高级的布局组件——标签页面板、模态弹窗、可折叠区域、分割面板。本章讲解 Makepad 的高级容器组件。

flowchart TD
    A["高级容器"] --> B["Dock — 可拖拽面板系统"]
    A --> C["Modal — 模态弹窗"]
    A --> D["PageFlip — 页面切换"]
    A --> E["ExpandablePanel — 可展开面板"]
    A --> F["FoldHeader — 折叠区"]
    A --> G["Splitter — 分割面板"]
    A --> H["GlassPanel — 毛玻璃面板"]

Dock:可拖拽面板

Dock 是 Makepad Studio 使用的核心组件——一个可拖拽、可分割、可合并的面板系统。适合 IDE、仪表板、多窗口应用。

Dock 的配置比较复杂,通常在 Rust 侧用代码构建面板树。本书不深入 Dock 的完整 API——它是 Part V 架构篇的内容(详见第22章:事件与 Action 系统中的 Dock 事件处理)。


Modal:模态弹窗

Modal 在内容之上叠加一个半透明遮罩层和弹窗内容:

modal := Modal{
    content: RoundedView{
        width: 300 height: Fit
        draw_bg.color: #x2a2a4e
        draw_bg.radius: 12.
        padding: 20 flow: Down spacing: 12 new_batch: true
        Label{text: "Confirm Delete?" draw_text.color: #xfff draw_text.text_style.font_size: 16}
        Label{text: "This action cannot be undone." draw_text.color: #x888}
        View{flow: Right spacing: 8 height: Fit
            Filler{}
            Button{text: "Cancel"}
            Button{text: "Delete" draw_bg.color: #xff4444}
        }
    }
}

Modal 的显示/隐藏通常在 Rust 侧通过 modal.open(cx)modal.close(cx) 控制。


PageFlip:页面切换

PageFlip 在多个"页面"之间切换,同一时刻只显示一个页面:

page_flip := PageFlip{
    active_page: page_home
    page_home := View{
        Label{text: "Home Page"}
    }
    page_settings := View{
        Label{text: "Settings Page"}
    }
}

在 Rust 侧切换页面:page_flip.set_active_page(cx, ids!(page_settings))。在 Splash 中可以用 on_render 条件渲染实现类似效果(详见第9章)。


ExpandablePanel:可展开面板

ExpandablePanel{
    width: Fill height: Fit
    header: View{height: 40 align: Align{y: 0.5}
        Label{text: "Details" draw_text.color: #xfff}
    }
    body: View{height: Fit flow: Down padding: 12
        Label{text: "Expanded content here"}
    }
}

ExpandablePanel 内置展开/折叠动画(Forward 过渡)。


FoldHeader:折叠区

FoldHeader 和 ExpandablePanel 类似,但更轻量——通常用在设置页面的分组中:

FoldHeader{
    header: View{height: Fit flow: Right align: Align{y: 0.5} spacing: 8
        FoldButton{}
        Label{text: "Advanced Settings"}
    }
    body: View{height: Fit flow: Down padding: Inset{left: 23} spacing: 8
        CheckBox{text: "Enable debug mode"}
        CheckBox{text: "Show FPS counter"}
    }
}

来源:splash.md:774-785

FoldButton 是一个小三角图标,点击时旋转(通过 Animator)。


Splitter:分割面板

Splitter 将区域分为两个可调大小的部分:

Splitter{
    axis: SplitterAxis.Horizontal
    align: SplitterAlign.FromA(250.)
    a := View{Label{text: "Left Panel"}}
    b := View{Label{text: "Right Panel"}}
}

改编自:splash.md:762-768

属性说明
axisHorizontal(左右分割)/ Vertical(上下分割)
alignFromA(px) / FromB(px) / Weighted(0.5)
a / b两个子面板(用 := 命名)

GlassPanel:毛玻璃面板

GlassPanel 创建一个带模糊效果的半透明面板,常用于 overlay 式的导航面板:

GlassPanel{
    width: 300 height: Fill
    // 内容
}

GlassPanel 的模糊效果是 GPU shader 级别的——在它后面的内容会被实时模糊。


模式提炼

模式:容器选择决策树

需要模态遮罩? → Modal
需要多页切换? → PageFlip 或 on_render 条件渲染
需要折叠展开? → FoldHeader(轻量)或 ExpandablePanel(带动画)
需要可调分割? → Splitter
需要可拖拽面板? → Dock
需要毛玻璃效果? → GlassPanel

对于简单的"显示/隐藏"需求,优先考虑 on_render 条件渲染(详见第9章)而非 Modal 或 PageFlip——条件渲染在纯 Splash 中就能工作,不需要 Rust 侧控制。


本章小结

容器用途复杂度
Modal模态弹窗
PageFlip页面切换
ExpandablePanel展开/折叠
FoldHeader轻量折叠
Splitter可调分割
GlassPanel毛玻璃面板
Dock可拖拽面板系统

下一章讲解如何创建自定义 Widget——#[derive(Script, ScriptHook, Widget)]、Widget trait 和 Widget 生命周期(详见第17章:自定义 Widget)。