nim_duilib/duilib/Control/VirtualListBox.h
jiajia_deng 4933d1f2bc Remove dependency on shared
Signed-off-by: jiajia_deng <2894220@gmail.com>
2019-09-20 16:27:58 +08:00

221 lines
4.8 KiB
C++
Raw Permalink 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.

// Copyright 2017, NetEase (Hangzhou) Network Co., Ltd. All rights reserved.
//
// zqw
// 2015/7/22
//
// virtual ListBox class
#pragma once
namespace ui
{
/**
* @brief 虚拟列表接口类
* 提供开发者对子项数据管理个性化定制
*/
class VirtualListInterface
{
public:
/**
* @brief 创建一个子项
* @return 返回创建后的子项指针
*/
virtual Control* CreateElement() = 0;
/**
* @brief 填充指定子项
* @param[in] control 子项控件指针
* @param[in] index 索引
* @return 返回创建后的子项指针
*/
virtual void FillElement(Control *control, int index) = 0;
/**
* @brief 获取子项总数
* @return 返回子项总数
*/
virtual int GetElementtCount() = 0;
};
/**
* @brief 虚拟列表
*/
class UILIB_API VirtualLayout : public VLayout
{
protected:
virtual ui::CSize ArrangeChild(const std::vector<ui::Control*>& items, ui::UiRect rc);
};
class UILIB_API VirtualListBox : public ListBox
{
friend class VirtualLayout;
public:
VirtualListBox(ui::Layout* pLayout = new VirtualLayout);
/**
* @brief 设置数据代理对象
* @param[in] pProvider 开发者需要重写 VirtualListInterface 的接口来作为数据代理对象
* @return 无
*/
virtual void SetDataProvider(VirtualListInterface *pProvider);
/**
* @brief 设置子项高度
* @param[in] nHeight 高度值
* @return 无
*/
virtual void SetElementHeight(int nHeight);
/**
* @brief 初始化子项
* @param[in] nMaxItemCount 初始化数量,默认 50
* @return 无
*/
virtual void InitElement(int nMaxItemCount = 50);
/**
* @brief 刷新列表
* @return 无
*/
virtual void Refresh();
/**
* @brief 删除所有子项
* @return 无
*/
virtual void RemoveAll() override;
/**
* @brief 设置是否强制重新布局
* @param[in] bForce 设置为 true 为强制,否则为不强制
* @return 无
*/
void SetForceArrange(bool bForce);
/**
* @brief 获取当前所有可见控件的索引
* @param[out] collection 索引列表
* @return 无
*/
void GetDisplayCollection(std::vector<int>& collection);
/**
* @brief 让控件在可见范围内
* @param[in] iIndex 控件索引
* @param[in] bToTop 是否在最上方
* @return 无
*/
void EnsureVisible(int iIndex, bool bToTop = false);
protected:
/// 重写父类接口,提供个性化功能
virtual void SetScrollPos(ui::CSize szPos) override;
virtual void HandleMessage(ui::EventArgs& event) override;
virtual void SetPos(UiRect rc) override;
/**
* @brief 重新布局子项
* @param[in] bForce 是否强制重新布局
* @return 无
*/
void ReArrangeChild(bool bForce);
/**
* @brief 添加一个子项
* @param[in] iIndex 要插入的位置
* @return 无
*/
void AddElement(int iIndex);
/**
* @brief 移除一个子项
* @param[in] iIndex 要移除的子项索引
* @return 无
*/
void RemoveElement(int iIndex);
/**
* @brief 键盘按下通知
* @param[in] ch 按键
* @return 无
*/
virtual void OnKeyDown(TCHAR ch) {}
/**
* @brief 键盘弹起通知
* @param[in] ch 按键
* @return 无
*/
virtual void OnKeyUp(TCHAR ch) {}
private:
enum ScrollDirection
{
kScrollUp = -1,
kScrollDown = 1
};
/**
* @brief 创建一个子项
* @return 返回创建后的子项指针
*/
Control* CreateElement();
/**
* @brief 填充指定子项
* @param[in] control 子项控件指针
* @param[in] index 索引
* @return 返回创建后的子项指针
*/
void FillElement(Control *pControl, int iIndex);
/**
* @brief 获取元素总数
* @return 返回元素总指数
*/
int GetElementCount();
/**
* @brief 使用默认布局
* @return 成功返回 true否则返回 false
*/
bool UseDefaultLayout();
/**
* @brief 得到n个元素对应的高度和
* @param[in] nCount 要得到多少元素的高度,-1表示全部元素
* @return 返回指定数量元素的高度和
*/
int CalcElementsHeight(int nCount);
/**
* @brief 得到可见范围内第一个元素的前一个元素索引
* @param[out] bottom 返回上一个元素的 bottom 值
* @return 返回上一个元素的索引
*/
int GetTopElementIndex(int &bottom);
/**
* @brief 判断某个元素是否在可见范围内
* @param[in] iIndex 元素索引
* @return 返回 true 表示可见,否则为不可见
*/
bool IsElementDisplay(int iIndex);
/**
* @brief 判断是否要重新布局
* @param[out] direction 向上滚动还是向下滚动
* @return true 为需要重新布局,否则为 false
*/
bool NeedReArrange(ScrollDirection &direction);
private:
VirtualListInterface *m_pDataProvider;
int m_nElementHeight; // 每个项的高度
int m_nMaxItemCount; // 列表真实控件数量上限
int m_nOldYScrollPos;
bool m_bArrangedOnce;
bool m_bForceArrange; // 强制布局标记
};
}