179 lines
4.2 KiB
C++
179 lines
4.2 KiB
C++
#include "ui/dl_ui_progress_bar.h"
|
|
|
|
#ifndef DL_DISABLE_RENDER
|
|
#include "ui/dl_ui_manager.h"
|
|
|
|
namespace dl::UI
|
|
{
|
|
|
|
//! 创建自身panel,并把子元素挂载进去
|
|
void ProgressBar::_init_panel()
|
|
{
|
|
_panel = g_ui->CreatePanel();
|
|
_panel->SetAutoRun(false);
|
|
_panel->SetAutoCoor(false);
|
|
_panel->SetOrderMode(Panel::FORCE);
|
|
_panel->SetPickupMode(Panel::E_ELEMENT);
|
|
|
|
// 子元素坐标系挂到自身panel,使其跟随整体移动
|
|
if (_bg) _panel->Add(_bg);
|
|
if (_mid) _panel->Add(_mid);
|
|
if (_txt) _panel->Add(_txt);
|
|
|
|
// 保存 mid 原图大小(填充区域默认用它)
|
|
if (_mid)
|
|
_sizeMidOrigin = _mid->GetSize();
|
|
|
|
_panel->SetSize(_bg->GetSize());
|
|
|
|
// 文本默认居中
|
|
_refresh_text_pos();
|
|
}
|
|
|
|
//! 刷新文本位置与旋转(默认居中,竖向按方向旋转)
|
|
void ProgressBar::_refresh_text_pos()
|
|
{
|
|
if (!_txt)
|
|
return;
|
|
|
|
Coor* coor = _txt->GetCoor();
|
|
Position size = _bg->GetSize();
|
|
Position size_txt = _txt->GetText()->GetSize();
|
|
float tw = size_txt.w;
|
|
float th = size_txt.h;
|
|
|
|
switch (_dir)
|
|
{
|
|
case Align::Dir4::RIGHT:
|
|
case Align::Dir4::LEFT:
|
|
// 水平:居中,不旋转
|
|
coor->SetRotate(0);
|
|
coor->SetPosition({ (size.w - tw) * 0.5f, (size.h - th) * 0.5f });
|
|
break;
|
|
case Align::Dir4::BOTTOM:
|
|
// 向下填充:顺时针旋转90°,居中
|
|
coor->SetRotate(Math::PIF(1, 2));
|
|
coor->SetPosition({ size.w * 0.5f + th * 0.5f, size.h * 0.5f - tw * 0.5f });
|
|
break;
|
|
case Align::Dir4::TOP:
|
|
// 向上填充:逆时针旋转90°,居中
|
|
coor->SetRotate(-Math::PIF(1, 2));
|
|
coor->SetPosition({ size.w * 0.5f - th * 0.5f, size.h * 0.5f + tw * 0.5f });
|
|
break;
|
|
}
|
|
}
|
|
|
|
ProgressBar::~ProgressBar()
|
|
{
|
|
// 接管子元素生命周期(子元素挂载在panel上,随panel一并释放)
|
|
g_ui->DeletePanel(_panel, true);
|
|
}
|
|
|
|
void ProgressBar::_refresh_mid()
|
|
{
|
|
if (!_mid)
|
|
return;
|
|
|
|
// mid 绘制区域:空则以 mid 原图大小
|
|
RectF rect = _rectMid;
|
|
if (Math::IsRectEmpty(rect))
|
|
rect = { 0, 0, _sizeMidOrigin.w, _sizeMidOrigin.h };
|
|
|
|
float rect_w = rect[2] - rect[0];
|
|
float rect_h = rect[3] - rect[1];
|
|
|
|
Position size{}; // 填充图大小
|
|
Position pos{}; // 填充图偏移(左/上方向填充时,对齐到对侧)
|
|
|
|
switch (_dir)
|
|
{
|
|
case Align::Dir4::RIGHT:
|
|
// 水平填充:宽随进度变化
|
|
size = { rect_w * _progress, rect_h };
|
|
pos = { rect[0], rect[1] };
|
|
break;
|
|
case Align::Dir4::LEFT:
|
|
size = { rect_w * _progress, rect_h };
|
|
pos = { rect[0] + rect_w - size.w, rect[1] };
|
|
break;
|
|
case Align::Dir4::BOTTOM:
|
|
// 垂直填充:高随进度变化
|
|
size = { rect_w, rect_h * _progress };
|
|
pos = { rect[0], rect[1] };
|
|
break;
|
|
case Align::Dir4::TOP:
|
|
size = { rect_w, rect_h * _progress };
|
|
pos = { rect[0], rect[1] + rect_h - size.h };
|
|
break;
|
|
}
|
|
|
|
_mid->SetSize(size);
|
|
_mid->GetCoor()->SetPosition(pos);
|
|
}
|
|
|
|
dl::UI::ProgressBar* ProgressBar::Create(UI::Background* bg, UI::Background* mid, UI::Text* txt /*= nullptr*/)
|
|
{
|
|
ProgressBar* ret = new ProgressBar;
|
|
ret->_bg = bg;
|
|
ret->_mid = mid;
|
|
ret->_txt = txt;
|
|
|
|
ret->_mid->SetUI(false);
|
|
// 挂载子元素到自身panel
|
|
ret->_init_panel();
|
|
|
|
ret->_order = Z_DEFAULT_UI;
|
|
ret->SetOrder(ret->_order);
|
|
ret->_init_cpt();
|
|
ret->_cptElemData._size = ret->_bg->GetSize();
|
|
return ret;
|
|
}
|
|
|
|
dl::UI::ProgressBar* ProgressBar::Clone()
|
|
{
|
|
ProgressBar* ret = new ProgressBar;
|
|
ret->_bg = _bg ? _bg->Clone() : nullptr;
|
|
ret->_mid = _mid ? _mid->Clone() : nullptr;
|
|
ret->_txt = _txt ? _txt->Clone() : nullptr;
|
|
|
|
ret->_progress = _progress;
|
|
ret->_progressK = _progressK;
|
|
ret->_cptElemData = _cptElemData;
|
|
ret->_order = _order;
|
|
ret->_dir = _dir;
|
|
ret->_fmt = _fmt;
|
|
ret->_rectMid = _rectMid;
|
|
ret->_sizeMidOrigin = _sizeMidOrigin;
|
|
|
|
// 挂载克隆出的子元素到自身panel
|
|
ret->_init_panel();
|
|
|
|
ret->_init_cpt();
|
|
|
|
ret->SetOrder(ret->_order);
|
|
// 恢复填充图尺寸(Background::Clone不会复制元素大小)
|
|
ret->_refresh_mid();
|
|
ret->_refresh_text();
|
|
return ret;
|
|
}
|
|
|
|
void ProgressBar::_refresh_text()
|
|
{
|
|
if (!_txt || _fmt.empty())
|
|
return;
|
|
float percent = _progress * _progressK;
|
|
std::string str = fmt::vformat(_fmt, fmt::make_format_args(percent));
|
|
_txt->SetString(str);
|
|
_refresh_text_pos();
|
|
}
|
|
|
|
void ProgressBar::SetDir(Align::Dir4 dir)
|
|
{
|
|
_dir = dir;
|
|
_refresh_mid();
|
|
_refresh_text_pos();
|
|
}
|
|
|
|
}
|
|
#endif
|