mirror of
https://github.com/thunderbrewhq/thunderbrew
synced 2025-10-28 23:06:04 +03:00
1350 lines
35 KiB
C++
1350 lines
35 KiB
C++
#include "ui/CSimpleEditBox.hpp"
|
|
#include "gx/Gx.hpp"
|
|
#include "gx/Coordinate.hpp"
|
|
#include "ui/CSimpleEditBoxScript.hpp"
|
|
#include "ui/CSimpleFontedFrameFont.hpp"
|
|
#include "ui/CSimpleFontString.hpp"
|
|
#include "ui/CSimpleTexture.hpp"
|
|
#include "ui/CSimpleTop.hpp"
|
|
#include "ui/LoadXML.hpp"
|
|
#include "util/Byte.hpp"
|
|
#include "util/CStatus.hpp"
|
|
#include "util/Lua.hpp"
|
|
#include "util/StringTo.hpp"
|
|
#include <cstring>
|
|
#include <common/XML.hpp>
|
|
#include <storm/String.hpp>
|
|
#include <storm/Unicode.hpp>
|
|
|
|
CSimpleEditBox* CSimpleEditBox::s_currentFocus;
|
|
int32_t CSimpleEditBox::s_metatable;
|
|
int32_t CSimpleEditBox::s_objectType;
|
|
|
|
void CSimpleEditBox::CreateScriptMetaTable() {
|
|
lua_State* L = FrameScript_GetContext();
|
|
int32_t ref = FrameScript_Object::CreateScriptMetaTable(L, &CSimpleEditBox::RegisterScriptMethods);
|
|
CSimpleEditBox::s_metatable = ref;
|
|
}
|
|
|
|
int32_t CSimpleEditBox::GetObjectType() {
|
|
if (!CSimpleEditBox::s_objectType) {
|
|
CSimpleEditBox::s_objectType = ++FrameScript_Object::s_objectTypes;
|
|
}
|
|
|
|
return CSimpleEditBox::s_objectType;
|
|
}
|
|
|
|
void CSimpleEditBox::RegisterScriptMethods(lua_State* L) {
|
|
CSimpleFrame::RegisterScriptMethods(L);
|
|
FrameScript_Object::FillScriptMethodTable(L, SimpleEditBoxMethods, NUM_SIMPLE_EDIT_BOX_SCRIPT_METHODS);
|
|
}
|
|
|
|
void CSimpleEditBox::SetKeyboardFocus(CSimpleEditBox* editBox) {
|
|
if (!editBox->m_visible) {
|
|
return;
|
|
}
|
|
|
|
if (CSimpleEditBox::s_currentFocus == editBox) {
|
|
return;
|
|
}
|
|
|
|
if (CSimpleEditBox::s_currentFocus) {
|
|
// TODO
|
|
// if (CSimpleEditBox::s_currentFocus->m_password) {
|
|
// nullsub_3();
|
|
// }
|
|
|
|
// TODO
|
|
// if (!(CSimpleEditBox::s_currentFocus->simpleeditbox_dword4 & 0xC)) {
|
|
// CSimpleEditBox::s_currentFocus->Sub963390();
|
|
// }
|
|
|
|
CSimpleEditBox::s_currentFocus->RunOnEditFocusLostScript();
|
|
CSimpleEditBox::s_currentFocus->m_dirtyFlags |= 0x4;
|
|
}
|
|
|
|
CSimpleEditBox::s_currentFocus = editBox;
|
|
|
|
// TODO
|
|
// if (editBox->m_password) {
|
|
// nullsub_3();
|
|
// }
|
|
|
|
// TODO
|
|
// if (!(editBox->simpleeditbox_dword4 & 0xC)) {
|
|
// OsIMEEnable(1);
|
|
// }
|
|
|
|
editBox->RunOnEditFocusGainedScript();
|
|
editBox->m_dirtyFlags |= 0x4;
|
|
}
|
|
|
|
CSimpleEditBox::CSimpleEditBox(CSimpleFrame* parent) : CSimpleFrame(parent) {
|
|
this->m_autoFocus = 1;
|
|
this->m_multiline = 0;
|
|
this->m_numeric = 0;
|
|
this->m_password = 0;
|
|
this->m_ignoreArrows = 0;
|
|
this->m_countInvisibleLetters = 0;
|
|
|
|
char* text = static_cast<char*>(SMemAlloc(this->m_textSize, __FILE__, __LINE__, 0));
|
|
text[0] = 0;
|
|
this->m_text = text;
|
|
|
|
uint32_t* textInfo = static_cast<uint32_t*>(SMemAlloc(sizeof(uint32_t) * this->m_textSize, __FILE__, __LINE__, 0));
|
|
memset(textInfo, 0, sizeof(uint32_t) * this->m_textSize);
|
|
this->m_textInfo = textInfo;
|
|
|
|
auto fontMem = SMemAlloc(sizeof(CSimpleFontedFrameFont), __FILE__, __LINE__, 0x0);
|
|
auto font = new (fontMem) CSimpleFontedFrameFont(this);
|
|
this->m_font = font;
|
|
|
|
this->m_font->m_attributes.SetJustifyH(0x1);
|
|
|
|
// TODO
|
|
// auto stringMem = CDataAllocator::GetData(CSimpleFontString::s_allocator, 0, __FILE__, __LINE__);
|
|
auto stringMem = SMemAlloc(sizeof(CSimpleFontString), __FILE__, __LINE__, 0x0);
|
|
auto string = new (stringMem) CSimpleFontString(this, DRAWLAYER_ARTWORK, 1);
|
|
this->m_string = string;
|
|
|
|
this->m_string->SetFontObject(this->m_font);
|
|
|
|
this->SetMultiLine(0);
|
|
|
|
for (int32_t i = 0; i < 3; i++) {
|
|
// TODO
|
|
// auto highlightMem = CDataAllocator::GetData(CSimpleTexture::s_allocator, 0, __FILE__, __LINE__);
|
|
auto highlightMem = SMemAlloc(sizeof(CSimpleTexture), __FILE__, __LINE__, 0x0);
|
|
auto highlight = new (highlightMem) CSimpleTexture(this, DRAWLAYER_ARTWORK, 0);
|
|
this->m_highlight[i] = highlight;
|
|
}
|
|
|
|
CImVector highlightColor = { 0x60, 0x60, 0x60, 0xFF };
|
|
|
|
for (int32_t i = 0; i < 3; i++) {
|
|
this->m_highlight[i]->SetTexture(highlightColor);
|
|
}
|
|
|
|
// TODO
|
|
// auto cursorMem = CDataAllocator::GetData(CSimpleTexture::s_allocator, 0, __FILE__, __LINE__);
|
|
auto cursorMem = SMemAlloc(sizeof(CSimpleTexture), __FILE__, __LINE__, 0x0);
|
|
auto cursor = new (cursorMem) CSimpleTexture(this, DRAWLAYER_ARTWORK_OVERLAY, 1);
|
|
cursor->Hide();
|
|
this->m_cursor = cursor;
|
|
|
|
CImVector cursorColor = { 0xFF, 0xFF, 0xFF, 0xFF };
|
|
this->m_cursor->SetTexture(cursorColor);
|
|
|
|
// TODO
|
|
// - initialize actions
|
|
|
|
this->EnableEvent(SIMPLE_EVENT_CHAR, -1);
|
|
this->EnableEvent(SIMPLE_EVENT_KEY, -1);
|
|
this->EnableEvent(SIMPLE_EVENT_MOUSE, -1);
|
|
}
|
|
|
|
int32_t CSimpleEditBox::ConvertCoordinateToIndex(float a2, float a3, int32_t& a4) {
|
|
// TODO
|
|
return 0;
|
|
}
|
|
|
|
void CSimpleEditBox::DeleteBackward(int32_t a2) {
|
|
if (this->m_highlightLeft != this->m_highlightRight) {
|
|
this->DeleteHighlight(a2);
|
|
return;
|
|
}
|
|
|
|
if (this->m_cursorPos > 0) {
|
|
int32_t len = this->GetNumToLen(this->m_cursorPos, -1, true);
|
|
this->DeleteSubstring(this->m_cursorPos - len, this->m_cursorPos, a2);
|
|
}
|
|
}
|
|
|
|
void CSimpleEditBox::DeleteForward(int32_t a2) {
|
|
if (this->m_highlightLeft != this->m_highlightRight) {
|
|
this->DeleteHighlight(a2);
|
|
return;
|
|
}
|
|
|
|
if (this->m_cursorPos < this->m_textLength) {
|
|
int32_t len = this->GetNumToLen(this->m_cursorPos, 1, true);
|
|
this->DeleteSubstring(this->m_cursorPos, this->m_cursorPos + len, a2);
|
|
}
|
|
}
|
|
|
|
void CSimpleEditBox::DeleteHighlight(int32_t a2) {
|
|
// TODO
|
|
}
|
|
|
|
void CSimpleEditBox::DeleteSubstring(int32_t left, int32_t right, int32_t a4) {
|
|
auto v5 = this->m_textInfo;
|
|
auto v6 = left;
|
|
|
|
if ((v5[left] & 0x80000000) != 0) {
|
|
auto v7 = left;
|
|
|
|
if (left >= 0) {
|
|
LABEL_3:
|
|
auto v8 = BYTE2(v5[v6]);
|
|
auto v9 = &v5[v6];
|
|
|
|
if (v8 == 1 || v8 == 5 || v8 == 7) {
|
|
if (v6 >= 0) {
|
|
LABEL_12:
|
|
auto v10 = BYTE2(v5[v6]);
|
|
auto v11 = &v5[v6];
|
|
|
|
if (v10 == 1 || v10 == 5 || v10 == 7) {
|
|
v7 = v6;
|
|
|
|
while (1) {
|
|
v6--;
|
|
v11--;
|
|
|
|
if (v6 < 0) {
|
|
break;
|
|
}
|
|
|
|
if (*v11) {
|
|
if (v6 >= 0) {
|
|
goto LABEL_12;
|
|
}
|
|
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
} else {
|
|
v7 = v6;
|
|
|
|
while (1) {
|
|
v6--;
|
|
v9--;
|
|
|
|
if (v6 < 0) {
|
|
break;
|
|
}
|
|
|
|
if (*v9) {
|
|
if (v6 >= 0) {
|
|
goto LABEL_3;
|
|
}
|
|
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
v6 = v7;
|
|
}
|
|
|
|
auto v12 = right;
|
|
if ((v5[right] & 0x80000000) != 0) {
|
|
auto v13 = this->m_textLength;
|
|
|
|
if (right < v13) {
|
|
do {
|
|
auto v14 = BYTE2(v5[v12]);
|
|
|
|
if (v14 == 2 || v14 == 6 || v14 == 8) {
|
|
break;
|
|
}
|
|
|
|
v12 += v5[v12] & 0xFFFF;
|
|
} while (v12 < v13);
|
|
|
|
for (; v12 < v13; v12 += v5[v12] & 0xFFFF) {
|
|
auto v15 = BYTE2(v5[v12]);
|
|
|
|
if (v15 != 2 && v15 != 6 && v15 != 8) {
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
auto v16 = v12 - v6;
|
|
auto v17 = &this->m_text[v6];
|
|
auto newLength = this->m_textLength - (v12 - v6);
|
|
|
|
this->m_cursorPos = v6;
|
|
|
|
auto v19 = &v5[v6];
|
|
|
|
if (newLength >= 0) {
|
|
this->m_textLength = newLength;
|
|
|
|
memcpy(v17, &v17[v16], newLength - v6);
|
|
memcpy(v19, &v19[v16], 4 * (this->m_textLength - this->m_cursorPos));
|
|
|
|
this->m_text[this->m_textLength] = '\0';
|
|
this->m_textInfo[this->m_textLength] = '\0';
|
|
|
|
if (this->m_highlightLeft != this->m_highlightRight) {
|
|
this->m_dirtyFlags |= 0x2;
|
|
|
|
this->m_highlightRight = 0;
|
|
this->m_highlightLeft = 0;
|
|
}
|
|
|
|
this->m_dirtyFlags |= 0x1 | 0x4;
|
|
|
|
if (!a4) {
|
|
this->m_dirtyFlags |= 0x8;
|
|
}
|
|
|
|
if (!this->m_textLength) {
|
|
// TODO this->simpleeditbox_dwordC = 0;
|
|
}
|
|
}
|
|
}
|
|
|
|
void CSimpleEditBox::FontUpdated(CSimpleFontedFrameFont* font, int32_t a3) {
|
|
// TODO
|
|
}
|
|
|
|
int32_t CSimpleEditBox::GetNumToLen(int32_t offset, int32_t amount, bool a4) {
|
|
uint32_t len = 0;
|
|
uint32_t* textInfo = this->m_textInfo + offset;
|
|
|
|
if (amount > 0) {
|
|
for (int32_t i = 0; i < amount; i++) {
|
|
if (!*textInfo) {
|
|
break;
|
|
}
|
|
|
|
uint32_t v8;
|
|
uint32_t v9;
|
|
uint32_t v10;
|
|
|
|
do {
|
|
do {
|
|
v8 = *((uint8_t*)textInfo + 2);
|
|
v9 = (uint16_t)*textInfo;
|
|
v10 = *textInfo & 0xFF000000;
|
|
|
|
len += v9;
|
|
textInfo += v9;
|
|
} while (v8 == 1);
|
|
} while (v8 == 5 || v8 == 7 || (a4 && v10 < 0 && v8 != 6));
|
|
|
|
uint32_t v11;
|
|
uint32_t v12;
|
|
|
|
while (1) {
|
|
v11 = *((uint8_t*)textInfo + 2);
|
|
v12 = *textInfo & 0xFFFF;
|
|
|
|
if (v11 != 2 && v11 != 6 && v11 != 8) {
|
|
break;
|
|
}
|
|
|
|
len += v12;
|
|
textInfo += v12;
|
|
}
|
|
}
|
|
} else {
|
|
for (int32_t i = 0; i < -amount; i++) {
|
|
if (textInfo <= this->m_textInfo) {
|
|
break;
|
|
}
|
|
|
|
uint32_t v14;
|
|
|
|
do {
|
|
for (--textInfo; textInfo > this->m_textInfo; --textInfo) {
|
|
if (*textInfo) {
|
|
break;
|
|
}
|
|
}
|
|
|
|
v14 = *((uint8_t*)textInfo + 2);
|
|
len += (uint16_t)*textInfo;
|
|
} while (v14 == 2 || v14 == 6 || v14 == 8 || (a4 && (*textInfo & 0x80000000) != 0 && v14 != 5));
|
|
|
|
if (textInfo > this->m_textInfo) {
|
|
uint32_t v15;
|
|
uint32_t v16;
|
|
|
|
while (1) {
|
|
for (--textInfo; textInfo > this->m_textInfo; --textInfo) {
|
|
if (*textInfo) {
|
|
break;
|
|
}
|
|
}
|
|
|
|
v15 = *((uint8_t*)textInfo + 2);
|
|
v16 = *textInfo & 0xFFFF;
|
|
|
|
if (v15 != 1 && v15 != 5 && v15 != 7) {
|
|
break;
|
|
}
|
|
|
|
len += v16;
|
|
|
|
if (textInfo <= this->m_textInfo) {
|
|
break;
|
|
}
|
|
}
|
|
|
|
if (textInfo > this->m_textInfo) {
|
|
textInfo += v16;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
return len;
|
|
}
|
|
|
|
FrameScript_Object::ScriptIx* CSimpleEditBox::GetScriptByName(const char* name, ScriptData& data) {
|
|
auto parentScript = CSimpleFrame::GetScriptByName(name, data);
|
|
|
|
if (parentScript) {
|
|
return parentScript;
|
|
}
|
|
|
|
if (!SStrCmpI(name, "OnEnterPressed", STORM_MAX_STR)) {
|
|
return &this->m_onEnterPressed;
|
|
}
|
|
|
|
if (!SStrCmpI(name, "OnEscapePressed", STORM_MAX_STR)) {
|
|
return &this->m_onEscapePressed;
|
|
}
|
|
|
|
if (!SStrCmpI(name, "OnSpacePressed", STORM_MAX_STR)) {
|
|
return &this->m_onSpacePressed;
|
|
}
|
|
|
|
if (!SStrCmpI(name, "OnTabPressed", STORM_MAX_STR)) {
|
|
return &this->m_onTabPressed;
|
|
}
|
|
|
|
if (!SStrCmpI(name, "OnTextChanged", STORM_MAX_STR)) {
|
|
data.wrapper = "return function(self, userInput) %s end";
|
|
return &this->m_onTextChanged;
|
|
}
|
|
|
|
if (!SStrCmpI(name, "OnTextSet", STORM_MAX_STR)) {
|
|
return &this->m_onTextSet;
|
|
}
|
|
|
|
if (!SStrCmpI(name, "OnCursorChanged", STORM_MAX_STR)) {
|
|
data.wrapper = "return function(self,x,y,w,h) %s end";
|
|
return &this->m_onCursorChanged;
|
|
}
|
|
|
|
if (!SStrCmpI(name, "OnInputLanguageChanged", STORM_MAX_STR)) {
|
|
data.wrapper = "return function(self,language) %s end";
|
|
return &this->m_onInputLanguageChanged;
|
|
}
|
|
|
|
if (!SStrCmpI(name, "OnEditFocusGained", STORM_MAX_STR)) {
|
|
return &this->m_onEditFocusGained;
|
|
}
|
|
|
|
if (!SStrCmpI(name, "OnEditFocusLost", STORM_MAX_STR)) {
|
|
return &this->m_onEditFocusLost;
|
|
}
|
|
|
|
if (!SStrCmpI(name, "OnCharComposition", STORM_MAX_STR)) {
|
|
data.wrapper = "return function(self,text) %s end";
|
|
return &this->m_onCharComposition;
|
|
}
|
|
|
|
return nullptr;
|
|
}
|
|
|
|
int32_t CSimpleEditBox::GetScriptMetaTable() {
|
|
return CSimpleEditBox::s_metatable;
|
|
}
|
|
|
|
void CSimpleEditBox::GrowText(int32_t size) {
|
|
if (size + 1 <= this->m_textSize) {
|
|
return;
|
|
}
|
|
|
|
this->m_textSize = (size + 32) & 0xFFFFFFE0;
|
|
|
|
this->m_text = static_cast<char*>(
|
|
SMemReAlloc(this->m_text, this->m_textSize, __FILE__, __LINE__, 0)
|
|
);
|
|
|
|
this->m_textInfo = static_cast<uint32_t*>(
|
|
SMemReAlloc(this->m_textInfo, this->m_textSize * sizeof(uint32_t), __FILE__, __LINE__, 0)
|
|
);
|
|
}
|
|
|
|
void CSimpleEditBox::Insert(uint32_t chr) {
|
|
if (chr == '\t') {
|
|
this->Insert(" ", nullptr, 1, 0, 0);
|
|
return;
|
|
}
|
|
|
|
if (chr == '|') {
|
|
this->Insert("||", nullptr, 1, 0, 0);
|
|
return;
|
|
}
|
|
|
|
if ((this->m_multiline && chr == '\n') || (chr >= ' ' && chr != 127)) {
|
|
char charBuf[8];
|
|
SUniSPutUTF8(chr, charBuf);
|
|
|
|
this->Insert(charBuf, nullptr, 1, 0, 0);
|
|
return;
|
|
}
|
|
}
|
|
|
|
void CSimpleEditBox::Insert(const char* a2, const char* a3, int32_t a4, int32_t a5, int32_t a6) {
|
|
if (
|
|
(this->m_textInfo[this->m_cursorPos] & 0x80000000)
|
|
&& this->m_cursorPos > 0
|
|
&& (this->m_textInfo[this->PrevCharOffset(this->m_cursorPos)] & 0x80000000)
|
|
) {
|
|
return;
|
|
}
|
|
|
|
if (this->m_highlightLeft != this->m_highlightRight) {
|
|
this->DeleteHighlight(a6);
|
|
}
|
|
|
|
if (!a2) {
|
|
a2 = "";
|
|
}
|
|
|
|
const char* v10 = a2;
|
|
|
|
if (this->m_numeric && !a5 && *v10) {
|
|
while (*v10) {
|
|
int32_t v33;
|
|
|
|
if (SUniSGetUTF8(reinterpret_cast<const uint8_t*>(a2), &v33) - 48 > 9) {
|
|
return;
|
|
}
|
|
|
|
v10 += v33;
|
|
}
|
|
}
|
|
|
|
int32_t v11 = SStrLen(a2);
|
|
|
|
this->GrowText(this->m_textLength + v11);
|
|
|
|
char* v14 = this->m_text + this->m_cursorPos;
|
|
|
|
if (this->m_cursorPos < this->m_textLength) {
|
|
memcpy(v14 + v11, v14, this->m_textLength - this->m_cursorPos);
|
|
}
|
|
|
|
memcpy(v14, a2, v11);
|
|
|
|
this->m_textLength += v11;
|
|
*(this->m_text + this->m_textLength) = 0;
|
|
|
|
int32_t v31 = this->m_cursorPos;
|
|
this->m_cursorPos += v11;
|
|
|
|
this->UpdateTextInfo();
|
|
|
|
this->m_dirtyFlags |= (0x1 | 0x4);
|
|
a6 ? this->m_dirtyFlags &= ~0x8 : this->m_dirtyFlags |= 0x8;
|
|
|
|
if (this->m_textLengthMax >= 0 && this->m_textLength > this->m_textLengthMax) {
|
|
// TODO
|
|
}
|
|
|
|
if (this->m_textLettersMax) {
|
|
// TODO
|
|
}
|
|
|
|
if (a5) {
|
|
this->m_highlightLeft = v31;
|
|
this->m_highlightRight = std::min(this->m_textLength, this->m_cursorPos);
|
|
this->m_dirtyFlags |= 2u;
|
|
}
|
|
|
|
// TODO
|
|
// if (!this->m_intC && this->m_textLength > 0) {
|
|
// this->m_intC = a3;
|
|
// }
|
|
|
|
if (a4) {
|
|
this->RunOnCharScript(a2);
|
|
|
|
// TODO
|
|
// - check for spaces and run onSpacePressed script
|
|
}
|
|
}
|
|
|
|
bool CSimpleEditBox::IsA(int32_t type) {
|
|
return type == CSimpleEditBox::s_objectType
|
|
|| type == CSimpleFrame::s_objectType
|
|
|| type == CScriptRegion::s_objectType
|
|
|| type == CScriptObject::s_objectType;
|
|
}
|
|
|
|
int32_t CSimpleEditBox::IsCurrentFocus() {
|
|
return this == CSimpleEditBox::s_currentFocus;
|
|
}
|
|
|
|
void CSimpleEditBox::LoadXML(XMLNode* node, CStatus* status) {
|
|
CSimpleFrame::LoadXML(node, status);
|
|
|
|
const char* fontAttr = node->GetAttributeByName("font");
|
|
if (fontAttr && *fontAttr) {
|
|
auto font = CSimpleFont::GetFont(fontAttr, 0);
|
|
|
|
if (font) {
|
|
this->m_font->SetFontObject(font);
|
|
} else {
|
|
status->Add(
|
|
STATUS_WARNING,
|
|
"%s %s: Couldn't find font object named %s",
|
|
this->GetObjectTypeName(),
|
|
this->GetDisplayName(),
|
|
fontAttr
|
|
);
|
|
}
|
|
}
|
|
|
|
// TODO
|
|
// - letters
|
|
|
|
const char* countInvisibleLettersAttr = node->GetAttributeByName("countInvisibleLetters");
|
|
if (countInvisibleLettersAttr && *countInvisibleLettersAttr) {
|
|
this->m_countInvisibleLetters = StringToBOOL(countInvisibleLettersAttr);
|
|
}
|
|
|
|
const char* blinkSpeedAttr = node->GetAttributeByName("blinkSpeed");
|
|
if (blinkSpeedAttr && *blinkSpeedAttr) {
|
|
float blinkSpeed = std::max(SStrToFloat(blinkSpeedAttr), 0.0f);
|
|
this->m_cursorBlinkSpeed = blinkSpeed;
|
|
}
|
|
|
|
const char* autoFocusAttr = node->GetAttributeByName("autoFocus");
|
|
if (autoFocusAttr && *autoFocusAttr) {
|
|
this->m_autoFocus = StringToBOOL(autoFocusAttr);
|
|
}
|
|
|
|
const char* multiLineAttr = node->GetAttributeByName("multiLine");
|
|
if (multiLineAttr && *multiLineAttr) {
|
|
this->m_multiline = StringToBOOL(multiLineAttr);
|
|
}
|
|
|
|
const char* numericAttr = node->GetAttributeByName("numeric");
|
|
if (numericAttr && *numericAttr) {
|
|
this->m_numeric = StringToBOOL(numericAttr);
|
|
}
|
|
|
|
const char* passwordAttr = node->GetAttributeByName("password");
|
|
if (passwordAttr && *passwordAttr) {
|
|
this->m_password = StringToBOOL(passwordAttr);
|
|
}
|
|
|
|
const char* ignoreArrowsAttr = node->GetAttributeByName("ignoreArrows");
|
|
if (ignoreArrowsAttr && *ignoreArrowsAttr) {
|
|
this->m_ignoreArrows = StringToBOOL(ignoreArrowsAttr);
|
|
}
|
|
|
|
const char* historyLinesAttr = node->GetAttributeByName("historyLines");
|
|
if (historyLinesAttr && *historyLinesAttr) {
|
|
int32_t historyLines = std::max(SStrToInt(historyLinesAttr), 0);
|
|
this->SetHistoryLines(historyLines);
|
|
}
|
|
|
|
for (XMLNode* child = node->m_child; child; child = child->m_next) {
|
|
if (!SStrCmpI(child->GetName(), "FontString", STORM_MAX_STR)) {
|
|
CSimpleFont* font = this->m_font;
|
|
|
|
if (font->GetFontObject()) {
|
|
status->Add(
|
|
STATUS_WARNING,
|
|
"%s: FontString element overriding font %s",
|
|
this->GetDisplayName(),
|
|
font->GetFontObject()->GetName()
|
|
);
|
|
}
|
|
|
|
this->m_font->LoadXML(child, status);
|
|
|
|
const char* bytesAttr = child->GetAttributeByName("bytes");
|
|
if (bytesAttr && *bytesAttr) {
|
|
int32_t bytes = SStrToInt(bytesAttr);
|
|
|
|
// TODO
|
|
// - set some member of CSimpleEditBox
|
|
}
|
|
|
|
} else if (!SStrCmpI(child->GetName(), "HighlightColor", STORM_MAX_STR)) {
|
|
// TODO
|
|
|
|
} else if (!SStrCmpI(child->GetName(), "TextInsets", STORM_MAX_STR)) {
|
|
float left, right, top, bottom;
|
|
|
|
if (LoadXML_Insets(child, left, right, top, bottom, status)) {
|
|
this->m_editTextInset.minX = left;
|
|
this->m_editTextInset.maxX = right;
|
|
this->m_editTextInset.maxY = top;
|
|
this->m_editTextInset.minY = bottom;
|
|
|
|
this->UpdateSizes();
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
void CSimpleEditBox::Move(int32_t distance, int32_t highlight) {
|
|
STORM_ASSERT(distance);
|
|
|
|
auto offset = this->GetNumToLen(this->m_cursorPos, distance, true);
|
|
if (distance < 0) {
|
|
offset = -offset;
|
|
}
|
|
|
|
if (highlight) {
|
|
if (this->m_highlightLeft == this->m_highlightRight) {
|
|
this->m_highlightLeft = this->m_cursorPos;
|
|
this->m_highlightRight = this->m_cursorPos;
|
|
}
|
|
|
|
// TODO this->Sub9631A0(offset);
|
|
|
|
this->m_cursorPos += offset;
|
|
this->m_dirtyFlags |= 0x4;
|
|
} else {
|
|
if (this->m_highlightLeft != this->m_highlightRight) {
|
|
this->m_dirtyFlags |= 0x2;
|
|
this->m_highlightLeft = 0;
|
|
this->m_highlightRight = 0;
|
|
}
|
|
|
|
this->m_cursorPos += offset;
|
|
this->m_dirtyFlags |= 0x4;
|
|
}
|
|
}
|
|
|
|
void CSimpleEditBox::MoveBackward(int32_t highlight) {
|
|
if (this->m_cursorPos > 0) {
|
|
this->Move(-1, highlight);
|
|
}
|
|
|
|
if (!highlight && this->m_highlightLeft != this->m_highlightRight) {
|
|
this->m_dirtyFlags |= 0x2;
|
|
this->m_highlightLeft = 0;
|
|
this->m_highlightRight = 0;
|
|
}
|
|
}
|
|
|
|
void CSimpleEditBox::MoveForward(int32_t highlight) {
|
|
if (this->m_cursorPos < this->m_textLength) {
|
|
this->Move(1, highlight);
|
|
}
|
|
|
|
if (!highlight && this->m_highlightLeft != this->m_highlightRight) {
|
|
this->m_dirtyFlags |= 0x2;
|
|
this->m_highlightLeft = 0;
|
|
this->m_highlightRight = 0;
|
|
}
|
|
}
|
|
|
|
void CSimpleEditBox::OnEnterPressed() {
|
|
this->RunOnEnterPressedScript();
|
|
|
|
// TODO
|
|
// - invoke action
|
|
}
|
|
|
|
void CSimpleEditBox::OnEscapePressed() {
|
|
// TODO
|
|
}
|
|
|
|
void CSimpleEditBox::OnFrameSizeChanged(float width, float height) {
|
|
CSimpleFrame::OnFrameSizeChanged(width, height);
|
|
this->UpdateSizes();
|
|
}
|
|
|
|
int32_t CSimpleEditBox::OnLayerChar(const CCharEvent& evt) {
|
|
if (!this->m_visible) {
|
|
return 0;
|
|
}
|
|
|
|
if (!CSimpleEditBox::s_currentFocus && this->m_autoFocus) {
|
|
CSimpleEditBox::SetKeyboardFocus(this);
|
|
} else if (!this->IsCurrentFocus()) {
|
|
return 0;
|
|
}
|
|
|
|
this->m_imeInputMode = 0;
|
|
|
|
this->Insert(evt.ch);
|
|
|
|
return 1;
|
|
}
|
|
|
|
int32_t CSimpleEditBox::OnLayerKeyDown(const CKeyEvent& evt) {
|
|
if (!this->m_visible) {
|
|
return 0;
|
|
}
|
|
|
|
if (evt.key == KEY_PRINTSCREEN
|
|
|| (
|
|
this->m_ignoreArrows
|
|
&& (evt.key == KEY_LEFT || evt.key == KEY_RIGHT || evt.key == KEY_UP || evt.key == KEY_DOWN)
|
|
&& !EventIsKeyDown(KEY_LALT)
|
|
&& !EventIsKeyDown(KEY_RALT)
|
|
)
|
|
) {
|
|
return 0;
|
|
}
|
|
|
|
if (!CSimpleEditBox::s_currentFocus && this->m_autoFocus) {
|
|
CSimpleEditBox::SetKeyboardFocus(this);
|
|
} else if (!this->IsCurrentFocus()) {
|
|
return 0;
|
|
}
|
|
|
|
this->UpdateDirtyBits();
|
|
|
|
switch (evt.key) {
|
|
case KEY_ESCAPE: {
|
|
this->OnEscapePressed();
|
|
return 1;
|
|
}
|
|
|
|
case KEY_ENTER: {
|
|
if (!this->m_multiline || this->m_onEnterPressed.luaRef) {
|
|
// TODO
|
|
// this->m_top->m_int1250 = 1;
|
|
|
|
this->OnEnterPressed();
|
|
|
|
// TODO
|
|
// this->m_top->m_int1250 = 0;
|
|
} else {
|
|
this->Insert("\n", 0, 1, 0, 0);
|
|
}
|
|
|
|
return 1;
|
|
}
|
|
|
|
case KEY_BACKSPACE: {
|
|
if (EventIsControlKeyDown()) {
|
|
// TODO this->DeleteBackwardWord(0);
|
|
} else {
|
|
this->DeleteBackward(0);
|
|
}
|
|
|
|
return 1;
|
|
}
|
|
|
|
case KEY_LEFT: {
|
|
if (EventIsControlKeyDown()) {
|
|
// TODO this->MoveBackwardWord(EventIsShiftKeyDown());
|
|
} else {
|
|
this->MoveBackward(EventIsShiftKeyDown());
|
|
}
|
|
|
|
return 1;
|
|
}
|
|
|
|
case KEY_RIGHT: {
|
|
if (EventIsControlKeyDown()) {
|
|
// TODO this->MoveForwardWord(EventIsShiftKeyDown());
|
|
} else {
|
|
this->MoveForward(EventIsShiftKeyDown());
|
|
}
|
|
|
|
return 1;
|
|
}
|
|
|
|
case KEY_DELETE: {
|
|
if (EventIsShiftKeyDown()) {
|
|
// TODO cut to clipboard
|
|
} else if (EventIsControlKeyDown()) {
|
|
// TODO this->DeleteForwardWord(0);
|
|
} else {
|
|
this->DeleteForward(0);
|
|
}
|
|
|
|
return 1;
|
|
}
|
|
|
|
// TODO
|
|
// - remaining keys
|
|
|
|
default:
|
|
return 1;
|
|
}
|
|
}
|
|
|
|
int32_t CSimpleEditBox::OnLayerMouseDown(const CMouseEvent& evt, const char* btn) {
|
|
int32_t eaten = CSimpleFrame::OnLayerMouseDown(evt, btn);
|
|
|
|
if (!eaten) {
|
|
this->UpdateDirtyBits();
|
|
|
|
int32_t position;
|
|
|
|
if (!this->m_imeInputMode && this->ConvertCoordinateToIndex(evt.x, evt.y, position)) {
|
|
if (this->m_highlightLeft != this->m_highlightRight) {
|
|
this->m_dirtyFlags |= 0x2;
|
|
this->m_highlightRight = 0;
|
|
this->m_highlightLeft = 0;
|
|
}
|
|
|
|
this->SetCursorPosition(position);
|
|
|
|
this->StartHighlight();
|
|
this->m_highlightDrag = 1;
|
|
|
|
eaten = 1;
|
|
}
|
|
|
|
CSimpleEditBox::SetKeyboardFocus(this);
|
|
}
|
|
|
|
return eaten;
|
|
}
|
|
|
|
int32_t CSimpleEditBox::OnLayerMouseUp(const CMouseEvent& evt, const char* btn) {
|
|
int32_t eaten = CSimpleFrame::OnLayerMouseUp(evt, btn);
|
|
|
|
if (!eaten) {
|
|
if (this->m_highlightDrag) {
|
|
this->m_highlightDrag = 0;
|
|
eaten = 1;
|
|
}
|
|
}
|
|
|
|
return eaten;
|
|
}
|
|
|
|
void CSimpleEditBox::OnLayerUpdate(float elapsedSec) {
|
|
CSimpleFrame::OnLayerUpdate(elapsedSec);
|
|
|
|
this->UpdateDirtyBits();
|
|
|
|
if (!GxCapsWindowHasFocus(-1)) {
|
|
this->m_cursor->Hide();
|
|
return;
|
|
}
|
|
|
|
if (this->m_cursorBlinkSpeed == 0.0f) {
|
|
return;
|
|
}
|
|
|
|
bool cursorVisible = this->m_cursorPos >= this->m_visiblePos
|
|
&& this->m_cursorPos <= this->m_visiblePos + this->m_visibleLen;
|
|
|
|
if (!cursorVisible) {
|
|
return;
|
|
}
|
|
|
|
this->m_blinkElapsedTime += elapsedSec;
|
|
|
|
if (this->IsCurrentFocus() && this->m_blinkElapsedTime > this->m_cursorBlinkSpeed) {
|
|
if (this->m_cursor->IsShown()) {
|
|
this->m_cursor->Hide();
|
|
} else {
|
|
this->m_cursor->Show();
|
|
}
|
|
|
|
this->m_blinkElapsedTime = 0.0f;
|
|
}
|
|
}
|
|
|
|
void CSimpleEditBox::OnTextChanged() {
|
|
this->RunOnTextChangedScript((this->m_dirtyFlags & 0x8) != 0);
|
|
|
|
// TODO
|
|
// - invoke action
|
|
}
|
|
|
|
int32_t CSimpleEditBox::PrevCharOffset(int32_t offset) {
|
|
int32_t prevCharOffset = offset;
|
|
|
|
while (prevCharOffset > 0 && !this->m_textInfo[prevCharOffset - 1]) {
|
|
prevCharOffset--;
|
|
}
|
|
|
|
return prevCharOffset;
|
|
}
|
|
|
|
void CSimpleEditBox::RunOnCursorChangedScript(float x, float y, float w, float h) {
|
|
// TODO
|
|
}
|
|
|
|
void CSimpleEditBox::RunOnEditFocusGainedScript() {
|
|
if (this->m_onEditFocusGained.luaRef) {
|
|
this->RunScript(this->m_onEditFocusGained, 0, 0);
|
|
}
|
|
}
|
|
|
|
void CSimpleEditBox::RunOnEditFocusLostScript() {
|
|
if (this->m_onEditFocusLost.luaRef) {
|
|
this->RunScript(this->m_onEditFocusLost, 0, 0);
|
|
}
|
|
}
|
|
|
|
void CSimpleEditBox::RunOnEnterPressedScript() {
|
|
if (this->m_onEnterPressed.luaRef) {
|
|
this->RunScript(this->m_onEnterPressed, 0, 0);
|
|
}
|
|
}
|
|
|
|
void CSimpleEditBox::RunOnTextChangedScript(int32_t changed) {
|
|
if (this->m_onTextChanged.luaRef) {
|
|
auto L = FrameScript_GetContext();
|
|
lua_pushboolean(L, changed);
|
|
|
|
this->RunScript(this->m_onTextChanged, 1, 0);
|
|
}
|
|
}
|
|
|
|
void CSimpleEditBox::SetCursorPosition(int32_t position) {
|
|
if (position >= 0) {
|
|
this->m_cursorPos = std::min(this->m_textLength, position);
|
|
} else {
|
|
this->m_cursorPos = 0;
|
|
}
|
|
|
|
this->m_dirtyFlags |= 0x4;
|
|
}
|
|
|
|
void CSimpleEditBox::SetHistoryLines(int32_t a2) {
|
|
// TODO
|
|
}
|
|
|
|
void CSimpleEditBox::SetMultiLine(int32_t enabled) {
|
|
if (enabled) {
|
|
this->m_multiline = 1;
|
|
} else {
|
|
this->m_multiline = 0;
|
|
}
|
|
|
|
this->m_visibleLines.SetCount(2);
|
|
|
|
if (this->m_multiline) {
|
|
this->m_string->SetJustifyV(0x8);
|
|
|
|
// TODO
|
|
// - unknown style change (remove flag 0x4000)
|
|
|
|
this->m_string->SetNonWordWrap(0);
|
|
} else {
|
|
this->m_string->SetJustifyV(0x10);
|
|
|
|
// TODO
|
|
// - unknown style change (add flag 0x4000)
|
|
|
|
this->m_string->SetNonWordWrap(1);
|
|
}
|
|
|
|
this->m_string->SetNonSpaceWrap(1);
|
|
|
|
this->UpdateSizes();
|
|
}
|
|
|
|
void CSimpleEditBox::StartHighlight() {
|
|
// TODO
|
|
}
|
|
|
|
void CSimpleEditBox::UpdateDirtyBits() {
|
|
int32_t textChanged = this->m_dirtyFlags & 0x1;
|
|
|
|
if (this->m_dirtyFlags & 0x4) {
|
|
// TODO
|
|
}
|
|
|
|
if (this->m_dirtyFlags & 0x1) {
|
|
this->m_dirtyFlags &= ~0x1;
|
|
this->UpdateVisibleText();
|
|
}
|
|
|
|
if (this->m_dirtyFlags & 0x2) {
|
|
this->m_dirtyFlags &= ~0x2;
|
|
this->UpdateVisibleHighlight();
|
|
}
|
|
|
|
if (this->m_dirtyFlags & 0x4) {
|
|
this->m_dirtyFlags &= ~0x4;
|
|
this->UpdateVisibleCursor();
|
|
}
|
|
|
|
if (textChanged) {
|
|
this->OnTextChanged();
|
|
this->m_dirtyFlags &= ~0x8;
|
|
}
|
|
}
|
|
|
|
void CSimpleEditBox::UpdateSizes() {
|
|
if (!(CLayoutFrame::m_flags & 0x1)) {
|
|
return;
|
|
}
|
|
|
|
this->m_string->ClearAllPoints();
|
|
|
|
float stringWidth = ((this->m_rect.maxX - this->m_rect.minX) / this->m_layoutScale)
|
|
- (this->m_editTextInset.maxX + this->m_editTextInset.minX);
|
|
|
|
this->m_string->SetWidth(stringWidth);
|
|
|
|
float stringHeight = 0.0f;
|
|
|
|
if (!this->m_multiline) {
|
|
stringHeight = ((this->m_rect.maxY - this->m_rect.minY) / this->m_layoutScale)
|
|
- (this->m_editTextInset.maxY + this->m_editTextInset.minY);
|
|
}
|
|
|
|
this->m_string->SetHeight(stringHeight);
|
|
|
|
this->m_string->SetPoint(
|
|
FRAMEPOINT_TOPLEFT,
|
|
this,
|
|
FRAMEPOINT_TOPLEFT,
|
|
this->m_editTextInset.minX,
|
|
-this->m_editTextInset.maxY,
|
|
1
|
|
);
|
|
|
|
float fontHeight = this->m_string->GetFontHeight(1);
|
|
|
|
for (int32_t i = 0; i < 3; i++) {
|
|
// TODO
|
|
// - highlight sizing
|
|
}
|
|
|
|
// TODO
|
|
// - clause highlight? sizing
|
|
|
|
float v13 = 4.0f / (CoordinateGetAspectCompensation() * 1024.0f);
|
|
float cursorWidth = NDCToDDCWidth(v13);
|
|
|
|
this->m_cursor->ClearAllPoints();
|
|
this->m_cursor->SetWidth(cursorWidth);
|
|
this->m_cursor->SetHeight(fontHeight);
|
|
|
|
this->m_dirtyFlags |= (0x1 | 0x2 | 0x4);
|
|
}
|
|
|
|
void CSimpleEditBox::UpdateTextInfo() {
|
|
memset(this->m_textInfo, 0, this->m_textSize * sizeof(uint32_t));
|
|
|
|
uint32_t i = 0;
|
|
uint32_t v9 = 0;
|
|
int32_t advance;
|
|
uint32_t code;
|
|
|
|
const char* text = this->m_text;
|
|
|
|
while (text && *text) {
|
|
QUOTEDCODE quotedCode = GxuDetermineQuotedCode(text, advance, nullptr, 0, code);
|
|
|
|
if (quotedCode == CODE_HYPERLINKSTART) {
|
|
v9 |= 0x80000000;
|
|
}
|
|
|
|
this->m_textInfo[i] = v9 | (quotedCode << 16) | static_cast<uint16_t>(advance);
|
|
|
|
if (quotedCode == CODE_HYPERLINKSTOP) {
|
|
v9 &= 0x7FFFFFFF;
|
|
}
|
|
|
|
i += advance;
|
|
text += advance;
|
|
}
|
|
}
|
|
|
|
void CSimpleEditBox::UpdateVisibleCursor() {
|
|
bool cursorVisible = this->m_cursorPos >= this->m_visiblePos
|
|
&& this->m_cursorPos <= this->m_visiblePos + this->m_visibleLen;
|
|
|
|
if (!cursorVisible) {
|
|
this->m_cursor->Hide();
|
|
return;
|
|
}
|
|
|
|
const char* text = this->m_password
|
|
? this->m_textHidden
|
|
: this->m_text;
|
|
|
|
float cursorX = 0.0f;
|
|
float cursorY = 0.0f;
|
|
|
|
float v8 = CSimpleTop::RoundToPixelHeight(this->m_string->GetFontHeight(1) * this->m_layoutScale);
|
|
float v10 = CSimpleTop::RoundToPixelHeight(this->m_string->m_spacing * this->m_layoutScale);
|
|
float v13 = (v10 + v8) / this->m_layoutScale;
|
|
|
|
int32_t cursorPos = this->m_cursorPos;
|
|
int32_t line = 0;
|
|
|
|
while (cursorPos >= this->m_visibleLines[line + 1] && line < this->m_visibleLines.Count() - 2) {
|
|
line++;
|
|
cursorY -= v13;
|
|
}
|
|
|
|
this->m_cursor->ClearAllPoints();
|
|
|
|
// Left aligned
|
|
if (this->m_string->m_styleFlags & 0x1) {
|
|
float v36;
|
|
|
|
if (cursorPos == this->m_visibleLines[line]) {
|
|
v36 = 0.0f;
|
|
} else {
|
|
v36 = this->m_string->GetTextWidth(
|
|
text + this->m_visibleLines[line],
|
|
cursorPos - this->m_visibleLines[line]
|
|
);
|
|
}
|
|
|
|
cursorX = v36;
|
|
|
|
if (this->m_multiline) {
|
|
this->m_cursor->SetPoint(
|
|
FRAMEPOINT_TOPLEFT,
|
|
this->m_string,
|
|
FRAMEPOINT_TOPLEFT,
|
|
cursorX,
|
|
cursorY,
|
|
1
|
|
);
|
|
} else {
|
|
this->m_cursor->SetPoint(
|
|
FRAMEPOINT_LEFT,
|
|
this->m_string,
|
|
FRAMEPOINT_LEFT,
|
|
cursorX,
|
|
cursorY,
|
|
1
|
|
);
|
|
}
|
|
|
|
// Center aligned
|
|
} else if (this->m_string->m_styleFlags & 0x2) {
|
|
float v28;
|
|
|
|
if (cursorPos == this->m_visibleLines[line]) {
|
|
v28 = 0.0f;
|
|
} else {
|
|
v28 = this->m_string->GetTextWidth(
|
|
text + this->m_visibleLines[line],
|
|
cursorPos - this->m_visibleLines[line]
|
|
);
|
|
}
|
|
|
|
float v29 = this->m_string->GetTextWidth(
|
|
text + this->m_visibleLines[line],
|
|
this->m_visibleLines[line + 1] - this->m_visibleLines[line]
|
|
);
|
|
|
|
cursorX = (v28 - v29) / 2.0f;
|
|
|
|
if (this->m_multiline) {
|
|
this->m_cursor->SetPoint(
|
|
FRAMEPOINT_TOPLEFT,
|
|
this->m_string,
|
|
FRAMEPOINT_TOP,
|
|
cursorX,
|
|
cursorY,
|
|
1
|
|
);
|
|
} else {
|
|
this->m_cursor->SetPoint(
|
|
FRAMEPOINT_LEFT,
|
|
this->m_string,
|
|
FRAMEPOINT_CENTER,
|
|
cursorX,
|
|
cursorY,
|
|
1
|
|
);
|
|
}
|
|
|
|
// Right aligned
|
|
} else if (this->m_string->m_styleFlags & 0x4) {
|
|
// TODO
|
|
}
|
|
|
|
this->m_blinkElapsedTime = 0.0f;
|
|
|
|
float cursorWidth = this->m_cursor->GetWidth();
|
|
float cursorHeight = this->m_cursor->GetHeight();
|
|
this->RunOnCursorChangedScript(cursorX, cursorY, cursorWidth, cursorHeight);
|
|
|
|
if (this->IsCurrentFocus()) {
|
|
this->m_cursor->Show();
|
|
} else {
|
|
this->m_cursor->Hide();
|
|
}
|
|
}
|
|
|
|
void CSimpleEditBox::UpdateVisibleHighlight() {
|
|
// TODO
|
|
}
|
|
|
|
void CSimpleEditBox::UpdateVisibleText() {
|
|
float stringWidth = this->m_string->GetWidth();
|
|
|
|
// Update password mask
|
|
if (this->m_password) {
|
|
int32_t textLen = SStrLen(this->m_text);
|
|
this->m_textHidden = static_cast<char*>(
|
|
SMemReAlloc(this->m_textHidden, textLen + 1, __FILE__, __LINE__, 0)
|
|
);
|
|
memset(this->m_textHidden, '*', textLen);
|
|
this->m_textHidden[textLen] = '\0';
|
|
}
|
|
|
|
char* text = this->m_password
|
|
? this->m_textHidden
|
|
: this->m_text;
|
|
|
|
if (this->m_multiline) {
|
|
// TODO
|
|
} else {
|
|
float v16 = 4.0f / (CoordinateGetAspectCompensation() * 1024.0f);
|
|
float v17 = stringWidth - NDCToDDCWidth(v16);
|
|
if (v17 <= 0.0) {
|
|
v17 = stringWidth;
|
|
}
|
|
|
|
this->m_visibleLen = this->m_string->GetNumCharsWithinWidth(
|
|
text + this->m_visiblePos,
|
|
0,
|
|
v17
|
|
);
|
|
|
|
if (this->m_text == text) {
|
|
this->m_visibleLen = this->GetNumToLen(
|
|
this->m_visiblePos,
|
|
this->m_visibleLen,
|
|
0
|
|
);
|
|
}
|
|
|
|
this->m_visibleLines[0] = this->m_visiblePos;
|
|
this->m_visibleLines[1] = this->m_visiblePos + this->m_visibleLen;
|
|
}
|
|
|
|
if (!this->m_password) {
|
|
// TODO
|
|
}
|
|
|
|
int32_t visibleEnd = this->m_visiblePos + this->m_visibleLen;
|
|
auto v42 = text[visibleEnd];
|
|
text[visibleEnd] = '\0';
|
|
this->m_string->SetText(text + this->m_visiblePos, 0);
|
|
text[visibleEnd] = v42;
|
|
|
|
if (this->m_multiline) {
|
|
auto height = this->m_string->GetStringHeight();
|
|
if (height == 0.0f) {
|
|
height = this->m_string->GetFontHeight(1);
|
|
}
|
|
|
|
this->SetHeight(height + this->m_editTextInset.minY + this->m_editTextInset.maxY);
|
|
}
|
|
}
|