659 lines
17 KiB
C++
659 lines
17 KiB
C++
#pragma once
|
||
#include "EzUI.h"
|
||
|
||
namespace ezui {
|
||
class UI_EXPORT Control :public Object
|
||
{
|
||
friend class HListView;
|
||
friend class VListView;
|
||
friend class TabLayout;
|
||
friend class TileListView;
|
||
friend class TextBox;
|
||
friend class UILoader;
|
||
friend class Frame;
|
||
friend class CheckBox;
|
||
friend class Window;
|
||
friend class ScrollBar;
|
||
friend class VLayout;
|
||
friend class HLayout;
|
||
private:
|
||
//顶层窗口句柄
|
||
HWND m_hWnd = NULL;
|
||
|
||
// 控件是否已经被移除或释放
|
||
bool* m_bRemove = NULL;
|
||
|
||
//控件是否被为按住状态
|
||
bool m_pressed = false;
|
||
|
||
// 控件是否可见。此标志为 true 时,控件为显示状态
|
||
bool m_bVisible = true;
|
||
|
||
//控件是否浮动
|
||
bool m_float = false;
|
||
|
||
// 当前控件的 DPI 缩放比例
|
||
float m_scale = 1.0f;
|
||
|
||
// 子控件集合
|
||
ControlCollection m_controls;
|
||
|
||
// 管理图片的释放
|
||
PtrManager<Image*> m_imgs;
|
||
|
||
// 布局状态
|
||
// AddControl、InsertControl、RemoveControl、OnSize 时此标志为挂起状态
|
||
// 调用 ResumeLayout 标志为布局中
|
||
// 调用 OnLayout() 之后标志为 None
|
||
ezui::LayoutState m_layoutState = ezui::LayoutState::None;
|
||
|
||
// 鼠标悬浮提示文字
|
||
UIString m_tipsText;
|
||
|
||
// 上一次位置
|
||
Point m_lastLocation;
|
||
|
||
// 上一次大小
|
||
Size m_lastSize;
|
||
|
||
// 是否根据内容自动宽度
|
||
bool m_bAutoWidth = false;
|
||
|
||
// 根据内容自动高度变化
|
||
bool m_bAutoHeight = false;
|
||
|
||
// 控件内容宽高
|
||
Size m_contentSize;
|
||
|
||
// 绝对尺寸
|
||
Size m_fixedSize;
|
||
|
||
//比例尺寸
|
||
SizeF m_rateSize;
|
||
|
||
//最小宽高
|
||
Size m_minSize;
|
||
|
||
//最大宽高
|
||
Size m_maxSize;
|
||
|
||
//基于父控件矩形区域
|
||
Rect m_realRect;
|
||
|
||
//基于客户端的矩形区域
|
||
Rect m_rectInClient;
|
||
|
||
//基于窗口剪裁过的区域
|
||
Rect m_viewClipRect;
|
||
|
||
// 控件是否可以被命中(值为false情况下就是穿透效果)
|
||
bool m_hitTestEnabled = true;
|
||
|
||
//存储的样式集合
|
||
std::list<ezui::Style> m_styles;
|
||
|
||
// 基于控件中的可见控件集合
|
||
ControlCollection m_viewControls;
|
||
|
||
// 父控件指针
|
||
Control* m_parent = NULL;
|
||
|
||
// 控件当前状态
|
||
ControlState m_state = ControlState::Static;
|
||
|
||
// 外边距
|
||
// 当父控件为布局控件或列表控件时生效(不可为负数)
|
||
Distance m_margin;
|
||
public:
|
||
|
||
// 控件的 ObjectName ID
|
||
UIString Name;
|
||
|
||
// 控件行为
|
||
ControlAction Action = ControlAction::None;
|
||
|
||
// 静态默认样式
|
||
ControlStyle Style;
|
||
|
||
//具有焦点的时候的样式
|
||
ControlStyle FocusStyle;
|
||
|
||
//禁用状态样式
|
||
ControlStyle DisabledStyle;
|
||
|
||
// 鼠标悬浮样式
|
||
ControlStyle HoverStyle;
|
||
|
||
// 鼠标按下样式
|
||
ControlStyle ActiveStyle;
|
||
|
||
//是否添加到所在窗口/IFrame中的OnNotify函数中
|
||
Event NotifyFlags = Event::OnMouseEvent | Event::OnKeyBoardEvent;
|
||
|
||
// 事件处理器
|
||
std::function<void(Control*, EventArgs&)> EventHandler = NULL;
|
||
private:
|
||
// 禁止拷贝构造
|
||
Control(const Control&) = delete;
|
||
|
||
// 禁止赋值
|
||
Control& operator=(const Control&) = delete;
|
||
|
||
// 计算基于父控件的裁剪区域
|
||
void ComputeClipRect();
|
||
|
||
// 所有事件优先进入此函数(内部处理)
|
||
void OnEvent(EventArgs& arg);
|
||
|
||
//递归子控件给匹配成功的样式应用上
|
||
void ApplyChildStyles(const std::list<ezui::Style>& styles);
|
||
|
||
//向上匹配样式(直到所属的Frame层)
|
||
void ApplyParentStyles();
|
||
protected:
|
||
//属性或者css样式都适用(css样式和属性都可以设置这些,只对静态样式生效)
|
||
virtual bool ApplyStyleProperty(const UIString& key, const UIString& value);
|
||
|
||
/// <summary>
|
||
/// 为当前控件的指定状态设置单个样式属性
|
||
/// </summary>
|
||
/// <param name="style">目标状态样式对象,例如 this->HoverStyle</param>
|
||
/// <param name="key">样式键名,例如 "font-size"</param>
|
||
/// <param name="value">样式值,例如 "13px"</param>
|
||
virtual void SetStyle(ControlStyle& style, const UIString& key, const UIString& value);
|
||
|
||
// 设置内容宽度,仅限子类使用
|
||
virtual void SetContentWidth(int width);
|
||
|
||
// 设置内容高度,仅限子类使用
|
||
virtual void SetContentHeight(int height);
|
||
|
||
// 设置内容尺寸,仅限子类使用
|
||
virtual void SetContentSize(const Size& size);
|
||
|
||
// 绘制之前
|
||
virtual void OnPaintBefore(PaintEventArgs& args);
|
||
|
||
// 控件绘制
|
||
virtual void OnPaint(PaintEventArgs& args);
|
||
|
||
// 子控件绘制,可重载此函数优化鼠标操作性能
|
||
virtual void OnChildPaint(PaintEventArgs& args);
|
||
|
||
// 背景绘制
|
||
virtual void OnBackgroundPaint(PaintEventArgs& painter);
|
||
|
||
// 前景绘制
|
||
virtual void OnForePaint(PaintEventArgs& e);
|
||
|
||
// 边框绘制
|
||
virtual void OnBorderPaint(PaintEventArgs& painter, const Border& border);
|
||
|
||
// 坐标发生改变
|
||
virtual void OnMove(const MoveEventArgs& arg);
|
||
|
||
// 大小发生改变
|
||
virtual void OnSize(const SizeEventArgs& arg);
|
||
|
||
// DPI 发生改变
|
||
virtual void OnDpiChange(const DpiChangeEventArgs& arg);
|
||
|
||
// 控件布局逻辑,需重写布局请重写此函数
|
||
virtual void OnLayout();
|
||
|
||
// 鼠标在控件上移动
|
||
virtual void OnMouseMove(const MouseEventArgs& arg);
|
||
|
||
// 鼠标离开控件
|
||
virtual void OnMouseLeave(const MouseEventArgs& args);
|
||
|
||
// 鼠标滚轮事件
|
||
virtual void OnMouseWheel(const MouseEventArgs& arg);
|
||
|
||
// 鼠标按下事件
|
||
virtual void OnMouseDown(const MouseEventArgs& arg);
|
||
|
||
// 鼠标弹起事件
|
||
virtual void OnMouseUp(const MouseEventArgs& arg);
|
||
|
||
// 鼠标双击事件
|
||
virtual void OnMouseDoubleClick(const MouseEventArgs& arg);
|
||
|
||
// 鼠标移入控件
|
||
virtual void OnMouseEnter(const MouseEventArgs& arg);
|
||
|
||
// 鼠标事件统一入口
|
||
virtual void OnMouseEvent(const MouseEventArgs& args);
|
||
|
||
// 键盘事件统一入口
|
||
virtual void OnKeyBoardEvent(const KeyboardEventArgs& _args);
|
||
|
||
// 字符输入事件(WM_CHAR)
|
||
virtual void OnKeyChar(const KeyboardEventArgs& _args);
|
||
|
||
// 键盘按下事件(WM_KEYDOWN)
|
||
virtual void OnKeyDown(const KeyboardEventArgs& _args);
|
||
|
||
// 键盘弹起事件(WM_KEYUP)
|
||
virtual void OnKeyUp(const KeyboardEventArgs& _args);
|
||
|
||
// 获得焦点事件
|
||
virtual void OnFocus(const FocusEventArgs& _args);
|
||
|
||
// 失去焦点事件
|
||
virtual void OnKillFocus(const KillFocusEventArgs& _args);
|
||
|
||
// 被移除时执行的逻辑
|
||
virtual void OnRemove();
|
||
|
||
public:
|
||
// 获取当前控件状态下的样式信息
|
||
virtual ControlStyle& GetStyle(const ControlState& _state);
|
||
|
||
// 获取左上圆角半径
|
||
Value<int16_t> GetBorderTopLeftRadius(ControlState _state = ControlState::None);
|
||
|
||
// 获取右上圆角半径
|
||
Value<int16_t> GetBorderTopRightRadius(ControlState _state = ControlState::None);
|
||
|
||
// 获取右下圆角半径
|
||
Value<int16_t> GetBorderBottomRightRadius(ControlState _state = ControlState::None);
|
||
|
||
// 获取左下圆角半径
|
||
Value<int16_t> GetBorderBottomLeftRadius(ControlState _state = ControlState::None);
|
||
|
||
// 获取左边框宽度
|
||
Value<int16_t> GetBorderLeft(ControlState _state = ControlState::None);
|
||
|
||
// 获取上边框宽度
|
||
Value<int16_t> GetBorderTop(ControlState _state = ControlState::None);
|
||
|
||
// 获取右边框宽度
|
||
Value<int16_t> GetBorderRight(ControlState _state = ControlState::None);
|
||
|
||
// 获取下边框宽度
|
||
Value<int16_t> GetBorderBottom(ControlState _state = ControlState::None);
|
||
|
||
// 获取边框颜色
|
||
Value<Color> GetBorderColor(ControlState _state = ControlState::None);
|
||
|
||
//获取边框样式
|
||
Value<StrokeStyle> GetBorderStyle(ControlState _state = ControlState::None);
|
||
|
||
// 获取前景图片
|
||
Value<Image*> GetForeImage(ControlState _state = ControlState::None);
|
||
|
||
// 获取背景图片
|
||
Value<Image*> GetBackImage(ControlState _state = ControlState::None);
|
||
|
||
// 获取背景颜色
|
||
Value<Color> GetBackColor(ControlState _state = ControlState::None);
|
||
|
||
// 获取旋转角度
|
||
Value<float> GetAngle(ControlState _state = ControlState::None);
|
||
|
||
// 获取透明度
|
||
Value<float> GetOpacity(ControlState _state = ControlState::None);
|
||
|
||
//获取当前控件的鼠标光标
|
||
virtual Value<HCURSOR> GetCursor(ControlState _state = ControlState::None);
|
||
|
||
// 获取前景颜色
|
||
Value<Color> GetForeColor(ControlState _state = ControlState::None);
|
||
|
||
// 获取字体 Family
|
||
Value<std::wstring> GetFontFamily(ControlState _state = ControlState::None);
|
||
|
||
// 获取字体大小
|
||
Value<int> GetFontSize(ControlState _state = ControlState::None);
|
||
|
||
// 获取字体粗度
|
||
Value<int> GetFontWeight(ControlState _state = ControlState::None);
|
||
|
||
//获取公共数据
|
||
WindowContext* GetWindowContext();
|
||
|
||
//获取上层Frame容器
|
||
Frame* GetFrame();
|
||
public:
|
||
|
||
// 构造函数 可传入父对象(由父对象自动管理内存)
|
||
Control(Object* ownerObject = NULL);
|
||
|
||
// 析构函数
|
||
virtual ~Control();
|
||
|
||
//绑定对象(跟随释放)
|
||
using Object::Attach;
|
||
|
||
//分离对象(解除跟随释放)
|
||
using Object::Detach;
|
||
|
||
//绑定图片(跟随释放)
|
||
Image* Attach(Image* img);
|
||
|
||
//分离图片(解除跟随释放)
|
||
void Detach(Image* img);
|
||
|
||
//窗口句柄
|
||
HWND Hwnd();
|
||
|
||
//设置窗口句柄
|
||
void SetHwnd(HWND hWnd);
|
||
|
||
// 以下函数请保证在父控件布局已完成的情况下使用,使用 ResumeLayout() 执行布局
|
||
// 获取 X 坐标
|
||
int X();
|
||
|
||
// 获取 Y 坐标
|
||
int Y();
|
||
|
||
// 获取宽度
|
||
int Width();
|
||
|
||
// 获取高度
|
||
int Height();
|
||
|
||
//计算带有策略的宽度
|
||
int CalcWidth();
|
||
|
||
//计算带有策略的度
|
||
int CalcHeight();
|
||
|
||
// 设置 X 坐标
|
||
void SetX(int X);
|
||
|
||
// 设置 Y 坐标
|
||
void SetY(int Y);
|
||
|
||
// 移动相对于父控件的位置
|
||
void SetLocation(const Point& pt);
|
||
|
||
// 设置控件大小(当重绘控件时不建议多次使用,影响性能,会调用 SetRect 函数)
|
||
void SetSize(const Size& size);
|
||
|
||
// 设置绝对宽高
|
||
void SetFixedSize(const Size& size);
|
||
|
||
// 设置宽度(当重绘控件时不建议多次使用,影响性能,会调用 SetRect 函数)
|
||
void SetWidth(int width);
|
||
|
||
// 设置高度(当重绘控件时不建议多次使用,影响性能,会调用 SetRect 函数)
|
||
void SetHeight(int height);
|
||
|
||
// 设置绝对宽度
|
||
void SetFixedWidth(int fixedWidth);
|
||
|
||
// 设置绝对高度
|
||
void SetFixedHeight(int fixedHeight);
|
||
|
||
//设置基于父控件百分比宽度(0~1.0f)
|
||
void SetRateWidth(float rateWidth);
|
||
|
||
//设置基于父控件百分比高度(0~1.0f)
|
||
void SetRateHeight(float rateHeight);
|
||
|
||
// 设置基于父控件百分比宽高(0.0f~1.0f)
|
||
void SetRateSize(const SizeF& size);
|
||
|
||
// 设置相对父控件矩形,返回实际的 rect
|
||
const Rect& SetRect(const Rect& rect);
|
||
|
||
// 获取绝对宽度
|
||
int GetFixedWidth();
|
||
|
||
// 获取绝对高度
|
||
int GetFixedHeight();
|
||
|
||
// 获取最小宽度
|
||
int GetMinWidth();
|
||
|
||
// 获取最小高度
|
||
int GetMinHeight();
|
||
|
||
// 获取最大宽度
|
||
int GetMaxWidth();
|
||
|
||
// 获取最大高度
|
||
int GetMaxHeight();
|
||
|
||
// 设置最小宽度
|
||
void SetMinWidth(int w);
|
||
|
||
// 设置最小高度
|
||
void SetMinHeight(int h);
|
||
|
||
// 设置最大宽度
|
||
void SetMaxWidth(int w);
|
||
|
||
// 设置最大高度
|
||
void SetMaxHeight(int h);
|
||
|
||
//设置最小size
|
||
void SetMinSize(const Size& sz);
|
||
|
||
//设置最大size
|
||
void SetMaxSize(const Size& sz);
|
||
|
||
// 获取光标位置
|
||
virtual Rect GetCareRect();
|
||
|
||
// 是否自动宽度
|
||
virtual bool IsAutoWidth();
|
||
|
||
// 是否自动高度
|
||
virtual bool IsAutoHeight();
|
||
|
||
// 设置自动宽度
|
||
virtual void SetAutoWidth(bool flag);
|
||
|
||
// 设置自动高度
|
||
virtual void SetAutoHeight(bool flag);
|
||
|
||
// 设置自动大小
|
||
virtual void SetAutoSize(bool flag);
|
||
|
||
// 获取控件内容大小
|
||
virtual const Size& GetContentSize();
|
||
|
||
// 获取控件大小
|
||
Size GetSize();
|
||
|
||
// 获取控件位置
|
||
Point GetLocation();
|
||
|
||
// 获取相对于父控件的矩形(布局计算后)
|
||
virtual const Rect& GetRect();
|
||
|
||
// 获取基于客户端区域的矩形
|
||
Rect GetRectInClient();
|
||
|
||
//获取控件基于屏幕的矩形位置
|
||
Rect GetRectInScreen();
|
||
|
||
//获取控件基于Frame层的矩形位置
|
||
Rect GetRectInFrame();
|
||
|
||
// 获取控件的缩放系数
|
||
float GetScale();
|
||
|
||
// 是否存在挂起的布局
|
||
bool IsPendLayout();
|
||
|
||
// 尝试挂起布局,返回当前布局状态
|
||
const LayoutState TryPendLayout();
|
||
|
||
// 获取当前布局状态
|
||
const LayoutState GetLayoutState();
|
||
|
||
// 结束当前布局(使其立即生效)
|
||
void EndLayout();
|
||
|
||
// 立即强制刷新布局
|
||
virtual void RefreshLayout();
|
||
|
||
// 设置提示文字(类似 tooltip)
|
||
void SetTips(const UIString& text);
|
||
|
||
// 获取提示文字
|
||
const UIString& GetTips();
|
||
|
||
// 获取控件的滚动条对象
|
||
virtual ScrollBar* GetScrollBar();
|
||
|
||
// 派发事件(如鼠标单击事件等...)返回true则事件成功派发 返回false代表派发途中当前控件已被释放
|
||
void SendEvent(const EventArgs& arg);
|
||
|
||
// 设置控件属性
|
||
virtual void SetAttribute(const UIString& attrName, const UIString& attrValue);
|
||
|
||
// 获取当前可见的子控件集合
|
||
const ControlCollection& GetCachedViewControls();
|
||
|
||
//获取父控件
|
||
Control* GetParent();
|
||
|
||
// 获取所有子控件集合
|
||
const ControlCollection& GetControls();
|
||
|
||
// 使用下标获取控件,自动跳过 spacer 类控件
|
||
Control* GetControl(int pos);
|
||
|
||
// 是否包含指定控件(递归遍历所有子控件)
|
||
bool Contains(Control* ctrl);
|
||
|
||
// 获取指定子控件的索引
|
||
int IndexOf(Control* childCtl);
|
||
|
||
// 根据 name 查找控件(包括自身)
|
||
Control* FindControl(const UIString& ctrlName);
|
||
|
||
// 根据属性查找所有匹配控件(包括自身)
|
||
ControlCollection FindControls(const UIString& attrName, const UIString& attrValue);
|
||
|
||
// 根据 name 查找子控件(仅限直接子集)
|
||
Control* FindChild(const UIString& ctlName);
|
||
|
||
// 根据属性查找所有匹配的子控件(仅限直接子集)
|
||
ControlCollection FindChildren(const UIString& attrName, const UIString& attrValue);
|
||
|
||
// 交换两个子控件的位置
|
||
virtual bool SwapChildren(Control* childCtl, Control* childCt2);
|
||
|
||
//是否启用控件
|
||
void SetEnabled(bool flag);
|
||
|
||
//是否禁用控件
|
||
void SetDisabled(bool flag);
|
||
|
||
//控件是否已启用
|
||
bool IsEnabled();
|
||
|
||
// 在指定位置插入子控件
|
||
virtual Control* InsertChild(int pos, Control* childCtl);
|
||
|
||
// 添加控件到末尾(如果是弹簧控件,在释放时将自动销毁)
|
||
virtual Control* AddChild(Control* childCtrl);
|
||
|
||
//解析xml字符串并添加到控件集合末尾
|
||
virtual Control* Append(const UIString& xmlStr);
|
||
|
||
//解析xml字符串并添加到控件集合第一位
|
||
virtual Control* Prepend(const UIString& xmlStr);
|
||
|
||
// 移除控件,freeCtrl 标志是否释放控件内存
|
||
virtual void RemoveChild(Control* childCtl, bool freeCtrl = false);
|
||
|
||
//移除并且销毁全部弹簧
|
||
void DestroySpacers();
|
||
|
||
// 设置控件的父控件
|
||
virtual void SetParent(Control* parentCtl);
|
||
|
||
// 移除所有子控件
|
||
virtual void RemoveAll();
|
||
|
||
// 移除所有子控件,freeChilds 决定是否释放子控件内存
|
||
virtual void RemoveAll(bool freeAll);
|
||
|
||
//是否为弹簧控件
|
||
virtual bool IsSpacer();
|
||
|
||
//是否为Frame
|
||
virtual bool IsFrame();
|
||
|
||
// 设置控件浮动
|
||
virtual void SetFloat(bool flag);
|
||
|
||
// 控件是否浮动
|
||
virtual bool IsFloat();
|
||
|
||
// 设置控件可见性
|
||
virtual void SetVisible(bool flag);
|
||
|
||
// 获取控件可见性状态
|
||
virtual bool IsVisible();
|
||
|
||
//设置控件是否可以被鼠标命中(false则是鼠标穿透效果)
|
||
void SetHitTestVisible(bool bEnable);
|
||
|
||
//控件是否可以被命中
|
||
bool IsHitTestVisible();
|
||
|
||
//隐藏控件
|
||
void Hide();
|
||
|
||
//显示控件
|
||
void Show();
|
||
|
||
// 标记控件区域为无效(将会延迟刷新UI)
|
||
virtual bool Invalidate();
|
||
|
||
// 立即强制刷新控件区域并更新无效区域(且立即触发布局)
|
||
virtual void Refresh();
|
||
|
||
/// <summary>
|
||
/// 为当前控件的指定状态批量设置样式(使用分号分隔)
|
||
/// </summary>
|
||
/// <param name="state">控件状态,例如 ControlState::Hover</param>
|
||
/// <param name="styleStr">样式字符串,例如 "font-size: 13px; color: #ffffff;"</param>
|
||
virtual void SetStyleSheet(ControlState state, const UIString& styleStr);
|
||
|
||
/// <summary>
|
||
/// 设置样式集合,并自动匹配应用到符合条件的子控件
|
||
/// </summary>
|
||
/// <param name="styleStr">样式字符串,例如 "#btn:hover { font-size:13px; }"</param>
|
||
virtual void SetStyleSheet(const UIString& styleStr);
|
||
|
||
//设置基于父控件的边距四周边距
|
||
void SetMargin(int allMargin);
|
||
|
||
//设置基于父控件的边距上下边距
|
||
void SetMargin(int topBottom, int leftRight);
|
||
|
||
//设置基于父控件的上边距
|
||
void SetMarginTop(int topMargin);
|
||
|
||
//设置基于父控件的左边距
|
||
void SetMarginLeft(int leftMargin);
|
||
|
||
//设置基于父控件的右边距
|
||
void SetMarginRight(int rightMargin);
|
||
|
||
//设置基于父控件的下边距
|
||
void SetMarginBottom(int bottomMargin);
|
||
|
||
//设置基于父控件的边距 上 右 下 左
|
||
void SetMargin(int top, int right, int bottom, int left);
|
||
|
||
//获取基于父控件的边距信息;
|
||
const Distance& GetMargin();
|
||
|
||
//控件是否被按住
|
||
bool IsPressed();
|
||
|
||
//给当前控件设置为焦点控件
|
||
void SetFocus();
|
||
};
|
||
|
||
}; |