Files
dl_old/dl/ui/dl_ui_manager.cpp
2026-09-14 12:15:01 +08:00

1141 lines
25 KiB
C++
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
#include "ui/dl_ui_manager.h"
#ifndef DL_DISABLE_RENDER
#include "io/dl_file.h"
#include "base/dl_string.h"
#include "render/dl_graphics.h"
#include "system/dl_system.h"
namespace dl::UI
{
UI::Text* Manager::CreateText(std::string_view name)
{
auto iter = _allText.find(std::string{ name });
if (iter == _allText.end())
{
log_err("UI::Text不存在,请使用Register注册:{}", name);
return UI::Text::Create(g_factory->CreateTextDefault());
}
return iter->second->Clone();
}
gcText Manager::CreateTextOnly(std::string_view name)
{
auto iter = _allText.find(std::string{ name });
if (iter == _allText.end())
{
log_err("UI::Text不存在,请使用Register注册:{}", name);
return g_factory->CreateTextDefault();
}
return g_factory->CloneText(iter->second->GetText());
}
UI::ButtonSprite* Manager::CreateButtonSprite(std::string_view name)
{
auto iter = _allBtnSprite.find(std::string{ name });
if (iter == _allBtnSprite.end())
{
log_err("ButtonSprite不存在,请使用Register注册:{}", name);
return CreateButtonSpriteDefault();
}
return iter->second->Clone();
}
Background* Manager::CreateBackground(std::string_view name)
{
auto iter = _allBackground.find(std::string{ name });
if (iter == _allBackground.end())
{
log_err("Background不存在,请使用Register注册:{}", name);
return CreateBackgroundDefault();
}
return iter->second->Clone();
}
dl::Locator::SL Manager::CreateLocator(std::string_view name)
{
auto iter = _allLocator.find(std::string{ name });
if (iter == _allLocator.end())
{
log_err("Locator不存在,请使用Register注册:{}", name);
return {};
}
return iter->second;
}
dl::UI::ListBox* Manager::CreateListBox(std::string_view name)
{
auto iter = _allListBox.find(std::string{ name });
if (iter == _allListBox.end())
{
log_err("ListBox不存在,请使用Register注册:{}", name);
return {};
}
return iter->second->Clone();
}
dl::UI::Text* Manager::CreateTextDefault()
{
return UI::Text::Create(g_factory->CreateTextDefault());
}
UI::ButtonSprite* Manager::CreateButtonSpriteDefault(ButtonStyle style)
{
//34/55 约等于 0.618
Position size;
switch (style)
{
case ButtonStyle::SMALL:
size = Math::CreatePositionByRatioGoldW(_arrSizeType[SizeType::SMALL]);
break;
case ButtonStyle::NORMAL:
size = Math::CreatePositionByRatioGoldW(_arrSizeType[SizeType::NORMAL]);
break;
case ButtonStyle::LARGE:
size = Math::CreatePositionByRatioGoldW(_arrSizeType[SizeType::LARGE]);
break;
case ButtonStyle::BOX:
size = { 30, 30 };
break;
case ButtonStyle::CLOSE:
size = { 24, 24 };
break;
case ButtonStyle::LONG:
size = { _arrSizeType[SizeType::LONG], 20 };
break;
case ButtonStyle::SWITCH:
size = { 18, 18 };
break;
default:
assert(0);
break;
}
std::vector<gcSprite> mul_spr;
mul_spr.resize(3);
for (size_t i = 0; i < 3; ++i)
{
mul_spr[i] = g_factory->CreateSpriteDefault();
mul_spr[i]->SetQuad(createQuad(size, false));
}
//
ButtonSprite* ret;
if (style == ButtonStyle::SWITCH)
{
mul_spr[0]->SetColor(ColorDef::GRAY_DARK);
mul_spr[1]->SetColor(ColorDef::WHITE);
mul_spr[2]->SetColor(ColorDef::GRAY_LIGHT);
ret = ButtonSprite::Create(mul_spr);
ret->SetMode(ButtonMode::SWITCH);
ret->AddText(g_factory->CreateTextDefault(),
toVector(ColorDef::BLACK, 5),
toVector(Position{40, 0}, 5));
ret->SetTextAlign(Align::LC);
ret->SetCustomRender([](Button* btn) {
// 描边
g_gfx->SetCoor(btn->GetCoor());
g_gfx->SetColor(ColorDef::BLACK);
g_gfx->Rectangle2D({}, btn->GetSize());
g_gfx->SetOrder(btn->GetOrder(-1));
//
Position size = btn->GetSize();
if (btn->IsSelect())
{
g_gfx->SetColor(ColorDef::GREEN_DARK);
g_gfx->StrokeLine({}, { size.w * 0.5f, size.h }, 2);
g_gfx->StrokeLine({ size.w * 0.5f, size.h } ,{ size.w , 0}, 2);
}
else
{
g_gfx->SetColor(ColorDef::RED);
g_gfx->StrokeLine({}, { size.w, size.h }, 2);
g_gfx->StrokeLine({ size.w, 0 }, { 0 , size.h }, 2);
}
});
}
else
{
mul_spr[0]->SetColor(ColorDef::GRAY_LIGHT);
mul_spr[1]->SetColor(ColorDef::WHITE);
mul_spr[2]->SetColor(ColorDef::GRAY);
ret = ButtonSprite::Create(mul_spr);
ret->AddTextDefault();
if (style != ButtonStyle::CLOSE)
{
ret->SetCustomRender([](Button* btn) {
Position size = btn->GetSize();
// 描边
g_gfx->SetCoor(btn->GetCoor());
g_gfx->SetColor(ColorDef::BLACK);
g_gfx->SetOrder(btn->GetOrder(-1));
g_gfx->Rectangle2D({}, size);
// 投影
if (!btn->IsDown())
{
g_gfx->SetOrder(btn->GetOrder(0));
g_gfx->Line2D({ size.w + 1, 0 }, { size.w + 1, size.h + 1 });
g_gfx->Line2D({ 1, size.h + 1 }, { size.w + 1, size.h + 1 });
}
else
{
g_gfx->Line2D({ 1, 1 }, { size.w, 1 });
g_gfx->Line2D({ 1, 1 }, { 1, size.h });
}
});
}
else
{
ret->SetCustomRender([](Button* btn) {
Position size = btn->GetSize();
// 描边
g_gfx->SetCoor(btn->GetCoor());
g_gfx->SetColor(ColorDef::BLACK);
g_gfx->SetOrder(btn->GetOrder(-1));
g_gfx->Rectangle2D({}, size);
// 投影
if (!btn->IsDown())
{
g_gfx->SetOrder(btn->GetOrder(0));
g_gfx->Line2D({ size.w + 1, 0 }, { size.w + 1, size.h + 1 });
g_gfx->Line2D({ 1, size.h + 1 }, { size.w + 1, size.h + 1 });
}
// 叉
g_gfx->SetOrder(btn->GetOrder(-1));
g_gfx->SetColor(ColorDef::GRAY_DARK);
g_gfx->StrokeLine(
{ size.w * 0.25f, size.h * 0.25f },
{ size.w * 0.75f, size.h * 0.75f }, 2);
g_gfx->StrokeLine(
{ size.w * 0.75f, size.h * 0.25f },
{ size.w * 0.25f , size.h * 0.75f }, 2);
});
}
}
return ret;
}
Background* Manager::CreateBackgroundDefault()
{
Background* ret = Background::Create();
gcSprite spr = g_factory->CreateSpriteDefault();
spr->SetColor(ColorDef::GRAY);
ret->Set(spr);
ret->SetCustomRender([](Background* bg) {
Position size = bg->GetSize();
// 描边
g_gfx->SetCoor(bg->GetCoor());
g_gfx->SetColor(ColorDef::GREEN);
g_gfx->SetOrder(bg->GetOrder(-1));
g_gfx->Rectangle2D({}, size);
// 投影
if (true)
{
g_gfx->SetColor(createColor(ColorDef::BLACK, 0.5f));
g_gfx->SetOrder(bg->GetOrder(0));
g_gfx->Line2D({ size.w + 1, 0 }, { size.w + 1, size.h + 1 });
g_gfx->Line2D({ 1, size.h + 1 }, { size.w + 1, size.h + 1 });
}
});
return ret;
}
ListBox* Manager::CreateListBoxDefault(bool add_text)
{
// item
Panel* item = g_ui->CreatePanel();
item->SetLocator(createLocatorZero());
{
ButtonSprite* btn = g_ui->CreateButtonSpriteDefault();
btn->SetMode(ButtonMode::RADIO);
btn->SetSpriteQuad(ButtonState::MAX_NUM, createQuad(
Size{ (unsigned)_arrSizeType[SizeType::LONG], 16 }, false));
btn->SetSpriteColor(ButtonState::NORMAL, ColorDef::WHITE);
btn->SetSpriteColor(ButtonState::OVER, ColorDef::GREEN);
btn->SetSpriteColor(ButtonState::DOWN, ColorDef::BLUE);
if (add_text)
btn->AddTextDefault();
item->Add(btn);
item->SetSize(btn->GetSize());
}
ListBox* ret = ListBox::Create(item, 10);
ret->SetItemLocator(createLocatorY(16.0f));
return ret;
}
dl::UI::EditBox* Manager::CreateEditBoxDefault(bool single_line)
{
// item
Panel* panel = g_ui->CreatePanel();
panel->SetLocator(createLocatorZero());
ButtonSprite* btn = g_ui->CreateButtonSpriteDefault();
btn->SetMode(ButtonMode::RADIO);
if (single_line)
btn->SetSpriteQuad(ButtonState::MAX_NUM, createQuad(
Size{ (unsigned)_arrSizeType[SizeType::LONG], 16 }, false));
else
btn->SetSpriteQuad(ButtonState::MAX_NUM, createQuad(
Size{ (unsigned)_arrSizeType[SizeType::LONG], 120 }, false));
btn->SetSpriteColor(ButtonState::NORMAL, ColorDef::WHITE);
btn->SetSpriteColor(ButtonState::OVER, ColorDef::GREEN);
btn->SetSpriteColor(ButtonState::DOWN, ColorDef::BLUE);
panel->Add(btn);
EditBox* ret = EditBox::Create(panel, g_factory->CreateTextDefault());
ret->SetSingleLine(single_line);
ret->SetColor({ ColorDef::RED, ColorDef::RED, ColorDef::WHITE });
// 多行输入框自动换行
if (!single_line)
{
ret->GetText()->SetMaxW(btn->GetSize()[0]);
}
return ret;
}
dl::UI::Tree* Manager::CreateTreeDefault()
{
// item
Panel* panel = g_ui->CreatePanel();
panel->SetLocator(createLocatorZero());
{
ButtonSprite* btn = g_ui->CreateButtonSpriteDefault();
btn->SetMode(ButtonMode::SWITCH);
btn->SetSpriteQuad(ButtonState::MAX_NUM, createQuad(Size{ 64, 20 }, false));
btn->SetSpriteColor(ButtonState::NORMAL, ColorDef::WHITE);
btn->SetSpriteColor(ButtonState::OVER, ColorDef::GREEN);
btn->SetSpriteColor(ButtonState::DOWN, ColorDef::BLUE);
panel->Add(btn);
}
Tree* ret = Tree::Create(panel);
ret->SetCallbackSetPosition([](UI::Panel* panel, size_t i, size_t extra) {
panel->SetPosPixel(Position{ 32.0f, (i + extra) * 20.0f });
});
return ret;
}
Menu* Manager::CreateMenuDefault()
{
Background* bg = g_ui->CreateBackgroundDefault();
Background* bg_combo = g_ui->CreateBackgroundDefault();
Panel* panel_menu = g_ui->CreatePanel();
panel_menu->SetLocator(createLocatorZero());
{
UI::Text* txt = g_ui->CreateTextDefault();
panel_menu->Add(txt);
}
Panel* panel_btn = g_ui->CreatePanel();
panel_btn->SetLocator(createLocatorZero());
{
UI::Text* txt = g_ui->CreateTextDefault();
panel_btn->Add(txt);
UI::Text* txt_hotkey = g_ui->CreateTextDefault();
panel_btn->Add(txt_hotkey);
}
Menu* ret = Menu::Create(
bg, panel_menu, createLocatorX(40, 0, 32) ,
bg_combo, panel_btn, createLocatorY(30, 0, 30));
return ret;
}
ProgressBar* Manager::CreateProgressBarDefault()
{
Background* bg = g_ui->CreateBackgroundDefault();
bg->SetSize({ 200, 24 });
bg->SetColor(ColorDef::WHITE);
Background* bg_mid = Background::Create();
bg_mid->Set(g_factory->CreateSpriteDefault(ColorDef::GRAY));
//Background* bg_front = g_ui->CreateBackgroundDefault();
Text* txt = g_ui->CreateTextDefault();
txt->GetText()->SetColor(ColorDef::GREEN);
txt->GetText()->SetOutline(1, ColorDef::BLACK);
ProgressBar* ret = ProgressBar::Create(bg, bg_mid, txt);
ret->SetMidRect({ 1, 1, 199, 23 });
return ret;
}
void Manager::Register(std::string_view json_path)
{
std::ifstream ifs = File::Get(json_path);
if (!ifs.is_open())
{
log_err("json文件并不存在:{}", json_path);
return;
}
json j = Json::ParseFile(json_path);
if (j.is_null())
return;
RegKey key;
//类型名字检查
std::string type;
Json::Get(j, "type", type);
if (type.empty())
{
log_err0("必须含有type字段!例如text");
return;
}
Json::Get(j, "name", key._name);
if (key._name.empty())
{
log_err0("必须含有name字段!例如normal");
return;
}
key._type = String2ElementType(type);
if (key._type == ElementType::UNKNOWN)
return;
key._json = j;
_allReg.push_back(key);
}
void Manager::_reg_background(json& j, const std::string& name)
{
if (_allBackground.contains(name))
{
log_err("name错误(不能为空,或重复):{}", name);
return;
}
Background* bg = nullptr;
std::string spr;
std::string spr9;
Json::DisableLog l;
Json::Get(j, "spr", spr);
Json::Get(j, "spr9", spr9);
if (!spr.empty())
{
gcSprite p_spr = g_factory->CreateSprite(spr);
bg = Background::Create();
bg->Set(p_spr);
}
else if (!spr9.empty())
{
Sprite9* p_spr9 = Sprite9::Create(spr9);
bg = Background::Create();
bg->Set(p_spr9);
}
if (bg)
{
/*Point extra;
if (Json::Get(j, "extra", extra))
bg->SetExtra(extra);
Point offset;
if (Json::Get(j, "offset", offset))
bg->SetOffset(offset);*/
_allBackground[name] = bg;
log_msg("成功注册一个Background:{}", name);
}
else
{
log_msg("没有有效的字段:{}(spr、spr9)", name);
}
}
void Manager::_reg_text(json& j, const std::string& name)
{
if (_allText.contains(name))
{
log_err("name错误(不能为空,或重复):{}", name);
return;
}
std::string color;
std::string color_o;
std::string color_s;
std::string anchor;
size_t id;
unsigned size;
unsigned size_o = 0;
unsigned size_s = 0;
std::string str;
std::optional<Color> opt_color;
std::optional<Color> opt_color_o;
std::optional<Color> opt_color_s;
Align::Direction2 hv;
//id、大小、颜色
Json::Get(j, "id", id);
if (id >= g_factory->GetFontSize())
{
log_err("id越界:{}", id);
return;
}
Json::Get(j, "size", size);
Json::DisableLog l;
Json::Get(j, "string", str);
// 大小
Json::Get(j, "size_o", size_o);
Json::Get(j, "size_s", size_s);
// 颜色
if (Json::Get(j, "color", color))
opt_color = g_factory->GetColorCheck(color);
if (Json::Get(j, "color_o", color_o))
opt_color_o = g_factory->GetColorCheck(color_o);
if (Json::Get(j, "color_s", color_s))
opt_color_s = g_factory->GetColorCheck(color_s);
// 对齐
if (Json::Get(j, "anchor", anchor))
{
hv = Align::Anchor2Direction(anchor);
}
gcText txt = g_factory->CreateText(id, size);
txt->SetOutline(size_o);
txt->SetShadow(size_s);
if (opt_color.has_value())
txt->SetColor(opt_color.value());
if (opt_color_o.has_value())
txt->SetColor(opt_color_o.value(), TextParam::OUTLINE);
if (opt_color_s.has_value())
txt->SetColor(opt_color_s.value(), TextParam::SHADOW);
txt->SetString(str);
UI::Text* ret = UI::Text::Create(txt);
ret->SetElementData(hv);
_allText[name] = ret;
log_msg("成功注册一个Text:{}", name);
}
void Manager::_reg_button(json& j, const std::string& name)
{
if (_allBtnSprite.contains(name))
{
log_err("name错误(不能为空,或重复):{}", name);
return;
}
std::string style;
std::string mode;
std::string spr;
std::string txt;
Json::Get(j, "style", style);
Json::DisableLog l;
Json::Get(j, "mode", mode);
Json::Get(j, "spr", spr);
Json::Get(j, "txt", txt);
if (style == "sprite")
{
std::vector<gcSprite> mul_spr = g_factory->CreateSpriteMulti(spr);
ButtonSprite* btn = ButtonSprite::Create(mul_spr);
if (!txt.empty())
{
gcText p_txt = CreateTextOnly(txt);
btn->AddText(p_txt, {}, {});
}
//mode
if (mode == "switch")
btn->SetMode(UI::Button::Mode::SWITCH);
else if (mode == "radio")
btn->SetMode(UI::Button::Mode::RADIO);
_allBtnSprite[name] = btn;
log_msg("成功注册一个ButtonSprite:{}", name);
}
else
{
log_msg("style未知:{}", style);
return;
}
}
void Manager::_reg_msg_box(json& j, const std::string& name)
{/*
if (_allMsgBox.contains(name))
{
log_err("name错误(不能为空,或重复):{}", name);
return;
}
std::string bg;
std::string txtTitle;
std::string txt;
std::string btn;
std::string btnClose;
Float dxBtn;
Json::Get(j, "bg", bg);
Json::Get(j, "txt_title", txtTitle);
Json::Get(j, "txt", txt);
Json::Get(j, "btn", btn);
Json::Get(j, "btn_close", btnClose);
Json::Get(j, "dx_btn", dxBtn);
Background* p_bg = CreateBackground(bg);
MsgBox* msg_box = MsgBox::Create(
p_bg,
CreateTextOnly(txtTitle),
CreateTextOnly(txt),
CreateButtonSprite(btn),
CreateButtonSprite(btnClose),
dxBtn);
_allMsgBox[name] = msg_box;
log_msg("成功注册一个MsgBox:{}", name);*/
}
void Manager::_reg_locator(json& j, std::string_view name)
{
if (_allLocator.contains(std::string{ name }))
{
log_err("name错误(不能为空,或重复):{}", name);
return;
}
Locator::SL loc;
std::string layout;
Json::DisableLog l;
Json::Get(j, "dt", loc._dt);
if (Json::Get(j, "layout", layout))
loc._layout = String2Layout(layout);
Json::Get(j, "num", loc._num);
Json::Get(j, "start", loc._start);
_allLocator[std::string{ name }] = loc;
log_msg("成功注册一个Locator:{}", name);
}
void Manager::_reg_list_box(json& j, std::string_view name)
{
if (_allListBox.contains(std::string{ name }))
{
log_err("name错误(不能为空,或重复):{}", name);
return;
}
std::string btn_name;
std::string txt_name;
size_t num = 10;
Float dy = 32.0_f;
Float scroll_k = 1.0_f;
Json::Get(j, "btn", btn_name);
Json::DisableLog l;
Json::Get(j, "text", txt_name);
Json::Get(j, "num", num);
Json::Get(j, "dy", dy);
Json::Get(j, "scroll_k", scroll_k);
ButtonSprite* btn = CreateButtonSprite(btn_name);
if (!txt_name.empty())
{
// todo 颜色
btn->AddText(CreateTextOnly(txt_name),
{ ColorDef::WHITE, ColorDef::WHITE, ColorDef::GREEN },
{ {}, {0, -1}, {0, 1} });
}
Panel* item = CreatePanel();
item->SetLocator(createLocatorZero());
item->Add(btn);
item->SetSize(btn->GetSize());
ListBox* list_box = ListBox::Create(item, num);
list_box->SetScrollK(scroll_k);
_allListBox[std::string{ name }] = list_box;
log_msg("成功注册一个ListBox:{}", name);
}
void Manager::RegisterEnd()
{
_allReg.sort();
for (RegKey& key : _allReg)
{
json& j = key._json;
switch (key._type)
{
case ElementType::BACKGROUND:
_reg_background(j, key._name);
break;
case ElementType::TEXT:
_reg_text(j, key._name);
break;
case ElementType::BUTTON:
_reg_button(j, key._name);
break;
case ElementType::MSG_BOX:
_reg_msg_box(j, key._name);
break;
case ElementType::LOCATOR:
_reg_locator(j, key._name);
break;
case ElementType::LIST_BOX:
_reg_list_box(j, key._name);
break;
default:
assert(0);
break;
}
}
}
void Manager::RegisterAll(std::string_view path)
{
std::vector<std::string> all_file;
File::GetPathFileAll(path, all_file, ".json");
for (auto& iter : all_file)
{
Register(iter);
}
RegisterEnd();
}
void Manager::_resize()
{
// 窗口大小为0,可能是最小化
if (Any::Zero(g_system->GetWindowSize()))
return;
// 更新ui缩放(未设置则不缩放)
_refresh_standard_size();
_resize_panel_root();
// 更新panel大小,和元素定位
auto fn = [&](Panel* p)
{
p->_refresh_size();
};
_allPanel.ForEach(fn);
// 根面板的所有子面板更新位置
for (auto* node : _panelRoot->_node->GetChild())
{
Panel* panel = node->GetValue();
if(panel->_bAutoCoor)
panel->_refresh_pos(_panelRoot->GetSize());
}
}
void Manager::_update_pre()
{
_bDebug = false;
_bHide = false;
for (auto& node : _allPanel)
{
node->GetValue()->_bUpdate = false;
node->GetValue()->_bRender = false;
}
}
void Manager::_update()
{
_update_window();
_panelRoot->Update();
}
void Manager::_render()
{
_panelRoot->Render();
if (_bDebug)
_debug_render();
}
void Manager::_resize_panel_root()
{
// 需要拉伸填充
Size size = g_system->GetWindowSize();
_panelRoot->SetSize(toPosition(size) / _uiScale);
}
void Manager::_refresh_standard_size()
{
if (Any::Zero(_sizeStandard))
return;
Position k = toPosition(g_system->GetWindowSize()) / toPosition(_sizeStandard);
Float s = Select::Min(k);
if (s < 0.1f)
s = 0.1f;
SetScale(s);
}
void Manager::RenderDebug()
{
_bDebug = true;
}
void Manager::_debug_render()
{
if (!_bDebug)
return;
for (auto& node : _allPanel)
{
Panel* panel = node->GetValue();
if (!panel->IsUpdate())
continue;
// 绘制:panel坐标
g_gfx->RenderCoor(panel->_coor,
panel->GetParent() != _panelRoot);
// 绘制:panel大小
/*g_gfx->SetCoor(panel->_coor);
g_gfx->SetColor(createColorRandom(0.1f));
g_gfx->RectangleSolid2D({}, panel->GetSize());*/
//组件处理
for (Components* cpts : panel->_allEle)
{
Cpt::GetCoor* comp_coor = cpts->Get<Cpt::GetCoor>();
Coor* coor = comp_coor ? comp_coor->Call() : nullptr;
if (coor)
{
if (Cpt::IsPickup* comp = cpts->Get<Cpt::IsPickup>())
{
if (comp->Call())
{
// 绘制:拾取到的组件坐标
g_gfx->RenderCoor(coor);
}
}
// 绘制:组件大小
if (Cpt::ElementData* comp = cpts->Get<Cpt::ElementData>())
{
RenderDebugElementData(coor, *comp);
}
}
// 绘制:组件自定义绘制
if (Cpt::RenderDebug* comp = cpts->Get<Cpt::RenderDebug>())
{
comp->Call();
}
}
}
Button* btn = Button::GetClickControl();
if (btn)
{
gcText txt = g_factory->RenderText();
txt->GetCoor()->SetParent(btn->GetCoor());
txt->SetString("当前锁定");
}
}
void Manager::_on_char(char32_t ch)
{
if (!_edtFocus)
return;
_edtFocus->_on_char(ch);
}
void Manager::_on_key(int action, bool ctrl)
{
if (!_edtFocus)
return;
KeyCode act = (KeyCode)action;
if (ctrl)
{
if (act == KeyCode::X)
{
g_system->SetClipboardString(_edtFocus->GetStringSelect());
_edtFocus->DeleteSelect();
}
else if (act == KeyCode::C)
g_system->SetClipboardString(_edtFocus->GetStringSelect());
else if (act == KeyCode::V)
_edtFocus->_on_string(g_system->GetClipboardString());
else if (act == KeyCode::A)
_edtFocus->_on_select_all();
}
else
{
if (act == KeyCode::BACKSPACE)
_edtFocus->_on_backspace();
else if (act == KeyCode::DELETE)
_edtFocus->_on_delete();
else if (act == KeyCode::LEFT)
_edtFocus->_on_left();
else if (act == KeyCode::RIGHT)
_edtFocus->_on_right();
else if (act == KeyCode::ENTER
|| act == KeyCode::KP_ENTER)
_edtFocus->_on_enter();
}
}
void Manager::SetFocusEditBox(EditBox* edt, bool focus /*= true*/)
{
if (focus)
{
if (_edtFocus == edt)
return;
// 前一个输入框,设为非激活
if(_edtFocus)
_edtFocus->_on_focus(false);
edt->_on_focus(true);
_edtFocus = edt;
}
else
{
if (_edtFocus == edt)
{
edt->_on_focus(false);
_edtFocus = nullptr;
}
}
}
void Manager::RenderDebugElementData(Coor* coor, const Cpt::ElementData& elem_data)
{
//Position p0 = coor->GetPosition() - elem_data.GetAnchor();
//Position p1 = p0 + elem_data.GetSize();
//g_gfx->SetCoor(coor->GetParent());
//g_gfx->SetColor(createColor(ColorDef::PURPLE, 1.0f));
//g_gfx->Rectangle2D(p0, p1);
/*Position p0 = coor->GetPosition();
Position p1 = p0 + elem_data.GetSize();
g_gfx->SetCoor(coor->GetParent());
g_gfx->SetColor(createColor(ColorDef::PURPLE, 1.0f));
g_gfx->Rectangle2D(p0, p1);*/
Position p0 = {};
Position p1 = elem_data.GetSize();
g_gfx->SetCoor(coor);
g_gfx->SetColor(createColor(ColorDef::PURPLE, 1.0f));
g_gfx->Rectangle2D(p0, p1);
}
Size Manager::GetStandardSize()
{
return Any::Zero(_sizeStandard) ?
g_system->GetWindowSize() : _sizeStandard;
}
void Manager::SetStandardSize(const Size& size)
{
if (!g_system->IsWindowExist())
{
log_err("必须创建窗口之后调用!");
return;
}
_sizeStandard = size;
_refresh_standard_size();
}
void Manager::AddWindow(std::string_view name, Window* win)
{
Window*& win_old = _allWindow[std::string{ name }];
if (win_old)
{
auto iter = std::find(_listShowWindow.begin(), _listShowWindow.end(), win_old);
if (iter != _listShowWindow.end())
{
_listShowWindow.erase(iter);
}
delete win_old;
log_info("已释放旧的同名窗口:{}", name);
}
win_old = win;
win->_bInManager = true;
win->_name = name;
_on_window_show_change(win, win->IsVisible());
}
Window* Manager::GetWindow(std::string_view name)
{
auto iter = _allWindow.find(std::string{ name });
if (iter == _allWindow.end())
{
log_warn("查找窗口失败:{}", name);
return nullptr;
}
return iter->second;
}
void Manager::_update_window()
{
// 防止遍历时删除自身
std::list<Window*> list_temp = _listShowWindow;
for (auto& iter : list_temp)
{
iter->Update();
}
}
void Manager::ShowWindow(Window* win, WindowShowMode mode /*= WindowShowMode::SHOW*/)
{
bool visible_old = win->IsVisible();
bool visible_new;
switch (mode)
{
case WindowShowMode::SHOW:
visible_new = true;
break;
case WindowShowMode::HIDE:
visible_new = false;
break;
case WindowShowMode::TOGGLE:
visible_new = !visible_old;
break;
default:
assert(0);
visible_new = true;
break;
}
if (visible_old != visible_new)
{
win->SetVisible(visible_new);
}
}
void Manager::ShowWindow(std::string_view name, WindowShowMode mode /*= WindowShowMode::SHOW*/)
{
Window* win = GetWindow(name);
if (!win)
return;
ShowWindow(win, mode);
}
void Manager::SetWindowTop(Window* win)
{
auto iter = std::find(_listShowWindow.begin(), _listShowWindow.end(), win);
if (iter == _listShowWindow.end())
{
log_warn("仅添加到管理器内调用有效!");
return;
}
// 只有自己一个,不处理
if (_listShowWindow.back() == win)
return;
_listShowWindow.erase(iter);
// 插入尾部
float order_min = _listShowWindow.back()->GetOrder();
if (order_min <= _orderMin)
{// 尾部已经即将超出范围,则重排order
_listShowWindow.push_back(win);
_refresh_window_order();
}
else
{
win->SetOrder(Math::OffsetOrder(order_min, -1));
_listShowWindow.push_back(win);
}
}
void Manager::_on_window_show_change(Window* win, bool visible)
{
if (visible)
{
if (_listShowWindow.empty())
{// 空列表直接插入
win->SetOrder(_orderMax);
_listShowWindow.push_back(win);
}
else
{
// 只有自己一个,不处理
if (_listShowWindow.back() == win)
return;
// 已存在则移除
auto iter = std::find(_listShowWindow.begin(), _listShowWindow.end(), win);
if(iter != _listShowWindow.end())
_listShowWindow.erase(iter);
// 插入尾部
float order_min = _listShowWindow.back()->GetOrder();
if (order_min <= _orderMin)
{// 尾部已经即将超出范围,则重排order
_listShowWindow.push_back(win);
_refresh_window_order();
}
else
{
win->SetOrder(Math::OffsetOrder(order_min, -1));
_listShowWindow.push_back(win);
}
}
}
else
{
auto iter = std::find(_listShowWindow.begin(), _listShowWindow.end(), win);
if (iter != _listShowWindow.end())
{
_listShowWindow.erase(iter);
}
}
}
void Manager::_refresh_window_order()
{
float order = _orderMax;
for (auto& iter : _listShowWindow)
{
iter->SetOrder(order);
order = Math::OffsetOrder(order, -1);
}
}
void Manager::_release_window(Window* win)
{
if (!win->_bInManager)
return;
auto iter = _allWindow.find(win->_name);
if (iter != _allWindow.end())
{
_on_window_show_change(win, false);
_allWindow.erase(iter);
}
}
Manager::~Manager()
{
_release();
for (auto& node : _allPanel)
{
delete node->GetValue();
}
}
void Manager::_release_window_all()
{
auto temp = _allWindow;
for (auto& iter : temp)
{
delete iter.second;
}
}
}
#endif