#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 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 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 EventHandler = NULL; private: // 禁止拷贝构造 Control(const Control&) = delete; // 禁止赋值 Control& operator=(const Control&) = delete; // 计算基于父控件的裁剪区域 void ComputeClipRect(); // 所有事件优先进入此函数(内部处理) void OnEvent(EventArgs& arg); //递归子控件给匹配成功的样式应用上 void ApplyChildStyles(const std::list& styles); //向上匹配样式(直到所属的Frame层) void ApplyParentStyles(); protected: //属性或者css样式都适用(css样式和属性都可以设置这些,只对静态样式生效) virtual bool ApplyStyleProperty(const UIString& key, const UIString& value); /// /// 为当前控件的指定状态设置单个样式属性 /// /// 目标状态样式对象,例如 this->HoverStyle /// 样式键名,例如 "font-size" /// 样式值,例如 "13px" 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 GetBorderTopLeftRadius(ControlState _state = ControlState::None); // 获取右上圆角半径 Value GetBorderTopRightRadius(ControlState _state = ControlState::None); // 获取右下圆角半径 Value GetBorderBottomRightRadius(ControlState _state = ControlState::None); // 获取左下圆角半径 Value GetBorderBottomLeftRadius(ControlState _state = ControlState::None); // 获取左边框宽度 Value GetBorderLeft(ControlState _state = ControlState::None); // 获取上边框宽度 Value GetBorderTop(ControlState _state = ControlState::None); // 获取右边框宽度 Value GetBorderRight(ControlState _state = ControlState::None); // 获取下边框宽度 Value GetBorderBottom(ControlState _state = ControlState::None); // 获取边框颜色 Value GetBorderColor(ControlState _state = ControlState::None); //获取边框样式 Value GetBorderStyle(ControlState _state = ControlState::None); // 获取前景图片 Value GetForeImage(ControlState _state = ControlState::None); // 获取背景图片 Value GetBackImage(ControlState _state = ControlState::None); // 获取背景颜色 Value GetBackColor(ControlState _state = ControlState::None); // 获取旋转角度 Value GetAngle(ControlState _state = ControlState::None); // 获取透明度 Value GetOpacity(ControlState _state = ControlState::None); //获取当前控件的鼠标光标 virtual Value GetCursor(ControlState _state = ControlState::None); // 获取前景颜色 Value GetForeColor(ControlState _state = ControlState::None); // 获取字体 Family Value GetFontFamily(ControlState _state = ControlState::None); // 获取字体大小 Value GetFontSize(ControlState _state = ControlState::None); // 获取字体粗度 Value 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(); /// /// 为当前控件的指定状态批量设置样式(使用分号分隔) /// /// 控件状态,例如 ControlState::Hover /// 样式字符串,例如 "font-size: 13px; color: #ffffff;" virtual void SetStyleSheet(ControlState state, const UIString& styleStr); /// /// 设置样式集合,并自动匹配应用到符合条件的子控件 /// /// 样式字符串,例如 "#btn:hover { font-size:13px; }" 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(); }; };