dl
dl_ui_button_base.h
浏览该文件的文档.
1
15#pragma once
16
17#ifndef DL_DISABLE_RENDER
18#include "math/dl_coor.h"
19#include "dl_type.h"
20#include "io/dl_input.h"
21#include "math/dl_align.h"
23#include "render/dl_text.h"
24
25namespace dl::UI
26{
27
29class Button
30{
31public:
32 using CbCustomRender = std::function<void(Button*)>;
33 using CbEventClick = std::function<void(Button*)>;
44
45 enum class Mode
46 {
50 };
51
52 struct TextData
53 {
55 Align::Direction2 _hv;// 在按钮的位置
58 bool _bSizeWithText; // text大小改变按钮的大小
59 Position _extraSize; // text大小改变按钮的大小(额外值)
60
62 _bSizeWithText{ false },
64 {
65 _hv = Align::CC;
66 for (auto& iter : _col)
67 iter = ColorDef::WHITE;
68 for (auto& iter : _offset)
69 iter = {};
70 }
71 };
72
74 _state{ State::NORMAL },
75 _statePre{ State::NORMAL },
76 _mode{ Mode::BUTTON },
77 _bOpen{ false },
78 _isClick{ false },
79 _bDisable{false},
80 _txtData{ nullptr },
81 _cpt{ this }
82 {
84 _init_cpt();
85 }
86
87 // 克隆使用,init_cpt不赋值值类的组件拷贝,需要手动处理
88 Button(const Button& b);
89
90
91 void Update();
92 void Render();
93
100 bool IsClick();
105 bool IsDown()
106 {
107 return _state == State::DOWN;
108 }
109
112
113 bool IsRadio() { return _mode == Mode::RADIO; }
118 bool IsSelect() { return _bOpen; }
119
120 void SetSelect(bool open);
121
122 void SetMode(Mode mode);
123
124 void SetDisable(bool disable) { _bDisable = disable; }
125
135 void SetSound(std::string_view click, std::string_view over)
136 {
137 _strSndClick = std::string{ click };
138 _strSndOver = std::string{ over };
139 }
140
141 State GetState() { return _state; }
142
147 Coor* GetCoor() { return _coor; }
148
152 virtual Button* Clone() = 0;
153 virtual bool IsPickup() = 0;
154 virtual void SetOrder(float order) = 0;
155 virtual float GetOrder() = 0;
156 virtual Position GetSize() = 0;
157 virtual Position GetAnchor() = 0;
158
159 float GetOrder(int offset)
160 {
161 return Math::OffsetOrder(GetOrder(), 0, 0, offset);
162 }
163
164 void SetElementData(const Align::Direction2& hv, const Position& pos = {})
165 {
166 _cptElemData._hv = hv;
167 _cptElemData._pos = pos;
169 }
170 void SetElementDataRunAble(bool able)
171 {
172 _cptElemData._bRunAble = able;
173 }
174 void SetElementDataAutoSize(bool parent_w, bool parent_h)
175 {
176 _cptElemData._bParentW = parent_w;
177 _cptElemData._bParentH = parent_h;
178 }
179
180 std::string GetString()
181 {
182 if (!_txtData)
183 {
184 return {};
185 }
186 return _txtData->_txt->GetString();
187 }
188
195 void AddText(gcText txt,
196 const std::vector<Color>& mul_col,
197 const std::vector<Position>& mul_offset);
199 void AddText(gcText txt);
200 void AddText(gcText txt, const std::vector<Color>& mul_col);
201
202 void SetString(std::string_view str);
204 {
205 if (_txtData)
206 _txtData->_hv = hv;
207 }
208
209 void SetSizeWithText(bool with, const Position& extra_size);
210
211 //
212 void SetName(std::string_view name)
213 {
214 _cptName.Set(std::string{ name });
215 }
216
218 {
219 _cbRender = cb;
220 }
222 {
223 _cbClick = cb;
224 }
225
226 Components* GetCpt() { return &_cpt; }
227
228 Mode GetMode() { return _mode; }
229
230
231 // not use
233 {
234 return _clickControl;
235 }
236
237 virtual ~Button()
238 {
239 if (_clickControl == this)
240 _clickControl = nullptr;
241 delete _coor;
242 delete _txtData;
243 }
244private:
245 State _state;
246 State _statePre;
247 bool _bDisable;
248
249 Mode _mode;
250 bool _bOpen;
251 bool _isClick;
252 TextData* _txtData;
253
255 std::string _strSndClick;
256 std::string _strSndOver;
257protected:
259
261 std::size_t GetIndex(State state)
262 {
263 if (_bDisable)
264 {
265 if (state == State::NORMAL || state == State::OVER)
266 return 3;
267 else
268 return 4;
269 }
270 else
271 {
272 return (std::size_t)state;
273 }
274 }
275
276 //
278 {
279 _cptElemData._size = GetSize();
280 _cptElemData._anchor = GetAnchor();
281 }
282
283 constexpr bool _use_over()
284 {
285#if DL_PLATFORM == DL_PLATFORM_ANDROID
286 return false;
287#else
288 return true;
289#endif
290 }
291
296 virtual void UpdateChild(State state_pre, State state);
297 virtual void RenderChild(State state_pre, State state);
298 virtual void RenderDebug();
299
303 void UpdateTextOrder(float order)
304 {
305 if (_txtData)
306 _txtData->_txt->SetOrder(Math::OffsetOrder(order, 0, 0, -1));
307 }
308 virtual void OnTextSizeChange(const Position& size) {};
309 TextData* GetTextData() { return _txtData; }
310private:
311 //
312 CbCustomRender _cbRender;
313 CbEventClick _cbClick;
314 //--------------------------组件------------------------
315 Components _cpt;
316 Cpt::DeleteThis _cptDeleteThis;
317 Cpt::Update _cptUpdate;
318 Cpt::Render _cptRender;
319 Cpt::IsPickup _cptIsPickup;
320 Cpt::SetOrder _cptSetOrder;
321 Cpt::GetCoor _cptGetCoor;
322 Cpt::IsClick _cptIsClick;
323 Cpt::IsDown _cptIsDown;
324 Cpt::IsSelect _cptIsOpen;
325 Cpt::SetSelect _cptSetOpen;
326 Cpt::RenderDebug _cptRenderDebug;
327 Cpt::ElementData _cptElemData;
328 Cpt::Clone _cptClone;
329 Cpt::GetSize _cptGetSize;
330 Cpt::CustomName _cptName;
331 Cpt::CustomTag _cptTag;
332
333 void _delete_this() { delete this; }
334
335 Components* _clone()
336 {
337 return Clone()->GetCpt();
338 }
339
340 void _init_cpt()
341 {
342 _cptDeleteThis = std::bind(&Button::_delete_this, this);
343 _cptUpdate = std::bind(&Button::Update, this);
344 _cptRender = std::bind(&Button::Render, this);
345 _cptIsPickup = std::bind(&Button::IsPickup, this);
346 _cptSetOrder = std::bind(&Button::SetOrder, this, std::placeholders::_1);
347 _cptGetCoor = std::bind(&Button::GetCoor, this);
348 _cptIsClick = std::bind(&Button::IsClick, this);
349 _cptIsDown = std::bind(&Button::IsDown, this);
350 _cptIsOpen = std::bind(&Button::IsSelect, this);
351 _cptSetOpen = std::bind(&Button::SetSelect, this, std::placeholders::_1);
352 _cptRenderDebug = std::bind(&Button::RenderDebug, this);
353 _cptClone = std::bind(&Button::_clone, this);
354 _cptGetSize = std::bind(&Button::GetSize, this);
355
356 _cpt.PushBack(&_cptDeleteThis);
357 _cpt.PushBack(&_cptUpdate);
358 _cpt.PushBack(&_cptRender);
359 _cpt.PushBack(&_cptIsPickup);
360 _cpt.PushBack(&_cptSetOrder);
361 _cpt.PushBack(&_cptGetCoor);
362 _cpt.PushBack(&_cptIsClick);
363 _cpt.PushBack(&_cptIsDown);
364 _cpt.PushBack(&_cptIsOpen);
365 _cpt.PushBack(&_cptSetOpen);
366 _cpt.PushBack(&_cptRenderDebug);
367 _cpt.PushBack(&_cptClone);
368 _cpt.PushBack(&_cptGetSize);
369 _cpt.PushBack(&_cptName);
370 _cpt.PushBack(&_cptTag);
371
372 _cpt.PushBack(&_cptElemData);
373 }
374
375
376 static Button* _clickControl;//防止在按钮外面按下左键移动到按钮内也能触发Click
377
378
379 void _update_button();
380 void _update_switch();
381 void _update_radio();
382};
383
386
387}
388
389#endif
枚举类数组
void PushBack(AnyType any)
添加一个任意对象
2d坐标系
static Coor * Create(Coor *parent=nullptr)
元素通用属性(默认左上对齐,便于理解)
void SetMode(Mode mode)
void AddText(gcText txt, const std::vector< Color > &mul_col)
constexpr bool _use_over()
void SetEevntClick(CbEventClick cb)
bool IsDown()
控件按下状态
std::function< void(Button *)> CbEventClick
void SetDisable(bool disable)
void SetTextAlign(const Align::Direction2 &hv)
void SetElementDataAutoSize(bool parent_w, bool parent_h)
void SetElementDataRunAble(bool able)
Coor * GetCoor()
添加到Panel后会自动设置Coor数据,要设置位置等 请调用SetElementData
virtual void UpdateChild(State state_pre, State state)
重载此函数,制定控件行为
virtual Button * Clone()=0
必须实现的函数
void UpdateTextOrder(float order)
order变化时需要调用
void AddText(gcText txt)
void SetElementData(const Align::Direction2 &hv, const Position &pos={})
bool IsClick()
控件被点击
virtual Position GetSize()=0
void SetSizeWithText(bool with, const Position &extra_size)
设置精灵大小跟随文本
void SetCustomRender(CbCustomRender cb)
float GetOrder(int offset)
virtual bool IsPickup()=0
void SetSound(std::string_view click, std::string_view over)
设置按钮音效
void AddText(gcText txt, const std::vector< Color > &mul_col, const std::vector< Position > &mul_offset)
添加文本属性
@ OVER
经过(仅有光标时使用)
@ DOWN_OVER
按下经过(Switch使用)
@ DOWN_DISABLE
按下禁用(Switch、Radio使用)
std::function< void(Button *)> CbCustomRender
virtual void RenderDebug()
bool IsSelect()
控件是选中状态
virtual float GetOrder()=0
Button(const Button &b)
bool IsOverOnce()
经过按钮,直到离开控件再次进入才会返回真
virtual void RenderChild(State state_pre, State state)
virtual Position GetAnchor()=0
void SetString(std::string_view str)
@ SWITCH
开关,按下后不会自动弹起,再次点击后弹起
@ RADIO
收音机按钮,按下后就不能弹起,只能通过代码弹起
void ClearState()
清理状态为普通
static Button * GetClickControl()
void AddTextDefault()
std::size_t GetIndex(State state)
返回索引
virtual void SetOrder(float order)=0
void SetSelect(bool open)
void SetName(std::string_view name)
virtual void OnTextSizeChange(const Position &size)
方向和对齐定义
组件实例
2d坐标系
键盘与手柄等按键操作
文本绘制
通用类型
Array< Direction, 2 > Direction2
constexpr Direction2 CC
constexpr Color WHITE
Variable< std::string, str_uid("CustomName")> CustomName
Function< std::function< bool()>, str_uid("IsSelect")> IsSelect
选择
Function< std::function< void(float)>, str_uid("SetOrder")> SetOrder
设置order
Function< std::function< void()>, str_uid("RenderD")> RenderDebug
调试绘图
Function< std::function< dl::Coor *()>, str_uid("GetCoor")> GetCoor
返回坐标系
Function< std::function< bool()>, str_uid("IsPickup")> IsPickup
---------------------------—具体组件----------------------------------—
Variable< int, str_uid("CustomTag")> CustomTag
Function< std::function< bool()>, str_uid("IsDown")> IsDown
按下状态
Function< std::function< Position(void)>, str_uid("GetSize")> GetSize
获取大小
Function< std::function< void(bool)>, str_uid("SetSelect")> SetSelect
设置是否选择
Function< std::function< void()>, str_uid("Render")> Render
绘制
Function< std::function< void()>, str_uid("DeleteThis")> DeleteThis
删除自身
Function< std::function< void()>, str_uid("Update")> Update
逻辑
Function< std::function< bool()>, str_uid("IsClick")> IsClick
点击
Function< std::function< Components *()>, str_uid("Clone")> Clone
克隆
constexpr float OffsetOrder(float order, int u=1, int v=0, int w=0)
偏移order
Button::State ButtonState
Button::Mode ButtonMode
Position2 Position
GC< Text > gcText
ArrayEnum< Position, Button::State::MAX_NUM > _offset
ArrayEnum< Color, Button::State::MAX_NUM > _col