221 lines
4.8 KiB
C++
221 lines
4.8 KiB
C++
// 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; // 强制布局标记
|
||
};
|
||
|
||
} |