Rewrite fonticon localized string caching to fix strings being reallocated
This commit is contained in:
parent
e70b329614
commit
70bc28ee7b
@ -40,17 +40,16 @@ namespace Components
|
||||
};
|
||||
|
||||
unsigned(*TextRenderer::currentColorTable)[TEXT_COLOR_COUNT];
|
||||
TextRenderer::FontIconAutocompleteContext TextRenderer::autocompleteContextArray[FONT_ICON_ACI_COUNT]{};
|
||||
TextRenderer::FontIconAutocompleteContext TextRenderer::autocompleteContextArray[FONT_ICON_ACI_COUNT];
|
||||
std::map<std::string, TextRenderer::FontIconTableEntry> TextRenderer::fontIconLookup;
|
||||
std::vector<TextRenderer::FontIconTableEntry> TextRenderer::fontIconList;
|
||||
|
||||
TextRenderer::FormattedStringBuffer<TextRenderer::STRING_BUFFER_SIZE_BIG> TextRenderer::stringSearchStartWith;
|
||||
TextRenderer::FormattedStringBuffer<TextRenderer::STRING_BUFFER_SIZE_SMALL> TextRenderer::stringHintAutoComplete;
|
||||
TextRenderer::FormattedStringBuffer<TextRenderer::STRING_BUFFER_SIZE_SMALL> TextRenderer::stringHintModifier;
|
||||
TextRenderer::FormattedStringBuffer<TextRenderer::STRING_BUFFER_SIZE_NONE> TextRenderer::stringListHeader;
|
||||
TextRenderer::FormattedStringBuffer<TextRenderer::STRING_BUFFER_SIZE_SMALL> TextRenderer::stringListFlipHorizontal;
|
||||
TextRenderer::FormattedStringBuffer<TextRenderer::STRING_BUFFER_SIZE_SMALL> TextRenderer::stringListFlipVertical;
|
||||
TextRenderer::FormattedStringBuffer<TextRenderer::STRING_BUFFER_SIZE_SMALL> TextRenderer::stringListBig;
|
||||
TextRenderer::BufferedLocalizedString TextRenderer::stringHintAutoComplete(REFERENCE_HINT_AUTO_COMPLETE, STRING_BUFFER_SIZE_SMALL);
|
||||
TextRenderer::BufferedLocalizedString TextRenderer::stringHintModifier(REFERENCE_HINT_MODIFIER, STRING_BUFFER_SIZE_SMALL);
|
||||
TextRenderer::BufferedLocalizedString TextRenderer::stringListHeader(REFERENCE_MODIFIER_LIST_HEADER, STRING_BUFFER_SIZE_SMALL);
|
||||
TextRenderer::BufferedLocalizedString TextRenderer::stringListFlipHorizontal(REFERENCE_MODIFIER_LIST_FLIP_HORIZONTAL, STRING_BUFFER_SIZE_SMALL);
|
||||
TextRenderer::BufferedLocalizedString TextRenderer::stringListFlipVertical(REFERENCE_MODIFIER_LIST_FLIP_VERTICAL, STRING_BUFFER_SIZE_SMALL);
|
||||
TextRenderer::BufferedLocalizedString TextRenderer::stringListBig(REFERENCE_MODIFIER_LIST_BIG, STRING_BUFFER_SIZE_SMALL);
|
||||
|
||||
Dvar::Var TextRenderer::cg_newColors;
|
||||
Dvar::Var TextRenderer::cg_fontIconAutocomplete;
|
||||
@ -61,6 +60,77 @@ namespace Components
|
||||
Game::dvar_t* TextRenderer::g_ColorBlind_EnemyTeam;
|
||||
Game::dvar_t** TextRenderer::con_inputBoxColor = reinterpret_cast<Game::dvar_t**>(0x9FD4BC);
|
||||
|
||||
TextRenderer::BufferedLocalizedString::BufferedLocalizedString(const char* reference, const size_t bufferSize)
|
||||
: stringReference(reference),
|
||||
stringBuffer(std::make_unique<char[]>(bufferSize)),
|
||||
stringBufferSize(bufferSize),
|
||||
stringWidth{-1}
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void TextRenderer::BufferedLocalizedString::Cache()
|
||||
{
|
||||
const auto* formattingString = Game::UI_SafeTranslateString(stringReference);
|
||||
|
||||
if (formattingString != nullptr)
|
||||
{
|
||||
strncpy(stringBuffer.get(), formattingString, stringBufferSize);
|
||||
for (auto& width : stringWidth)
|
||||
width = -1;
|
||||
}
|
||||
}
|
||||
|
||||
const char* TextRenderer::BufferedLocalizedString::Format(const char* value)
|
||||
{
|
||||
const auto* formattingString = Game::UI_SafeTranslateString(stringReference);
|
||||
if (formattingString == nullptr)
|
||||
{
|
||||
stringBuffer[0] = '\0';
|
||||
return stringBuffer.get();
|
||||
}
|
||||
|
||||
Game::ConversionArguments conversionArguments{};
|
||||
conversionArguments.args[conversionArguments.argCount++] = value;
|
||||
Game::UI_ReplaceConversions(formattingString, &conversionArguments, stringBuffer.get(), stringBufferSize);
|
||||
|
||||
for (auto& width : stringWidth)
|
||||
width = -1;
|
||||
return stringBuffer.get();
|
||||
}
|
||||
|
||||
const char* TextRenderer::BufferedLocalizedString::GetString() const
|
||||
{
|
||||
return stringBuffer.get();
|
||||
}
|
||||
|
||||
int TextRenderer::BufferedLocalizedString::GetWidth(const FontIconAutocompleteInstance autocompleteInstance, Game::Font_s* font)
|
||||
{
|
||||
assert(autocompleteInstance < FONT_ICON_ACI_COUNT);
|
||||
if (stringWidth[autocompleteInstance] < 0)
|
||||
stringWidth[autocompleteInstance] = Game::R_TextWidth(GetString(), std::numeric_limits<int>::max(), font);
|
||||
|
||||
return stringWidth[autocompleteInstance];
|
||||
}
|
||||
|
||||
TextRenderer::FontIconAutocompleteContext::FontIconAutocompleteContext()
|
||||
: autocompleteActive(false),
|
||||
inModifiers(false),
|
||||
userClosed(false),
|
||||
lastHash(0u),
|
||||
results{},
|
||||
resultCount(0u),
|
||||
hasMoreResults(false),
|
||||
resultOffset(0u),
|
||||
lastResultOffset(0u),
|
||||
selectedOffset(0u),
|
||||
maxFontIconWidth(0.0f),
|
||||
maxMaterialNameWidth(0.0f),
|
||||
stringSearchStartWith(REFERENCE_SEARCH_START_WITH, STRING_BUFFER_SIZE_BIG)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
unsigned TextRenderer::HsvToRgb(HsvColor hsv)
|
||||
{
|
||||
unsigned rgb;
|
||||
@ -199,7 +269,7 @@ namespace Components
|
||||
}
|
||||
}
|
||||
|
||||
void TextRenderer::UpdateAutocompleteContext(TextRenderer::FontIconAutocompleteContext& context, const Game::field_t* edit, Game::Font_s* font, const float textXScale)
|
||||
void TextRenderer::UpdateAutocompleteContext(FontIconAutocompleteContext& context, const Game::field_t* edit, Game::Font_s* font, const float textXScale)
|
||||
{
|
||||
int fontIconStart = -1;
|
||||
auto inModifiers = false;
|
||||
@ -283,18 +353,24 @@ namespace Components
|
||||
context.lastHash = currentFontIconHash;
|
||||
}
|
||||
|
||||
// Update results for query and scroll
|
||||
// Update results for query and scroll and update search string
|
||||
context.lastQuery = std::string(&edit->buffer[fontIconStart], edit->cursor - fontIconStart);
|
||||
stringSearchStartWith.Format(context.lastQuery.c_str());
|
||||
context.stringSearchStartWith.Format(context.lastQuery.c_str());
|
||||
UpdateAutocompleteContextResults(context, font, textXScale);
|
||||
}
|
||||
|
||||
void TextRenderer::DrawAutocompleteModifiers(const FontIconAutocompleteContext& context, const float x, const float y, Game::Font_s* font, float textXScale, float textYScale)
|
||||
void TextRenderer::DrawAutocompleteModifiers(const FontIconAutocompleteInstance instance, const float x, const float y, Game::Font_s* font, const float textXScale, const float textYScale)
|
||||
{
|
||||
const auto textWidth = std::max(std::max(std::max(stringListHeader.GetWidth(font), stringListFlipHorizontal.GetWidth(font)),
|
||||
stringListFlipVertical.GetWidth(font)),
|
||||
stringListBig.GetWidth(font));
|
||||
const auto boxWidth = static_cast<float>(textWidth) * textXScale;
|
||||
assert(instance < FONT_ICON_ACI_COUNT);
|
||||
const auto& context = autocompleteContextArray[instance];
|
||||
|
||||
// Check which is the longest string to be able to calculate how big the box needs to be
|
||||
const auto longestStringLength = std::max(std::max(std::max(stringListHeader.GetWidth(instance, font), stringListFlipHorizontal.GetWidth(instance, font)),
|
||||
stringListFlipVertical.GetWidth(instance, font)),
|
||||
stringListBig.GetWidth(instance, font));
|
||||
|
||||
// Draw background box
|
||||
const auto boxWidth = static_cast<float>(longestStringLength) * textXScale;
|
||||
constexpr auto totalLines = 4u;
|
||||
const auto lineHeight = static_cast<float>(font->pixelHeight) * textYScale;
|
||||
DrawAutocompleteBox(context,
|
||||
@ -306,8 +382,11 @@ namespace Components
|
||||
|
||||
auto currentY = y + lineHeight;
|
||||
|
||||
// Draw header line: "Following modifiers are available:"
|
||||
Game::R_AddCmdDrawText(stringListHeader.GetString(), std::numeric_limits<int>::max(), font, x, currentY, textXScale, textYScale, 0.0, TEXT_COLOR, 0);
|
||||
currentY += lineHeight;
|
||||
|
||||
// Draw modifier hints
|
||||
Game::R_AddCmdDrawText(stringListFlipHorizontal.GetString(), std::numeric_limits<int>::max(), font, x, currentY, textXScale, textYScale, 0.0, TEXT_COLOR, 0);
|
||||
currentY += lineHeight;
|
||||
Game::R_AddCmdDrawText(stringListFlipVertical.GetString(), std::numeric_limits<int>::max(), font, x, currentY, textXScale, textYScale, 0.0, TEXT_COLOR, 0);
|
||||
@ -315,18 +394,23 @@ namespace Components
|
||||
Game::R_AddCmdDrawText(stringListBig.GetString(), std::numeric_limits<int>::max(), font, x, currentY, textXScale, textYScale, 0.0, TEXT_COLOR, 0);
|
||||
}
|
||||
|
||||
void TextRenderer::DrawAutocompleteResults(const FontIconAutocompleteContext& context, const float x, const float y, Game::Font_s* font, const float textXScale, const float textYScale)
|
||||
void TextRenderer::DrawAutocompleteResults(const FontIconAutocompleteInstance instance, const float x, const float y, Game::Font_s* font, const float textXScale, const float textYScale)
|
||||
{
|
||||
assert(instance < FONT_ICON_ACI_COUNT);
|
||||
auto& context = autocompleteContextArray[instance];
|
||||
|
||||
const auto hintEnabled = cg_fontIconAutocompleteHint.get<bool>();
|
||||
|
||||
auto longestStringLength = stringSearchStartWith.GetWidth(font);
|
||||
// Check which is the longest string to be able to calculate how big the box needs to be
|
||||
auto longestStringLength = context.stringSearchStartWith.GetWidth(instance, font);
|
||||
if(hintEnabled)
|
||||
longestStringLength = std::max(std::max(longestStringLength, stringHintAutoComplete.GetWidth(font)), stringHintModifier.GetWidth(font));
|
||||
longestStringLength = std::max(std::max(longestStringLength, stringHintAutoComplete.GetWidth(instance, font)), stringHintModifier.GetWidth(instance, font));
|
||||
|
||||
const auto colSpacing = FONT_ICON_AUTOCOMPLETE_COL_SPACING * textXScale;
|
||||
const auto boxWidth = std::max(context.maxFontIconWidth + context.maxMaterialNameWidth + colSpacing, static_cast<float>(longestStringLength) * textXScale);
|
||||
const auto lineHeight = static_cast<float>(font->pixelHeight) * textYScale;
|
||||
|
||||
// Draw background box
|
||||
const auto totalLines = 1u + context.resultCount + (hintEnabled ? 2u : 0u);
|
||||
const auto arrowPadding = context.resultOffset > 0 || context.hasMoreResults ? FONT_ICON_AUTOCOMPLETE_ARROW_SIZE : 0.0f;
|
||||
DrawAutocompleteBox(context,
|
||||
@ -336,10 +420,12 @@ namespace Components
|
||||
static_cast<float>(totalLines) * lineHeight + FONT_ICON_AUTOCOMPLETE_BOX_PADDING * 2,
|
||||
(*con_inputBoxColor)->current.vector);
|
||||
|
||||
// Draw header line "Search results for: xyz"
|
||||
auto currentY = y + lineHeight;
|
||||
Game::R_AddCmdDrawText(stringSearchStartWith.GetString(), std::numeric_limits<int>::max(), font, x, currentY, textXScale, textYScale, 0.0, TEXT_COLOR, 0);
|
||||
Game::R_AddCmdDrawText(context.stringSearchStartWith.GetString(), std::numeric_limits<int>::max(), font, x, currentY, textXScale, textYScale, 0.0, TEXT_COLOR, 0);
|
||||
currentY += lineHeight;
|
||||
|
||||
// Draw search results
|
||||
const auto selectedIndex = context.selectedOffset - context.resultOffset;
|
||||
for(auto resultIndex = 0u; resultIndex < context.resultCount; resultIndex++)
|
||||
{
|
||||
@ -353,6 +439,7 @@ namespace Components
|
||||
currentY += lineHeight;
|
||||
}
|
||||
|
||||
// Draw extra hint if enabled
|
||||
if(hintEnabled)
|
||||
{
|
||||
Game::R_AddCmdDrawText(stringHintAutoComplete.GetString(), std::numeric_limits<int>::max(), font, x, currentY, textXScale, textYScale, 0.0, HINT_COLOR, 0);
|
||||
@ -361,12 +448,15 @@ namespace Components
|
||||
}
|
||||
}
|
||||
|
||||
void TextRenderer::DrawAutocomplete(const FontIconAutocompleteContext& context, const float x, const float y, Game::Font_s* font, const float textXScale, const float textYScale)
|
||||
void TextRenderer::DrawAutocomplete(const FontIconAutocompleteInstance instance, const float x, const float y, Game::Font_s* font, const float textXScale, const float textYScale)
|
||||
{
|
||||
assert(instance < FONT_ICON_ACI_COUNT);
|
||||
const auto& context = autocompleteContextArray[instance];
|
||||
|
||||
if (context.inModifiers)
|
||||
DrawAutocompleteModifiers(context, x, y, font, textXScale, textYScale);
|
||||
DrawAutocompleteModifiers(instance, x, y, font, textXScale, textYScale);
|
||||
else
|
||||
DrawAutocompleteResults(context, x, y, font, textXScale, textYScale);
|
||||
DrawAutocompleteResults(instance, x, y, font, textXScale, textYScale);
|
||||
}
|
||||
|
||||
void TextRenderer::Con_DrawInput_Hk(const int localClientNum)
|
||||
@ -386,7 +476,7 @@ namespace Components
|
||||
{
|
||||
const auto x = Game::conDrawInputGlob->leftX;
|
||||
const auto y = Game::con_screenMin[1] + 6.0f + static_cast<float>(2 * Game::R_TextHeight(Game::cls->consoleFont));
|
||||
DrawAutocomplete(autocompleteContext, x, y, Game::cls->consoleFont, 1.0f, 1.0f);
|
||||
DrawAutocomplete(FONT_ICON_ACI_CONSOLE, x, y, Game::cls->consoleFont, 1.0f, 1.0f);
|
||||
}
|
||||
}
|
||||
|
||||
@ -415,7 +505,7 @@ namespace Components
|
||||
UpdateAutocompleteContext(autocompleteContext, edit, font, ww);
|
||||
if (autocompleteContext.autocompleteActive)
|
||||
{
|
||||
DrawAutocomplete(autocompleteContext, std::floor(xx), std::floor(yy), font, ww, hh);
|
||||
DrawAutocomplete(FONT_ICON_ACI_CHAT, std::floor(xx), std::floor(yy), font, ww, hh);
|
||||
}
|
||||
}
|
||||
|
||||
@ -1442,23 +1532,11 @@ namespace Components
|
||||
|
||||
void TextRenderer::InitFontIconStrings()
|
||||
{
|
||||
stringSearchStartWith.Load("FONT_ICON_SEARCH_START_WITH");
|
||||
|
||||
stringHintAutoComplete.Load("FONT_ICON_HINT_AUTO_COMPLETE");
|
||||
stringHintAutoComplete.Format("TAB");
|
||||
|
||||
stringHintModifier.Load("FONT_ICON_HINT_MODIFIER");
|
||||
stringHintModifier.Format(Utils::String::VA("%c", FONT_ICON_MODIFIER_SEPARATOR_CHARACTER));
|
||||
|
||||
stringListHeader.Load("FONT_ICON_MODIFIER_LIST_HEADER");
|
||||
|
||||
stringListFlipHorizontal.Load("FONT_ICON_MODIFIER_LIST_FLIP_HORIZONTAL");
|
||||
stringListHeader.Cache();
|
||||
stringListFlipHorizontal.Format(Utils::String::VA("%c", FONT_ICON_MODIFIER_FLIP_HORIZONTALLY));
|
||||
|
||||
stringListFlipVertical.Load("FONT_ICON_MODIFIER_LIST_FLIP_VERTICAL");
|
||||
stringListFlipVertical.Format(Utils::String::VA("%c", FONT_ICON_MODIFIER_FLIP_VERTICALLY));
|
||||
|
||||
stringListBig.Load("FONT_ICON_MODIFIER_LIST_BIG");
|
||||
stringListBig.Format(Utils::String::VA("%c", FONT_ICON_MODIFIER_BIG));
|
||||
}
|
||||
|
||||
|
@ -42,108 +42,16 @@ namespace Components
|
||||
|
||||
class TextRenderer : public Component
|
||||
{
|
||||
public:
|
||||
enum FontIconAutocompleteInstance : unsigned
|
||||
{
|
||||
FONT_ICON_ACI_CONSOLE,
|
||||
FONT_ICON_ACI_CHAT,
|
||||
static constexpr auto STRING_BUFFER_SIZE_BIG = 1024;
|
||||
static constexpr auto STRING_BUFFER_SIZE_SMALL = 128;
|
||||
|
||||
FONT_ICON_ACI_COUNT
|
||||
};
|
||||
|
||||
private:
|
||||
struct FontIconTableEntry
|
||||
{
|
||||
std::string iconName;
|
||||
std::string materialName;
|
||||
Game::Material* material;
|
||||
};
|
||||
|
||||
struct HsvColor
|
||||
{
|
||||
unsigned char h;
|
||||
unsigned char s;
|
||||
unsigned char v;
|
||||
};
|
||||
|
||||
class FontIconAutocompleteResult
|
||||
{
|
||||
public:
|
||||
std::string fontIconName;
|
||||
std::string materialName;
|
||||
};
|
||||
|
||||
class FontIconAutocompleteContext
|
||||
{
|
||||
public:
|
||||
static constexpr auto MAX_RESULTS = 10;
|
||||
|
||||
bool autocompleteActive;
|
||||
bool inModifiers;
|
||||
bool userClosed;
|
||||
unsigned int lastHash;
|
||||
std::string lastQuery;
|
||||
FontIconAutocompleteResult results[MAX_RESULTS];
|
||||
size_t resultCount;
|
||||
bool hasMoreResults;
|
||||
size_t resultOffset;
|
||||
size_t lastResultOffset;
|
||||
size_t selectedOffset;
|
||||
float maxFontIconWidth;
|
||||
float maxMaterialNameWidth;
|
||||
};
|
||||
|
||||
template<size_t S>
|
||||
class FormattedStringBuffer
|
||||
{
|
||||
public:
|
||||
FormattedStringBuffer()
|
||||
: formattingString(nullptr),
|
||||
stringBuffer{0},
|
||||
stringWidth(-1)
|
||||
{
|
||||
}
|
||||
|
||||
void Load(const char* reference)
|
||||
{
|
||||
formattingString = Game::UI_SafeTranslateString(reference);
|
||||
}
|
||||
|
||||
const char* Format(const char* value)
|
||||
{
|
||||
if (formattingString == nullptr)
|
||||
return stringBuffer;
|
||||
|
||||
Game::ConversionArguments conversionArguments{};
|
||||
conversionArguments.args[conversionArguments.argCount++] = value;
|
||||
Game::UI_ReplaceConversions(formattingString, &conversionArguments, stringBuffer, sizeof(stringBuffer));
|
||||
|
||||
stringWidth = -1;
|
||||
return stringBuffer;
|
||||
}
|
||||
|
||||
const char* GetString() const
|
||||
{
|
||||
if(stringBuffer[0] != '\0')
|
||||
return stringBuffer;
|
||||
if(formattingString)
|
||||
return formattingString;
|
||||
return stringBuffer;
|
||||
}
|
||||
|
||||
int GetWidth(Game::Font_s* font)
|
||||
{
|
||||
if (stringWidth < 0)
|
||||
stringWidth = Game::R_TextWidth(GetString(), std::numeric_limits<int>::max(), font);
|
||||
|
||||
return stringWidth;
|
||||
}
|
||||
|
||||
private:
|
||||
const char* formattingString;
|
||||
char stringBuffer[S];
|
||||
int stringWidth;
|
||||
};
|
||||
static constexpr auto REFERENCE_SEARCH_START_WITH = "FONT_ICON_SEARCH_START_WITH";
|
||||
static constexpr auto REFERENCE_HINT_AUTO_COMPLETE = "FONT_ICON_HINT_AUTO_COMPLETE";
|
||||
static constexpr auto REFERENCE_HINT_MODIFIER = "FONT_ICON_HINT_MODIFIER";
|
||||
static constexpr auto REFERENCE_MODIFIER_LIST_HEADER = "FONT_ICON_MODIFIER_LIST_HEADER";
|
||||
static constexpr auto REFERENCE_MODIFIER_LIST_FLIP_HORIZONTAL = "FONT_ICON_MODIFIER_LIST_FLIP_HORIZONTAL";
|
||||
static constexpr auto REFERENCE_MODIFIER_LIST_FLIP_VERTICAL = "FONT_ICON_MODIFIER_LIST_FLIP_VERTICAL";
|
||||
static constexpr auto REFERENCE_MODIFIER_LIST_BIG = "FONT_ICON_MODIFIER_LIST_BIG";
|
||||
|
||||
static constexpr unsigned MY_ALTCOLOR_TWO = 0x0DCE6FFE6;
|
||||
static constexpr unsigned COLOR_MAP_HASH = 0xA0AB1041;
|
||||
@ -180,6 +88,93 @@ namespace Components
|
||||
1.0f
|
||||
};
|
||||
|
||||
public:
|
||||
static constexpr char FONT_ICON_SEPARATOR_CHARACTER = ':';
|
||||
static constexpr char FONT_ICON_MODIFIER_SEPARATOR_CHARACTER = '+';
|
||||
static constexpr char FONT_ICON_MODIFIER_FLIP_HORIZONTALLY = 'h';
|
||||
static constexpr char FONT_ICON_MODIFIER_FLIP_VERTICALLY = 'v';
|
||||
static constexpr char FONT_ICON_MODIFIER_BIG = 'b';
|
||||
|
||||
static constexpr char COLOR_FIRST_CHAR = '0';
|
||||
static constexpr char COLOR_LAST_CHAR = CharForColorIndex(TEXT_COLOR_COUNT - 1);
|
||||
|
||||
enum FontIconAutocompleteInstance : unsigned
|
||||
{
|
||||
FONT_ICON_ACI_CONSOLE,
|
||||
FONT_ICON_ACI_CHAT,
|
||||
|
||||
FONT_ICON_ACI_COUNT
|
||||
};
|
||||
|
||||
struct FontIconInfo
|
||||
{
|
||||
Game::Material* material;
|
||||
bool flipHorizontal;
|
||||
bool flipVertical;
|
||||
bool big;
|
||||
};
|
||||
|
||||
private:
|
||||
struct FontIconTableEntry
|
||||
{
|
||||
std::string iconName;
|
||||
std::string materialName;
|
||||
Game::Material* material;
|
||||
};
|
||||
|
||||
struct HsvColor
|
||||
{
|
||||
unsigned char h;
|
||||
unsigned char s;
|
||||
unsigned char v;
|
||||
};
|
||||
|
||||
class FontIconAutocompleteResult
|
||||
{
|
||||
public:
|
||||
std::string fontIconName;
|
||||
std::string materialName;
|
||||
};
|
||||
|
||||
class BufferedLocalizedString
|
||||
{
|
||||
public:
|
||||
BufferedLocalizedString(const char* reference, size_t bufferSize);
|
||||
void Cache();
|
||||
const char* Format(const char* value);
|
||||
const char* GetString() const;
|
||||
int GetWidth(FontIconAutocompleteInstance autocompleteInstance, Game::Font_s* font);
|
||||
|
||||
private:
|
||||
const char* stringReference;
|
||||
std::unique_ptr<char[]> stringBuffer;
|
||||
size_t stringBufferSize;
|
||||
int stringWidth[FONT_ICON_ACI_COUNT];
|
||||
};
|
||||
|
||||
class FontIconAutocompleteContext
|
||||
{
|
||||
public:
|
||||
static constexpr auto MAX_RESULTS = 10;
|
||||
|
||||
bool autocompleteActive;
|
||||
bool inModifiers;
|
||||
bool userClosed;
|
||||
unsigned int lastHash;
|
||||
std::string lastQuery;
|
||||
FontIconAutocompleteResult results[MAX_RESULTS];
|
||||
size_t resultCount;
|
||||
bool hasMoreResults;
|
||||
size_t resultOffset;
|
||||
size_t lastResultOffset;
|
||||
size_t selectedOffset;
|
||||
float maxFontIconWidth;
|
||||
float maxMaterialNameWidth;
|
||||
BufferedLocalizedString stringSearchStartWith;
|
||||
|
||||
FontIconAutocompleteContext();
|
||||
};
|
||||
|
||||
static unsigned colorTableDefault[TEXT_COLOR_COUNT];
|
||||
static unsigned colorTableNew[TEXT_COLOR_COUNT];
|
||||
static unsigned(*currentColorTable)[TEXT_COLOR_COUNT];
|
||||
@ -187,16 +182,12 @@ namespace Components
|
||||
static std::map<std::string, FontIconTableEntry> fontIconLookup;
|
||||
static std::vector<FontIconTableEntry> fontIconList;
|
||||
|
||||
static constexpr auto STRING_BUFFER_SIZE_BIG = 1024;
|
||||
static constexpr auto STRING_BUFFER_SIZE_SMALL = 128;
|
||||
static constexpr auto STRING_BUFFER_SIZE_NONE = 1;
|
||||
static FormattedStringBuffer<STRING_BUFFER_SIZE_BIG> stringSearchStartWith;
|
||||
static FormattedStringBuffer<STRING_BUFFER_SIZE_SMALL> stringHintAutoComplete;
|
||||
static FormattedStringBuffer<STRING_BUFFER_SIZE_SMALL> stringHintModifier;
|
||||
static FormattedStringBuffer<STRING_BUFFER_SIZE_NONE> stringListHeader;
|
||||
static FormattedStringBuffer<STRING_BUFFER_SIZE_SMALL> stringListFlipHorizontal;
|
||||
static FormattedStringBuffer<STRING_BUFFER_SIZE_SMALL> stringListFlipVertical;
|
||||
static FormattedStringBuffer<STRING_BUFFER_SIZE_SMALL> stringListBig;
|
||||
static BufferedLocalizedString stringHintAutoComplete;
|
||||
static BufferedLocalizedString stringHintModifier;
|
||||
static BufferedLocalizedString stringListHeader;
|
||||
static BufferedLocalizedString stringListFlipHorizontal;
|
||||
static BufferedLocalizedString stringListFlipVertical;
|
||||
static BufferedLocalizedString stringListBig;
|
||||
|
||||
static Dvar::Var cg_newColors;
|
||||
static Dvar::Var cg_fontIconAutocomplete;
|
||||
@ -208,23 +199,6 @@ namespace Components
|
||||
static Game::dvar_t** con_inputBoxColor;
|
||||
|
||||
public:
|
||||
static constexpr char FONT_ICON_SEPARATOR_CHARACTER = ':';
|
||||
static constexpr char FONT_ICON_MODIFIER_SEPARATOR_CHARACTER = '+';
|
||||
static constexpr char FONT_ICON_MODIFIER_FLIP_HORIZONTALLY = 'h';
|
||||
static constexpr char FONT_ICON_MODIFIER_FLIP_VERTICALLY = 'v';
|
||||
static constexpr char FONT_ICON_MODIFIER_BIG = 'b';
|
||||
|
||||
static constexpr char COLOR_FIRST_CHAR = '0';
|
||||
static constexpr char COLOR_LAST_CHAR = CharForColorIndex(TEXT_COLOR_COUNT - 1);
|
||||
|
||||
struct FontIconInfo
|
||||
{
|
||||
Game::Material* material;
|
||||
bool flipHorizontal;
|
||||
bool flipVertical;
|
||||
bool big;
|
||||
};
|
||||
|
||||
static void DrawText2D(const char* text, float x, float y, Game::Font_s* font, float xScale, float yScale, float sinAngle, float cosAngle, Game::GfxColor color, int maxLength, int renderFlags, int cursorPos, char cursorLetter, float padding, Game::GfxColor glowForcedColor, int fxBirthTime, int fxLetterTime, int fxDecayStartTime, int fxDecayDuration, Game::Material* fxMaterial, Game::Material* fxMaterialGlow);
|
||||
static int R_TextWidth_Hk(const char* text, int maxChars, Game::Font_s* font);
|
||||
static unsigned int ColorIndex(char index);
|
||||
@ -247,9 +221,9 @@ namespace Components
|
||||
static unsigned HsvToRgb(HsvColor hsv);
|
||||
|
||||
static void DrawAutocompleteBox(const FontIconAutocompleteContext& context, float x, float y, float w, float h, const float* color);
|
||||
static void DrawAutocompleteModifiers(const FontIconAutocompleteContext& context, float x, float y, Game::Font_s* font, float textXScale, float textYScale);
|
||||
static void DrawAutocompleteResults(const FontIconAutocompleteContext& context, float x, float y, Game::Font_s* font, float textXScale, float textYScale);
|
||||
static void DrawAutocomplete(const FontIconAutocompleteContext& context, float x, float y, Game::Font_s* font, float textXScale, float textYScale);
|
||||
static void DrawAutocompleteModifiers(FontIconAutocompleteInstance instance, float x, float y, Game::Font_s* font, float textXScale, float textYScale);
|
||||
static void DrawAutocompleteResults(FontIconAutocompleteInstance instance, float x, float y, Game::Font_s* font, float textXScale, float textYScale);
|
||||
static void DrawAutocomplete(FontIconAutocompleteInstance instance, float x, float y, Game::Font_s* font, float textXScale, float textYScale);
|
||||
static void UpdateAutocompleteContextResults(FontIconAutocompleteContext& context, Game::Font_s* font, float textXScale);
|
||||
static void UpdateAutocompleteContext(FontIconAutocompleteContext& context, const Game::field_t* edit, Game::Font_s* font, const float textXScale);
|
||||
static void Field_Draw_Say(int localClientNum, Game::field_t* edit, int x, int y, int horzAlign, int vertAlign);
|
||||
|
Loading…
Reference in New Issue
Block a user