Files
dl_old/dl/ui/dl_ui_edit_box.cpp
T
2025-05-29 19:09:26 +08:00

333 lines
6.1 KiB
C++

#include "dl_ui_edit_box.h"
#ifndef DL_DISABLE_RENDER
#include "ui/dl_ui_manager.h"
namespace dl::UI
{
void EditBox::_init(gcText txt)
{
_colTip = ColorDef::GRAY;
_strTip = "在这里输入内容……";
_colCursor = ColorDef::GREEN;
_colSelect = createColor(ColorDef::WHITE, 0.5f);
_timerCursor.Set(0.5, true);
_panel->SetAutoRun(false);
_panel->SetAutoCoor(false);
_panel->SetPickupMode(Panel::E_ELEMENT);
_txt = txt;
_sprCursor = g_factory->CreateSpriteDefault(_colCursor);
_sprCursor->SetQuad(createQuad(toPosition(1.0f, _txt->GetFontSize()), false));
_init_coor();
}
void EditBox::_init_coor()
{
_txt->GetCoor()->SetParent(_panel->GetCoor());
_sprCursor->AddCoor()->SetParent(_panel->GetCoor());
}
dl::UI::EditBox* EditBox::Clone()
{
EditBox* ret = new EditBox(*this);
ret->_cpt = ret;
ret->_init_cpt();
ret->_panel = _panel->Clone();
ret->_txt = g_factory->CloneText(_txt);
ret->_sprCursor = g_factory->CloneSprite(_sprCursor);
ret->_init_coor();
return ret;
}
void EditBox::SetFocus(bool focus)
{
g_ui->SetFocusEditBox(this, focus);
}
void EditBox::_on_char(char32_t ch)
{
//log_test0(CodeCvt::Utf32ToUtf8(std::u32string{ ch }));
_str.insert(_iCursor, 1, ch);
++_iCursor;
_bChange = true;
_refresh_txt();
_refresh_cursor();
_refresh_select();
}
void EditBox::_on_string(std::string_view str)
{
log_test0(str);
std::u32string s = CodeCvt::Utf8ToUtf32(String::CvtLineBreak(str));
_str.insert(_str.begin() + _iCursor, s.begin(), s.end());
_iCursor += s.size();
_bChange = true;
_refresh_txt();
_refresh_cursor();
_refresh_select();
}
bool EditBox::IsFocus()
{
return g_ui->GetFocusEditBox() == this;
}
void EditBox::SetSingleLine(bool single_line)
{
if (_bSingleLine == single_line)
return;
_bSingleLine = single_line;
if (single_line)
{
if (Any::Equal(_str, '\n'))
{
log_warn0("多行输入框变为单行,存在换行符!");
}
}
else
{
_txt->SetMaxW((unsigned)_panel->GetSize()[0]);
}
}
void EditBox::DeleteSelect()
{
_delete_select();
_refresh_txt();
_refresh_cursor();
_refresh_select();
}
void EditBox::_refresh_txt(bool* focus)
{
bool f = focus ? *focus : IsFocus();
if (_str.empty() && !f)
{
_txt->SetColor(_colTip);
_txt->SetString(_strTip);
return;
}
_txt->SetColor(f ? _col[2] : _col[0]);
_txt->SetString(CodeCvt::Utf32ToUtf8(_str));
}
void EditBox::_refresh_cursor()
{
_limit_range();
Position pos = Cursor2Pos(_iCursor);
//RoundVec2(pos);
size_t i = _iCursor;
if (i >= _txt->GetString().size())
i = _txt->GetString().size() - 1;
unsigned font_size = _txt->GetNodeFontSize(i);
_sprCursor->SetQuad(createQuad(toPosition(1.0f, font_size), false));
_sprCursor->GetCoor()->SetPosition(pos);
}
void EditBox::_refresh_select()
{
_limit_range();
//CCLOG("%d, %d", _iBeg, _iEnd);
_vecSprSelect.clear();
if (_iBeg == _iEnd)
return;
size_t i_min = std::min(_iBeg, _iEnd);
size_t i_max = std::max(_iBeg, _iEnd);
Position p0 = Cursor2Pos(i_min);
for (size_t i = i_min + 1; i < i_max; ++i)
{
Position p1 = Cursor2Pos(i);
if (p1[1] != p0[1])
{// y变了,开启新行
Position p_last = Cursor2Pos(i - 1);
Position size_last = _txt->GetNodeSize(i - 1);
gcSprite spr = g_factory->CreateSpriteDefault(_colSelect);
spr->SetCoor(_panel->GetCoor());
spr->SetQuad(createQuad(p0, p_last + size_last));
_vecSprSelect.push_back(spr);
p0 = Cursor2Pos(i);
}
}
Position p_last = Cursor2Pos(i_max - 1);
Position size_last = _txt->GetNodeSize(i_max - 1);
gcSprite spr = g_factory->CreateSpriteDefault(_colSelect);
spr->SetCoor(_panel->GetCoor());
spr->SetQuad(createQuad(p0, p_last + size_last));
_vecSprSelect.push_back(spr);
}
void EditBox::_limit_range()
{
if (_str.empty())
{
_iCursor = 0;
_iBeg = 0;
_iEnd = 0;
return;
}
if (_iCursor > _str.size())
_iCursor = _str.size();
if (_iBeg > _str.size())
_iBeg = _str.size();
if (_iEnd > _str.size())
_iEnd = _str.size();
}
void EditBox::_delete_select()
{
if (_iBeg == _iEnd)
return;
size_t i_min = std::min(_iBeg, _iEnd);
size_t i_max = std::max(_iBeg, _iEnd);
_str.erase(_str.begin() + i_min, _str.begin() + i_max);
_iCursor = i_min;
_bChange = true;
_iBeg = _iCursor;
_iEnd = _iCursor;
}
void EditBox::_on_focus(bool focus)
{
_panel->SetSelectAll(focus);
_refresh_txt(&focus);
}
void EditBox::_on_backspace()
{
if (_str.empty())
return;
if (_iBeg == _iEnd)
{
if (_iCursor > 0)
{
_str.erase(_iCursor - 1, 1);
--_iCursor;
_bChange = true;
}
}
else
{
_delete_select();
}
_refresh_txt();
_refresh_cursor();
_refresh_select();
}
void EditBox::_on_delete()
{
if (_str.empty())
return;
if (_iBeg == _iEnd)
{
if (_iCursor < _str.size())
{
_str.erase(_iCursor, 1);
_bChange = true;
}
}
else
{
_delete_select();
}
_refresh_txt();
_refresh_cursor();
_refresh_select();
}
void EditBox::_on_left()
{
if (_iCursor == 0)
return;
--_iCursor;
_timerCursor.Reset(true);
_refresh_cursor();
}
void EditBox::_on_right()
{
if (_iCursor == _str.size())
return;
++_iCursor;
_timerCursor.Reset(true);
_refresh_cursor();
}
void EditBox::_on_enter()
{
if (_bSingleLine)
return;
_on_char('\n');
}
void EditBox::_on_select_all()
{
_iBeg = 0;
_iEnd = _str.size();
_refresh_select();
}
void EditBox::_update()
{
if (!_bChangeSelect)
{
if (g_input->KeyDown(MouseCode::LEFT))
{
_bChangeSelect = true;
Point xy = g_input->GetCursorPosition();
Position pos = GetCoor()->WorldToThis(toPosition(xy));
_iCursor = Pos2Cursor(pos);
_refresh_cursor();
_iBeg = _iCursor;
_iEnd = _iBeg;
_refresh_select();
}
}
else
{
if (g_input->KeyUp(MouseCode::LEFT))
{
_bChangeSelect = false;
}
else if (g_input->KeyState(MouseCode::LEFT))
{
Point xy = g_input->GetCursorPosition();
Position pos = GetCoor()->WorldToThis(toPosition(xy));
_iCursor = Pos2Cursor(pos);
_refresh_cursor();
_iEnd = _iCursor;
_refresh_select();
}
}
}
std::string EditBox::GetStringSelect()
{
if (_iBeg == _iEnd)
return {};
size_t i_min = std::min(_iBeg, _iEnd);
size_t i_max = std::max(_iBeg, _iEnd);
return CodeCvt::Utf32ToUtf8({ _str.begin() + i_min, _str.begin() + i_max });
}
}
#endif