103 lines
2.9 KiB
C++
103 lines
2.9 KiB
C++
#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);
|
||
}
|
||
}
|