#pragma once
/**
 * @file mbox.h
 * @brief 定义水平和垂直布局盒子组件
 *
 * 本文件定义了两种基本的布局容器：水平盒子(mh_box)和垂直盒子(mv_box)，
 * 用于分别在水平和垂直方向上排列多个子组件。
 */

#include "widget/mpanel_widget.h"
#include "geometry/margin.h"
#include "widget/widget_size.h"

/**
 * @struct hbox_slot
 * @brief 水平盒子布局的插槽结构
 *
 * 定义了水平盒子布局中每个子组件的插槽属性，
 * 包括尺寸控制和边距设置。
 */
struct hbox_slot : mpanel_widget_slot<hbox_slot> {
    /** 定义尺寸相关属性，用于控制子组件在布局中的大小 */
    SLOT_SIZE()
    /** 定义边距属性，控制子组件周围的空间 */
    SLOT_ATTRIBUTE(margin_t, margin)
};

/**
 * @class mh_box
 * @brief 水平盒子布局组件
 *
 * 将子组件从左到右水平排列的容器组件。
 * 可以通过插槽属性控制子组件的大小和边距。
 */
class mh_box : public mpanel_widget<hbox_slot> {
public:
    /**
     * @brief 排列子组件
     * @param in_allotted_geometry 分配给组件的几何区域
     *
     * 在水平方向上排列所有子组件，考虑各自的大小、边距和间距。
     */
    virtual void arrange_children(const geometry_t& in_allotted_geometry) override;

    /**
     * @brief 计算组件的期望大小
     * @param in_layout_scale_multiplier 布局缩放系数
     * @return 组件的期望大小
     *
     * 基于所有子组件的期望大小、边距和间距，计算水平盒子组件的总体期望大小。
     */
    [[nodiscard]] virtual auto compute_desired_size(float in_layout_scale_multiplier) const -> Eigen::Vector2f override;

private:
    /** 子组件之间的间距 */
    float spacing_{};
};

/**
 * @struct vbox_slot
 * @brief 垂直盒子布局的插槽结构
 *
 * 定义了垂直盒子布局中每个子组件的插槽属性，
 * 包括尺寸控制和边距设置。
 */
struct vbox_slot : mpanel_widget_slot<vbox_slot> {
    /** 定义尺寸相关属性，用于控制子组件在布局中的大小 */
    SLOT_SIZE()
    /** 定义边距属性，控制子组件周围的空间 */
    SLOT_ATTRIBUTE(margin_t, margin)
};

/**
 * @class mv_box
 * @brief 垂直盒子布局组件
 *
 * 将子组件从上到下垂直排列的容器组件。
 * 可以通过插槽属性控制子组件的大小和边距。
 */
class mv_box : public mpanel_widget<vbox_slot> {
public:
    /**
     * @brief 排列子组件
     * @param in_allotted_geometry 分配给组件的几何区域
     *
     * 在垂直方向上排列所有子组件，考虑各自的大小、边距和间距。
     */
    virtual void arrange_children(const geometry_t& in_allotted_geometry) override;

    /**
     * @brief 计算组件的期望大小
     * @param in_layout_scale_multiplier 布局缩放系数
     * @return 组件的期望大小
     *
     * 基于所有子组件的期望大小、边距和间距，计算垂直盒子组件的总体期望大小。
     */
    [[nodiscard]] virtual auto compute_desired_size(float in_layout_scale_multiplier) const -> Eigen::Vector2f override;

private:
    /** 子组件之间的间距 */
    float spacing_{};
};
