mrDarker
2025-08-26 43c7dc211f10851480352b12bd01f3443079bb01
SourceCode/Bond/Servo/CExpandableListCtrl.h
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,58 @@
#pragma once
#include <vector>
#include <memory>
class CExpandableListCtrl : public CListCtrl
{
    DECLARE_DYNAMIC(CExpandableListCtrl)
public:
    struct Node {
        Node* parent = nullptr;
        std::vector<std::unique_ptr<Node>> children;
        std::vector<CString> cols; // å„列文本
        bool expanded = false;
        int level = 0; // ç¼©è¿›å±‚级
        Node(int nCols = 1) : cols(nCols) {}
    };
    CExpandableListCtrl();
    virtual ~CExpandableListCtrl();
    // æ•°æ®æž„建
    Node* InsertRoot(const std::vector<CString>& cols);
    Node* InsertChild(Node* parent, const std::vector<CString>& cols);
    // å±•å¼€/折叠
    void Expand(Node* n);
    void Collapse(Node* n);
    void Toggle(Node* n);
    // åˆ·æ–°å¯è§åˆ—表
    void RebuildVisible();
    // ä¾¿æ·ï¼šé€šè¿‡å¯è§è¡Œå·å– Node*
    Node* GetNodeByVisibleIndex(int i) const;
private:
    void appendVisible(Node* n);
    CRect expanderRectForRow(int row) const;        // é¦–列展开按钮区域
    virtual void PreSubclassWindow();
protected:
    // æ¶ˆæ¯
    afx_msg int  OnCreate(LPCREATESTRUCT lpCreateStruct);
    afx_msg void OnClick(NMHDR* pNMHDR, LRESULT* pResult);
    afx_msg void OnCustomDraw(NMHDR* pNMHDR, LRESULT* pResult);
    DECLARE_MESSAGE_MAP()
private:
    std::vector<std::unique_ptr<Node>> m_roots;     // é¡¶å±‚节点
    std::vector<Node*>                 m_visible;   // å±•开后的可见节点顺序
    int  m_expanderPadding = 6;                     // é¦–列内侧边距
    int  m_expanderSize = 10;                       // å°ä¸‰è§’/方块大小
    int  m_textGap = 6;
};