dl
dl_ui_panel.h
浏览该文件的文档.
1
14#pragma once
15
16#ifndef DL_DISABLE_RENDER
18#include "base/dl_type_def.h"
19#include "misc/dl_locator.h"
20#include "base/dl_tree.h"
21#include "dl_ui_background.h"
22#include "render/dl_factory.h"
23#include "ui/dl_ui_sprite.h"
24#include "ui/dl_ui_text.h"
27#include "io/dl_json.h"
28
29namespace dl::UI
30{
41
42inline ElementType String2ElementType(std::string_view str)
43{
44 if (String::EqualToLower(str, "text"))
45 return ElementType::TEXT;
46 if (String::EqualToLower(str, "msg_box"))
48 if (String::EqualToLower(str, "button"))
50 if (String::EqualToLower(str, "background"))
52 if (String::EqualToLower(str, "locator"))
54 if (String::EqualToLower(str, "list_box"))
56
57 log_err("未知的type字段:{}", str);
59}
60
61class EditBox;
62
64class Panel
65{
66 friend class Manager;
67public:
69 {
70 E_SIZE = 1 << 1,
71 E_ELEMENT = 1 << 2,
72 E_CHILD = 1 << 4,
73 };
75 {
79 };
80
83 void AddCpt(Components* cpt);
87 template<typename T>
88 void Add(T* p)
89 {
90 AddCpt(p->GetCpt());
91 }
92
93 void Add(Text* p) { AddCpt(p->GetCpt()); }
97 void Add(std::string_view json_path);
101 void AddPanel(Panel* child);
102
107 void DelCpt(Components* cpt);
111 template<typename T>
112 void Del(T* p)
113 {
114 DelCpt(p->GetCpt());
115 }
116
119 Panel* Clone();
120
124 void SetPosPixel(const Position& pos_pixel)
125 {
126 if (!_bAutoCoor)
127 {
128 log_err0("关闭了自动设置位置,设置像素位置无效!");
129 return;
130 }
131 _posPixel = pos_pixel;
132 _coor->SetPosition(_posPixel - Align::Size2Anchor(GetSize(), _align) + Align::Dir2Offset(GetSize(), _dir));
133 }
134 void DtPosPixel(const Position& dt)
135 {
136 if (!_bAutoCoor)
137 {
138 log_err0("关闭了自动设置位置,设置像素位置无效!");
139 return;
140 }
141 _posPixel += dt;
142 _coor->DtPosition(dt);
143 }
144
147 void SetPosScale(const Position& pos_scale)
148 {
149 assert(_bAutoCoor);
150 if (!_bAutoCoor)
151 {
152 log_err0("关闭了自动设置位置,设置比例位置无效!");
153 return;
154 }
155 _posScale = pos_scale;
156 _bNeedRefreshPos = true;
157 }
158
167 {
168 assert(_bAutoCoor);
169 _align = hv;
170 _bNeedRefreshPos = true;
171 }
172
176 void SetLocator(const Locator& loc)
177 {
178 assert(_bAutoCoor);
179 _locator = loc;
180 _bNeedRefreshLocator = true;
181 }
182 void SetLocator(const Locator::SL& sl)
183 {
184 SetLocator(Locator{ sl });
185 }
186 void SetLocator(std::string_view name);
191 void SetAutoCoor(bool auto_coor) { _bAutoCoor = auto_coor; }
196 void SetAutoRun(bool auto_run) { _bAutoRun = auto_run; }
201 void SetAutoRender(bool auto_render) { _bAutoRender = auto_render; }
207 {
208 _orderMode = mode;
209 _refresh_order();
210 }
211
215 void SetOrder(float order)
216 {
217 assert(_orderMode == OrderMode::FORCE);
218 if (_orderMode == OrderMode::FORCE)
219 {
220 _order = order;
221 _refresh_order();
222 }
223 }
224
228 void SetOrderInParent(int order_parent)
229 {
230 assert(_orderMode == OrderMode::CUSTOM);
231 if (_orderMode == OrderMode::CUSTOM)
232 {
233 _orderInParent = order_parent;
234 _refresh_order();
235 }
236 }
238 {
239 _refresh_order();
240 }
241
244 void SetName(std::string_view name)
245 {
246 _name = name;
247 }
248
252 void SetSelect(size_t index)
253 {
254 size_t i = 0;
255 for (auto& iter : _allEle)
256 {
257 if (auto comp = iter->Get<Cpt::SetSelect>())
258 {
259 comp->Call(i == index);
260 }
261 ++i;
262 }
263 }
264
267 void ElementSetSelect(size_t index, bool select)
268 {
269 if (index >= _allEle.size())
270 log_err0("越界!");
271 if (auto comp = _allEle[index]->Get<Cpt::SetSelect>())
272 {
273 comp->Call(select);
274 return;
275 }
276 log_err0("对象没有SetSelect组件!");
277 }
278
281 void SetSelectAll(bool select)
282 {
283 for (auto& iter : _allEle)
284 {
285 if (auto comp = iter->Get<Cpt::SetSelect>())
286 {
287 comp->Call(select);
288 }
289 }
290 }
291
295 void Update();
302 void Render();
311 bool IsUpdate() { return _bUpdate; }
315 bool IsRender() { return _bRender; }
319 std::string GetName() const { return _name; }
325 {
326 assert(!_bAutoCoor);
327 return _coor;
328 }
330 {
331 return _coor;
332 }
333 Align::Dir4 GetDir() { return _dir; }
337 Panel* GetParent()
338 {
339 if(_node->GetParent())
340 return _node->GetParent()->GetValue();
341 return nullptr;
342 }
343
346 std::vector<Panel*> GetChildAll()
347 {
348 std::vector<Panel*> ret;
349 for (auto& iter : _node->GetChild())
350 ret.push_back(iter->GetValue());
351 return ret;
352 }
353
356 size_t GetChildNum(bool recursion = false)
357 {
358 size_t ret = _node->GetChild().size();
359 if (recursion)
360 {
361 for (auto& iter : _node->GetChild())
362 ret += iter->GetValue()->GetChildNum(true);
363 }
364 return ret;
365 }
366
369 size_t GetChildIndex(Panel* child)
370 {
371 size_t i = 0;
372 for (auto& iter : _node->GetChild())
373 {
374 if (iter->GetValue() == child)
375 return i;
376 ++i;
377 }
378 return -1;
379 }
380
384 Panel* GetChild(size_t i)
385 {
386 auto& vec = _node->GetChild();
387 if (i >= vec.size())
388 {
389 log_err("下标越界!");
390 return nullptr;
391 }
392 return vec[i]->GetValue();
393 }
394
401 void SetChildSelect(Panel* panel);
406
408 template<typename T>
409 std::size_t GetIndex()
410 {
411 size_t i = 0;
412 for (auto& iter : _allEle)
413 {
414 if (auto comp = iter->Get<T>())
415 {
416 if (comp->Call())
417 return i;
418 }
419 ++i;
420 }
421 return -1;
422 }
423
424 template<typename T>
426 {
427 for (auto& iter : _allEle)
428 {
429 if (auto comp = iter->Get<T>())
430 {
431 if (comp->Call())
432 return iter;
433 }
434 }
435 return nullptr;
436 }
437
443 {
444 return GetIndex<Cpt::IsClick>();
445 }
446 std::string GetClickName()
447 {
448 size_t i = GetClickIndex();
449 if (i != -1)
450 {
451 Cpt::CustomName* comp = _allEle[i]->Get<Cpt::CustomName>();
452 if (comp)
453 return comp->Get();
454 }
455 return "";
456 }
457
462 {
463 return GetIndex<Cpt::IsDown>();
464 }
465
471 {
473 }
474
480 {
481 return Get<Cpt::IsSelect>();
482 }
483
484 std::string GetSelectName()
485 {
486 Components* cpt = GetSelect();
487 return cpt ? cpt->GetName() : "";
488 }
489
494 bool IsSelectIndex(size_t index)
495 {
496 if (index >= _allEle.size())
497 {
498 log_err0("越界!");
499 return false;
500 }
501 if (auto comp = _allEle[index]->Get<Cpt::IsSelect>())
502 {
503 return comp->Call();
504 }
505
506 log_err0("对象没有Open组件!");
507 return false;
508 }
509
525
527 {
528 return _coor->GetPosition();
529 }
530 float GetOrder()
531 {
532 return _order;
533 }
534
536 {
537 return _locator;
538 }
539
543 template<typename T>
544 T* GetElement(size_t n = 0)
545 {
546 if(n == 0)
547 return Cpt::GetFirst<T>(_allEle);
548 else
549 return Cpt::GetN<T>(_allEle, n);
550 }
551
553 template<typename T>
554 std::vector<T*> GetElementVector()
555 {
556 std::vector<T*> ret;
557 for (auto& iter : _allEle)
558 {
559 T* cpt = iter->Cast<T>();
560 if (cpt)
561 ret.push_back(cpt);
562 }
563 return ret;
564 }
565
567 bool IsPickup()
568 {
569 if (_pickupMode & E_SIZE)
570 {
571 if (g_factory->GetOrderPickup() < _order)
572 return false;
573 Position pos = _coor->WorldToThis(toPosition(g_input->GetCursorPosition()));
574 Position size = toPosition(GetSize());
575 if (pos[0] >= 0
576 && pos[1] >= 0
577 && pos[0] <= size[0]
578 && pos[1] <= size[1])
579 return true;
580 }
581 if (_pickupMode & E_ELEMENT)
582 {
583 for (Components* cpt : _allEle)
584 {
585 Cpt::IsPickup* comp = cpt->Get<Cpt::IsPickup>();
586 if (!comp)
587 continue;
588 if (comp->Call())
589 return true;
590 }
591 }
592 if (_pickupMode & E_CHILD)
593 {
594 for (auto& iter : _node->GetChild())
595 {
596 Panel* child = iter->GetValue();
597 if (child->IsPickup())
598 return true;
599 }
600 }
601 return false;
602 }
603
604 // 指定大小
605 void SetSize(const Position& size)
606 {
607 _size = size;
608 _bSizeAuto = false;
609 _bSizeFull = false;
610 _refresh_size();
611 }
612 void SetAutoSize(bool auto_size)
613 {
614 _bSizeAuto = true;
615 _bSizeFull = false;
616 _refresh_size();
617 }
618 // 设置拾取模式
620 {
621 _pickupMode = mode;
622 }
623 void SetPickupMode(int mode)
624 {
626 }
627 // 与父节点一样大
629 {
630 _bSizeFull = true;
631 _refresh_size();
632 }
633
635
636 bool IsAutoRun() { return _bAutoRun; }
637 //----------------------------------辅助函数-----------------------------
639 UI::Button* ExGetButton(size_t n = 0, bool show_log = true);
640 UI::ButtonSprite* ExGetButtonSprite(size_t n = 0, bool show_log = true);
641 UI::ButtonSprite9* ExGetButtonSprite9(size_t n = 0, bool show_log = true);
643 UI::EditBox* ExGetEditBox(size_t n = 0, bool show_log = true);
645 UI::Text* ExGetText(size_t n = 0, bool show_log = true);
647 UI::Background* ExGetBackground(size_t n = 0, bool show_log = true);
649 void ExSetString(std::string_view str, size_t n = 0);
650
651 void SetDebugName(std::string_view name)
652 {
653#ifndef NDEBUG
654 _debugName = name;
655#endif
656 }
657private:
658 Panel() :
659 _order{ Z_DEFAULT_PANEL },
660 _orderMode{ OrderMode::AUTO },
661 _orderInParent{ -1 },
662 _bAutoRun{ true },
663 _bAutoRender{ true },
664 _bNeedRefreshPos{ false },
665 _bNeedRefreshLocator{ false },
666 _bDisableLocator{ false },
667 _bAutoCoor{ true },
668 _bUpdate{ false },
669 _bRender{ false },
670 _pickupMode{ E_SIZE },
671 _align{ Align::LT },
672 _dir{ Align::Dir4::RIGHT },
673 _posPixel{},
674 _posScale{},
675 _size{},
676 _bSizeFull{ true },
677 _bSizeAuto{ false }
678 {
679 _coor = Coor::Create();
680 }
681 ~Panel()
682 {
683 //删除元素
684 for (Components*& cpt : _allEle)
685 {
686 if (cpt->IsPure())
687 delete cpt;
688 else if (auto comp = cpt->Get<Cpt::DeleteThis>())
689 {
690 comp->Call();
691 }
692
693 }
694 delete _coor;
695 }
696#ifndef NDEBUG
697 std::string _debugName;
698#endif
699
700 // 添加到 Scene时自动设置
701 std::string _name;
702 std::vector<Components*> _allEle;// 子元素
703
704 Coor* _coor;
705 // 全局偏移(受 order模式控制)
706 float _order;
707 OrderMode _orderMode;
708 int _orderInParent;
709
710 bool _bAutoRun;// 自动运行(由父节点调用Update和Render)
711 bool _bAutoRender;// 如果调用了Update,则自动调用Render(由父节点)
712 bool _bNeedRefreshPos; // 更新位置
713 bool _bNeedRefreshLocator; // 重新定位
714 bool _bDisableLocator;// 禁用定位器,暂未使用
715 bool _bAutoCoor;// 接手Coor后,需要设为真
716 bool _bUpdate;// 此帧是否已运行
717 bool _bRender;// 此帧是否已绘制
718 PickupMode _pickupMode;
719
720 // 树节点引用
721 NTree<Panel*>::Node* _node;
722
723 // location
724 Align::Direction2 _align; // 自己大小对齐
725 Align::Dir4 _dir; // 自己朝向
726 Position _posPixel;
727 Position _posScale;
728
729 // locator
730 Locator _locator;
731
732 Position _size; // 指定大小(0表示跟随父节点大小)
733 bool _bSizeFull;// 与父节点同大小
734 bool _bSizeAuto; // 自动大小
735
736 void _refresh_lang()
737 {
738
739 }
740
742 void _refresh_pos(const Position& size);
743
745 void _refresh_size();
747 void _refresh_order();
748
749 void _update_child();
750 void _render_child();
751
752 void _update_cpt_drag(Components* cpt);
753 void _update_cpt_radio(Components* cpt);
754};
755
756}
757
758#endif
std::string GetName()
2d坐标系
static Coor * Create(Coor *parent=nullptr)
2d定位器
按钮(Button、Switch、Radio)
精灵按钮(注意精灵没有Coor)
void DtPosPixel(const Position &dt)
UI::ButtonSprite * ExGetButtonSprite(size_t n=0, bool show_log=true)
void Add(T *p)
添加一个Element
bool IsSelectIndex(size_t index)
index元素是否选中状态
const Locator & GetLocator()
size_t GetClickIndex()
返回被点击的元素
Align::Dir4 GetDir()
void Update()
执行逻辑 @node 默认情况会自动调用
void Add(Text *p)
脚本导出使用
UI::EditBox * ExGetEditBox(size_t n=0, bool show_log=true)
返回第n个列表框
@ E_ELEMENT
子元素
@ E_SIZE
自己大小
size_t GetChildNum(bool recursion=false)
返回子panel数量
Panel * GetChildPickup()
返回光标悬停的子panel
void SetLocator(const Locator::SL &sl)
@ AUTO
自动设置
@ CUSTOM
手动设置
@ FORCE
强行设置全局
void SetName(std::string_view name)
设置名字
void SetOrder(float order)
设置order
Components * GetSelect()
返回被选中的元素
std::size_t GetIndex()
返回第一个满足条件的组件下标
UI::Text * ExGetText(size_t n=0, bool show_log=true)
返回第n个text
std::string GetClickName()
void SetAutoRender(bool auto_render)
设置是否自动绘制
void AddPanel(Panel *child)
添加子panel
void SetLocator(const Locator &loc)
设置Locator
std::vector< T * > GetElementVector()
返回所有类型的元素
size_t GetDownIndex()
返回被按下的元素
void SetSize(const Position &size)
Panel * GetChildSelect()
返回被选中的子panel
RectF GetRect()
返回所有元素和子节点组成的包围盒
void Render()
执行绘制 @node 默认情况会自动调用
void SetOrderMode(OrderMode mode)
设置order模式
std::vector< Panel * > GetChildAll()
返回子panel
void SetPosPixel(const Position &pos_pixel)
设置 像素位置
void ElementSetSelect(size_t index, bool select)
设置元素是否选中
std::string GetSelectName()
void SetAutoCoor(bool auto_coor)
设置是否自动调整位置
void ExSetString(std::string_view str, size_t n=0)
设置第n个text内容
UI::Button * ExGetButton(size_t n=0, bool show_log=true)
返回第n个按钮
void OnChangeElementData(Components *cpt)
T * GetElement(size_t n=0)
返回第n个元素
void SetDebugName(std::string_view name)
bool IsRender()
执行了Render
bool IsUpdate()
执行了Update
UI::Background * ExGetBackground(size_t n=0, bool show_log=true)
返回第n个bg
Panel * GetParent()
返回父panel
size_t GetSelectIndex()
返回被选中的元素下标
void SetDir(Align::Dir4 dir)
设置朝向,基于Coor旋转,旋转后仍然定位到左上角
void SetAutoRun(bool auto_run)
设置是否自动执行
void DelCpt(Components *cpt)
移除子Element,不删除
void UpdateRadio()
执行逻辑Radio @node 手动调用,把子panel作为radio处理
Panel * Clone()
克隆
std::string GetName() const
返回名字
size_t GetChildIndex(Panel *child)
返回子panel下标
void SetChildSelect(Panel *panel)
设置被选中的子panel,可以传空
UI::ButtonSprite9 * ExGetButtonSprite9(size_t n=0, bool show_log=true)
void SetAlign(const Align::Direction2 &hv)
设置 在父节点的对齐
void SetLocator(std::string_view name)
void Del(T *p)
添加一个Element
Position GetSize()
返回大小
void SetSelectAll(bool select)
设置所有子元素的选中状态
Position GetParentSize()
返回父节点大小
void SetAutoSize(bool auto_size)
void SetOrderInParent(int order_parent)
设置order
friend class Manager
void SetSelect(size_t index)
设置被选中的元素
bool IsPickup()
是否被鼠标选中(任意子元素、子面板被选中)
Coor * GetCoor()
返回坐标系
void Add(std::string_view json_path)
添加多个Element,通过json文件
void SetPickupMode(int mode)
void SetPickupMode(PickupMode mode)
Panel * GetChild(size_t i)
返回子panel
Position GetPosition()
void AddCpt(Components *cpt)
添加一个Element
void SetPosScale(const Position &pos_scale)
设置 比例位置
Components * Get()
返回第一个满足条件的组件
Components * GetCpt()
组件实例
资源工厂
json格式相关
2d定位器
#define log_err(...)
N叉树
通用类型定义
作为绘图背景
九图精灵按钮
UI之精灵
UI之文本
方向、对齐定义
Array< Direction, 2 > Direction2
constexpr Array< T, N > Dir2Offset(const Array< T, N > &size, Dir4 dir)
根据大小和朝向,计算偏移
constexpr Array< T, N > Size2Anchor(const Array< T, N > &size, const Array< Direction, N > &dir)
根据大小和对齐,计算锚点
Variable< std::string, str_uid("CustomName")> CustomName
Function< std::function< bool()>, str_uid("IsPickup")> IsPickup
---------------------------—具体组件----------------------------------—
Function< std::function< void(bool)>, str_uid("SetSelect")> SetSelect
设置是否选择
T * GetN(std::vector< Components * > &vec, size_t n)
从vector<Components*>返回指定类型的第n个元素
Function< std::function< void()>, str_uid("DeleteThis")> DeleteThis
删除自身
T * GetFirst(std::vector< Components * > &vec)
从vector<Components*>返回指定类型的第一个元素
ElementType String2ElementType(std::string_view str)
Position2 Position
constexpr Array< Position::value_type, N > toPosition(const Array< T, N > &a)
转换到Position,已知长度
Input * g_input
Factory * g_factory
void log_err0(std::string_view str, DL_SOURCE_LOCATION)
Position4 RectF
constexpr float Z_DEFAULT_PANEL