mirage/src/mirage_widget/widget/mpanel_widget.h

103 lines
2.9 KiB
C++
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#pragma once
/**
* @file mpanel_widget.h
* @brief 定义可容纳多个子组件的面板组件基类
*
* 本文件定义了mpanel_widget模板类这是一种可以容纳多个子组件的面板组件。
* 通过模板参数SlotType可以自定义子组件插槽的具体行为。
*/
#include "mwidget.h"
#include "slot_util.h"
/**
* @struct mpanel_widget_slot
* @brief 面板组件的插槽结构,管理子组件
*
* @tparam T 插槽的具体类型,通常是派生自此模板的类
*
* 提供了对子组件的内容管理功能。
* 使用SLOT宏来定义插槽的标准功能。
*/
template<typename T>
struct mpanel_widget_slot {
/**
* @brief 获取当前实例的引用转换为具体类型T
* @return 当前实例的引用类型为T&
*/
auto& me() {
return static_cast<T&>(*this);
}
std::weak_ptr<mwidget> slot_owner;
// 插槽功能宏 - 定义内容管理
SLOT_CONTENT()
};
/**
* @class mpanel_widget
* @brief 可布局多个子组件的面板组件基类
*
* @tparam SlotType 插槽类型,控制如何管理子组件
*
* 这个类是所有需要容纳多个子组件的面板组件的基类。
* 它提供了子组件的管理和查询功能。
*/
template<typename SlotType>
class mpanel_widget : public mwidget {
public:
//-------------- 绘制 --------------
/**
* @brief 绘制组件
* @param in_context 绘制上下文
*
* 基类实现为空,因为面板组件通常不需要自己绘制,而是依赖子组件的绘制。
*/
void on_paint(mirage_paint_context& in_context) override {}
void cache_all_children_desired_size(float in_layout_scale_multiplier, bool in_force = false) const;
//-------------- 子项管理 --------------
// 1. 创建一个新的entity
// 2. 给entity添加一个slot component
// 3. 更新父子关系
// 4. 通知父组件需要重新计算布局
// 5. 返回slot component的引用便于链式调用设置属性
/**
* @brief 添加新的子组件插槽
* @return 新添加的插槽引用,允许链式调用设置插槽属性
*
* 创建并添加一个新的子组件插槽到面板中。
*/
auto add_slot() -> SlotType& {
auto& slot = slots_.emplace_back();
slot.slot_owner = shared_from_this();
invalidate(invalidate_reason::all);
return slot;
}
template<typename... Args>
auto add_child(Args&&... in_args) -> SlotType& {
auto& slot = slots_.emplace_back(std::forward<Args>(in_args)...);
slot.slot_owner = shared_from_this();
invalidate(invalidate_reason::all);
return slot;
}
const auto& get_slots() const {
return slots_;
}
private:
std::vector<SlotType> slots_;
};
template<typename SlotType>
void mpanel_widget<SlotType>::cache_all_children_desired_size(float in_layout_scale_multiplier, bool in_force) const {
for (const auto& slot: slots_) {
const auto& ptr = slot.get();
ptr->cache_desired_size(in_layout_scale_multiplier, in_force);
}
}