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

644 lines
15 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.

#ifndef UI_CORE_BOX_H_
#define UI_CORE_BOX_H_
#pragma once
namespace ui
{
class Box;
class UILIB_API Layout
{
public:
Layout();
Layout& operator=(const Layout& r) = delete;
virtual ~Layout() {}
/**
* @brief 设置所有者
* @return 无
*/
void SetOwner(Box* pOwner);
/**
* @brief 设置浮动状态下的坐标信息
* @param[in] pControl 控件句柄
* @param[in] rcContainer 要设置的位置信息
* @return 返回控件最终的位置信息
*/
static CSize SetFloatPos(Control* pControl, UiRect rcContainer);
/**
* @brief 设置布局属性
* @param[in] strName 要设置的属性名
* @param[in] strValue 要设置的属性值
* @return true 设置成功false 属性不存在
*/
virtual bool SetAttribute(const std::wstring& strName, const std::wstring& strValue);
/**
* @brief 调整内部所有控件的位置信息
* @param[in] items 控件列表
* @param[in] rc 当前容器位置信息
* @return 返回排列后最终盒子的宽度和高度信息
*/
virtual CSize ArrangeChild(const std::vector<Control*>& items, UiRect rc);
/**
* @brief 根据内部子控件大小调整容器自身大小
* @param[in] items 控件列表
* @param[in] szAvailable 子控件允许的最大宽度
* @return 返回排列后最终盒子的宽度和高度信息
*/
virtual CSize AjustSizeByChild(const std::vector<Control*>& items, CSize szAvailable);
/**
* @brief 获取内边距
* @return 返回内边距四边的大小
*/
virtual UiRect GetPadding() const;
/**
* @brief 设置内边距,相当于设置客户区
* @param[in] rcPadding 内边距数据
* @param[in] bNeedDpiScale 是否根据 DPI 自适应,默认为 true
* @return 无
*/
virtual void SetPadding(UiRect rcPadding, bool bNeedDpiScale = true);
/**
* @brief 获取子控件之间的额外边距
* @return 返回额外间距的数值
*/
virtual int GetChildMargin() const;
/**
* @brief 设置子控件之间的额外边距
* @param[in] iMargin 要设置的边距数值
* @return 无
*/
virtual void SetChildMargin(int iMargin);
/**
* @brief 获取除了内边距外的可用范围
* @return 返回可用范围位置信息
*/
UiRect GetInternalPos() const;
protected:
UiRect m_rcPadding;
int m_iChildMargin;
Box *m_pOwner;
};
/////////////////////////////////////////////////////////////////////////////////////
//
class ScrollBar;
class UILIB_API Box : public Control
{
public:
Box(Layout* pLayout = new Layout());
Box(const Box& r);
Box& operator=(const Box& r) = delete;
virtual ~Box();
public:
/// 重写父类接口,提供个性化功能。方法具体说明请查看 Control 控件 */
virtual void SetWindow(Window* pManager, Box* pParent, bool bInit = true) override;
virtual void SetAttribute(const std::wstring& strName, const std::wstring& strValue) override;
virtual void SetPos(UiRect rc) override;
virtual void HandleMessageTemplate(EventArgs& msg) override;
virtual void PaintChild(IRenderContext* pRender, const UiRect& rcPaint) override;
virtual void SetVisible_(bool bVisible) override;
virtual void SetInternVisible(bool bVisible = true) override;
virtual void SetEnabled(bool bEnabled) override;
virtual CSize EstimateSize(CSize szAvailable) override;
virtual Control* FindControl(FINDCONTROLPROC Proc, LPVOID pData, UINT uFlags, CPoint scrollPos = CPoint()) override;
virtual void InvokeLoadImageCache() override;
virtual void UnLoadImageCache() override;
virtual void ClearImageCache() override;
virtual UINT GetControlFlags() const override;
/// 容器自有方法
/**
* @brief 查找指定子控件
* @param[in] pstrSubControlName 子控件名称
* @return 返回子控件指针
*/
Control* FindSubControl(const std::wstring& pstrSubControlName);
/**
* @brief 查找下一个可选控件的索引(面向 list、combo
* @param[in] iIndex 指定要起始查找的索引
* @param[in] bForward true 为递增查找, false 为递减查找
* @return 下一个可选控件的索引,返回 -1 为没有可选控件
*/
virtual int FindSelectable(int iIndex, bool bForward = true) const;
/**
* @brief 根据索引查找指定控件
* @param[in] iIndex 控件索引
* @return 返回控件指针
*/
virtual Control* GetItemAt(std::size_t iIndex) const;
/**
* @brief 根据控件指针获取索引
* @param[in] pControl 控件指针
* @return 返回 pControl 所指向的控件索引
*/
virtual int GetItemIndex(Control* pControl) const;
/**
* @brief 设置控件索引(内部会重新排列控件位置)
* @param[in] pControl 控件指针
* @param[in] iIndex 要设置的索引值
* @return 返回 true 设置成功false 设置失败
*/
virtual bool SetItemIndex(Control* pControl, std::size_t iIndex);
/**
* @brief 获取子控件数量
* @return 返回子控件数量
*/
virtual int GetCount() const;
/**
* @brief 添加一个控件到容器中
* @param[in] pControl 控件指针
* @return 返回 true 添加成功false 为添加失败
*/
virtual bool Add(Control* pControl);
/**
* @brief 向指定位置添加一个控件
* @param[in] pControl 控件指针
* @param[in] iIndex 在该索引之后插入控件
* @return 返回 true 为添加成功false 为添加失败
*/
virtual bool AddAt(Control* pControl, std::size_t iIndex);
/**
* @brief 根据控件指针从容器中移除一个控件
* @param[in] pControl 控件的指针
* @return 返回 true 为移除成功false 为移除失败(控件可能不存在)
*/
virtual bool Remove(Control* pControl);
/**
* @brief 根据控件索引从容器中移除一个控件
* @param[in] iIndex 要移除的控件索引
* @return 返回 true 为移除成功false 为移除失败(索引值太小或超出了子控件总数)
*/
virtual bool RemoveAt(std::size_t iIndex);
/**
* @brief 移除所有子控件
* @return 无
*/
virtual void RemoveAll();
/**
* @brief 交换子控件位置
* @param[in] pChild1 子控件1 指针
* @param[in] pChild2 子控件2 指针
* @return 无
*/
void SwapChild(Control* pChild1, Control* pChild2);
/**
* @brief 重置一个子控件位置
* @param[in] pChild 控件指针
* @param[in] iIndex 要重置的位置
* @return 无
*/
void ResetChildIndex(Control* pChild, std::size_t iIndex);
/**
* @brief 判断是否自动销毁
* @return true 为自动销毁false 为不自动销毁
*/
virtual bool IsAutoDestroy() const;
/**
* @brief 设置控件是否自动销毁
* @param[in] bAuto true 为自动销毁false 为不自动销毁
* @return 无
*/
virtual void SetAutoDestroy(bool bAuto);
/**
* @brief 判断窗口关闭后是否自动销毁
* @return true 为自动销毁false 为不自动销毁
*/
virtual bool IsDelayedDestroy() const;
/**
* @brief 设置窗口关闭后是否自动销毁
* @param[in] bDelayed true 为自动销毁false 为不自动销毁
* @return 无
*/
virtual void SetDelayedDestroy(bool bDelayed);
/**
* @brief 获取容器是否响应鼠标操作
* @return true 为响应false 为不响应
*/
virtual bool IsMouseChildEnabled() const;
/**
* @brief 设置容器响应鼠标操作
* @param[in] bEnable 设置为 true 为响应鼠标操作,设置为 false 为不响应,默认为 true
* @return 无
*/
virtual void SetMouseChildEnabled(bool bEnable = true);
/**
* @brief 获取容器布局对象指针
* @return 返回容器关联的布局对象指针
*/
virtual Layout* GetLayout() const;
/**
* @brief 重新关联布局对象
* @param[in] pLayout 布局对象指针
* @return 无
*/
virtual void RetSetLayout(Layout* pLayout);
/**
* @brief 获取内边距的位置信息
* @return 返回内边距的位置信息
*/
virtual UiRect GetPaddingPos() const;
/**
* @brief 绑定事件处理函数
* @param[in] eventType 事件类型
* @return callback 指定回调函数
*/
void AttachBubbledEvent(EventType eventType, const EventCallback& callback) { OnBubbledEvent[eventType] += callback; }
private:
friend WindowBuilder;
/**
* @brief 绑定 XML 中编写的 Event 和 BubbleEvent 事件的处理函数
* @param[in] eventType 事件类型
* @return callback 指定回调函数
*/
void AttachXmlBubbledEvent(EventType eventType, const EventCallback& callback) { OnXmlBubbledEvent[eventType] += callback; }
EventMap OnXmlBubbledEvent;
protected:
std::unique_ptr<Layout> m_pLayout;
bool m_bAutoDestroy;
bool m_bDelayedDestroy;
bool m_bMouseChildEnabled;
std::vector<Control*> m_items;
EventMap OnBubbledEvent;
};
/// 带有垂直或水平滚动条的容器,使容器可以容纳更多内容
class UILIB_API ScrollableBox : public Box
{
public:
ScrollableBox(Layout* pLayout);
ScrollableBox(const ScrollableBox& r);
ScrollableBox& operator=(const ScrollableBox& r) = delete;
virtual void SetAttribute(const std::wstring& pstrName, const std::wstring& pstrValue) override;
virtual void SetPos(UiRect rc) override;
virtual void HandleMessage(EventArgs& event) override;
virtual bool MouseEnter(EventArgs& msg) override;
virtual bool MouseLeave(EventArgs& msg) override;
virtual void PaintChild(IRenderContext* pRender, const UiRect& rcPaint) override;
virtual void SetMouseEnabled(bool bEnable = true) override;
virtual void SetWindow(Window* pManager, Box* pParent, bool bInit) override;
virtual Control* FindControl(FINDCONTROLPROC Proc, LPVOID pData, UINT uFlags, CPoint scrollPos = CPoint()) override;
virtual void ClearImageCache() override;
/**
* @brief 获取滚动条位置
* @return 返回滚动条的位置信息
*/
virtual CSize GetScrollPos() const;
/**
* @brief 获取滚动条的范围
* @return 返回滚动条的范围信息
*/
virtual CSize GetScrollRange() const;
/**
* @brief 设置滚动条位置
* @param[in] szPos 要设置的位置数据
* @return 无
*/
virtual void SetScrollPos(CSize szPos);
/**
* @brief 设置滚动条 Y 轴坐标
* @param[in] y 要设置的 Y 轴坐标数值
* @return 无
*/
virtual void SetScrollPosY(int y);
/**
* @brief 设置滚动条 X 轴坐标
* @param[in] x 要设置的 X 轴坐标数值
* @return 无
*/
virtual void SetScrollPosX(int x);
/**
* @brief 向上滚动滚动条
* @param[in] deltaValue 滚动距离,默认为 DUI_NOSET_VALUE
* @param[in] withAnimation 是否附带动画效果,默认为 true
* @return 无
*/
virtual void LineUp(int detaValue = DUI_NOSET_VALUE, bool withAnimation = true);
/**
* @brief 向下滚动滚动条
* @param[in] deltaValue 滚动距离,默认为 DUI_NOSET_VALUE
* @param[in] withAnimation 是否附带动画效果,默认为 true
* @return 无
*/
virtual void LineDown(int detaValue = DUI_NOSET_VALUE, bool withAnimation = true);
/**
* @brief 向左滚动滚动条
* @param[in] deltaValue 滚动距离,默认为 DUI_NOSET_VALUE
* @return 无
*/
virtual void LineLeft(int detaValue = DUI_NOSET_VALUE);
/**
* @brief 向右滚动滚动条
* @param[in] deltaValue 滚动距离,默认为 DUI_NOSET_VALUE
* @return 无
*/
virtual void LineRight(int detaValue = DUI_NOSET_VALUE);
/**
* @brief 向上滚动一个页面大小的距离
* @return 无
*/
virtual void PageUp();
/**
* @brief 向下滚动一个页面大小的距离
* @return 无
*/
virtual void PageDown();
/**
* @brief 回到滚动条最上方
* @return 无
*/
virtual void HomeUp();
/**
* @brief 滚动到最下方位置
* @param[in] arrange 是否重置滚动条位置,默认为 true
* @param[in] withAnimation 是否包含动画特效,默认为 true
* @return 无
*/
virtual void EndDown(bool arrange = true, bool withAnimation = true);
/**
* @brief 向左滚动一个页面大小的距离
* @return 无
*/
virtual void PageLeft();
/**
* @brief 向右滚动一个页面大小的距离
* @return 无
*/
virtual void PageRight();
/**
* @brief 滚动到最左侧
* @return 无
*/
virtual void HomeLeft();
/**
* @brief 滚动到最右侧
* @return 无
*/
virtual void EndRight();
/**
* @brief 触摸向上滚动(响应 WM_TOUCH 消息)
* @param[in] deltaValue 滚动距离
* @return 无
*/
virtual void TouchUp(int deltaValue);
/**
* @brief 触摸向下滚动(响应 WM_TOUCH 消息)
* @param[in] deltaValue 滚动距离
* @return 无
*/
virtual void TouchDown(int deltaValue);
/**
* @brief 启用滚动条
* @param[in] bEnableVertical 是否启用垂直滚动条,默认为 true
* @param[in] bEnableHorizontal 是否启用水平滚动条,默认为 true
* @return 无
*/
virtual void EnableScrollBar(bool bEnableVertical = true, bool bEnableHorizontal = false);
/**
* @brief 获取垂直滚动条对象指针
* @return 返回垂直滚动条对象指针
*/
virtual ScrollBar* GetVerticalScrollBar() const;
/**
* @brief 获取水平滚动条对象指针
* @return 返回水平滚动条对象指针
*/
virtual ScrollBar* GetHorizontalScrollBar() const;
/**
* @brief 待补充
* @param[in] 待补充
* @return 待补充
*/
virtual void ProcessVScrollBar(UiRect rc, int cyRequired);
/**
* @brief 待补充
* @param[in] 待补充
* @return 待补充
*/
virtual void ProcessHScrollBar(UiRect rc, int cxRequired);
/**
* @brief 判断垂直滚动条是否有效
* @return 返回 true 表示有效,否则 false 为无效
*/
bool IsVScrollBarValid() const;
/**
* @brief 判断水平滚动条是否有效
* @return 返回 true 表示有效,否则 false 为无效
*/
bool IsHScrollBarValid() const;
/**
* @brief 待补充
* @param[in] 待补充
* @return 待补充
*/
void ReomveLastItemAnimation();
/**
* @brief 待补充
* @param[in] 待补充
* @return 待补充
*/
void PlayRenderOffsetYAnimation(int nRenderY);
/**
* @brief 是否已经在底部
* @return 返回 true 表示已经在底部,否则为 false
*/
bool IsAtEnd() const;
/**
* @brief 是否锁定到底部
* @return 回 true 表示锁定在底部,否则为 false
*/
bool IsHoldEnd() const;
/**
* @brief 设置滚动条是否始终锁定到底部位置
* @param[in] bHoldEnd 设置 true 表示锁定false 为不锁定
* @return 无
*/
void SetHoldEnd(bool bHoldEnd);
/**
* @brief 获取垂直滚动条滚动步长
* @return 返回滚动步长
*/
int GetVerScrollUnitPixels() const;
/**
* @brief 设置垂直滚动条滚动步长
* @param[in] nUnitPixels 要设置的步长
* @return 无
*/
void SetVerScrollUnitPixels(int nUnitPixels);
/**
* @brief 获取横向滚动条滚动步长
* @return 返回滚动步长
*/
int GetHorScrollUnitPixels() const;
/**
* @brief 设置横向滚动条滚动步长
* @param[in] nUnitPixels 要设置的步长
* @return 无
*/
void SetHorScrollUnitPixels(int nUnitPixels);
/**
* @brief 获取容器的滚动条是否悬浮在子控件上面
* @return 返回 true 表示悬浮在滚动条上,否则为 false
*/
bool GetScrollBarFloat() const;
/**
* @brief 设置容器的滚动条是否悬浮在子控件上面
* @param[in] bScrollBarFloat true 表示悬浮在滚动条上false 表示不悬浮在控件上
* @return 无
*/
void SetScrollBarFloat(bool bScrollBarFloat);
/**
* @brief 获取滚动条的外边距
* @return 返回边距信息
*/
UiRect GetScrollBarPadding() const;
/**
* @brief 设置滚动条的外边距,可以让滚动条不占满容器
* @param[in] rcScrollBarPadding 要设置的边距
* @return 无
*/
void SetScrollBarPadding(UiRect rcScrollBarPadding);
/**
* @brief 待补充
* @param[in] 待补充
* @return 待补充
*/
bool GetDefaultDisplayScrollbar() const;
/**
* @brief 待补充
* @param[in] 待补充
* @return 待补充
*/
void SetDefaultDisplayScrollbar(bool bDefaultDisplay);
/**
* @brief 监听滚动条位置变化事件
* @param[in] callback 有变化后通知的回调函数
* @return 无
*/
void AttachScrollChange(const EventCallback& callback) { OnEvent[kEventScrollChange] += callback; }
protected:
/**
* @brief 计算所需的尺寸
* @param[in] rc 当前位置信息
* @return 返回所需尺寸大小
*/
virtual CSize CalcRequiredSize(const UiRect& rc);
/**
* @brief 加载图片缓存,仅供 ScrollableBox 内部使用
* @param[in] bFromTopLeft 暂无意义
* @return 无
*/
void LoadImageCache(bool bFromTopLeft);
private:
/**
* @brief 待补充
* @param[in] 待补充
* @return 待补充
*/
void SetPosInternally(UiRect rc);
protected:
std::unique_ptr<ScrollBar> m_pVerticalScrollBar;
std::unique_ptr<ScrollBar> m_pHorizontalScrollBar;
int m_nVerScrollUnitPixels;
int m_nHerScrollUnitPixels;
bool m_bScrollProcess; // 防止SetPos循环调用
bool m_bHoldEnd;
bool m_bScrollBarFloat;
bool m_bDefaultDisplayScrollbar;
UiRect m_rcScrollBarPadding;
CPoint m_ptLastTouchPos;
AnimationPlayer m_scrollAnimation;
AnimationPlayer m_renderOffsetYAnimation;
};
} // namespace ui
#endif // UI_CORE_BOX_H_